Esempio n. 1
0
        private Dictionary <uint, dynamic> AlreadyReadNodes = new Dictionary <uint, dynamic>(); //Offset in the file, reference to node
        private dynamic ReadNode(BinaryDataReader reader, ByamlNodeType nodeType = 0)
        {
            // Read the node type if it has not been provided yet.
            bool nodeTypeGiven = nodeType != 0;

            if (!nodeTypeGiven)
            {
                nodeType = (ByamlNodeType)reader.ReadByte();
            }
            if (nodeType >= ByamlNodeType.Array && nodeType <= ByamlNodeType.PathArray)
            {
                // Get the length of arrays.
                long?oldPos = null;
                uint offset = 0;
                if (nodeTypeGiven)
                {
                    // If the node type was given, the array value is read from an offset.
                    offset = reader.ReadUInt32();
                    if (AlreadyReadNodes.ContainsKey(offset))
                    {
                        return(AlreadyReadNodes[offset]);
                    }
                    oldPos = reader.Position;
                    reader.Seek(offset, SeekOrigin.Begin);
                }
                else
                {
                    reader.Seek(-1);
                }
                dynamic value  = null;
                int     length = (int)Get3LsbBytes(reader.ReadUInt32());
                switch (nodeType)
                {
                case ByamlNodeType.Array:
                    value = ReadArrayNode(reader, length, offset);
                    break;

                case ByamlNodeType.Dictionary:
                    value = ReadDictionaryNode(reader, length, offset);
                    break;

                case ByamlNodeType.StringArray:
                    value = ReadStringArrayNode(reader, length);
                    break;

                case ByamlNodeType.PathArray:
                    value = ReadPathArrayNode(reader, length);
                    break;

                default:
                    throw new ByamlException($"Unknown node type '{nodeType}'.");
                }
                // Seek back to the previous position if this was a value positioned at an offset.
                if (oldPos.HasValue)
                {
                    reader.Seek(oldPos.Value, SeekOrigin.Begin);
                }
                return(value);
            }
            else
            {
                // Read the following UInt32 which is representing the value directly.
                switch (nodeType)
                {
                case ByamlNodeType.StringIndex:
                    return(_stringArray[reader.ReadInt32()]);

                case ByamlNodeType.PathIndex:
                    return(_pathArray[reader.ReadInt32()]);

                case ByamlNodeType.Boolean:
                    return(reader.ReadInt32() != 0);

                case ByamlNodeType.Integer:
                    return(reader.ReadInt32());

                case ByamlNodeType.Float:
                    return(reader.ReadSingle());

                case ByamlNodeType.Null:
                    reader.Seek(0x4);
                    return(null);

                default:
                    throw new ByamlException($"Unknown node type '{nodeType}'.");
                }
            }
        }
Esempio n. 2
0
        private void WriteDictionary(BinaryDataWriter writer, object obj)
        {
            // Create a string-object dictionary out of the members.
            Dictionary <string, object> dictionary = new Dictionary <string, object>();
            // Add the custom members if any have been created when collecting node contents previously.
            Dictionary <string, object> customMembers;

            if (_customMembers.TryGetValue(obj, out customMembers))
            {
                foreach (KeyValuePair <string, object> customMember in customMembers)
                {
                    dictionary.Add(customMember.Key, customMember.Value);
                }
            }
            // Add the ByamlMemberAttribute decorated members.
            ByamlObjectInfo objectInfo = _byamlObjectInfos[obj.GetType()];

            foreach (KeyValuePair <string, ByamlMemberInfo> member in objectInfo.Members)
            {
                object value = member.Value.GetValue(obj);
                if (value != null || !member.Value.Optional)
                {
                    dictionary.Add(member.Key, value);
                }
            }
            // Dictionaries need to be sorted ordinally by key.
            var sortedDict = dictionary.Values.Zip(dictionary.Keys, (Value, Key) => new { Key, Value })
                             .OrderBy(x => x.Key, StringComparer.Ordinal).ToList();

            WriteTypeAndElementCount(writer, ByamlNodeType.Dictionary, dictionary.Count);

            // Write the key-value pairs.
            Dictionary <Offset, object> offsetElements = new Dictionary <Offset, object>();

            foreach (var keyValuePair in sortedDict)
            {
                string key     = keyValuePair.Key;
                object element = keyValuePair.Value;

                // Get the index of the key string in the file's name array and write it together with the type.
                uint          keyIndex = (uint)_nameArray.IndexOf(key);
                ByamlNodeType nodeType = element == null ? ByamlNodeType.Null : GetNodeType(element.GetType());
                if (Settings.ByteOrder == ByteOrder.BigEndian)
                {
                    writer.Write(keyIndex << 8 | (uint)nodeType);
                }
                else
                {
                    writer.Write(keyIndex | (uint)nodeType << 24);
                }

                // Write the elements. Complex types are just offsets, primitive types are directly written as values.
                if (nodeType == ByamlNodeType.Array || nodeType == ByamlNodeType.Dictionary)
                {
                    offsetElements.Add(writer.ReserveOffset(), element);
                }
                else
                {
                    WritePrimitiveType(writer, nodeType, element);
                }
            }

            // Write the array or dictionary elements and satisfy their offsets.
            foreach (KeyValuePair <Offset, object> offsetElement in offsetElements)
            {
                WriteArrayOrDictionary(writer, offsetElement.Key, offsetElement.Value);
            }
        }
