예제 #1
0
        public void Load(byte[] data, RpfFileEntry entry)
        {
            //MemoryStream ms = new MemoryStream(data);

            FileEntry = entry;

            MemoryStream ms = new MemoryStream(data);

            if (PsoFile.IsPSO(ms))
            {
                Pso = new PsoFile();
                Pso.Load(ms);

                //PsoTypes.EnsurePsoTypes(Pso);

                var root = PsoTypes.GetRootEntry(Pso);
                if (root != null)
                {
                }
                return;
            }
            else
            {
            }
        }
예제 #2
0
        private void LoadPso()
        {
            var vVariationInfo = PsoTypes.GetRootItem <CPedVariationInfo>(Pso);

            VariationInfo = new MCPedVariationInfo();
            VariationInfo.Load(Pso, vVariationInfo);
        }
예제 #3
0
 public void Load(PsoFile pso)
 {
     Data          = PsoTypes.GetRootItem <CScenarioPointManifest>(pso);
     RegionDefs    = PsoTypes.ConvertDataArray <CScenarioPointRegionDef>(pso, _Data.RegionDefs);
     Groups        = PsoTypes.ConvertDataArray <CScenarioPointGroup>(pso, _Data.Groups);
     InteriorNames = PsoTypes.GetHashArray(pso, _Data.InteriorNames);
 }
예제 #4
0
        private static int GetEnumInt(MetaName type, string enumString, PsoDataType dataType)
        {
            var infos = PsoTypes.GetEnumInfo(type);

            if (infos == null)
            {
                return(0);
            }


            bool isFlags = (dataType == PsoDataType.Flags);// ||

            //(dataType == PsoDataType.IntFlags2);// ||
            //(dataType == PsoDataType.ShortFlags);

            if (isFlags)
            {
                //flags enum. (multiple values, comma-separated)
                var split   = enumString.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                int enumVal = 0;

                for (int i = 0; i < split.Length; i++)
                {
                    var enumName = (MetaName)(uint)GetHash(split[i].Trim());

                    for (int j = 0; j < infos.Entries.Length; j++)
                    {
                        var entry = infos.Entries[j];
                        if (entry.EntryNameHash == enumName)
                        {
                            enumVal += (1 << entry.EntryKey);
                            break;
                        }
                    }
                }

                return(enumVal);
            }
            else
            {
                //single value enum.

                var enumName = (MetaName)(uint)GetHash(enumString);

                for (int j = 0; j < infos.Entries.Length; j++)
                {
                    var entry = infos.Entries[j];

                    if (entry.EntryNameHash == enumName)
                    {
                        return(entry.EntryKey);
                    }
                }
            }

            return(-1);
        }
예제 #5
0
 public override void Init(PsoFile pso, ref CMapDataGroup v)
 {
     DataGroup    = v;
     Bounds       = PsoTypes.GetHashArray(pso, v.Bounds);
     WeatherTypes = PsoTypes.GetHashArray(pso, v.WeatherTypes);
     Name         = v.Name;
     Flags        = v.Flags;
     HoursOnOff   = v.HoursOnOff;
 }
예제 #6
0
 public void AddEnumInfo(MetaName name)
 {
     if (!EnumInfos.ContainsKey(name))
     {
         PsoEnumInfo ei = PsoTypes.GetEnumInfo(name);
         if (ei != null)
         {
             EnumInfos[name] = ei;
         }
     }
 }
예제 #7
0
 public void AddStructureInfo(MetaName name)
 {
     if (!StructureInfos.ContainsKey(name))
     {
         PsoStructureInfo si = PsoTypes.GetStructureInfo(name);
         if (si != null)
         {
             StructureInfos[name] = si;
         }
     }
 }
예제 #8
0
        private void ProcessPSO()
        {
            //See x64m.rpf\levels\gta5\_cityw\venice_01\venice_metadata.rpf\_manifest.ymf
            //for TIMED YMAP stuff!!!!
            //check CMapDataGroup.HoursOnOff


            var d = PsoTypes.GetRootItem <CPackFileMetaData>(Pso);

            MapDataGroups = PsoTypes.GetObjectArray <YmfMapDataGroup, CMapDataGroup>(Pso, d.MapDataGroups);

            imapDependencies = PsoTypes.GetItemArray <CImapDependency>(Pso, d.imapDependencies);

            imapDependencies2 = PsoTypes.GetObjectArray <YmfImapDependency2, CImapDependencies>(Pso, d.imapDependencies_2);

            itypDependencies2 = PsoTypes.GetObjectArray <YmfItypDependency2, CItypDependencies>(Pso, d.itypDependencies_2);

            HDTxdAssetBindings = PsoTypes.GetItemArray <CHDTxdAssetBinding>(Pso, d.HDTxdBindingArray);

            Interiors = PsoTypes.GetObjectArray <YmfInterior, CInteriorBoundsFiles>(Pso, d.Interiors);
        }
