Exemplo n.º 1
0
        public IPsoValue Parse(PsoFile meta)
        {
            var blockKeys = new List <int>();
            var blocks    = new List <List <IPsoValue> >();

            var t1       = (PsoStructureInfo)null;
            var t2       = (PsoElementIndexInfo)null;
            var rootHash = meta.DataMappingSection.Entries[meta.DataMappingSection.RootIndex - 1].NameHash;

            for (int i = 0; i < meta.DefinitionSection.Count; i++)
            {
                if (meta.DefinitionSection.EntriesIdx[i].NameHash == rootHash)
                {
                    t1 = (PsoStructureInfo)meta.DefinitionSection.Entries[i];
                    t2 = meta.DefinitionSection.EntriesIdx[i];
                }
            }

            var resultStructure = new PsoStructure(meta, t1, t2, null);

            var reader = new PsoDataReader(meta);

            reader.SetSectionIndex(meta.DataMappingSection.RootIndex - 1);
            reader.Position = 0;
            resultStructure.Read(reader);
            return(resultStructure);
        }
Exemplo n.º 2
0
 private void WriteStructureContentXml(PsoStructure value, XmlTextWriter writer)
 {
     foreach (var field in value.Values)
     {
         var fieldNameHash = field.Key;
         var fieldValue    = field.Value;
         writer.WriteStartElement(GetNameForHash(fieldNameHash));
         WriteStructureElementContentXml(fieldValue, writer);
         writer.WriteEndElement();
     }
 }