Esempio n. 3
0
            public UnamedNode(EndianBinaryReader reader)
            {
                Address = reader.BaseStream.Position;

                Nodes = new Collection <ByamlNode>();

                int count = reader.ReadInt32() & 0xffffff;

                byte[] types = reader.ReadBytes(count);

                while (reader.BaseStream.Position % 4 != 0)
                {
                    reader.ReadByte();
                }

                long start = reader.BaseStream.Position;

                for (int i = 0; i < count; i++)
                {
                    ByamlNodeType type = (ByamlNodeType)types[i];

                    switch (type)
                    {
                    case ByamlNodeType.String:
                        Nodes.Add(new String(reader));
                        break;

                    case ByamlNodeType.Data:
                        Nodes.Add(new Data(reader));
                        break;

                    case ByamlNodeType.Boolean:
                        Nodes.Add(new Boolean(reader));
                        break;

                    case ByamlNodeType.Int:
                        Nodes.Add(new Int(reader));
                        break;

                    case ByamlNodeType.Single:
                        Nodes.Add(new Single(reader));
                        break;

                    case ByamlNodeType.UnamedNode:
                        reader.BaseStream.Position = reader.ReadInt32();
                        Nodes.Add(new UnamedNode(reader));
                        break;

                    case ByamlNodeType.NamedNode:
                        reader.BaseStream.Position = reader.ReadInt32();
                        Nodes.Add(new NamedNode(reader));
                        break;

                    case ByamlNodeType.Null:
                        Nodes.Add(new Null(reader));
                        break;

                    default:
                        throw new InvalidDataException();
                    }

                    reader.BaseStream.Position = start + (i + 1) * 4;
                }

                Length = reader.BaseStream.Position - Length;
            }