예제 #9
0
        public void Load(byte[] data, RpfFileEntry entry)
        {
            Name         = entry.Name;
            RpfFileEntry = entry;
            RpfResourceFileEntry resentry = entry as RpfResourceFileEntry;

            if (resentry == null)
            {
                MemoryStream ms = new MemoryStream(data);
                if (RbfFile.IsRBF(ms))
                {
                    Rbf = new RbfFile();
                    Rbf.Load(ms);
                }
                else if (PsoFile.IsPSO(ms))
                {
                    Pso = new PsoFile();
                    Pso.Load(ms);
                    //PsoTypes.EnsurePsoTypes(Pso);
                }
                else
                {
                }
                return;
            }



            ResourceDataReader rd = new ResourceDataReader(resentry, data);

            Meta = rd.ReadBlock <Meta>();


            _CMapTypes = MetaTypes.GetTypedData <CMapTypes>(Meta, MetaName.CMapTypes);


            List <Archetype> allarchs = new List <Archetype>();

            var ptrs = MetaTypes.GetPointerArray(Meta, _CMapTypes.archetypes);

            if (ptrs != null)
            {
                for (int i = 0; i < ptrs.Length; i++)
                {
                    var ptr    = ptrs[i];
                    var offset = ptr.Offset;
                    var block  = Meta.GetBlock(ptr.BlockID);
                    if (block == null)
                    {
                        continue;
                    }
                    if ((offset < 0) || (block.Data == null) || (offset >= block.Data.Length))
                    {
                        continue;
                    }

                    Archetype a = null;
                    switch (block.StructureNameHash)
                    {
                    case MetaName.CBaseArchetypeDef:
                        var basearch = PsoTypes.ConvertDataRaw <CBaseArchetypeDef>(block.Data, offset);
                        a = new Archetype();
                        a.Init(this, ref basearch);
                        a.Extensions = MetaTypes.GetExtensions(Meta, basearch.extensions);
                        break;

                    case MetaName.CTimeArchetypeDef:
                        var timearch = PsoTypes.ConvertDataRaw <CTimeArchetypeDef>(block.Data, offset);
                        var ta       = new TimeArchetype();
                        ta.Init(this, ref timearch);
                        ta.Extensions = MetaTypes.GetExtensions(Meta, timearch._BaseArchetypeDef.extensions);
                        a             = ta;
                        break;

                    case MetaName.CMloArchetypeDef:
                        var mloarch = PsoTypes.ConvertDataRaw <CMloArchetypeDef>(block.Data, offset);
                        var ma      = new MloArchetype();
                        ma.Init(this, ref mloarch);
                        ma.Extensions = MetaTypes.GetExtensions(Meta, mloarch._BaseArchetypeDef.extensions);

                        ma.LoadChildren(Meta);

                        a = ma;
                        break;

                    default:
                        continue;
                    }

                    if (a != null)
                    {
                        allarchs.Add(a);
                    }
                }
            }
            AllArchetypes = allarchs.ToArray();


            Extensions = MetaTypes.GetExtensions(Meta, _CMapTypes.extensions);

            if (Extensions != null)
            {
            }


            //AudioEmitters = MetaTypes.GetTypedDataArray<CExtensionDefAudioEmitter>(Meta, MetaName.CExtensionDefAudioEmitter);
            //if (AudioEmitters != null)
            //{ }

            //CEntityDefs = MetaTypes.GetTypedDataArray<CEntityDef>(Meta, MetaName.CEntityDef);


            CompositeEntityTypes = MetaTypes.ConvertDataArray <CCompositeEntityType>(Meta, MetaName.CCompositeEntityType, _CMapTypes.compositeEntityTypes);
            if (CompositeEntityTypes != null)
            {
            }

            NameHash = _CMapTypes.name;
            if (NameHash == 0)
            {
                int ind = entry.NameLower.LastIndexOf('.');
                if (ind > 0)
                {
                    NameHash = JenkHash.GenHash(entry.NameLower.Substring(0, ind));
                }
                else
                {
                    NameHash = JenkHash.GenHash(entry.NameLower);
                }
            }

            Strings = MetaTypes.GetStrings(Meta);
            if (Strings != null)
            {
                foreach (string str in Strings)
                {
                    JenkIndex.Ensure(str); //just shove them in there
                }
            }


            //foreach (var block in Meta.DataBlocks)
            //{
            //    switch(block.StructureNameHash)
            //    {
            //        case MetaName.CMapTypes:
            //        case MetaName.CTimeArchetypeDef:
            //        case MetaName.CBaseArchetypeDef:
            //        case MetaName.CMloArchetypeDef:
            //        case MetaName.CMloTimeCycleModifier:
            //        case MetaName.CMloRoomDef:
            //        case MetaName.CMloPortalDef:
            //        case MetaName.CMloEntitySet:
            //        case MetaName.CEntityDef:
            //        case MetaName.CExtensionDefParticleEffect:
            //        case MetaName.CExtensionDefAudioCollisionSettings:
            //        case MetaName.CExtensionDefSpawnPoint:
            //        case MetaName.CExtensionDefSpawnPointOverride:
            //        case MetaName.CExtensionDefExplosionEffect:
            //        case MetaName.CExtensionDefAudioEmitter:
            //        case MetaName.CExtensionDefLadder:
            //        case MetaName.CExtensionDefBuoyancy:
            //        case MetaName.CExtensionDefExpression:
            //        case MetaName.CExtensionDefLightShaft:
            //        case MetaName.CExtensionDefLightEffect:
            //        case MetaName.CExtensionDefDoor:
            //        case MetaName.CExtensionDefWindDisturbance:
            //        case MetaName.CExtensionDefProcObject:
            //        case MetaName.CLightAttrDef:
            //        case (MetaName)MetaTypeName.STRING:
            //        case (MetaName)MetaTypeName.POINTER:
            //        case (MetaName)MetaTypeName.UINT:
            //        case (MetaName)MetaTypeName.VECTOR4:
            //            break;
            //        default:
            //            break;
            //    }
            //}



            //MetaTypes.ParseMetaData(Meta);
        }