Exemplo n.º 3
0
        public static IPsoValue Make(PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo entryInfo)
        {
            switch (entryInfo.Type)
            {
            case DataType.Array:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0:
                {
                    var t = structureInfo.Entries[entryInfo.ReferenceKey & 0x0000FFFF];
                    return(new PsoArray0(pso, structureInfo, t));
                }

                case 1:
                {
                    var typeIndex = entryInfo.ReferenceKey & 0x0000FFFF;
                    var num       = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF;
                    var t         = structureInfo.Entries[typeIndex];
                    return(new PsoArray1(pso, structureInfo, t, num));
                }

                case 4:
                {
                    var typeIndex = entryInfo.ReferenceKey & 0x0000FFFF;
                    var num       = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF;
                    var t         = structureInfo.Entries[typeIndex];
                    return(new PsoArray4(pso, structureInfo, t, num));
                }

                default:
                {
                    throw new Exception("Unsupported array type.");
                }
                }
            }

            case DataType.String:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0:
                {
                    var len = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF;
                    return(new PsoString0(len));
                }

                case 1:
                {
                    return(new PsoString1());
                }

                case 2:
                {
                    return(new PsoString2());
                }

                case 3:
                {
                    return(new PsoString3());
                }

                case 7:
                {
                    return(new PsoString7());
                }

                case 8:
                {
                    return(new PsoString8());
                }

                default:
                {
                    throw new Exception("Unsupported string type.");
                }
                }
            }

            case DataType.Enum:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0:
                {
                    var entryValue = new PsoEnumInt();
                    entryValue.TypeInfo = GetEnumInfo(pso, entryInfo.ReferenceKey);
                    return(entryValue);
                }

                case 2:
                {
                    var entryValue = new PsoEnumByte();
                    entryValue.TypeInfo = GetEnumInfo(pso, entryInfo.ReferenceKey);
                    return(entryValue);
                }

                default:
                {
                    throw new Exception("Unsupported enum type.");
                }
                }
            }

            case DataType.Flags:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0:
                {
                    var entryValue = new PsoFlagsInt();
                    var sidx       = entryInfo.ReferenceKey & 0x0000FFFF;

                    if (sidx != 0xfff)
                    {
                        var reftype = structureInfo.Entries[sidx];
                        entryValue.TypeInfo = GetEnumInfo(pso, reftype.ReferenceKey);
                    }


                    return(entryValue);
                }

                case 1:
                {
                    var entryValue = new PsoFlagsShort();
                    var sidx       = entryInfo.ReferenceKey & 0x0000FFFF;

                    var reftype = structureInfo.Entries[sidx];
                    entryValue.TypeInfo = GetEnumInfo(pso, reftype.ReferenceKey);

                    return(entryValue);
                }

                case 2:
                {
                    var entryValue = new PsoFlagsByte();
                    var sidx       = entryInfo.ReferenceKey & 0x0000FFFF;
                    var reftype    = structureInfo.Entries[sidx];
                    entryValue.TypeInfo = GetEnumInfo(pso, reftype.ReferenceKey);
                    return(entryValue);
                }

                default:
                {
                    throw new Exception("Unsupported flags type.");
                }
                }
            }

            case DataType.Integer:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoIntSigned());

                case 1: return(new PsoIntUnsigned());

                default: throw new Exception("Unsupported integer type.");
                }
            }

            case DataType.Structure:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0:
                {
                    var t1         = GetStructureInfo(pso, entryInfo.ReferenceKey);
                    var t2         = GetStructureIndexInfo(pso, entryInfo.ReferenceKey);
                    var entryValue = new PsoStructure(pso, t1, t2, entryInfo);
                    return(entryValue);
                }

                case 3:
                {
                    return(new PsoStructure3(pso, structureInfo, entryInfo));
                }

                default:
                {
                    throw new Exception("Unsupported structure type.");
                }
                }
            }

            case DataType.Map:
            {
                switch (entryInfo.Unk_5h)
                {
                case 1:
                {
                    var idx1     = entryInfo.ReferenceKey & 0x0000FFFF;
                    var idx2     = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF;
                    var reftype1 = structureInfo.Entries[idx2];
                    var reftype2 = structureInfo.Entries[idx1];
                    return(new PsoMap(pso, structureInfo, reftype1, reftype2));
                }

                default: throw new Exception("Unsupported PsoType5 type.");
                }
            }

            case DataType.INT_05h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoType5());

                default: throw new Exception("Unsupported PsoType5 type.");
                }
            }

            case DataType.Byte:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoByte());

                default: throw new Exception("Unsupported PsoByte type.");
                }
            }

            case DataType.Boolean:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoBoolean());

                default: throw new Exception("Unsupported boolean type.");
                }
            }

            case DataType.Float:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoFloat());

                default: throw new Exception("Unsupported float type.");
                }
            }

            case DataType.Float2:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoFloat2());

                default: throw new Exception("Unsupported float2 type.");
                }
            }

            case DataType.Float3:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoFloat4A());

                default: throw new Exception("Unsupported float3 type.");
                }
            }

            case DataType.Float4:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoFloat4B());

                default: throw new Exception("Unsupported float4 type.");
                }
            }

            case DataType.TYPE_09h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoType9());

                default: throw new Exception("Unsupported PsoType9 type.");
                }
            }

            case DataType.LONG_20h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoType32());

                default: throw new Exception("Unsupported PsoType32 type.");
                }
            }

            case DataType.SHORT_1Eh:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoXXHalf());

                default: throw new Exception("Unsupported PsoType30 type.");
                }
            }

            case DataType.SHORT_03h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoType3());

                default: throw new Exception("Unsupported PsoType3 type.");
                }
            }

            case DataType.SHORT_04h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoType4());

                default: throw new Exception("Unsupported PsoType4 type.");
                }
            }

            case DataType.LONG_01h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoXXByte());

                default: throw new Exception("Unsupported PsoType1 type.");
                }
            }

            case DataType.TYPE_14h:
            {
                switch (entryInfo.Unk_5h)
                {
                case 0: return(new PsoFloat3());

                default: throw new Exception("Unsupported PsoType20 type.");
                }
            }

            default:
                throw new Exception("Unsupported type.");
            }
        }