Esempio n. 4
0
        private object ReadValue(BinaryDataReader reader, Type type, ByamlNodeType nodeType = 0)
        {
            // Read the node type if it has not been provided from an array or dictionary.
            bool nodeTypeGiven = nodeType != 0;

            if (!nodeTypeGiven)
            {
                nodeType = (ByamlNodeType)reader.ReadByte();
            }
            if (nodeType >= ByamlNodeType.Array && nodeType <= ByamlNodeType.PathArray)
            {
                // Get the length of arrays. If the node type was given, the array value is read from an offset.
                long?oldPos = null;
                if (nodeTypeGiven)
                {
                    uint offset = reader.ReadUInt32();
                    oldPos = reader.Position;
                    reader.Seek(offset, SeekOrigin.Begin);
                }
                else
                {
                    reader.Seek(-1);
                }
                int length = (int)Get3LsbBytes(reader.ReadUInt32());
                // Read the array data.
                object value = null;
                switch (nodeType)
                {
                case ByamlNodeType.Array:
                    value = ReadArray(reader, type, length);
                    break;

                case ByamlNodeType.Dictionary:
                    value = ReadDictionary(reader, type, length);
                    break;

                case ByamlNodeType.StringArray:
                    value = ReadStringArray(reader, type, length);
                    break;

                case ByamlNodeType.PathArray:
                    if (!Settings.SupportPaths)
                    {
                        throw new ByamlException("Path found, but set to be unsupported.");
                    }
                    value = ReadPathArray(reader, type, length);
                    break;
                }
                // Seek back to the previous position if this was a value read from an offset.
                if (oldPos.HasValue)
                {
                    reader.Seek(oldPos.Value, SeekOrigin.Begin);
                }
                return(value);
            }
            else
            {
                // Read the following uint which is representing the value directly.
                switch (nodeType)
                {
                case ByamlNodeType.StringIndex:
                    return(_stringArray[reader.ReadInt32()]);

                case ByamlNodeType.PathIndex:
                    if (!Settings.SupportPaths)
                    {
                        throw new ByamlException("Path found, but set to be unsupported.");
                    }
                    return(_pathArray[reader.ReadInt32()]);

                case ByamlNodeType.Boolean:
                    return(reader.ReadInt32() != 0);

                case ByamlNodeType.Integer:
                    return(reader.ReadInt32());

                case ByamlNodeType.Float:
                    return(reader.ReadSingle());

                case ByamlNodeType.Null:
                    int value = reader.ReadInt32();
                    if (value != 0)
                    {
                        throw new ByamlException($"Null node has unexpected value of {value}.");
                    }
                    return(null);

                default:
                    throw new ByamlException($"Invalid BYAML node type {nodeType}.");
                }
            }
        }
Esempio n. 5
0
        private object ReadDictionary(BinaryDataReader reader, Type type, int length)
        {
            // Get the information required to serialize this type (for Nullables take the underlying type).
            ByamlObjectInfo objectInfo;
            Type            nullableType = Nullable.GetUnderlyingType(type);

            if (nullableType != null)
            {
                type = nullableType;
            }
            if (!_byamlObjectInfos.TryGetValue(type, out objectInfo))
            {
                objectInfo = new ByamlObjectInfo(type);
                _byamlObjectInfos.Add(type, objectInfo);
            }

            // Instantiate the type and read in the elements. Use a given instance as the root if available.
            object instance;

            if (_instance == null)
            {
                instance = Activator.CreateInstance(type, true);
            }
            else
            {
                instance  = _instance;
                _instance = null;
            }
            // Collect them in a dictionary for custom deserialization.
            Dictionary <string, object> dictionary = new Dictionary <string, object>();

            for (int i = 0; i < length; i++)
            {
                uint          indexAndType  = reader.ReadUInt32();
                int           nodeNameIndex = (int)Get3MsbBytes(indexAndType);
                ByamlNodeType nodeType      = (ByamlNodeType)Get1MsbByte(indexAndType);
                string        key           = _nameArray[nodeNameIndex];
                // Find a member for it to map the value to.
                object          value;
                ByamlMemberInfo member;
                if (objectInfo.Members.TryGetValue(key, out member))
                {
                    // The key could be mapped to a member, read it as the member's type.
                    value = ReadValue(reader, member.Type, nodeType);
                    member.SetValue(instance, value);
                }
                else
                {
                    // If the key could not be mapped to a member, add it to the dictionary for custom deserialization.
                    //Debug.WriteLine($"No member in {type.Name} found to map key \"{key}\" to.");
                    value = ReadValue(reader, nodeType.GetInstanceType(), nodeType);
                }
                dictionary.Add(key, value);
            }

            // Call IByamlSerializable methods if the interface was implemented.
            if (objectInfo.ImplementsByamlSerializable)
            {
                IByamlSerializable byamlSerializable = (IByamlSerializable)instance;
                byamlSerializable.DeserializeByaml(dictionary);
            }

            // Check if any required fields were not filled.
            foreach (ByamlMemberInfo member in objectInfo.Members.Values)
            {
                if (!member.Optional && member.GetValue(instance) == null)
                {
                    throw new ByamlException(
                              $"Member {type.Name}.{member.MemberInfo.Name} is not optional, but has not been deserialized.");
                }
            }

            return(instance);
        }
Esempio n. 6
0
 public ByamlEntry(ByamlNodeType NodeType, object Value)
 {
     this.Value    = Value;
     this.NodeType = NodeType;
 }
