public DIRFile(DBPFFile file, byte[] bytes) { var stream = new MemoryStream(bytes); reader = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN); var count = 0; while (stream.Position < bytes.Length) { var entry = new DIREntry(); entry.TypeID = reader.ReadUInt32(); entry.GroupID = reader.ReadUInt32(); if (entry.GroupID == 0xFFFFFFFF && file.fname != "") { entry.GroupID = Hash.GroupHash(Path.GetFileNameWithoutExtension(file.fname)); } entry.InstanceID = reader.ReadUInt32(); entry.InstanceID2 = 0x0; if (file.IndexMinorVersion >= 2) { entry.InstanceID2 = reader.ReadUInt32(); } //m_EntryByID.Add((((ulong)entry.InstanceID) << 32) + (ulong)entry.InstanceID2 + (ulong)entry.TypeID, entry); /* * var idEntry = new EntryRef(entry.InstanceID, entry.InstanceID2, entry.TypeID); * if (!m_EntryByID.ContainsKey(idEntry)) * m_EntryByID.Add(idEntry, entry);*/ var idEntry2 = Hash.TGIRHash(entry.InstanceID, entry.InstanceID2, entry.TypeID, entry.GroupID); if (!m_EntryByFullID.ContainsKey(idEntry2)) { m_EntryByFullID.Add(idEntry2, entry); } entry.UncompressedFileSize = reader.ReadUInt32(); count += 1; } reader.Dispose(); stream.Dispose(); }
/// <summary> /// Disposes this DBPF instance. /// </summary> public void Dispose() { Io.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; } } } }
/// <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(); } }
public NeighborhoodTerrainFile(byte[] data, Neighborhood nehood) { var stream = new MemoryStream(data); var io = new IoBuffer(stream); io.ByteOrder = ByteOrder.LITTLE_ENDIAN; var version = io.ReadUInt32(); io.Skip(2); var treeCount = io.ReadUInt32(); for (var i = 0; i < treeCount; i++) { var treeByte = io.ReadByte(); var treeY = io.ReadFloat(); var treeX = io.ReadFloat(); var treeZ = io.ReadFloat(); var treeBBTopLeftY = io.ReadFloat(); var treeBBTopRightX = io.ReadFloat(); var treeBBBotLeftY = io.ReadFloat(); var treeBBBotRightX = io.ReadFloat(); var treeByte2 = io.ReadByte(); var treeRotation = io.ReadFloat(); var treeGUID = io.ReadUInt32(); NHoodDecorationDescription decoResource = null; if (Environment.hoodDecoByGUID.ContainsKey(treeGUID)) { decoResource = Environment.hoodDecoByGUID[treeGUID]; } if (decoResource != null) { var deco = new NHoodDecoration(); deco.description = decoResource; deco.position = new Vector3(treeY, treeZ, treeX); deco.rotation = treeRotation * -1; decos.Add(deco); } //io.Skip(38); // ToDo: Load Trees } io.Skip(2); var roadCount = io.ReadUInt32(); for (var i = 0; i < roadCount; i++) { io.Skip(124); // ToDo: Load Roads } io.Skip(2); var bridgeCount = io.ReadUInt32(); for (var i = 0; i < bridgeCount; i++) { io.Skip(165); // ToDo: Load Bridges } io.Skip(2); var decorationCount = io.ReadUInt32(); for (var i = 0; i < decorationCount; i++) { io.Skip(1); var yPos = io.ReadFloat(); var xPos = io.ReadFloat(); var zPos = io.ReadFloat(); var BBTopLeftY = io.ReadFloat(); var BBTopRightX = io.ReadFloat(); var BBBotLeftY = io.ReadFloat(); var BBBotRightX = io.ReadFloat(); io.Skip(1); var resourceID = io.ReadUInt32(); var rotation = io.ReadFloat(); NHoodDecorationDescription decoResource = null; if (Environment.hoodDecoByGUID.ContainsKey(resourceID)) { decoResource = Environment.hoodDecoByGUID[resourceID]; } if (decoResource != null) { var deco = new NHoodDecoration(); deco.description = decoResource; deco.position = new Vector3(yPos, zPos, xPos); deco.rotation = rotation * -1; decos.Add(deco); } } io.Dispose(); stream.Dispose(); }