/// <summary> /// Reads a DBPF archive from a stream. /// </summary> /// <param name="stream">The stream to read from.</param> public void Read(Stream stream) { groupID = Hash.GroupHash(Path.GetFileNameWithoutExtension(fname)); m_EntryByFullID = new Dictionary <int, DBPFEntry>(); m_EntriesList = new List <DBPFEntry>(); var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN); m_Reader = io; this.Io = io; var magic = io.ReadCString(4); if (magic != "DBPF") { throw new Exception("Not a DBPF file"); } var majorVersion = io.ReadUInt32(); var minorVersion = io.ReadUInt32(); var version = majorVersion + (((double)minorVersion) / 10.0); /** Unknown, set to 0 **/ io.Skip(12); if (version <= 1.2) { this.DateCreated = io.ReadInt32(); this.DateModified = io.ReadInt32(); } if (version < 2.0) { IndexMajorVersion = io.ReadUInt32(); } NumEntries = io.ReadUInt32(); uint indexOffset = 0; if (version < 2.0) { indexOffset = io.ReadUInt32(); } var indexSize = io.ReadUInt32(); //uint indexMinor = 0; if (version < 2.0) { var trashEntryCount = io.ReadUInt32(); var trashIndexOffset = io.ReadUInt32(); var trashIndexSize = io.ReadUInt32(); IndexMinorVersion = io.ReadUInt32(); } else if (version == 2.0) { IndexMinorVersion = io.ReadUInt32(); indexOffset = io.ReadUInt32(); io.Skip(4); } /** Padding **/ io.Skip(32); io.Seek(SeekOrigin.Begin, indexOffset); var nameMaps = new List <DBPFEntry>(); var rcols = new List <DBPFEntry>(); for (int i = 0; i < NumEntries; i++) { var entry = new DBPFEntry(); entry.file = this; entry.TypeID = io.ReadUInt32(); entry.GroupID = io.ReadUInt32(); if (entry.GroupID == 0xFFFFFFFF) { entry.GroupID = groupID; } entry.InstanceID = io.ReadUInt32(); if (IndexMinorVersion >= 2) { entry.InstanceID2 = io.ReadUInt32(); } entry.FileOffset = io.ReadUInt32(); entry.FileSize = io.ReadUInt32(); var id = Hash.TGIHash(entry.InstanceID, entry.TypeID, entry.GroupID); var fullID = Hash.TGIRHash(entry.InstanceID, entry.InstanceID2, entry.TypeID, entry.GroupID); m_EntryByID[id] = entry; m_EntryByFullID[fullID] = entry; if (!m_EntriesByType.ContainsKey(entry.TypeID)) { m_EntriesByType.Add(entry.TypeID, new List <DBPFEntry>()); } m_EntriesByType[entry.TypeID].Add(entry); } var dirEntry = GetItemByFullID(Hash.TGIRHash((uint)0x286B1F03, (uint)0x00000000, (uint)0xE86B1EEF, (uint)0xE86B1EEF)); if (dirEntry != null) { hasCompression = true; DIRFile.Read(this, dirEntry); } foreach (var element in nameMaps) { var b1g = GetEntry(element); var stream1 = new MemoryStream(b1g); var read = new IoBuffer(stream1); read.ByteOrder = ByteOrder.LITTLE_ENDIAN; var numNames = read.ReadUInt32(); for (var j = 0; j < numNames; j++) { var gID = read.ReadUInt32(); if (gID == 0xFFFFFFFF) { gID = groupID; } var iID = read.ReadUInt32(); var nameLength = read.ReadUInt32(); var fileNam = read.ReadCString((int)nameLength).ToLower(); DBPFEntry hash = null; hash = GetEntryByID(Hash.TGIHash(iID, element.InstanceID, gID)); var gNam = "##0x" + gID.ToString("x8") + "!" + fileNam; if (hash != null) { m_EntryByName[fileNam] = hash; m_EntryByName[gNam] = hash; } } read.Dispose(); stream1.Dispose(); } }
/// <summary> /// Reads a DBPF archive from a stream. /// </summary> /// <param name="stream">The stream to read from.</param> public void Read(Stream stream, bool global = false, bool isDownload = false) { groupID = Hash.GroupHash(Path.GetFileNameWithoutExtension(fname)); m_EntryByFullID = new Dictionary <int, DBPFEntry>(); m_EntriesList = new List <DBPFEntry>(); var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN); m_Reader = io; this.Io = io; var magic = io.ReadCString(4); if (magic != "DBPF") { throw new Exception("Not a DBPF file"); } var majorVersion = io.ReadUInt32(); var minorVersion = io.ReadUInt32(); var version = majorVersion + (((double)minorVersion) / 10.0); /** Unknown, set to 0 **/ io.Skip(12); if (version <= 1.2) { this.DateCreated = io.ReadInt32(); this.DateModified = io.ReadInt32(); } if (version < 2.0) { IndexMajorVersion = io.ReadUInt32(); } NumEntries = io.ReadUInt32(); uint indexOffset = 0; if (version < 2.0) { indexOffset = io.ReadUInt32(); } var indexSize = io.ReadUInt32(); //uint indexMinor = 0; if (version < 2.0) { var trashEntryCount = io.ReadUInt32(); var trashIndexOffset = io.ReadUInt32(); var trashIndexSize = io.ReadUInt32(); IndexMinorVersion = io.ReadUInt32(); } else if (version == 2.0) { IndexMinorVersion = io.ReadUInt32(); indexOffset = io.ReadUInt32(); io.Skip(4); } /** Padding **/ io.Skip(32); io.Seek(SeekOrigin.Begin, indexOffset); var nameMaps = new List <DBPFEntry>(); var rcols = new List <DBPFEntry>(); for (int i = 0; i < NumEntries; i++) { var entry = new DBPFEntry(); entry.file = this; entry.TypeID = io.ReadUInt32(); entry.GroupID = io.ReadUInt32(); if (entry.GroupID == 0xFFFFFFFF) { entry.GroupID = groupID; } entry.InstanceID = io.ReadUInt32(); if (IndexMinorVersion >= 2) { entry.InstanceID2 = io.ReadUInt32(); } entry.FileOffset = io.ReadUInt32(); entry.FileSize = io.ReadUInt32(); //Debug.Log("Found type: " + entry.TypeID.ToString("x")); //Debug.Log("Instance: " + entry.InstanceID.ToString("x")); //m_EntriesList.Add(entry); //var id = new EntryRef(entry.InstanceID, entry.InstanceID2, entry.TypeID); var id = Hash.TGIHash(entry.InstanceID, entry.TypeID, entry.GroupID); var fullID = Hash.TGIRHash(entry.InstanceID, entry.InstanceID2, entry.TypeID, entry.GroupID); //ulong id = (((ulong)entry.InstanceID) << 32) + (ulong)entry.InstanceID2 + (ulong)entry.TypeID; // if (!m_EntryByID.ContainsKey(id)) m_EntryByID[id] = entry; m_EntryByFullID[fullID] = entry; if (entry.TypeID == 0x4E6D6150) { nameMaps.Add(entry); } if (RCOLFile.RCOLTypeIDs.IndexOf(entry.TypeID) >= 0) { rcols.Add(entry); } //if (!m_EntryByFullID.ContainsKey(fullID)) /* * m_EntryByFullID[fullID] = entry;*/ if (!m_EntriesByType.ContainsKey(entry.TypeID)) { m_EntriesByType.Add(entry.TypeID, new List <DBPFEntry>()); } m_EntriesByType[entry.TypeID].Add(entry); entry.global = global; if (Environment.entryByFullID.ContainsKey(fullID)) { entry.global = false; } if (entry.global) { Environment.entryByID[id] = entry; Environment.entryByFullID[fullID] = entry; if (!Environment.entryByType.ContainsKey(entry.TypeID)) { Environment.entryByType.Add(entry.TypeID, new List <DBPFEntry>()); } Environment.entryByType[entry.TypeID].Add(entry); } } //var dirEntry = GetItemByID((((ulong)0x286B1F03) << 32) + (ulong)0x00000000 + (ulong)0xE86B1EEF); var dirEntry = GetItemByFullID(Hash.TGIRHash((uint)0x286B1F03, (uint)0x00000000, (uint)0xE86B1EEF, (uint)0xE86B1EEF)); if (dirEntry != null) { DIRFile.Read(this, dirEntry); //DIR = new DIRFile(this, dirEntry); } foreach (var element in nameMaps) { var b1g = GetEntry(element); var stream1 = new MemoryStream(b1g); var read = new IoBuffer(stream1); read.ByteOrder = ByteOrder.LITTLE_ENDIAN; var numNames = read.ReadUInt32(); for (var j = 0; j < numNames; j++) { var gID = read.ReadUInt32(); if (gID == 0xFFFFFFFF) { gID = groupID; } var iID = read.ReadUInt32(); var nameLength = read.ReadUInt32(); var fileNam = read.ReadCString((int)nameLength).ToLower(); DBPFEntry hash = null; /* * var gotGlobal = false; * * if (global) * { * hash = Environment.GetEntryTGI(Hash.TGIHash(iID, element.InstanceID, gID)); * gotGlobal = true; * } * else*/ hash = GetEntryByID(Hash.TGIHash(iID, element.InstanceID, gID)); //Debug.Log(filenam); var gNam = "##0x" + gID.ToString("x8") + "!" + fileNam; if (hash != null) { //Debug.Log("Can't find instance (InstanceID: " + iID.ToString("X") + ", TypeID: " + element.InstanceID.ToString("X") + ", GroupID: " + gID.ToString("X") + ") for name '" + fileNam + "/" + gNam + "'(Package:"+fname+")");*/ /* * if (!gotGlobal) * {*/ m_EntryByName[fileNam] = hash; m_EntryByName[gNam] = hash; //} if (hash.global) { Environment.entryByName[fileNam] = hash; Environment.entryByName[gNam] = hash; } } /* * else * Debug.Log("Can't find instance (InstanceID: " + iID.ToString("X") + ", TypeID: " + element.InstanceID.ToString("X") + ", GroupID: " + gID.ToString("X") + ") for name '" + fileNam + "/" + gNam + "'(Package:" + fname + ")");*/ } read.Dispose(); stream1.Dispose(); } if (nameMaps.Count == 0 || isDownload) { foreach (var element in rcols) { var ent = GetEntry(element); var gId = "0x" + element.GroupID.ToString("x8"); var nam = ""; if (element.TypeID == 0xE519C933) { try { nam = RCOLFile.GetCRESName(ent).ToLower(); }catch (Exception e) { } } else if (element.TypeID == 0x7BA3838C) { try { nam = RCOLFile.GetGMNDName(ent).ToLower(); } catch (Exception e) { } } else { try { nam = RCOLFile.GetName(ent).ToLower(); } catch (Exception e) { //Uhmmm... Fail silently! } } var gNam = "##" + gId + "!" + nam; m_EntryByName[nam] = element; m_EntryByName[gNam] = element; if (element.global) { Environment.entryByName[nam] = element; Environment.entryByName[gNam] = element; } } } }