예제 #10
0
 public override void Init(PsoFile pso, ref CInteriorBoundsFiles v)
 {
     Interior = v;
     Bounds   = PsoTypes.GetHashArray(pso, v.Bounds);
 }
예제 #11
0
        }                                           //ytyp hashes?

        public override void Init(PsoFile pso, ref CItypDependencies v)
        {
            Dep          = v;
            itypDepArray = PsoTypes.GetHashArray(pso, v.itypDepArray);
        }
예제 #12
0
        public void Load(byte[] data, RpfFileEntry entry)
        {
            RpfFileEntry = entry;
            Name         = entry.Name;
            FilePath     = Name;


            RpfResourceFileEntry resentry = entry as RpfResourceFileEntry;

            if (resentry != null)
            {
                ResourceDataReader rd = new ResourceDataReader(resentry, data);

                Meta = rd.ReadBlock <Meta>();

                var rootblock = Meta.GetRootBlock();
                if (rootblock != null)
                {
                    if (rootblock.StructureNameHash == MetaName.CScenarioPointRegion)
                    {
                        LoadScenarioPointRegion(Meta, rootblock);
                    }
                }

                Loaded = true;
                return;
            }


            MemoryStream ms = new MemoryStream(data);

            if (RbfFile.IsRBF(ms))
            {
                Rbf = new RbfFile();
                var rbfstruct = Rbf.Load(ms);

                if (rbfstruct.Name == "CMapParentTxds")
                {
                    LoadMapParentTxds(rbfstruct);
                }



                Loaded = true;
                return;
            }
            if (PsoFile.IsPSO(ms))
            {
                Pso = new PsoFile();
                Pso.Load(ms);

                //PsoTypes.EnsurePsoTypes(Pso);

                var root = PsoTypes.GetRootEntry(Pso);
                if (root != null)
                {
                    if (root.NameHash == MetaName.CScenarioPointManifest)
                    {
                        LoadScenarioPointManifest(Pso);
                    }
                }


                Loaded = true;
                return;
            }
            else
            {
            }
        }
예제 #13
0
파일: YmfFile.cs 프로젝트: rt-2/CodeWalker
 public override void Init(PsoFile pso, ref Unk_741495440 v)
 {
     Interior = v;
     Bounds   = PsoTypes.GetHashArray(pso, v.Bounds);
 }
