public HashFile(string filePath, RootFileSystem rfs) { _path = filePath; _rfs = rfs; if (!File.Exists(_path)) { return; } Fs = File.OpenRead(_path); Entries = new Dictionary <ulong, ScsHashEntry>(); Header = new ScsHeader { Magic = ReadUint(Fs, 0x0), Version = ReadUshort(Fs, 0x04), Salt = ReadUshort(Fs, 0x06), HashMethod = ReadUint(Fs, 0x08), EntryCount = ReadInt(Fs, 0x0C), StartOffset = ReadInt(Fs, 0x10) }; if (Header.Magic != Magic) { Log.Msg("Incorrect File Structure"); return; } if (Header.HashMethod != HashMethod) { Log.Msg("Incorrect Hash Method"); return; } if (Header.Version != SupportedHashVersion) { Log.Msg("Unsupported Hash Version"); return; } for (var i = 0; i < Header.EntryCount; i++) { var offset = Header.StartOffset + i * EntryBlockSize; var entry = new ScsHashEntry { Hash = ReadUlong(Fs, offset), Offset = ReadLong(Fs, offset + 0x08), Flags = ReadUint(Fs, offset + 0x10), Crc = ReadUint(Fs, offset + 0x14), Size = ReadInt(Fs, offset + 0x18), CompressedSize = ReadInt(Fs, offset + 0x1C), Hf = this }; Entries.Add(entry.Hash, entry); } _rfs.AddDirEntry(GetEntry(RootDirHash)); }
public HashFile(string filePath, RootFileSystem rfs) : base(filePath, rfs) { if (!File.Exists(_path)) { return; } Br = new BinaryReader(File.OpenRead(_path)); Entries = new Dictionary <ulong, ScsHashEntry>(); Header = new ScsHeader { Magic = ReadUInt32(Br, 0x0), Version = ReadUInt16(Br, 0x04), Salt = ReadUInt16(Br, 0x06), HashMethod = ReadUInt32(Br, 0x08), EntryCount = ReadInt32(Br, 0x0C), StartOffset = ReadInt32(Br, 0x10) }; if (Header.Magic != Magic) { Log.Msg("Incorrect File Structure"); return; } if (Header.HashMethod != HashMethod) { Log.Msg("Incorrect Hash Method"); return; } if (Header.Version != SupportedHashVersion) { Log.Msg("Unsupported Hash Version"); return; } Br.BaseStream.Seek(Header.StartOffset, SeekOrigin.Begin); var entriesRaw = Br.ReadBytes(Header.EntryCount * EntryBlockSize); for (var i = 0; i < Header.EntryCount; i++) { var offset = i * EntryBlockSize; var entry = new ScsHashEntry { Hash = MemoryHelper.ReadUInt64(entriesRaw, offset), Offset = MemoryHelper.ReadInt64(entriesRaw, offset + 0x08), Flags = MemoryHelper.ReadUInt32(entriesRaw, offset + 0x10), Crc = MemoryHelper.ReadUInt32(entriesRaw, offset + 0x14), Size = MemoryHelper.ReadInt32(entriesRaw, offset + 0x18), CompressedSize = MemoryHelper.ReadInt32(entriesRaw, offset + 0x1C), Hf = this }; Entries.Add(entry.Hash, entry); } var rootDir = GetEntry(RootDirHash); if (rootDir == null) // Try to add important sub directories directly { var defEntry = (ScsHashEntry)GetEntry("def"); if (defEntry != null) { var dir = _rfs.GetDirectory("def"); dir?.AddHashEntry(defEntry); } var mapEntry = (ScsHashEntry)GetEntry("map"); if (mapEntry != null) { var dir = _rfs.GetDirectory("map"); dir?.AddHashEntry(mapEntry); } var materialEntry = (ScsHashEntry)GetEntry("material"); if (materialEntry != null) { var dir = _rfs.GetDirectory("material"); dir?.AddHashEntry(materialEntry); } var prefabEntry = (ScsHashEntry)GetEntry("prefab"); if (prefabEntry != null) { var dir = _rfs.GetDirectory("prefab"); dir?.AddHashEntry(prefabEntry); } var prefab2Entry = (ScsHashEntry)GetEntry("prefab2"); if (prefab2Entry != null) { var dir = _rfs.GetDirectory("prefab2"); dir?.AddHashEntry(prefab2Entry); } var modelEntry = (ScsHashEntry)GetEntry("model"); if (modelEntry != null) { var dir = _rfs.GetDirectory("model"); dir?.AddHashEntry(modelEntry); } var model2Entry = (ScsHashEntry)GetEntry("model2"); if (model2Entry != null) { var dir = _rfs.GetDirectory("model2"); dir?.AddHashEntry(model2Entry); } var localeEntry = (ScsHashEntry)GetEntry("locale"); if (localeEntry != null) { var dir = _rfs.GetDirectory("locale"); if (dir == null) { _rfs.GetRootDirectory()?.AddDirectoryManually("locale", localeEntry); dir = _rfs.GetDirectory("locale"); if (dir == null) { Log.Msg("F**k"); } } dir?.AddHashEntry(localeEntry); } } else { _rfs.AddHashEntry(rootDir); } }
public HashFile(string filePath, RootFileSystem rfs) { _path = filePath; _rfs = rfs; if (!File.Exists(_path)) { return; } Br = new BinaryReader(File.OpenRead(_path)); Entries = new Dictionary <ulong, ScsHashEntry>(); Header = new ScsHeader { Magic = ReadUInt32(Br, 0x0), Version = ReadUInt16(Br, 0x04), Salt = ReadUInt16(Br, 0x06), HashMethod = ReadUInt32(Br, 0x08), EntryCount = ReadInt32(Br, 0x0C), StartOffset = ReadInt32(Br, 0x10) }; if (Header.Magic != Magic) { Log.Msg("Incorrect File Structure"); return; } if (Header.HashMethod != HashMethod) { Log.Msg("Incorrect Hash Method"); return; } if (Header.Version != SupportedHashVersion) { Log.Msg("Unsupported Hash Version"); return; } Br.BaseStream.Seek(Header.StartOffset, SeekOrigin.Begin); var entriesRaw = Br.ReadBytes(Header.EntryCount * EntryBlockSize); for (var i = 0; i < Header.EntryCount; i++) { var offset = i * EntryBlockSize; var entry = new ScsHashEntry { Hash = MemoryHelper.ReadUInt64(entriesRaw, offset), Offset = MemoryHelper.ReadInt64(entriesRaw, offset + 0x08), Flags = MemoryHelper.ReadUInt32(entriesRaw, offset + 0x10), Crc = MemoryHelper.ReadUInt32(entriesRaw, offset + 0x14), Size = MemoryHelper.ReadInt32(entriesRaw, offset + 0x18), CompressedSize = MemoryHelper.ReadInt32(entriesRaw, offset + 0x1C), Hf = this }; Entries.Add(entry.Hash, entry); } _rfs.AddDirEntry(GetEntry(RootDirHash)); }