Exemplo n.º 4
0
        public PsoStructure ParseStructure(XmlNode node, PsoStructureXml info)
        {
            PsoStructure resultStructure = null;

            foreach (var x in strList)
            {
                if (x.Item1 == info.NameHash)
                {
                    resultStructure                       = new PsoStructure();
                    resultStructure.psoSection            = x.Item2;
                    resultStructure.psoEntryInfo          = new PsoElementIndexInfo();
                    resultStructure.psoEntryInfo.NameHash = x.Item1;
                }
            }

            resultStructure.Values = new Dictionary <int, IPsoValue>();

            foreach (var xmlEntry in info.Entries)
            {
                XmlNode xmlNode = null;
                foreach (XmlNode x in node.ChildNodes)
                {
                    var hash = GetHashForName(x.Name);
                    if (hash == xmlEntry.NameHash)
                    {
                        xmlNode = x;
                    }
                }

                PsoStructureEntryInfo entryInfo = null;
                foreach (var x in resultStructure.psoSection.Entries)
                {
                    if (x.EntryNameHash == xmlEntry.NameHash)
                    {
                        entryInfo = x;
                    }
                }

                var type = (DataType)xmlEntry.Type;
                if (type == DataType.Array)
                {
                    var arrayType = (DataType)xmlEntry.ArrayType.Type;
                    if (arrayType == DataType.Structure)
                    {
                        PsoArray arrayValue = ReadStructureArray(xmlNode, xmlEntry.ArrayType.TypeHash);
                        arrayValue.psoSection = resultStructure.psoSection.Entries[entryInfo.ReferenceKey];
                        resultStructure.Values.Add(xmlEntry.NameHash, arrayValue);
                    }
                    else if (arrayType == DataType.INT_0Bh)
                    {
                        PsoArray arryVal = Read11Array(xmlNode);
                        arryVal.psoSection = resultStructure.psoSection.Entries[entryInfo.ReferenceKey];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    else if (arrayType == DataType.SHORT_0Fh)
                    {
                        PsoArray arryVal = Read14Array(xmlNode);
                        arryVal.psoSection = resultStructure.psoSection.Entries[entryInfo.ReferenceKey];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    else
                    {
                        throw new Exception("Unsupported array type.");
                    }
                }
                else if (type == DataType.INT_06h)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadType6(xmlNode));
                }
                else if (type == DataType.INT_0Bh)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadType11(xmlNode, xmlEntry.Unknown == 0));
                }
                else if (type == DataType.BYTE_ENUM_VALUE)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadType14(xmlNode));
                }
                else if (type == DataType.SHORT_0Fh)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadType15(xmlNode));
                }
                else if (type == DataType.Structure)
                {
                    var xmlInfo        = FindAndCheckStructure(xmlEntry.TypeHash, xmlNode);
                    var structureValue = ParseStructure(xmlNode, xmlInfo);
                    resultStructure.Values.Add(xmlEntry.NameHash, structureValue);
                }
                else
                {
                    throw new Exception("Unsupported type.");
                }
            }

            return(resultStructure);
        }
Exemplo n.º 5
0
        public IPsoValue Parse(PsoFile meta)
        {
            var blockKeys = new List <int>();
            var blocks    = new List <List <IPsoValue> >();


            var resultStructure = new PsoStructure();

            resultStructure.pso = meta;

            var rootHash = meta.DataMappingSection.Entries[meta.DataMappingSection.RootIndex - 1].NameHash;

            for (int i = 0; i < meta.DefinitionSection.Count; i++)
            {
                if (meta.DefinitionSection.EntriesIdx[i].NameHash == rootHash)
                {
                    resultStructure.psoSection   = (PsoStructureInfo)meta.DefinitionSection.Entries[i];
                    resultStructure.psoEntryInfo = meta.DefinitionSection.EntriesIdx[i];
                }
            }

            var reader = new DataReader(new MemoryStream(meta.DataSection.Data), Endianess.BigEndian);

            reader.Position = meta.DataMappingSection.Entries[meta.DataMappingSection.RootIndex - 1].Offset;
            resultStructure.Read(reader);


            var stack = new Stack <PsoStructure>();

            stack.Push(resultStructure);
            while (stack.Count > 0)
            {
                var x = stack.Pop();
                foreach (var ee in x.psoSection.Entries)
                {
                    if (ee.EntryNameHash == 0x100)
                    {
                        continue;
                    }

                    var value = x.Values[ee.EntryNameHash];

                    if (value is PsoStructure)
                    {
                        stack.Push((PsoStructure)value);
                    }
                    if (value is PsoArray)
                    {
                        var arrayValue = (PsoArray)value;
                        switch (arrayValue.psoSection.Type)
                        {
                        case DataType.Structure:
                        {
                            if (arrayValue.NumberOfEntries > 0)
                            {
                                arrayValue.Entries = new List <IPsoValue>();
                                reader.Position    = meta.DataMappingSection.Entries[arrayValue.BlockIndex - 1].Offset + arrayValue.Offset;
                                for (int i = 0; i < arrayValue.NumberOfEntries; i++)
                                {
                                    PsoStructure item = new PsoStructure();
                                    item.pso        = meta;
                                    item.psoSection = null;
                                    for (int y = 0; y < meta.DefinitionSection.Count; y++)
                                    {
                                        if (meta.DefinitionSection.EntriesIdx[y].NameHash == arrayValue.psoSection.ReferenceKey)
                                        {
                                            item.psoSection   = (PsoStructureInfo)meta.DefinitionSection.Entries[y];
                                            item.psoEntryInfo = meta.DefinitionSection.EntriesIdx[y];
                                        }
                                    }

                                    item.Read(reader);
                                    arrayValue.Entries.Add(item);
                                    stack.Push(item);
                                }
                            }

                            break;
                        }

                        case DataType.INT_0Bh:
                        {
                            if (arrayValue.NumberOfEntries > 0)
                            {
                                arrayValue.Entries = new List <IPsoValue>();
                                reader.Position    = meta.DataMappingSection.Entries[arrayValue.BlockIndex - 1].Offset + arrayValue.Offset;
                                for (int i = 0; i < arrayValue.NumberOfEntries; i++)
                                {
                                    PsoType11 item = new PsoType11(0);
                                    item.Read(reader);
                                    arrayValue.Entries.Add(item);
                                }
                            }


                            break;
                        }

                        default:
                            throw new System.Exception("Unknown array type.");
                        }
                    }
                }
            }

            return(resultStructure);
        }