예제 #14
0
        private static byte[] Traverse(XmlNode node, PsoBuilder pb, MetaName type = 0, bool isRoot = false)
        {
            if (type == 0)
            {
                type = (MetaName)(uint)GetHash(node.Name);
            }

            var infos = PsoTypes.GetStructureInfo(type);

            if (infos != null)
            {
                byte[] data         = new byte[infos.StructureLength];
                var    arrayResults = new PsoArrayResults();

                arrayResults.Structures        = new Dictionary <int, Array_Structure>();
                arrayResults.StructurePointers = new Dictionary <int, Array_StructurePointer>();
                arrayResults.UInts             = new Dictionary <int, Array_uint>();
                arrayResults.UShorts           = new Dictionary <int, Array_ushort>();
                arrayResults.UBytes            = new Dictionary <int, Array_byte>();
                arrayResults.Floats            = new Dictionary <int, Array_float>();
                arrayResults.Float_XYZs        = new Dictionary <int, Array_Vector3>();
                arrayResults.Hashes            = new Dictionary <int, Array_uint>();

                Array.Clear(data, 0, infos.StructureLength); //shouldn't really be necessary...

                PsoStructureEntryInfo arrEntry = null;


                //if (isRoot)
                //{
                //    pb.EnsureBlock(type);
                //}

                for (int i = 0; i < infos.Entries.Length; i++)
                {
                    var entry = infos.Entries[i];
                    var cnode = GetEntryNode(node.ChildNodes, entry.EntryNameHash);

                    if (entry.EntryNameHash == (MetaName)MetaTypeName.ARRAYINFO)
                    {
                        arrEntry = entry;
                        continue;
                    }

                    if (cnode == null)
                    {
                        //warning: node not found in XML for this entry!
                        continue;
                    }

                    switch (entry.Type)
                    {
                    case PsoDataType.Array:
                    {
                        TraverseArray(cnode, pb, entry, arrEntry, arrayResults, data, infos);
                        break;
                    }

                    case PsoDataType.Structure:
                    {
                        var stype = (MetaName)entry.ReferenceKey;
                        if (stype == 0)
                        {
                            var stypestr = Xml.GetStringAttribute(cnode, "type");
                            if (!string.IsNullOrEmpty(stypestr))
                            {
                                stype = (MetaName)(uint)GetHash(stypestr);
                            }
                        }
                        var struc = Traverse(cnode, pb, stype);
                        if (struc != null)
                        {
                            switch (entry.Unk_5h)
                            {
                            default:
                                //ErrorXml(sb, cind, ename + ": Unexpected Structure subtype: " + entry.Unk_5h.ToString());
                                break;

                            case 0:             //default structure

                                Buffer.BlockCopy(struc, 0, data, entry.DataOffset, struc.Length);

                                break;

                            case 3:             //structure pointer...
                            case 4:             //also pointer? what's the difference?

                                var bptr = pb.AddItem(stype, struc);
                                var ptr  = new PsoPOINTER(bptr.BlockID, bptr.Offset);
                                ptr.SwapEnd();
                                var ptrb = MetaTypes.ConvertToBytes(ptr);

                                Buffer.BlockCopy(ptrb, 0, data, entry.DataOffset, ptrb.Length);

                                break;
                            }
                        }
                        else
                        {
                        }
                        break;
                    }

                    case PsoDataType.Map:
                    {
                        TraverseMap(cnode, pb, entry, infos, data, arrayResults);

                        break;
                    }

                    case PsoDataType.Bool:
                    {
                        byte val = (cnode.Attributes["value"].Value == "false") ? (byte)0 : (byte)1;
                        data[entry.DataOffset] = val;
                        break;
                    }

                    case PsoDataType.SByte:
                    {
                        var val = Convert.ToSByte(cnode.Attributes["value"].Value);
                        data[entry.DataOffset] = (byte)val;
                        break;
                    }

                    case PsoDataType.UByte:
                    {
                        var val = Convert.ToByte(cnode.Attributes["value"].Value);
                        data[entry.DataOffset] = val;
                        break;
                    }

                    case PsoDataType.SShort:
                    {
                        var val = Convert.ToInt16(cnode.Attributes["value"].Value);
                        Write(val, data, entry.DataOffset);
                        break;
                    }

                    case PsoDataType.UShort:
                    {
                        var val = Convert.ToUInt16(cnode.Attributes["value"].Value);
                        Write(val, data, entry.DataOffset);
                        break;
                    }

                    case PsoDataType.SInt:
                    {
                        var val = Convert.ToInt32(cnode.Attributes["value"].Value);
                        Write(val, data, entry.DataOffset);
                        break;
                    }

                    case PsoDataType.UInt:
                    {
                        switch (entry.Unk_5h)
                        {
                        default:
                            //ErrorXml(sb, cind, ename + ": Unexpected Integer subtype: " + entry.Unk_5h.ToString());
                            break;

                        case 0:             //signed int (? flags?)
                            var sval = Convert.ToInt32(cnode.Attributes["value"].Value);
                            Write(sval, data, entry.DataOffset);
                            break;

                        case 1:             //unsigned int
                            var  ustr = cnode.Attributes["value"].Value;
                            uint uval = 0;
                            if (ustr.StartsWith("0x"))
                            {
                                ustr = ustr.Substring(2);
                                uval = Convert.ToUInt32(ustr, 16);
                            }
                            else
                            {
                                uval = Convert.ToUInt32(ustr);
                            }
                            Write(uval, data, entry.DataOffset);
                            break;
                        }

                        break;
                    }

                    case PsoDataType.Float:
                    {
                        float val = FloatUtil.Parse(cnode.Attributes["value"].Value);
                        Write(val, data, entry.DataOffset);
                        break;
                    }

                    case PsoDataType.Float2:
                    {
                        float x = FloatUtil.Parse(cnode.Attributes["x"].Value);
                        float y = FloatUtil.Parse(cnode.Attributes["y"].Value);
                        Write(x, data, entry.DataOffset);
                        Write(y, data, entry.DataOffset + sizeof(float));
                        break;
                    }

                    case PsoDataType.Float3:
                    {
                        float x = FloatUtil.Parse(cnode.Attributes["x"].Value);
                        float y = FloatUtil.Parse(cnode.Attributes["y"].Value);
                        float z = FloatUtil.Parse(cnode.Attributes["z"].Value);
                        Write(x, data, entry.DataOffset);
                        Write(y, data, entry.DataOffset + sizeof(float));
                        Write(z, data, entry.DataOffset + sizeof(float) * 2);
                        break;
                    }

                    case PsoDataType.Float4:
                    {
                        float x = FloatUtil.Parse(cnode.Attributes["x"].Value);
                        float y = FloatUtil.Parse(cnode.Attributes["y"].Value);
                        float z = FloatUtil.Parse(cnode.Attributes["z"].Value);
                        float w = FloatUtil.Parse(cnode.Attributes["w"].Value);
                        Write(x, data, entry.DataOffset);
                        Write(y, data, entry.DataOffset + sizeof(float));
                        Write(z, data, entry.DataOffset + sizeof(float) * 2);
                        Write(w, data, entry.DataOffset + sizeof(float) * 3);
                        break;
                    }

                    case PsoDataType.String:
                    {
                        TraverseString(cnode, pb, entry, data);
                        break;
                    }

                    case PsoDataType.Enum:
                    {
                        pb.AddEnumInfo((MetaName)entry.ReferenceKey);
                        switch (entry.Unk_5h)
                        {
                        default:
                            //ErrorXml(sb, cind, ename + ": Unexpected Enum subtype: " + entry.Unk_5h.ToString());
                            break;

                        case 0:             //int enum
                            int ival = GetEnumInt((MetaName)entry.ReferenceKey, cnode.InnerText, entry.Type);
                            Write(ival, data, entry.DataOffset);
                            break;

                        case 1:             //short enum?
                            short sval = (short)GetEnumInt((MetaName)entry.ReferenceKey, cnode.InnerText, entry.Type);
                            Write(sval, data, entry.DataOffset);
                            break;

                        case 2:             //byte enum
                            byte bval = (byte)GetEnumInt((MetaName)entry.ReferenceKey, cnode.InnerText, entry.Type);
                            data[entry.DataOffset] = bval;
                            break;
                        }
                        break;
                    }

                    case PsoDataType.Flags:
                    {
                        //uint fCount = (entry.ReferenceKey >> 16) & 0x0000FFFF;
                        uint        fEntry    = (entry.ReferenceKey & 0xFFF);
                        var         fEnt      = (fEntry != 0xFFF) ? infos.GetEntry((int)fEntry) : null;
                        PsoEnumInfo flagsInfo = null;
                        MetaName    fEnum     = (MetaName)(fEnt?.ReferenceKey ?? 0);
                        if ((fEnt != null) && (fEnt.EntryNameHash == (MetaName)MetaTypeName.ARRAYINFO))
                        {
                            flagsInfo = PsoTypes.GetEnumInfo(fEnum);
                        }
                        if (flagsInfo == null)
                        {
                            if (fEntry != 0xFFF)
                            {
                            }
                            //flagsInfo = PsoTypes.GetEnumInfo(entry.EntryNameHash);
                        }
                        if (flagsInfo != null)
                        {
                            pb.AddEnumInfo(flagsInfo.IndexInfo.NameHash);
                        }
                        else
                        {
                        }          //error?

                        switch (entry.Unk_5h)
                        {
                        default:
                            //ErrorXml(sb, cind, ename + ": Unexpected Flags subtype: " + entry.Unk_5h.ToString());
                            break;

                        case 0:             //int flags
                            int ival = GetEnumInt(fEnum, cnode.InnerText, entry.Type);
                            Write(ival, data, entry.DataOffset);
                            break;

                        case 1:             //short flags
                            short sval = (short)GetEnumInt(fEnum, cnode.InnerText, entry.Type);
                            Write(sval, data, entry.DataOffset);
                            break;

                        case 2:             //byte flags
                            byte bval = (byte)GetEnumInt(fEnum, cnode.InnerText, entry.Type);
                            data[entry.DataOffset] = bval;
                            break;
                        }
                        break;
                    }

                    case PsoDataType.Float3a:
                    {
                        float x = FloatUtil.Parse(cnode.Attributes["x"].Value);
                        float y = FloatUtil.Parse(cnode.Attributes["y"].Value);
                        float z = FloatUtil.Parse(cnode.Attributes["z"].Value);
                        Write(x, data, entry.DataOffset);
                        Write(y, data, entry.DataOffset + sizeof(float));
                        Write(z, data, entry.DataOffset + sizeof(float) * 2);
                        break;
                    }

                    case PsoDataType.Float4a:
                    {
                        float x = FloatUtil.Parse(cnode.Attributes["x"].Value);
                        float y = FloatUtil.Parse(cnode.Attributes["y"].Value);
                        float z = FloatUtil.Parse(cnode.Attributes["z"].Value);
                        //float w = FloatUtil.Parse(cnode.Attributes["w"].Value);
                        Write(x, data, entry.DataOffset);
                        Write(y, data, entry.DataOffset + sizeof(float));
                        Write(z, data, entry.DataOffset + sizeof(float) * 2);
                        //Write(w, data, entry.DataOffset + sizeof(float) * 3);
                        break;
                    }

                    case PsoDataType.HFloat:
                    {
                        var val = Convert.ToInt16(cnode.Attributes["value"].Value);
                        Write(val, data, entry.DataOffset);
                        break;
                    }

                    case PsoDataType.Long:
                    {
                        var uval = Convert.ToUInt64(cnode.Attributes["value"].Value);
                        Write(uval, data, entry.DataOffset);
                        break;
                    }


                    default:
                        break;
                    }
                }


                arrayResults.WriteArrays(data);

                pb.AddStructureInfo(infos.IndexInfo.NameHash);

                if (isRoot)
                {
                    pb.RootPointer = pb.AddItem(type, data);
                }

                return(data);
            }
            else
            {
            }  //info not found

            return(null);
        }
