Пример #1
0
        public void Parse(string fileDecomp)
        {
            _workingSource = new DataSource(FileMap.FromFile(fileDecomp));
            RFHeader rfheader = *(RFHeader*)_workingSource.Address;
            Header = new RfHeaderObject
            {
                Tag = rfheader._rf,
                HeaderLen1 = rfheader._headerLen1,
                Pad = rfheader._pad0,
                EntriesChunkOffset = rfheader._headerLen2,
                EntriesChunkLen = rfheader._0x18EntriesLen,
                UnixTimestamp = rfheader._unixTimestamp,
                CompressedLen = rfheader._compressedLen,
                DecompressedLen = rfheader._decompressedLen,
                StrsChunkOffset = rfheader._strsPlus,
                StrsChunkLen = rfheader._strsLen,
                EntryCount = rfheader._resourceEntries
            };

            VoidPtr addr = _workingSource.Address + Header.StrsChunkOffset;
            strChunks = new byte[*(uint*)addr][];
            addr += 4;

            for (int i = 0; i < strChunks.Length; i++)
                strChunks[i] = _workingSource.Slice((int)(Header.StrsChunkOffset + 4) + i * 0x2000,
                    0x2000);

            addr += strChunks.Length * 0x2000;
            ExtensionOffsets = new uint[*(uint*)addr];
            Extensions = new string[ExtensionOffsets.Length];
            addr += 4;

            for (int i = 0; i < ExtensionOffsets.Length; i++)
            {
                ExtensionOffsets[i] = *(uint*)(addr + i * 4);
                var ext = Encoding.ASCII.GetString(str_from_offset((int)ExtensionOffsets[i], 64));
                Extensions[i] = ext.Remove(ext.IndexOf('\0'));
            }

            addr = _workingSource.Address + Header.EntriesChunkOffset;
            uint size1 = *(uint*)addr * 8 + 4;
            addr += size1;
            uint size2 = *(uint*)addr + 4;
            addr += size2;

            ResourceEntries = new ResourceEntryObject[Header.EntryCount];

            for (int i = 0; i < Header.EntryCount; i++, addr += 0x18)
            {
                ResourceEntry entry = *(ResourceEntry*)addr;
                ResourceEntryObject rsobj = new ResourceEntryObject()
                {
                    OffInPack = entry.offInPack,
                    NameOffsetEtc = entry.nameOffsetEtc,
                    CmpSize = entry.cmpSize,
                    DecSize = entry.decSize,
                    Timestamp = entry.timestamp,
                    Flags = entry.flags,
                };

                if (rsobj.OffInPack == 0xBBBBBBBB)
                {
                    ResourceEntries[i] = null;
                    continue;
                }

                var strbytes = str_from_offset((int)rsobj.NameOffset, 128);
                var name = Encoding.ASCII.GetString(str_from_offset((int)rsobj.NameOffset, 128));
                if ((entry.nameOffsetEtc & 0x00800000) > 0)
                {
                    var reference = BitConverter.ToUInt16(strbytes, 0);

                    var referenceLen = (reference & 0x1f) + 4;
                    var refReloff = (reference & 0xe0) >> 6 << 8 | (reference >> 8);
                    name = Encoding.ASCII.GetString(str_from_offset((int)rsobj.NameOffset - refReloff, referenceLen)) +
                           name.Substring(2);
                }
                if (name.Contains('\0'))
                    name = name.Substring(0, name.IndexOf('\0'));

                rsobj.EntryString = name + Extensions[rsobj.extIndex];
                ResourceEntries[i] = rsobj;
            }
            //_workingSource.Close();
        }
Пример #2
0
        public void Parse(string fileDecomp)
        {
            _workingSource = new DataSource(FileMap.FromFile(fileDecomp));
            RFHeader rfheader = *(RFHeader *)_workingSource.Address;

            Header = new RfHeaderObject
            {
                Tag                = rfheader._rf,
                RegionEtc          = rfheader._regionEtc,
                HeaderLen1         = rfheader._headerLen1,
                Pad                = rfheader._pad0,
                EntriesChunkOffset = rfheader._headerLen2,
                EntriesChunkLen    = rfheader._0x18EntriesLen,
                UnixTimestamp      = rfheader._unixTimestamp,
                CompressedLen      = rfheader._compressedLen,
                DecompressedLen    = rfheader._decompressedLen,
                StrsChunkOffset    = rfheader._strsPlus,
                StrsChunkLen       = rfheader._strsLen,
                EntryCount         = rfheader._resourceEntries
            };

            VoidPtr addr = _workingSource.Address + Header.StrsChunkOffset;

            strChunks = new byte[*(uint *)addr][];
            addr     += 4;

            for (int i = 0; i < strChunks.Length; i++)
            {
                strChunks[i] = _workingSource.Slice((int)(Header.StrsChunkOffset + 4) + i * 0x2000,
                                                    0x2000);
            }

            addr            += strChunks.Length * 0x2000;
            ExtensionOffsets = new uint[*(uint *)addr];
            Extensions       = new string[ExtensionOffsets.Length];
            addr            += 4;

            for (int i = 0; i < ExtensionOffsets.Length; i++)
            {
                ExtensionOffsets[i] = *(uint *)(addr + i * 4);
                var ext = Encoding.ASCII.GetString(str_from_offset((int)ExtensionOffsets[i], 64));
                Extensions[i] = ext.Remove(ext.IndexOf('\0'));
            }

            addr = _workingSource.Address + Header.EntriesChunkOffset;
            uint size1 = *(uint *)addr * 8 + 4;

            addr += size1;
            uint size2 = *(uint *)addr + 4;

            addr += size2;

            ResourceEntries = new ResourceEntryObject[Header.EntryCount];

            for (int i = 0; i < Header.EntryCount; i++, addr += 0x18)
            {
                ResourceEntry       entry = *(ResourceEntry *)addr;
                ResourceEntryObject rsobj = new ResourceEntryObject()
                {
                    OffInPack     = entry.offInPack,
                    NameOffsetEtc = entry.nameOffsetEtc,
                    CmpSize       = entry.cmpSize,
                    DecSize       = entry.decSize,
                    Timestamp     = entry.timestamp,
                    Flags         = entry.flags,
                };

                if (rsobj.OffInPack == 0xBBBBBBBB)
                {
                    ResourceEntries[i] = null;
                    continue;
                }

                var strbytes = str_from_offset((int)rsobj.NameOffset, 128);
                var name     = Encoding.ASCII.GetString(str_from_offset((int)rsobj.NameOffset, 128));
                if ((entry.nameOffsetEtc & 0x00800000) > 0)
                {
                    var reference = BitConverter.ToUInt16(strbytes, 0);

                    var referenceLen = (reference & 0x1f) + 4;
                    var refReloff    = (reference & 0xe0) >> 6 << 8 | (reference >> 8);
                    name = Encoding.ASCII.GetString(str_from_offset((int)rsobj.NameOffset - refReloff, referenceLen)) +
                           name.Substring(2);
                }
                if (name.Contains('\0'))
                {
                    name = name.Substring(0, name.IndexOf('\0'));
                }

                rsobj.EntryString  = name + Extensions[rsobj.extIndex];
                ResourceEntries[i] = rsobj;
            }
            //_workingSource.Close();
        }