Пример #1
0
bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
    const QString &fname, QString currentPath, bool ignoreErrors)
{
    Q_ASSERT(m_errorDevice);
    const QChar slash = QLatin1Char('/');
    if (!currentPath.isEmpty() && !currentPath.endsWith(slash))
        currentPath += slash;

    QDomDocument document;
    {
        QString errorMsg;
        int errorLine = 0;
        int errorColumn = 0;
        if (!document.setContent(inputDevice, &errorMsg, &errorLine, &errorColumn)) {
            if (ignoreErrors)
                return true;
            const QString msg = QString::fromUtf8("RCC Parse Error: '%1' Line: %2 Column: %3 [%4]\n").arg(fname).arg(errorLine).arg(errorColumn).arg(errorMsg);
            m_errorDevice->write(msg.toUtf8());
            return false;
        }
    }

    QDomElement domRoot = document.firstChildElement(m_strings.TAG_RCC).toElement();
    if (!domRoot.isNull() && domRoot.tagName() == m_strings.TAG_RCC) {
        for (QDomNode node = domRoot.firstChild(); !node.isNull(); node = node.nextSibling()) {
            if (!node.isElement())
                continue;

            QDomElement child = node.toElement();
            if (!child.isNull() && child.tagName() == m_strings.TAG_RESOURCE) {
                QLocale::Language language = QLocale::c().language();
                QLocale::Country country = QLocale::c().country();

                if (child.hasAttribute(m_strings.ATTRIBUTE_LANG)) {
                    QString attribute = child.attribute(m_strings.ATTRIBUTE_LANG);
                    QLocale lang = QLocale(attribute);
                    language = lang.language();
                    if (2 == attribute.length()) {
                        // Language only
                        country = QLocale::AnyCountry;
                    } else {
                        country = lang.country();
                    }
                }

                QString prefix;
                if (child.hasAttribute(m_strings.ATTRIBUTE_PREFIX))
                    prefix = child.attribute(m_strings.ATTRIBUTE_PREFIX);
                if (!prefix.startsWith(slash))
                    prefix.prepend(slash);
                if (!prefix.endsWith(slash))
                    prefix += slash;

                for (QDomNode res = child.firstChild(); !res.isNull(); res = res.nextSibling()) {
                    if (res.isElement() && res.toElement().tagName() == m_strings.TAG_FILE) {

                        QString fileName(res.firstChild().toText().data());
                        if (fileName.isEmpty()) {
                            const QString msg = QString::fromUtf8("RCC: Warning: Null node in XML of '%1'\n").arg(fname);
                            m_errorDevice->write(msg.toUtf8());
                        }
                        QString alias;
                        if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_ALIAS))
                            alias = res.toElement().attribute(m_strings.ATTRIBUTE_ALIAS);
                        else
                            alias = fileName;

                        int compressLevel = m_compressLevel;
                        if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_COMPRESS))
                            compressLevel = res.toElement().attribute(m_strings.ATTRIBUTE_COMPRESS).toInt();
                        int compressThreshold = m_compressThreshold;
                        if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_THRESHOLD))
                            compressThreshold = res.toElement().attribute(m_strings.ATTRIBUTE_THRESHOLD).toInt();

                        // Special case for -no-compress. Overrides all other settings.
                        if (m_compressLevel == -2)
                            compressLevel = 0;

                        alias = QDir::cleanPath(alias);
                        while (alias.startsWith(QLatin1String("../")))
                            alias.remove(0, 3);
                        alias = QDir::cleanPath(m_resourceRoot) + prefix + alias;

                        QString absFileName = fileName;
                        if (QDir::isRelativePath(absFileName))
                            absFileName.prepend(currentPath);
                        QFileInfo file(absFileName);
                        if (!file.exists()) {
                            m_failedResources.push_back(absFileName);
                            const QString msg = QString::fromUtf8("RCC: Error in '%1': Cannot find file '%2'\n").arg(fname).arg(fileName);
                            m_errorDevice->write(msg.toUtf8());
                            if (ignoreErrors)
                                continue;
                            else
                                return false;
                        } else if (file.isFile()) {
                            const bool arc =
                                addFile(alias,
                                        RCCFileInfo(alias.section(slash, -1),
                                                    file,
                                                    language,
                                                    country,
                                                    RCCFileInfo::NoFlags,
                                                    compressLevel,
                                                    compressThreshold)
                                        );
                            if (!arc)
                                m_failedResources.push_back(absFileName);
                        } else {
                            QDir dir;
                            if (file.isDir()) {
                                dir.setPath(file.filePath());
                            } else {
                                dir.setPath(file.path());
                                dir.setNameFilters(QStringList(file.fileName()));
                                if (alias.endsWith(file.fileName()))
                                    alias = alias.left(alias.length()-file.fileName().length());
                            }
                            if (!alias.endsWith(slash))
                                alias += slash;
                            QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories);
                            while (it.hasNext()) {
                                it.next();
                                QFileInfo child(it.fileInfo());
                                if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) {
                                    const bool arc =
                                        addFile(alias + child.fileName(),
                                                RCCFileInfo(child.fileName(),
                                                            child,
                                                            language,
                                                            country,
                                                            RCCFileInfo::NoFlags,
                                                            compressLevel,
                                                            compressThreshold)
                                                );
                                    if (!arc)
                                        m_failedResources.push_back(child.fileName());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (m_root == 0) {
        const QString msg = QString::fromUtf8("RCC: Warning: No resources in '%1'.\n").arg(fname);
        m_errorDevice->write(msg.toUtf8());
        if (!ignoreErrors && m_format == Binary) {
            // create dummy entry, otherwise loading qith QResource will crash
            m_root = new RCCFileInfo(QString(), QFileInfo(),
                    QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory);
        }
    }

    return true;
}
Пример #2
0
    bool LegacyAvatarSerializer::ReadAvatarAppearance(RexLogic::EC_AvatarAppearance& dest, const QDomDocument& source, bool read_mesh)
    {
        PROFILE(Avatar_ReadAvatarAppearance);
        
        QDomElement avatar = source.firstChildElement("avatar");
        if (avatar.isNull())
        {
            RexLogicModule::LogError("No avatar element");
            return false;
        }

        // Get mesh & skeleton
        if (read_mesh)
        {
            dest.Clear();
            QDomElement base_elem = avatar.firstChildElement("base");
            if (!base_elem.isNull())
            {
                AvatarAsset mesh;
                mesh.name_ = base_elem.attribute("mesh").toStdString();
                dest.SetMesh(mesh);
            }
            // Get skeleton
            QDomElement skeleton_elem = avatar.firstChildElement("skeleton");
            if (!skeleton_elem.isNull())
            {
                AvatarAsset skeleton;
                skeleton.name_ = skeleton_elem.attribute("name").toStdString();
                dest.SetSkeleton(skeleton);
            }        
        }
               
        // Get materials, should be 2 of them
        uint mat_index = 0;
        QDomElement material_elem = avatar.firstChildElement("material");
        AvatarMaterialVector materials;
        while (!material_elem.isNull())
        {
            AvatarMaterial material;
            material.asset_.name_ = material_elem.attribute("name").toStdString();
            
            // Check for texture override
            QDomElement texture_elem;
            switch (mat_index)
            {
            case 0:
                texture_elem = avatar.firstChildElement("texture_body");
                break;
            case 1:
                texture_elem = avatar.firstChildElement("texture_face");
                break;
            }
            
            if (!texture_elem.isNull())
            {
                std::string tex_name = texture_elem.attribute("name").toStdString();
                if (!tex_name.empty())
                {
                    AvatarAsset texture;
                    texture.name_ = tex_name;
                    material.textures_.push_back(texture);
                }
            }
            
            materials.push_back(material);
            
            material_elem = material_elem.nextSiblingElement("material");
            ++mat_index;
        }
        dest.SetMaterials(materials);
        
        // Get main transform
        QDomElement transform_elem = avatar.firstChildElement("transformation");
        if (!transform_elem.isNull())
        {
            Transform trans;
            trans.position_ = ParseVector3(transform_elem.attribute("position").toStdString());
            trans.orientation_ = ParseQuaternion(transform_elem.attribute("rotation").toStdString());
            trans.scale_ = ParseVector3(transform_elem.attribute("scale").toStdString());
            dest.SetTransform(trans);
        }
        
        // Get attachments
        QDomElement attachment_elem = avatar.firstChildElement("attachment");
        AvatarAttachmentVector attachments;
        while (!attachment_elem.isNull())
        {
            ReadAttachment(attachments, attachment_elem);
            attachment_elem = attachment_elem.nextSiblingElement("attachment");
        }
        dest.SetAttachments(attachments);
        
        // Get bone modifiers
        QDomElement bonemodifier_elem = avatar.firstChildElement("dynamic_animation");
        BoneModifierSetVector bonemodifiers;
        while (!bonemodifier_elem.isNull())
        {
            ReadBoneModifierSet(bonemodifiers, bonemodifier_elem);
            bonemodifier_elem = bonemodifier_elem.nextSiblingElement("dynamic_animation");
        }        
        // Get bone modifier parameters
        QDomElement bonemodifierparam_elem = avatar.firstChildElement("dynamic_animation_parameter");
        while (!bonemodifierparam_elem.isNull())
        {
            ReadBoneModifierParameter(bonemodifiers, bonemodifierparam_elem);
            bonemodifierparam_elem = bonemodifierparam_elem.nextSiblingElement("dynamic_animation_parameter");
        }
        dest.SetBoneModifiers(bonemodifiers);
        
        // Get morph modifiers
        QDomElement morphmodifier_elem = avatar.firstChildElement("morph_modifier");
        MorphModifierVector morphmodifiers;
        while (!morphmodifier_elem.isNull())
        {
            ReadMorphModifier(morphmodifiers, morphmodifier_elem);
            morphmodifier_elem = morphmodifier_elem.nextSiblingElement("morph_modifier");
        }
        dest.SetMorphModifiers(morphmodifiers);
        
        // Get master modifiers
        QDomElement mastermodifier_elem = avatar.firstChildElement("master_modifier");
        MasterModifierVector mastermodifiers;
        while (!mastermodifier_elem.isNull())
        {
            ReadMasterModifier(mastermodifiers, mastermodifier_elem);
            mastermodifier_elem = mastermodifier_elem.nextSiblingElement("master_modifier");
        }              
        dest.SetMasterModifiers(mastermodifiers);
              
        // Get animations
        QDomElement animation_elem = avatar.firstChildElement("animation");
        AnimationDefinitionMap animations;
        while (!animation_elem.isNull())
        {
            ReadAnimationDefinition(animations, animation_elem);
            animation_elem = animation_elem.nextSiblingElement("animation");
        }
        dest.SetAnimations(animations);
        
        // Get properties
        QDomElement property_elem = avatar.firstChildElement("property");
        while (!property_elem.isNull())
        {
            std::string name = property_elem.attribute("name").toStdString();
            std::string value = property_elem.attribute("value").toStdString();
            if ((!name.empty()) && (!value.empty()))
                dest.SetProperty(name, value);
            
            property_elem = property_elem.nextSiblingElement("property");
        }
        
        // Get assetmap (optional, inventory based avatars only)
        QDomElement assetmap_elem = avatar.firstChildElement("assetmap");
        if (!assetmap_elem.isNull())
        {
            AvatarAssetMap new_map;
            QDomElement asset_elem = assetmap_elem.firstChildElement("asset");
            while (!asset_elem.isNull())
            {
                std::string name = asset_elem.attribute("name").toStdString();
                std::string id = asset_elem.attribute("id").toStdString();
                new_map[name] = id;
                asset_elem = asset_elem.nextSiblingElement("asset");
            }
            dest.SetAssetMap(new_map);
        }                 
        
        return true;
    }
