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(); }
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(); }