Esempio n. 7
0
        // ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------

        // ---- Loading ----
        private dynamic Read(Stream stream)
        {
            // Open a reader on the given stream.
            using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.UTF8, true))
            {
                reader.ByteOrder = _byteOrder;

                // Load the header, specifying magic bytes ("BY"), version and main node offsets.
                if (reader.ReadUInt16() != _magicBytes)
                {
                    _byteOrder                 = _byteOrder == ByteOrder.LittleEndian ? ByteOrder.BigEndian : ByteOrder.LittleEndian;
                    reader.ByteOrder           = _byteOrder;
                    reader.BaseStream.Position = 0;
                    if (reader.ReadUInt16() != _magicBytes)
                    {
                        throw new Exception("Header mismatch");
                    }
                }
                _version = reader.ReadUInt16();
                uint nameArrayOffset   = reader.ReadUInt32();
                uint stringArrayOffset = reader.ReadUInt32();

                using (reader.TemporarySeek())
                {
                    // Paths are supported if the third offset is a path array (or null) and the fourth a root.
                    ByamlNodeType thirdNodeType = PeekNodeType(reader);
                    reader.Seek(sizeof(uint));
                    ByamlNodeType fourthNodeType = PeekNodeType(reader);

                    _supportPaths = (thirdNodeType == ByamlNodeType.None || thirdNodeType == ByamlNodeType.PathArray) &&
                                    (fourthNodeType == ByamlNodeType.Array || fourthNodeType == ByamlNodeType.Dictionary);
                }


                uint pathArrayOffset = 0;
                if (_supportPaths)
                {
                    pathArrayOffset = reader.ReadUInt32();
                }
                uint rootNodeOffset = reader.ReadUInt32();

                // Read the name array, holding strings referenced by index for the names of other nodes.
                if (nameArrayOffset != 0)
                {
                    reader.Seek(nameArrayOffset, SeekOrigin.Begin);
                    _nameArray = ReadNode(reader);
                }

                // Read the optional string array, holding strings referenced by index in string nodes.
                if (stringArrayOffset != 0)
                {
                    reader.Seek(stringArrayOffset, SeekOrigin.Begin);
                    _stringArray = ReadNode(reader);
                }

                // Read the optional path array, holding paths referenced by index in path nodes.
                if (_supportPaths && pathArrayOffset != 0)
                {
                    // The third offset is the root node, so just read that and we're done.
                    reader.Seek(pathArrayOffset, SeekOrigin.Begin);
                    _pathArray = ReadNode(reader);
                }

                if (rootNodeOffset == 0) //empty byml
                {
                    return(new List <dynamic>());
                }

                // Read the root node.
                reader.Seek(rootNodeOffset, SeekOrigin.Begin);
                return(ReadNode(reader, 0));
            }
        }