예제 #15
0
        public PsoStructureInfo AddMapNodeStructureInfo(MetaName valType)
        {
            PsoStructureInfo inf = null;

            if (valType == 0)
            {
                inf = PsoTypes.GetStructureInfo((MetaName)MetaTypeName.ARRAYINFO); //default ARRAYINFO with pointer
                if (!StructureInfos.ContainsKey(inf.IndexInfo.NameHash))
                {
                    StructureInfos[inf.IndexInfo.NameHash] = inf;
                }
                return(inf);
            }

            var structInfo = PsoTypes.GetStructureInfo(valType);

            if (structInfo == null)
            {
            }  //error?

            MetaName xName  = (MetaName)MetaTypeName.ARRAYINFO + 1; //257
            bool     nameOk = !StructureInfos.ContainsKey(xName);

            while (!nameOk)
            {
                var exInfo     = StructureInfos[xName];
                var exInfoItem = exInfo.FindEntry(MetaName.Item);
                if (((MetaName)(exInfoItem?.ReferenceKey ?? 0) == valType))
                {
                    return(exInfo); //this one already exists.. use it!
                }
                xName++;
                nameOk = !StructureInfos.ContainsKey(xName);
            }



            inf = new PsoStructureInfo(xName, 0, 2, 8 + structInfo.StructureLength,
                                       new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
                                       new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, valType)
                                       );

            if (!StructureInfos.ContainsKey(xName))
            {
                StructureInfos[xName] = inf;
            }

            return(inf);


            //switch (valType)
            //{
            //    case MetaName.fwClipDictionaryMetadata: return PsoTypes.GetStructureInfo((MetaName)257);
            //    case MetaName.fwMemoryGroupMetadata: return PsoTypes.GetStructureInfo((MetaName)258);
            //    case (MetaName)3219912345: return PsoTypes.GetStructureInfo((MetaName)259);
            //    case (MetaName)0: return PsoTypes.GetStructureInfo((MetaName)MetaTypeName.ARRAYINFO);
            //    default:
            //        return PsoTypes.GetStructureInfo((MetaName)MetaTypeName.ARRAYINFO);//error?
            //}
            //case (MetaName)257:
            //    return new PsoStructureInfo((MetaName)257, 0, 2, 32,
            //     new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
            //     new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, MetaName.fwClipDictionaryMetadata)
            //    );
            //case (MetaName)258:
            //    return new PsoStructureInfo((MetaName)258, 0, 2, 24,
            //        new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
            //        new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, MetaName.fwMemoryGroupMetadata)
            //    );
            //case (MetaName)259:
            //    return new PsoStructureInfo((MetaName)259, 0, 2, 32,
            //        new PsoStructureEntryInfo(MetaName.Key, PsoDataType.String, 0, 7, 0),
            //        new PsoStructureEntryInfo(MetaName.Item, PsoDataType.Structure, 8, 0, (MetaName)3219912345)
            //    );
            //case (MetaName)3219912345:
            //    return new PsoStructureInfo((MetaName)3219912345, 0, 0, 24,
            //        new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Structure, 0, 0, (MetaName)2356519750),
            //        new PsoStructureEntryInfo(MetaName.Adjustments, PsoDataType.Array, 8, 0, 0)
            //    );
        }
