public FieldDefinition GetFieldDefinition(uint hash, IEnumerable <FileFormats.BinaryObject> chain)
        {
            if (this._FieldLookup.ContainsKey(hash) == true)
            {
                return(this._FieldLookup[hash]);
            }

            foreach (var friend in this.Friends)
            {
                if (string.IsNullOrEmpty(friend.ConditionField) == false)
                {
                    if (chain == null)
                    {
                        throw new NotSupportedException();
                    }

                    byte[] fieldData;
                    var    hasFieldData = GetFieldData(friend.ConditionField, chain, out fieldData);
                    if (hasFieldData == false)
                    {
                        continue;
                    }

                    var conditionData = FieldTypeSerializers.Serialize(friend.ConditionType, friend.ConditionValue);
                    if (fieldData.SequenceEqual(conditionData) == false)
                    {
                        continue;
                    }
                }

                var def = friend.Class.GetFieldDefinition(hash, chain);
                if (def != null)
                {
                    return(def);
                }
            }

            return(null);
        }
示例#2
0
        private void ReadNode(BinaryObject node,
                              IEnumerable <BinaryObject> parentChain,
                              ClassDefinition objectDef,
                              string basePath,
                              XPathNavigator nav)
        {
            var chain = parentChain.Concat(new[] { node });

            string className;
            uint   classNameHash;

            LoadNameAndHash(nav, out className, out classNameHash);

            if (objectDef != null &&
                objectDef.ClassFieldHash.HasValue == true)
            {
                var hash = GetClassDefinitionByField(objectDef.ClassFieldName, objectDef.ClassFieldHash, nav);
                if (hash.HasValue == false)
                {
                    throw new InvalidOperationException();
                }

                objectDef = this._InfoManager.GetClassDefinition(hash.Value);
            }

            node.NameHash = classNameHash;

            var fields = nav.Select("field");

            while (fields.MoveNext() == true)
            {
                if (fields.Current == null)
                {
                    throw new InvalidOperationException();
                }

                string fieldName;
                uint   fieldNameHash;

                LoadNameAndHash(fields.Current, out fieldName, out fieldNameHash);

                FieldType fieldType;
                var       fieldTypeName = fields.Current.GetAttribute("type", "");
                if (Enum.TryParse(fieldTypeName, true, out fieldType) == false)
                {
                    throw new InvalidOperationException();
                }

                var arrayFieldType     = FieldType.Invalid;
                var arrayFieldTypeName = fields.Current.GetAttribute("array_type", "");
                if (string.IsNullOrEmpty(arrayFieldTypeName) == false)
                {
                    if (Enum.TryParse(arrayFieldTypeName, true, out arrayFieldType) == false)
                    {
                        throw new InvalidOperationException();
                    }
                }

                var fieldDef = objectDef != null?objectDef.GetFieldDefinition(fieldNameHash, chain) : null;

                var data = FieldTypeSerializers.Serialize(fieldDef, fieldType, arrayFieldType, fields.Current);
                node.Fields.Add(fieldNameHash, data);
            }

            var children = nav.Select("object");

            while (children.MoveNext() == true)
            {
                var child = new BinaryObject();
                LoadChildNode(child, chain, objectDef, basePath, children.Current);
                node.Children.Add(child);
            }
        }