Exemplo n.º 6
0
        private void WriteStructure(MetaDataWriter writer, PsoStructure value)
        {
            var updateStack = new Stack <IPsoValue>();

            // build stack for update...
            var structuresToCheck = new Stack <PsoStructure>();

            structuresToCheck.Push(value);
            while (structuresToCheck.Count > 0)
            {
                var structureToCheck = structuresToCheck.Pop();

                // add structure to list of occurring structures
                usedStructureKeys.Add(structureToCheck.psoEntryInfo.NameHash);

                foreach (var structureEntryToCheck in structureToCheck.Values)
                {
                    if (structureEntryToCheck.Value is PsoArray)
                    {
                        updateStack.Push(structureEntryToCheck.Value);

                        var arrayStructureEntryToCheck = structureEntryToCheck.Value as PsoArray;
                        if (arrayStructureEntryToCheck.Entries != null)
                        {
                            for (int k = arrayStructureEntryToCheck.Entries.Count - 1; k >= 0; k--)
                            {
                                var x = arrayStructureEntryToCheck.Entries[k];
                                if (x is PsoStructure)
                                {
                                    structuresToCheck.Push(x as PsoStructure);
                                }
                            }
                        }
                    }
                    if (structureEntryToCheck.Value is PsoStructure)
                    {
                        structuresToCheck.Push((PsoStructure)structureEntryToCheck.Value);
                    }
                }
            }

            // update structures...
            while (updateStack.Count > 0)
            {
                var v = updateStack.Pop();
                if (v is PsoArray)
                {
                    var arrayValue = (PsoArray)v;
                    if (arrayValue.Entries != null)
                    {
                        if (arrayValue.psoSection.Type == DataType.Structure)
                        {
                            writer.SelectBlockByNameHash((int)arrayValue.psoSection.ReferenceKey);
                            writer.Position = writer.Length;
                        }
                        else if (arrayValue.psoSection.Type == DataType.INT_0Bh)
                        {
                            writer.SelectBlockByNameHash(6);
                            writer.Position = writer.Length;
                        }
                        else
                        {
                            throw new Exception("Unknown array type.");
                        }



                        arrayValue.BlockIndex      = writer.BlockIndex + 1;
                        arrayValue.Offset          = (int)writer.Position;
                        arrayValue.NumberOfEntries = arrayValue.Entries.Count;
                        foreach (var entry in arrayValue.Entries)
                        {
                            entry.Write(writer);
                        }
                    }
                    else
                    {
                        arrayValue.BlockIndex      = 0;
                        arrayValue.Offset          = 0;
                        arrayValue.NumberOfEntries = 0;
                    }
                }
            }

            // now only the root itself is left...
            writer.SelectBlockByNameHash(value.psoEntryInfo.NameHash);
            writer.Position = writer.Length;
            value.Write(writer);
        }