예제 #16
0
        private static void TraverseArray(XmlNode node, PsoBuilder pb, PsoStructureEntryInfo entry, PsoStructureEntryInfo arrEntry, PsoArrayResults results, byte[] data, PsoStructureInfo structInfo)
        {
            int  offset = entry.DataOffset;
            uint aCount = (entry.ReferenceKey >> 16) & 0x0000FFFF;
            uint aPtr   = (entry.ReferenceKey) & 0x0000FFFF;

            byte[] adata = null;

            //how do we know when it's an "embedded" array?
            bool embedded = true;

            switch (entry.Unk_5h)
            {
            default:
                //ErrorXml(sb, indent, ename + ": WIP! Unsupported Array subtype: " + entry.Unk_5h.ToString());
                break;

            case 0:     //Array_Structure
                //var arrStruc = MetaTypes.ConvertData<Array_Structure>(data, eoffset);
                embedded = false;
                break;

            case 1:     //Raw in-line array
                break;

            case 2:     //also raw in-line array, but how different from above?
                break;

            case 4:                       //pointer array? default array?
                if (arrEntry.Unk_5h == 3) //pointers...
                {
                    //var arrStruc4 = MetaTypes.ConvertData<Array_Structure>(data, eoffset);
                    embedded = false;
                }
                else
                {
                }
                break;

            case 129:     //also raw inline array? in junctions.pso  (AutoJunctionAdjustments)
                break;
            }



            switch (arrEntry.Type)
            {
            case PsoDataType.Structure:
            {
                if (embedded)
                {
                    if (arrEntry.ReferenceKey != 0)
                    {
                        var datas   = TraverseArrayStructureRaw(node, pb, (MetaName)arrEntry.ReferenceKey);
                        int aoffset = offset;
                        for (int i = 0; i < datas.Length; i++)
                        {
                            Buffer.BlockCopy(datas[i], 0, data, aoffset, datas[i].Length);
                            aoffset += datas[i].Length;
                        }
                    }
                    else
                    {
                        var ptrs = TraverseArrayStructurePointerRaw(node, pb);
                        adata = MetaTypes.ConvertArrayToBytes(ptrs);
                    }
                }
                else
                {
                    if (arrEntry.ReferenceKey != 0)
                    {
                        results.Structures[offset] = TraverseArrayStructure(node, pb, (MetaName)arrEntry.ReferenceKey);
                    }
                    else
                    {
                        results.StructurePointers[offset] = TraverseArrayStructurePointer(node, pb);
                    }
                }
                break;
            }

            case PsoDataType.Float2:
            {
                var arr = TraverseVector2ArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 8;
                }
                else
                {
                    results.Float_XYZs[offset] = pb.AddVector2ArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.Float3:
            {
                var arr = TraverseVector3ArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 16;
                }
                else
                {
                    results.Float_XYZs[offset] = pb.AddPaddedVector3ArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.UByte:
            {
                var arr = TraverseUByteArrayRaw(node);
                if (embedded)
                {
                    adata = arr;
                }
                else
                {
                    results.UBytes[offset] = pb.AddByteArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.Bool:
            {
                var arr = TraverseUByteArrayRaw(node);
                if (embedded)
                {
                    adata = arr;
                }
                else
                {
                    results.UBytes[offset] = pb.AddByteArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.UInt:
            {
                var arr = TraverseUIntArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 4;
                }
                else
                {
                    results.UInts[offset] = pb.AddUIntArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.SInt:
            {
                var arr = TraverseSIntArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 4;
                }
                else
                {
                    results.UInts[offset] = pb.AddSIntArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.Float:
            {
                var arr = TraverseFloatArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 4;
                }
                else
                {
                    results.Floats[offset] = pb.AddFloatArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.UShort:
            {
                var arr = TraverseUShortArrayRaw(node);
                if (embedded)
                {
                    adata   = MetaTypes.ConvertArrayToBytes(arr);
                    aCount *= 2;
                }
                else
                {
                    results.UShorts[offset] = pb.AddUShortArrayPtr(arr);
                }
                break;
            }

            case PsoDataType.String:
            {
                switch (entry.Unk_5h)
                {
                default:
                    //ErrorXml(sb, indent, ename + ": Unexpected String array subtype: " + entry.Unk_5h.ToString());
                    break;

                case 0:             //hash array...
                    var hashes = TraverseHashArrayRaw(node);
                    if (embedded)
                    {
                        adata   = MetaTypes.ConvertArrayToBytes(hashes);
                        aCount *= 4;
                    }
                    else
                    {
                        results.Hashes[offset] = pb.AddHashArrayPtr(hashes);
                    }
                    break;
                }


                break;
            }


            case PsoDataType.Enum:
            {
                var hashes = TraverseHashArrayRaw(node);

                if (arrEntry.ReferenceKey != 0)
                {
                    var _infos = PsoTypes.GetEnumInfo((MetaName)arrEntry.ReferenceKey);
                    pb.AddEnumInfo(_infos.IndexInfo.NameHash);

                    var values = new uint[hashes.Length];
                    for (int i = 0; i < hashes.Length; i++)
                    {
                        var enumname = (MetaName)MetaTypes.SwapBytes(hashes[i]);        //yeah swap it back to little endian..!
                        var enuminf  = _infos.FindEntryByName(enumname);
                        if (enuminf != null)
                        {
                            values[i] = MetaTypes.SwapBytes((uint)enuminf.EntryKey);
                        }
                        else
                        {
                        }           //error?
                    }

                    if (embedded)
                    {
                    }           //TODO?
                    else
                    {
                        results.UInts[offset] = pb.AddUIntArrayPtr(values);
                    }
                }
                else
                {
                }


                break;
            }


            case PsoDataType.Array:
            {
                //array array...
                var rk0 = (entry.ReferenceKey >> 16) & 0x0000FFFF;
                var rk1 = arrEntry.ReferenceKey & 0x0000FFFF;
                if (rk0 > 0)         //should be count of items
                {
                    var subarrEntry = structInfo.GetEntry((int)rk1);
                    var subarrType  = (MetaName)subarrEntry.ReferenceKey;

                    var origOffset = arrEntry.DataOffset;
                    arrEntry.DataOffset = entry.DataOffset;        //slight hack for traversing array array
                    foreach (XmlNode cnode in node.ChildNodes)
                    {
                        TraverseArray(cnode, pb, arrEntry, subarrEntry, results, data, structInfo);

                        arrEntry.DataOffset += 16;        //ptr size... todo: what if not pointer array?
                    }
                    arrEntry.DataOffset = origOffset;
                }


                break;
            }



            default:
                break;
            }

            if (embedded)
            {
                if (adata?.Length > 0)
                {
                    if (adata.Length > aCount)
                    {
                    }  //bad! old data won't fit in new slot...

                    Buffer.BlockCopy(adata, 0, data, offset, adata.Length);
                }
                else
                {
                }
            }
        }
예제 #17
0
        public void Load(byte[] data, RpfFileEntry entry)
        {
            FileEntry = entry;
            RpfResourceFileEntry resentry = entry as RpfResourceFileEntry;

            if (resentry == null)
            {
                MemoryStream ms = new MemoryStream(data);
                if (RbfFile.IsRBF(ms))
                {
                    Rbf = new RbfFile();
                    Rbf.Load(ms);
                }
                else if (PsoFile.IsPSO(ms))
                {
                    Pso = new PsoFile();
                    Pso.Load(ms);
                    //PsoTypes.EnsurePsoTypes(Pso);
                }
                else
                {
                }
                return;
            }



            ResourceDataReader rd = new ResourceDataReader(resentry, data);

            Meta = rd.ReadBlock <Meta>();


            CMapTypes = MetaTypes.GetTypedData <CMapTypes>(Meta, MetaName.CMapTypes);


            List <Archetype> allarchs = new List <Archetype>();

            var ptrs = MetaTypes.GetPointerArray(Meta, CMapTypes.archetypes);

            if (ptrs != null)
            {
                for (int i = 0; i < ptrs.Length; i++)
                {
                    var ptr    = ptrs[i];
                    int blocki = ptr.BlockID - 1;
                    int offset = ptr.ItemOffset * 16;//block data size...
                    if (blocki >= Meta.DataBlocks.Count)
                    {
                        continue;
                    }
                    var block = Meta.DataBlocks[blocki];
                    if ((offset < 0) || (block.Data == null) || (offset >= block.Data.Length))
                    {
                        continue;
                    }

                    var ba = new Archetype();
                    switch (block.StructureNameHash)
                    {
                    case MetaName.CBaseArchetypeDef:
                        var basearch = PsoTypes.ConvertDataRaw <CBaseArchetypeDef>(block.Data, offset);
                        ba.Init(this, basearch);
                        ba.Extensions = MetaTypes.GetExtensions(Meta, basearch.extensions);
                        break;

                    case MetaName.CTimeArchetypeDef:
                        var timearch = PsoTypes.ConvertDataRaw <CTimeArchetypeDef>(block.Data, offset);
                        ba.Init(this, timearch);
                        ba.Extensions = MetaTypes.GetExtensions(Meta, timearch.CBaseArchetypeDef.extensions);
                        break;

                    case MetaName.CMloArchetypeDef:
                        var mloarch = PsoTypes.ConvertDataRaw <CMloArchetypeDef>(block.Data, offset);
                        ba.Init(this, mloarch);
                        ba.Extensions = MetaTypes.GetExtensions(Meta, mloarch.CBaseArchetypeDef.extensions);

                        MloArchetypeData mlod = new MloArchetypeData();
                        mlod.entities           = MetaTypes.ConvertDataArray <CEntityDef>(Meta, MetaName.CEntityDef, mloarch.entities);
                        mlod.rooms              = MetaTypes.ConvertDataArray <CMloRoomDef>(Meta, MetaName.CMloRoomDef, mloarch.rooms);
                        mlod.portals            = MetaTypes.ConvertDataArray <CMloPortalDef>(Meta, MetaName.CMloPortalDef, mloarch.portals);
                        mlod.entitySets         = MetaTypes.ConvertDataArray <CMloEntitySet>(Meta, MetaName.CMloEntitySet, mloarch.entitySets);
                        mlod.timeCycleModifiers = MetaTypes.ConvertDataArray <CMloTimeCycleModifier>(Meta, MetaName.CMloTimeCycleModifier, mloarch.timeCycleModifiers);
                        ba.MloData              = mlod;

                        //if (mlod.entities != null)
                        //{
                        //    for (int e = 0; e < mlod.entities.Length; e++)
                        //    {
                        //        EnsureEntityExtensions(Meta, ref mlod.entities[e]);
                        //    }
                        //}

                        break;

                    default:
                        continue;
                    }


                    allarchs.Add(ba);
                }
            }
            AllArchetypes = allarchs.ToArray();


            Extensions = MetaTypes.GetExtensions(Meta, CMapTypes.extensions);
            if (Extensions != null)
            {
            }


            AudioEmitters = MetaTypes.GetTypedDataArray <CExtensionDefAudioEmitter>(Meta, MetaName.CExtensionDefAudioEmitter);
            if (AudioEmitters != null)
            {
            }

            //CEntityDefs = MetaTypes.GetTypedDataArray<CEntityDef>(Meta, MetaName.CEntityDef);

            CompositeEntityTypes = MetaTypes.ConvertDataArray <CCompositeEntityType>(Meta, MetaName.CCompositeEntityType, CMapTypes.compositeEntityTypes);
            if (CompositeEntityTypes != null)
            {
            }

            NameHash = CMapTypes.name;
            if (NameHash == 0)
            {
                int ind = entry.NameLower.LastIndexOf('.');
                if (ind > 0)
                {
                    NameHash = JenkHash.GenHash(entry.NameLower.Substring(0, ind));
                }
                else
                {
                    NameHash = JenkHash.GenHash(entry.NameLower);
                }
            }

            Strings = MetaTypes.GetStrings(Meta);
            if (Strings != null)
            {
                foreach (string str in Strings)
                {
                    JenkIndex.Ensure(str); //just shove them in there
                }
            }


            foreach (var block in Meta.DataBlocks)
            {
                switch (block.StructureNameHash)
                {
                case MetaName.CMapTypes:
                case MetaName.CTimeArchetypeDef:
                case MetaName.CBaseArchetypeDef:
                case MetaName.CMloArchetypeDef:
                case MetaName.CMloTimeCycleModifier:
                case MetaName.CMloRoomDef:
                case MetaName.CMloPortalDef:
                case MetaName.CMloEntitySet:
                case MetaName.CEntityDef:
                case MetaName.CExtensionDefParticleEffect:
                case MetaName.CExtensionDefAudioCollisionSettings:
                case MetaName.CExtensionDefSpawnPoint:
                case MetaName.CExtensionDefSpawnPointOverride:
                case MetaName.CExtensionDefExplosionEffect:
                case MetaName.CExtensionDefAudioEmitter:
                case MetaName.CExtensionDefLadder:
                case MetaName.CExtensionDefBuoyancy:
                case MetaName.CExtensionDefExpression:
                case MetaName.CExtensionDefLightShaft:
                case MetaName.CExtensionDefLightEffect:
                case MetaName.CExtensionDefDoor:
                case MetaName.CExtensionDefWindDisturbance:
                case MetaName.CExtensionDefProcObject:
                case MetaName.CLightAttrDef:
                case MetaName.STRING:
                //case MetaName.SectionUNKNOWN2:
                //case MetaName.SectionUNKNOWN3:
                //case MetaName.SectionUNKNOWN8:
                case MetaName.POINTER:
                case MetaName.UINT:
                case MetaName.VECTOR4:
                    break;

                default:
                    break;
                }
            }



            //MetaTypes.ParseMetaData(Meta);



            //RpfResourceFileEntry resentry = entry as RpfResourceFileEntry;
            //if (resentry == null)
            //{
            //      throw new Exception("File entry wasn't a resource! (is it binary data?)");
            //}

            //ResourceDataReader rd = new ResourceDataReader(resentry, data);

            //Meta = rd.ReadBlock<Meta>();

            //MetaTypes.EnsureMetaTypes(Meta);

            //MetaTypes.ParseMetaData(Meta);
        }