Esempio n. 8
0
            public NamedNode(EndianBinaryReader reader)
            {
                Address = reader.BaseStream.Position;

                Nodes = new Collection <KeyValuePair <int, ByamlNode> >();

                int count = reader.ReadInt32() & 0xffffff;

                for (int i = 0; i < count; i++)
                {
                    uint          temp = reader.ReadUInt32();
                    int           name = (int)(temp >> 8);
                    ByamlNodeType type = (ByamlNodeType)(byte)temp;
                    //Console.WriteLine(i.ToString() + "(" + type.ToString() + "): " + temp.ToString());

                    switch (type)
                    {
                    case ByamlNodeType.String:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new String(reader)));
                        break;

                    case ByamlNodeType.Data:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new Data(reader)));
                        break;

                    case ByamlNodeType.Boolean:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new Boolean(reader)));
                        break;

                    case ByamlNodeType.Int:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new Int(reader)));
                        break;

                    case ByamlNodeType.Single:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new Single(reader)));
                        break;

                    case ByamlNodeType.Double:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new Double(reader)));
                        break;

                    case ByamlNodeType.UnamedNode:
                        reader.BaseStream.Position = reader.ReadInt32();
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new UnamedNode(reader)));
                        break;

                    case ByamlNodeType.NamedNode:
                        reader.BaseStream.Position = reader.ReadInt32();
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new NamedNode(reader)));
                        break;

                    case ByamlNodeType.Null:
                        Nodes.Add(new KeyValuePair <int, ByamlNode>(name, new Null(reader)));
                        break;

                    default:
                        throw new InvalidDataException();
                    }

                    reader.BaseStream.Position = Address + (i + 1) * 8 + 4;
                }

                Length = reader.BaseStream.Position - Length;
            }
        protected bool TryStartLoading()
        {
            // Load the header, specifying magic bytes ("BY"), version and main node offsets.
            if (_reader.ReadUInt16() != BYAML_MAGIC)
            {
                //switch endian and try again
                _byteOrder = _byteOrder == ByteOrder.LittleEndian ? ByteOrder.BigEndian : ByteOrder.LittleEndian;

                _reader = new BinaryDataReader(_reader.BaseStream, ByamlFile.GetEncoding(_byteOrder), true)
                {
                    ByteOrder = _byteOrder
                };

                _reader.Position = 0;
                if (_reader.ReadUInt16() != BYAML_MAGIC)
                {
                    throw new Exception("Header mismatch");
                }
            }
            _version = _reader.ReadUInt16();
            uint nameArrayOffset   = _reader.ReadUInt32();
            uint stringArrayOffset = _reader.ReadUInt32();

            if (_reader.Length == 16)
            {
                _supportPaths = false;
            }
            else
            {
                using (_reader.TemporarySeek())
                {
                    // Paths are supported if the third offset is a path array (or unknown) and the fourth a root.
                    ByamlNodeType thirdNodeType = PeekNodeType(_reader);
                    _reader.Seek(sizeof(uint));
                    ByamlNodeType fourthNodeType = PeekNodeType(_reader);

                    _supportPaths = (thirdNodeType == ByamlNodeType.Unknown || thirdNodeType == ByamlNodeType.PathArray) &&
                                    (fourthNodeType == ByamlNodeType.Array || fourthNodeType == ByamlNodeType.Dictionary);
                }
            }


            uint pathArrayOffset = 0;

            if (_supportPaths)
            {
                pathArrayOffset = _reader.ReadUInt32();
            }
            uint rootNodeOffset = _reader.ReadUInt32();

            if (rootNodeOffset == 0) //empty byml
            {
                return(false);
            }

            // Read the name array, holding strings referenced by index for the names of other nodes.
            if (nameArrayOffset != 0)
            {
                _reader.Seek(nameArrayOffset, SeekOrigin.Begin);
                _nameArray = ReadCollectionNode(_reader.ReadUInt32());
            }

            // Read the optional string array, holding strings referenced by index in string nodes.
            if (stringArrayOffset != 0)
            {
                _reader.Seek(stringArrayOffset, SeekOrigin.Begin);
                _stringArray = ReadCollectionNode(_reader.ReadUInt32());
            }

            // Read the optional path array, holding paths referenced by index in path nodes.
            if (_supportPaths && pathArrayOffset != 0)
            {
                // The third offset is the root node, so just read that and we're done.
                _reader.Seek(pathArrayOffset, SeekOrigin.Begin);
                _pathArray = ReadCollectionNode(_reader.ReadUInt32());
            }

            // Read the root node.
            _reader.Seek(rootNodeOffset, SeekOrigin.Begin);

            return(true);



            dynamic ReadCollectionNode(uint lengthAndType)
            {
                int           length   = (int)Get3LsbBytes(lengthAndType);
                ByamlNodeType nodeType = (ByamlNodeType)Get1MsbByte(lengthAndType);

                switch (nodeType)
                {
                case ByamlNodeType.Array:
                    return(ReadArrayNode(_reader, length));

                case ByamlNodeType.Dictionary:
                    return(ReadDictionaryNode(_reader, length));

                case ByamlNodeType.StringArray:
                    return(ReadStringArrayNode(_reader, length));

                case ByamlNodeType.PathArray:
                    return(ReadPathArrayNode(_reader, length));

                default:
                    return(null);    //should never happen
                }
            }
        }
 protected static bool IsReferenceType(ByamlNodeType nodeType) =>
 (ByamlNodeType.Array <= nodeType && nodeType <= ByamlNodeType.PathArray);
        protected dynamic ReadNodeValue(BinaryDataReader _reader, ByamlNodeType nodeType)
        {
            if (ByamlNodeType.Array <= nodeType && nodeType <= ByamlNodeType.PathArray)
            {
                int length = (int)Get3LsbBytes(_reader.ReadUInt32());


                switch (nodeType)
                {
                case ByamlNodeType.Array:
                    return(ReadArrayNode(_reader, length));

                case ByamlNodeType.Dictionary:
                    return(ReadDictionaryNode(_reader, length));

                case ByamlNodeType.StringArray:
                    return(ReadStringArrayNode(_reader, length));

                case ByamlNodeType.PathArray:
                    return(ReadPathArrayNode(_reader, length));

                default:
                    return(null);    //should never happen
                }
            }


            // Read the following UInt32 which is representing the value directly.
            switch (nodeType)
            {
            case ByamlNodeType.StringIndex:
                return(_stringArray[_reader.ReadInt32()]);

            case ByamlNodeType.PathIndex:
                return(_pathArray[_reader.ReadInt32()]);

            case ByamlNodeType.Boolean:
                return(_reader.ReadInt32() != 0);

            case ByamlNodeType.Integer:
                return(_reader.ReadInt32());

            case ByamlNodeType.Float:
                return(_reader.ReadSingle());

            case ByamlNodeType.UInteger:
                return(_reader.ReadUInt32());

            case ByamlNodeType.Long:
            case ByamlNodeType.ULong:
            case ByamlNodeType.Double:
                var pos = _reader.Position;
                _reader.Position = _reader.ReadUInt32();
                dynamic value = readLongValFromOffset(nodeType);
                _reader.Position = pos + 4;
                return(value);

            case ByamlNodeType.Null:
                _reader.Seek(0x4);
                return(null);

            default:
                throw new Exception($"Unknown node type '{nodeType}'.");
            }

            dynamic readLongValFromOffset(ByamlNodeType type)
            {
                switch (type)
                {
                case ByamlNodeType.Long:
                    return(_reader.ReadInt64());

                case ByamlNodeType.ULong:
                    return(_reader.ReadUInt64());

                case ByamlNodeType.Double:
                    return(_reader.ReadDouble());
                }
                throw new Exception($"Unknown node type '{nodeType}'.");
            }
        }
        /// <summary>
        /// Create from Reading the games files
        /// </summary>
        public void Create(string StageDataPath)
        {
            string[] Zones   = Directory.GetFiles(StageDataPath, "*Map1.szs");
            string[] Designs = Directory.GetFiles(StageDataPath, "*Design1.szs");
            string[] Sounds  = Directory.GetFiles(StageDataPath, "*Sound1.szs");

            Dictionary <string, List <ObjectInfo> > MAPinfosByListName = new Dictionary <string, List <ObjectInfo> >()
            {
                ["AreaList"]       = new List <ObjectInfo>(),
                ["CheckPointList"] = new List <ObjectInfo>(),
                ["DemoObjList"]    = new List <ObjectInfo>(),
                ["GoalList"]       = new List <ObjectInfo>(),
                ["ObjectList"]     = new List <ObjectInfo>(),
                ["PlayerList"]     = new List <ObjectInfo>(),
                ["SkyList"]        = new List <ObjectInfo>(),
                ["Links"]          = new List <ObjectInfo>()
            };
            Dictionary <string, List <ObjectInfo> > DESIGNinfosByListName = new Dictionary <string, List <ObjectInfo> >()
            {
                ["AreaList"]       = new List <ObjectInfo>(),
                ["CheckPointList"] = new List <ObjectInfo>(),
                ["DemoObjList"]    = new List <ObjectInfo>(),
                ["GoalList"]       = new List <ObjectInfo>(),
                ["ObjectList"]     = new List <ObjectInfo>(),
                ["PlayerList"]     = new List <ObjectInfo>(),
                ["SkyList"]        = new List <ObjectInfo>(),
                ["Links"]          = new List <ObjectInfo>()
            };
            Dictionary <string, List <ObjectInfo> > SOUNDinfosByListName = new Dictionary <string, List <ObjectInfo> >()
            {
                ["AreaList"]       = new List <ObjectInfo>(),
                ["CheckPointList"] = new List <ObjectInfo>(),
                ["DemoObjList"]    = new List <ObjectInfo>(),
                ["GoalList"]       = new List <ObjectInfo>(),
                ["ObjectList"]     = new List <ObjectInfo>(),
                ["PlayerList"]     = new List <ObjectInfo>(),
                ["SkyList"]        = new List <ObjectInfo>(),
                ["Links"]          = new List <ObjectInfo>()
            };

            for (int i = 0; i < Zones.Length; i++)
            {
                GetObjectInfos(Zones[i], MAPinfosByListName);
            }
            for (int i = 0; i < Designs.Length; i++)
            {
                GetObjectInfos(Designs[i], DESIGNinfosByListName);
            }
            for (int i = 0; i < Sounds.Length; i++)
            {
                GetObjectInfos(Sounds[i], SOUNDinfosByListName);
            }


            void GetParameters <T>(Dictionary <string, List <ObjectInfo> > infosByListName) where T : Parameter, new()
            {
                byte ListID = 0;

                foreach (KeyValuePair <string, List <ObjectInfo> > keyValuePair in infosByListName)
                {
                    for (int j = 0; j < keyValuePair.Value.Count; j++)
                    {
                        if (keyValuePair.Value[j].ClassName == "Rail")
                        {
                            continue;
                        }

                        ObjectInfo Tmp = keyValuePair.Value[j];
                        if (ObjectParameters.ContainsKey(Tmp.ClassName))
                        {
                            if (Tmp.ObjectName != "" && !ObjectParameters[Tmp.ClassName].ObjectNames.Any(O => O == Tmp.ObjectName))
                            {
                                ObjectParameters[Tmp.ClassName].ObjectNames.Add(Tmp.ObjectName);
                            }

                            if (Tmp.ModelName != "" && !ObjectParameters[Tmp.ClassName].ModelNames.Any(O => O == Tmp.ModelName))
                            {
                                ObjectParameters[Tmp.ClassName].ModelNames.Add(Tmp.ModelName);
                            }

                            foreach (var propertyEntry in Tmp.PropertyEntries)
                            {
                                if (!ObjectParameters[Tmp.ClassName].Properties.Any(O => O.Key == propertyEntry.Key))
                                {
                                    ByamlNodeType type = propertyEntry.Value.NodeType;
                                    if (type == ByamlNodeType.Null)
                                    {
                                        type = ByamlNodeType.StringIndex;
                                    }
                                    ObjectParameters[Tmp.ClassName].Properties.Add(new KeyValuePair <string, string>(propertyEntry.Key, type == ByamlNodeType.StringIndex ? "String" : type.ToString()));
                                }
                            }

                            foreach (string key in Tmp.LinkEntries.Keys)
                            {
                                if (!ObjectParameters[Tmp.ClassName].LinkNames.Any(O => O == key))
                                {
                                    ObjectParameters[Tmp.ClassName].LinkNames.Add(key);
                                }
                            }
                        }
                        else
                        {
                            T OP = new T()
                            {
                                ClassName = Tmp.ClassName
                            };
                            if (Tmp.ObjectName != "")
                            {
                                OP.ObjectNames.Add(Tmp.ObjectName);
                            }
                            if (Tmp.ModelName != "" && Tmp.ModelName != null)
                            {
                                OP.ModelNames.Add(Tmp.ModelName);
                            }

                            foreach (var propertyEntry in Tmp.PropertyEntries)
                            {
                                ByamlNodeType type = propertyEntry.Value.NodeType;
                                if (type == ByamlNodeType.Null)
                                {
                                    type = ByamlNodeType.StringIndex;
                                }
                                OP.Properties.Add(new KeyValuePair <string, string>(propertyEntry.Key, type == ByamlNodeType.StringIndex ? "String" : type.ToString()));
                            }

                            foreach (string key in Tmp.LinkEntries.Keys)
                            {
                                OP.LinkNames.Add(key);
                            }

                            OP.ObjList = (ObjList)ListID;
                            ObjectParameters.Add(Tmp.ClassName, OP);
                        }
                    }
                    ListID++;
                }
            }

            GetParameters <ObjectParameter>(MAPinfosByListName);
            GetParameters <DesignParameter>(DESIGNinfosByListName);
            GetParameters <SoundFXParameter>(SOUNDinfosByListName);
        }