Пример #3
0
Core::IDocument::OpenResult ResourceFile::load()
{
    m_error_message.clear();

    if (m_file_name.isEmpty()) {
        m_error_message = tr("The file name is empty.");
        return Core::IDocument::OpenResult::ReadError;
    }

    QFile file(m_file_name);
    if (!file.open(QIODevice::ReadOnly)) {
        m_error_message = file.errorString();
        return Core::IDocument::OpenResult::ReadError;
    }
    QByteArray data = file.readAll();
    // Detect line ending style
    m_textFileFormat = Utils::TextFileFormat::detect(data);
    // we always write UTF-8 when saving
    m_textFileFormat.codec = QTextCodec::codecForName("UTF-8");
    file.close();

    clearPrefixList();

    QDomDocument doc;

    QString error_msg;
    int error_line, error_col;
    if (!doc.setContent(data, &error_msg, &error_line, &error_col)) {
        m_error_message = tr("XML error on line %1, col %2: %3")
                    .arg(error_line).arg(error_col).arg(error_msg);
        return Core::IDocument::OpenResult::CannotHandle;
    }

    QDomElement root = doc.firstChildElement(QLatin1String("RCC"));
    if (root.isNull()) {
        m_error_message = tr("The <RCC> root element is missing.");
        return Core::IDocument::OpenResult::CannotHandle;
    }

    QDomElement relt = root.firstChildElement(QLatin1String("qresource"));
    for (; !relt.isNull(); relt = relt.nextSiblingElement(QLatin1String("qresource"))) {

        QString prefix = fixPrefix(relt.attribute(QLatin1String("prefix")));
        if (prefix.isEmpty())
            prefix = QString(QLatin1Char('/'));
        const QString language = relt.attribute(QLatin1String("lang"));

        const int idx = indexOfPrefix(prefix, language);
        Prefix * p = 0;
        if (idx == -1) {
            p = new Prefix(prefix, language);
            m_prefix_list.append(p);
        } else {
            p = m_prefix_list[idx];
        }
        Q_ASSERT(p);

        QDomElement felt = relt.firstChildElement(QLatin1String("file"));
        for (; !felt.isNull(); felt = felt.nextSiblingElement(QLatin1String("file"))) {
            const QString fileName = absolutePath(felt.text());
            const QString alias = felt.attribute(QLatin1String("alias"));
            File * const file = new File(p, fileName, alias);
            file->compress = felt.attribute(QLatin1String("compress"));
            file->threshold = felt.attribute(QLatin1String("threshold"));
            p->file_list.append(file);
        }
    }

    return Core::IDocument::OpenResult::Success;
}