public void saveIndex() { FileStream dbpffile = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); BinaryReader readFile = new BinaryReader(dbpffile); BinaryWriter writeFile = new BinaryWriter(dbpffile); string dbpfString = Encoding.ASCII.GetString(readFile.ReadBytes(4)); bool longIdx = false; if (dbpfString == "DBBF") { longIdx = true; } int dbpfVersion = readFile.ReadInt32(); dbpffile.Seek(7 * 4, SeekOrigin.Current); int entryCount = readFile.ReadInt32(); int indexSize = 0; int indexSizeHi = 0; int indexStartV2 = 0; int indexStartHi = 0; if (longIdx == true) { indexSize = readFile.ReadInt32(); indexSizeHi = readFile.ReadInt32(); dbpffile.Seek(4 * 2, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); indexStartHi = readFile.ReadInt32(); } else { // Skip old first entry offset readFile.ReadInt32(); indexSize = readFile.ReadInt32(); // Skip 4 entries dbpffile.Seek(4 * 4, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); } // Parse the index dbpffile.Seek(indexStartV2, SeekOrigin.Begin); indexType = readFile.ReadInt32(); // Save the indexes uint globalTypeID = 0; uint globalGroupID = 0; int indexNull = 0; indexRecord indexEntry; switch (indexType) { // Sims 3 uses index types 0 to 3 case 0: for (int i = 0; i < entryCount; i++) { indexEntry = (indexRecord)indexEntries[i]; writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.groupID); writeFile.Write(indexEntry.instanceHi); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); //writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } break; //case 1: // break; case 2: indexEntry = (indexRecord)indexEntries[0]; writeFile.Write(indexEntry.groupID); for (int i = 0; i < entryCount; i++) { indexEntry = (indexRecord)indexEntries[i]; writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.instanceHi); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); //writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } break; case 3: indexEntry = (indexRecord)indexEntries[0]; writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.groupID); for (int i = 0; i < entryCount; i++) { indexEntry = (indexRecord)indexEntries[i]; writeFile.Write(indexEntry.instanceHi); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); //writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } break; // Case 4 is used by both TS3 and Spore case 4: if (longIdx == true) { // Spore? writeFile.Write(indexNull); for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.groupID); writeFile.Write(indexNull); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } } else { // TS3 indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } } break; case 5: if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 5)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 6: if (longIdx == true) { errorMessage = "Type 6 index is not implemented for DBBF format"; break; } if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 6)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 7: if (longIdx == true) { errorMessage = "Type 7 index is not implemented for DBBF format"; break; } if (16 + (entryCount * 20) != indexSize) { errorMessage = "Entry count/index size mismatch (type 7)"; break; } globalTypeID = readFile.ReadUInt32(); globalGroupID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = globalGroupID; indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; default: errorMessage = "Unknown index type"; break; } writeFile.Close(); readFile.Close(); dbpffile.Close(); }
public void replaceIndex(int destIndex, indexRecord indexEntry) { indexEntries[destIndex] = indexEntry; }
public bool open(string filename) { FileStream dbpffile = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader readFile = new BinaryReader(dbpffile); string dbpfString = Encoding.ASCII.GetString(readFile.ReadBytes(4)); if (dbpfString != "DBPF" && dbpfString != "DBBF") { errorMessage = "Not a DBPF/DBBF file"; readFile.Close(); dbpffile.Close(); return false; } bool longIdx = false; if (dbpfString == "DBBF") { longIdx = true; } packageHeader.MajorVersion = readFile.ReadInt32(); if (packageHeader.MajorVersion != 2 && packageHeader.MajorVersion != 3) { errorMessage = "Expecting version 2 or 3!"; readFile.Close(); dbpffile.Close(); return false; } packageHeader.MinorVersion = readFile.ReadInt32(); packageHeader.Unknown0C = readFile.ReadUInt32(); packageHeader.Unknown10 = readFile.ReadUInt32(); packageHeader.Unknown14 = readFile.ReadUInt32(); packageHeader.Unknown18 = readFile.ReadUInt32(); packageHeader.Unknown1C = readFile.ReadUInt32(); packageHeader.Unknown20 = readFile.ReadUInt32(); int entryCount = readFile.ReadInt32(); if (entryCount == 0) { errorMessage = "Empty Archive. Nothing to extract!"; readFile.Close(); dbpffile.Close(); return false; } int indexSize = 0; int indexSizeHi = 0; int indexStartV2 = 0; int indexStartHi = 0; if (longIdx == true) { indexSize = readFile.ReadInt32(); indexSizeHi = readFile.ReadInt32(); dbpffile.Seek(4 * 2, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); indexStartHi = readFile.ReadInt32(); } else { // Skip old first entry offset readFile.ReadInt32(); indexSize = readFile.ReadInt32(); // Skip 4 entries dbpffile.Seek(4 * 4, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); } // Parse the index dbpffile.Seek(indexStartV2, SeekOrigin.Begin); indexType = readFile.ReadInt32(); lookupTypes(); uint globalTypeID = 0; uint globalGroupID = 0; int indexNull = 0; indexRecord indexEntry; switch (indexType) { // Sims 3 uses index types 0 to 3 case 0: if (4 + (entryCount * 32) != indexSize) { errorMessage = "Entry count/index size mismatch (type 0)"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = readFile.ReadUInt32(); indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; //case 1: // break; case 2: if (8 + (entryCount * 28) != indexSize) { errorMessage = "Entry count/index size mismatch (type 2)"; break; } globalGroupID = readFile.ReadUInt32(); for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = globalGroupID; indexEntry.instanceHi = readFile.ReadUInt32(); indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 3: if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 3)"; break; } globalTypeID = readFile.ReadUInt32(); globalGroupID = readFile.ReadUInt32(); for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = globalGroupID; indexEntry.instanceHi = readFile.ReadUInt32(); indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; // Case 4 is used by both TS3 and Spore case 4: if (longIdx == true) { // Spore? if (8 + (entryCount * 32) != indexSize) { errorMessage = "Entry count/index size mismatch (type 4)"; break; } indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = readFile.ReadUInt32(); indexEntry.size = readFile.ReadInt32(); indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } } else { // TS3 if (8 + (entryCount * 28) != indexSize) { errorMessage = "Entry count/index size mismatch (type 4)"; break; } indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } } break; case 5: if (longIdx == true) { errorMessage = "Type 5 index is not implemented for DBBF format"; break; } if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 5)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 6: if (longIdx == true) { errorMessage = "Type 6 index is not implemented for DBBF format"; break; } if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 6)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 7: if (longIdx == true) { errorMessage = "Type 7 index is not implemented for DBBF format"; break; } if (16 + (entryCount * 20) != indexSize) { errorMessage = "Entry count/index size mismatch (type 7)"; break; } globalTypeID = readFile.ReadUInt32(); globalGroupID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = globalGroupID; indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; default: errorMessage = "Unknown index type"; break; } if (errorMessage != "") { readFile.Close(); dbpffile.Close(); return false; } this.filename = filename; readFile.Close(); dbpffile.Close(); return true; }
public bool open(string filename) { FileStream dbpffile = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader readFile = new BinaryReader(dbpffile); string dbpfString = Encoding.ASCII.GetString(readFile.ReadBytes(4)); if (dbpfString != "DBPF" && dbpfString != "DBBF") { errorMessage = "Not a DBPF/DBBF file"; readFile.Close(); dbpffile.Close(); return(false); } bool longIdx = false; if (dbpfString == "DBBF") { longIdx = true; } packageHeader.MajorVersion = readFile.ReadInt32(); if (packageHeader.MajorVersion != 2 && packageHeader.MajorVersion != 3) { errorMessage = "Expecting version 2 or 3!"; readFile.Close(); dbpffile.Close(); return(false); } packageHeader.MinorVersion = readFile.ReadInt32(); packageHeader.Unknown0C = readFile.ReadUInt32(); packageHeader.Unknown10 = readFile.ReadUInt32(); packageHeader.Unknown14 = readFile.ReadUInt32(); packageHeader.Unknown18 = readFile.ReadUInt32(); packageHeader.Unknown1C = readFile.ReadUInt32(); packageHeader.Unknown20 = readFile.ReadUInt32(); int entryCount = readFile.ReadInt32(); if (entryCount == 0) { errorMessage = "Empty Archive. Nothing to extract!"; readFile.Close(); dbpffile.Close(); return(false); } int indexSize = 0; int indexSizeHi = 0; int indexStartV2 = 0; int indexStartHi = 0; if (longIdx == true) { indexSize = readFile.ReadInt32(); indexSizeHi = readFile.ReadInt32(); dbpffile.Seek(4 * 2, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); indexStartHi = readFile.ReadInt32(); } else { // Skip old first entry offset readFile.ReadInt32(); indexSize = readFile.ReadInt32(); // Skip 4 entries dbpffile.Seek(4 * 4, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); } // Parse the index dbpffile.Seek(indexStartV2, SeekOrigin.Begin); indexType = readFile.ReadInt32(); lookupTypes(); uint globalTypeID = 0; uint globalGroupID = 0; int indexNull = 0; indexRecord indexEntry; switch (indexType) { // Sims 3 uses index types 0 to 3 case 0: if (4 + (entryCount * 32) != indexSize) { errorMessage = "Entry count/index size mismatch (type 0)"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = readFile.ReadUInt32(); indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; //case 1: // break; case 2: if (8 + (entryCount * 28) != indexSize) { errorMessage = "Entry count/index size mismatch (type 2)"; break; } globalGroupID = readFile.ReadUInt32(); for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = globalGroupID; indexEntry.instanceHi = readFile.ReadUInt32(); indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 3: if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 3)"; break; } globalTypeID = readFile.ReadUInt32(); globalGroupID = readFile.ReadUInt32(); for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = globalGroupID; indexEntry.instanceHi = readFile.ReadUInt32(); indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; // Case 4 is used by both TS3 and Spore case 4: if (longIdx == true) { // Spore? if (8 + (entryCount * 32) != indexSize) { errorMessage = "Entry count/index size mismatch (type 4)"; break; } indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = readFile.ReadUInt32(); indexEntry.size = readFile.ReadInt32(); indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } } else { // TS3 if (8 + (entryCount * 28) != indexSize) { errorMessage = "Entry count/index size mismatch (type 4)"; break; } indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } } break; case 5: if (longIdx == true) { errorMessage = "Type 5 index is not implemented for DBBF format"; break; } if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 5)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 6: if (longIdx == true) { errorMessage = "Type 6 index is not implemented for DBBF format"; break; } if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 6)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 7: if (longIdx == true) { errorMessage = "Type 7 index is not implemented for DBBF format"; break; } if (16 + (entryCount * 20) != indexSize) { errorMessage = "Entry count/index size mismatch (type 7)"; break; } globalTypeID = readFile.ReadUInt32(); globalGroupID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = globalGroupID; indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; default: errorMessage = "Unknown index type"; break; } if (errorMessage != "") { readFile.Close(); dbpffile.Close(); return(false); } this.filename = filename; readFile.Close(); dbpffile.Close(); return(true); }
public void saveIndex() { FileStream dbpffile = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); BinaryReader readFile = new BinaryReader(dbpffile); BinaryWriter writeFile = new BinaryWriter(dbpffile); string dbpfString = Encoding.ASCII.GetString(readFile.ReadBytes(4)); bool longIdx = false; if (dbpfString == "DBBF") { longIdx = true; } int dbpfVersion = readFile.ReadInt32(); dbpffile.Seek(7 * 4, SeekOrigin.Current); int entryCount = readFile.ReadInt32(); int indexSize = 0; int indexSizeHi = 0; int indexStartV2 = 0; int indexStartHi = 0; if (longIdx == true) { indexSize = readFile.ReadInt32(); indexSizeHi = readFile.ReadInt32(); dbpffile.Seek(4 * 2, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); indexStartHi = readFile.ReadInt32(); } else { // Skip old first entry offset readFile.ReadInt32(); indexSize = readFile.ReadInt32(); // Skip 4 entries dbpffile.Seek(4 * 4, SeekOrigin.Current); indexStartV2 = readFile.ReadInt32(); } // Parse the index dbpffile.Seek(indexStartV2, SeekOrigin.Begin); indexType = readFile.ReadInt32(); // Save the indexes uint globalTypeID = 0; uint globalGroupID = 0; int indexNull = 0; indexRecord indexEntry; switch (indexType) { // Sims 3 uses index types 0 to 3 case 0: for (int i = 0; i < entryCount; i++) { indexEntry = (indexRecord)indexEntries[i]; writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.groupID); writeFile.Write(indexEntry.instanceHi); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); //writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } break; //case 1: // break; case 2: indexEntry = (indexRecord)indexEntries[0]; writeFile.Write(indexEntry.groupID); for (int i = 0; i < entryCount; i++) { indexEntry = (indexRecord)indexEntries[i]; writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.instanceHi); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); //writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } break; case 3: indexEntry = (indexRecord)indexEntries[0]; writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.groupID); for (int i = 0; i < entryCount; i++) { indexEntry = (indexRecord)indexEntries[i]; writeFile.Write(indexEntry.instanceHi); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); //writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } break; // Case 4 is used by both TS3 and Spore case 4: if (longIdx == true) { // Spore? writeFile.Write(indexNull); for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); writeFile.Write(indexEntry.typeID); writeFile.Write(indexEntry.groupID); writeFile.Write(indexNull); writeFile.Write(indexEntry.instance); writeFile.Write(indexEntry.offset); writeFile.Write(indexEntry.offsetHi); writeFile.Write(indexEntry.size); writeFile.Write(indexEntry.realsize); writeFile.Write(indexEntry.flags); } } else { // TS3 indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = readFile.ReadUInt32(); indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } } break; case 5: if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 5)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 6: if (longIdx == true) { errorMessage = "Type 6 index is not implemented for DBBF format"; break; } if (12 + (entryCount * 24) != indexSize) { errorMessage = "Entry count/index size mismatch (type 6)"; break; } globalTypeID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = readFile.ReadUInt32(); indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; case 7: if (longIdx == true) { errorMessage = "Type 7 index is not implemented for DBBF format"; break; } if (16 + (entryCount * 20) != indexSize) { errorMessage = "Entry count/index size mismatch (type 7)"; break; } globalTypeID = readFile.ReadUInt32(); globalGroupID = readFile.ReadUInt32(); indexNull = readFile.ReadInt32(); if (indexNull != 0) { errorMessage = "Invalid index null"; break; } for (int i = 0; i < entryCount; i++) { indexEntry = new indexRecord(); indexEntry.typeID = globalTypeID; indexEntry.groupID = globalGroupID; indexEntry.instanceHi = 0; indexEntry.instance = readFile.ReadUInt32(); indexEntry.offset = readFile.ReadUInt32(); indexEntry.offsetHi = 0; indexEntry.size = readFile.ReadInt32() & 0x7FFFFFFF; indexEntry.realsize = readFile.ReadUInt32(); indexEntry.flags = readFile.ReadInt32(); if ((indexEntry.flags & 0x0000ffff) != 0) { indexEntry.compressed = true; } indexEntry.metaEntry = lookupList.lookup(indexEntry.typeID); indexEntries.Add(indexEntry); } break; default: errorMessage = "Unknown index type"; break; } writeFile.Close(); readFile.Close(); dbpffile.Close(); }
public void replaceIndex(int destIndex, indexRecord indexEntry) { indexEntries[destIndex] = indexEntry; }