public static Stream getStream(Database db, int typeID, int groupID, long instanceID) { Stream matchChunk = null; int searchType = 0; if (typeID != -1) { searchType += 1; } if (groupID != -1) { searchType += 2; } if (instanceID != -1) { searchType += 4; } bool foundMatch = false; foreach (MadScience.Wrappers.ResourceKey entry in db._Entries.Keys) { //ResourceKey key = db.Entries.Keys[i]; //DatabasePackedFile.Entry entry = db.Entries.Keys[i]; //DatabasePackedFile.Entry entry = db.dbpfEntries[i]; //MadScience.Wrappers.ResourceKey entry = new MadScience.Wrappers.ResourceKey(keyString); switch (searchType) { case 7: if (entry.typeId == typeID && entry.groupId == groupID && entry.instanceId == (ulong)instanceID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; case 6: if (entry.groupId == groupID && entry.instanceId == (ulong)instanceID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; case 5: if (entry.typeId == typeID && entry.instanceId == (ulong)instanceID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; case 4: if (entry.instanceId == (ulong)instanceID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; case 3: if (entry.typeId == typeID && entry.groupId == groupID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; case 2: if (entry.groupId == groupID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; case 1: if (entry.typeId == typeID) { //loadedCasPart = entry; matchChunk = db.GetResourceStream(entry); foundMatch = true; } break; } if (foundMatch) { break; } } return matchChunk; }
public PackageType getType(Database db, bool loopAll) { // Do some quick sanity checks switch (db.dbpf.packageType) { case PackageTypes.genericPackage: break; case PackageTypes.corruptBadDownload: case PackageTypes.corruptChaavik: case PackageTypes.corruptIndex: case PackageTypes.corruptPeggy: case PackageTypes.corruptNotADBPF: case PackageTypes.corruptTXTC: this.isCorrupt = true; this.pType.SubType = ""; this.pType.MainType = db.dbpf.packageType; return this.pType; case PackageTypes.sims3Store: case PackageTypes.sims2Package: case PackageTypes.pngThumbnail: this.pType.SubType = ""; this.pType.MainType = db.dbpf.packageType; return this.pType; } rc.Clear(); this.pType = new PackageType(); //print(db.dbpf.Entries.Count + " entries found"); for (int i = 0; i < db.dbpf.Entries.Count; i++) { DatabasePackedFile.Entry entry = db.dbpf.Entries[i]; if ((entry.Key.typeId == (uint)ResourceTypes.NULL) && (entry.Key.groupId == (uint)ResourceTypes.NULL) && (entry.Key.instanceId == (uint)ResourceTypes.NULL)) { // Check the first 4 bytes of the stream Stream checkDbpf = db.GetResourceStream(entry.Key); string magic = MadScience.StreamHelpers.ReadStringASCII(checkDbpf, 4); if (magic == "DBPF" || magic == "DBBF") // DBPF & DBBF { this.isCorrupt = true; this.pType.MainType = PackageTypes.corruptRecursive; this.pType.SubType = "This package contains another package inside it."; if (!loopAll) return this.pType; } checkDbpf.Close(); } if (entry.Key.typeId == (uint)ResourceTypes.TXTC) { int isValid = checkValidEntry(entry, db); if (isValid > 0) { if (isValid == 2) { this.isCorrupt = true; this.pType.MainType = PackageTypes.corruptTXTC; if (!loopAll) return this.pType; } } } if (entry.Key.typeId == (uint)ResourceTypes.PTRN) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.patternGeneric; if (!loopAll) return this.pType; } if (Enum.IsDefined(typeof(ResourceTypes), entry.Key.typeId)) { if (rc.ContainsKey(Enum.GetName(typeof(ResourceTypes), entry.Key.typeId))) { rc[Enum.GetName(typeof(ResourceTypes), entry.Key.typeId)]++; } else { rc.Add(Enum.GetName(typeof(ResourceTypes), entry.Key.typeId), 1); } } } //print("Done"); if (rc.ContainsKey("WLOT") && rc.ContainsKey("UNKW1")) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.neighbourhood; this.isCorrupt = true; return this.pType; } if (rc.ContainsKey("WLTL") && rc.ContainsKey("ARY2")) { this.pType.MainType = PackageTypes.lot; return this.pType; } if (rc.ContainsKey("SIMO") && rc.ContainsKey("SIME") && rc.ContainsKey("SNAP") && rc.ContainsKey("SNAPL")) { this.pType.MainType = PackageTypes.sim; return this.pType; } //this.pType.MainType = PackageTypes.genericPackage; // Check Objects if (rc.ContainsKey("OBJD")) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.objectGeneric; Stream objStream = MadScience.Package.Search.getStream(db, 0x319E4F1D, -1, -1); if (StreamHelpers.isValidStream(objStream)) { OBJD objd = new OBJD(objStream); this.pType.SubType = objd.ToString(); objd = null; } return this.pType; } if (rc.ContainsKey("S3SA")) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.coremod; } if (rc.ContainsKey("CASP")) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.casPartGeneric; Stream casStream = MadScience.Package.Search.getStream(db, 0x034AEECB, -1, -1); if (StreamHelpers.isValidStream(casStream)) { casPartFile cFile = new casPartFile(); cFile.Load(casStream); this.pType.SubType = cFile.clothingType(); switch (cFile.casType()) { case "Hair": this.pType.MainType = PackageTypes.casPartHair; break; case "Scalp": break; case "Face Overlay": switch (cFile.clothingType()) { case "Lipstick": case "Eyeshadow": case "Eyeliner": case "Blush": case "Makeup": case "Mascara": this.pType.MainType = PackageTypes.casPartMakeup; break; default: this.pType.MainType = PackageTypes.casPartFaceOverlay; break; } break; case "Body": this.pType.MainType = PackageTypes.casPartClothing; this.pType.SubType = cFile.clothingCategory(); // Check the TYPE of clothing we have switch (cFile.clothingType()) { case "Body": case "Top": case "Bottom": case "Shoes": // Check the age too // If we have Toddler OR Child OR Teen, plus other ages bool ageCorrupt = false; //if ((cFile.cFile.ageGender.baby || cFile.cFile.ageGender.toddler || cFile.cFile.ageGender.child || cFile.cFile.ageGender.teen) && (cFile.cFile.ageGender.youngAdult || cFile.cFile.ageGender.adult || cFile.cFile.ageGender.elder)) //{ // ageCorrupt = true; //} // If we have Baby AND any other age... if (cFile.cFile.ageGender.baby && (cFile.cFile.ageGender.toddler || cFile.cFile.ageGender.child || cFile.cFile.ageGender.teen || cFile.cFile.ageGender.youngAdult || cFile.cFile.ageGender.adult || cFile.cFile.ageGender.elder)) { ageCorrupt = true; } // If we have Toddler AND any other age... if (cFile.cFile.ageGender.toddler && (cFile.cFile.ageGender.child || cFile.cFile.ageGender.teen || cFile.cFile.ageGender.youngAdult || cFile.cFile.ageGender.adult || cFile.cFile.ageGender.elder)) { ageCorrupt = true; } // If we have Child AND any other age if (cFile.cFile.ageGender.child && (cFile.cFile.ageGender.teen || cFile.cFile.ageGender.youngAdult || cFile.cFile.ageGender.adult || cFile.cFile.ageGender.elder)) { ageCorrupt = true; } // If we have Teen AND any other age if (cFile.cFile.ageGender.teen && (cFile.cFile.ageGender.youngAdult || cFile.cFile.ageGender.adult || cFile.cFile.ageGender.elder)) { ageCorrupt = true; } if (ageCorrupt) { this.isCorrupt = true; this.pType.MainType = PackageTypes.corruptBadAges; if (!loopAll) return this.pType; } break; default: break; } break; case "Accessory": this.pType.MainType = PackageTypes.casPartAccessory; break; } this.pType.SubType += " (" + cFile.ageGender() + ")"; } return this.pType; } if (rc.ContainsKey("FBLN") && rc.ContainsKey("FACE") && rc.ContainsKey("BOND")) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.casSlider; return this.pType; } if (rc.ContainsKey("_IMG") && rc.Count == 1) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.textureReplacement; } if (rc.Count == 1 && (rc.ContainsKey("_XML") || rc.ContainsKey("_XML2"))) { if (this.pType.MainType == PackageTypes.genericPackage) this.pType.MainType = PackageTypes.xmltuningmod; } return this.pType; }
private bool checkTXTCEntry(DatabasePackedFile.Entry entry, Database db) { if (entry.Key.typeId == 0x033A1435) { //textBox1.Text += " " + entry.Key.ToString() + Environment.NewLine; // textBox1.Text += " Checking for corrupted TGI offset... "; // Quick and dirty way Stream TXTC = db.GetResourceStream(entry.Key); // Read offset, first 4 bytes after ID StreamHelpers.ReadValueU32(TXTC); uint offset = StreamHelpers.ReadValueU32(TXTC); // textBox1.Text += offset.ToString() + "..."; // Seek to this offset + 8 and read the number there. TXTC.Seek(offset + 8, SeekOrigin.Begin); uint numTGIs = StreamHelpers.ReadValueU8(TXTC); // textBox1.Text += numTGIs.ToString() + " TGIs... "; // Since each TGI is 16 bytes we can calculate how many bytes they are. uint tgiSize = numTGIs * 16; uint tgiOffsetEnd = offset + 8 + 1 + tgiSize; //textBox1.Text += "TGI block end is at " + tgiOffsetEnd.ToString() + "..."; if (tgiOffsetEnd == TXTC.Length) { TXTC = null; return true; } else { TXTC = null; return false; } } return true; }
private void btnDumpFromFullbuild2_Click(object sender, EventArgs e) { // Go through the list of DDS files and dump them string s3root = MadScience.Helpers.findSims3Root(); if (s3root != "") { bool hasShownDialog = false; toolStripProgressBar1.Visible = true; toolStripProgressBar1.Minimum = 0; toolStripProgressBar1.Value = 0; toolStripStatusLabel1.Text = "Searching for textures... please wait"; statusStrip1.Refresh(); Stream fbuild2 = File.Open(Path.Combine(s3root, Helpers.getGameSubPath("\\GameData\\Shared\\Packages\\FullBuild2.package")), FileMode.Open, FileAccess.Read, FileShare.Read); MadScience.Wrappers.Database db = new MadScience.Wrappers.Database(fbuild2, true); toolStripProgressBar1.Maximum = casPartSrc.tgi64list.Count; Dictionary<ulong, string> keyNames = new Dictionary<ulong, string>(); long nowTicks = DateTime.Now.Ticks; Console.WriteLine("Started at: " + nowTicks); foreach (MadScience.Wrappers.ResourceKey entry in db._Entries.Keys) { //DatabasePackedFile.Entry entry = db.dbpfEntries[i]; if (entry.typeId == (int)0x0166038C) { keyNames = Helpers.getKeyNames(db.GetResourceStream(entry)); break; } } int numFound = 0; folderBrowserDialog1.SelectedPath = ""; for (int j = 0; j < casPartSrc.tgi64list.Count; j++) { toolStripProgressBar1.Value++; //keyName tgi = new keyName((tgi64)casPartSrc.tgi64list[j]); MadScience.Wrappers.ResourceKey tgi = casPartSrc.tgi64list[j]; if (tgi.typeId == (int)0x736884F1) // VPXY { // Find the meshes, then dump any textures the meshes reference too // Use the VPXY to get the mesh lod Stream vpxyStream = KeyUtils.findKey(tgi, 0); //int numFound = 0; //folderBrowserDialog1.SelectedPath = ""; if (vpxyStream != null) { VPXYFile vpxyFile = new VPXYFile(vpxyStream); // Get the first VPXY internal link if (vpxyFile.vpxy.linkEntries.Count >= 1 && vpxyFile.vpxy.linkEntries[0].tgiList.Count >= 1) { for (int i = 0; i < vpxyFile.vpxy.linkEntries[0].tgiList.Count; i++) { //meshStreams.Add(KeyUtils.findKey(vpxyFile.vpxy.linkEntries[0].tgiList[i], 0)); //KeyUtils.findKey(vpxyFile.vpxy.linkEntries[0].tgiList[i], 0); //ResourceKey entry = vpxyFile.vpxy.linkEntries[0].tgiList[i]; Stream meshFile = KeyUtils.findKey(vpxyFile.vpxy.linkEntries[0].tgiList[i], 0); SimGeomFile sgf = new SimGeomFile(meshFile); if (!hasShownDialog) { folderBrowserDialog1.Description = "Please select a folder to save the extracted textures to."; folderBrowserDialog1.ShowDialog(); hasShownDialog = true; } if (folderBrowserDialog1.SelectedPath != "") { string extension = ""; for (int k = 0; k < sgf.simgeom.keytable.keys.Count; k++) { ResourceKey entry = sgf.simgeom.keytable.keys[k]; if (entry.typeId == 0x00B2D882) { extension = ".dds"; string fileNameToSave = ""; if (keyNames.ContainsKey(entry.instanceId)) { fileNameToSave = keyNames[entry.instanceId]; if (fileNameToSave.Contains("0x") == false) { fileNameToSave += "_0x" + entry.instanceId.ToString("X16"); } } else { fileNameToSave = entry.typeId.ToString("X8") + "_" + entry.groupId.ToString("X8") + "_" + entry.instanceId.ToString("X16"); } FileStream saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(KeyUtils.findKey(entry, 2, db), saveFile); saveFile.Close(); } } //numFound++; } meshFile.Close(); //output.Close(); } } } } if (tgi.typeId == (int)0x00B2D882) // DDS { //Stream textureStream = KeyUtils.searchForKey(tgi.ToString(), 2); Stream textureStream = KeyUtils.findKey(tgi); if (textureStream != null) { string fileNameToSave = ""; if (keyNames.ContainsKey(tgi.instanceId)) { fileNameToSave = keyNames[tgi.instanceId]; } else { fileNameToSave = tgi.typeId.ToString("X8") + "_" + tgi.groupId.ToString("X8") + "_" + tgi.instanceId.ToString("X16"); } if (!hasShownDialog) { folderBrowserDialog1.Description = "Please select a folder to save the extracted textures to."; folderBrowserDialog1.ShowDialog(); hasShownDialog = true; } if (folderBrowserDialog1.SelectedPath != "") { Stream output = db.GetResourceStream(tgi); FileStream saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + ".dds"), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(output, saveFile); saveFile.Close(); output.Close(); numFound++; } } } } toolStripProgressBar1.Value = 0; toolStripStatusLabel1.Text = numFound + " textures found."; toolStripProgressBar1.Visible = false; statusStrip1.Refresh(); fbuild2.Close(); } }
private Image extractCASThumbnail(string meshName) { //Console.WriteLine("Started " + meshName + " at " + DateTime.Now.ToString()); Helpers.logMessageToFile("Attemping to extract thumbnail for " + meshName); Image tempImage = null; if (String.IsNullOrEmpty(sims3root)) { sims3root = MadScience.Helpers.findSims3Root(); } string thumbnailPackage = Helpers.getGameSubPath(@"\Thumbnails\CasThumbnails.package"); Helpers.logMessageToFile(Path.Combine(sims3root, thumbnailPackage)); if (sims3root != "" && File.Exists(Path.Combine(sims3root, thumbnailPackage))) { // Open CAS Thumbnails package Stream cast = File.Open(Path.Combine(sims3root, thumbnailPackage), FileMode.Open, FileAccess.Read, FileShare.Read); Database castdb = new Database(cast, true); ulong instanceid = MadScience.StringHelpers.HashFNV64(meshName); if (casThumbsKeyList.Count == 0) { Helpers.logMessageToFile("Populating casThumbs entry lists from " + castdb._Entries.Count.ToString() + " entries"); foreach (MadScience.Wrappers.ResourceKey entry in castdb._Entries.Keys) { //DatabasePackedFile.Entry entry = castdb.dbpfEntries[i]; if (entry.groupId == 0x00000000 && entry.typeId == 0x626f60ce) { casThumbsKeyList.Add(entry.instanceId, entry); } if (entry.groupId == 0x00000001 && entry.typeId == 0x626f60ce) { casThumbsKeyList2.Add(entry.instanceId, entry); } } Helpers.logMessageToFile("casThumbs now contains " + casThumbsKeyList.Count.ToString() + " entries"); Helpers.logMessageToFile("casThumbs2 now contains " + casThumbsKeyList2.Count.ToString() + " entries"); } bool foundPic = false; ResourceKey temp = new ResourceKey(); if (casThumbsKeyList.ContainsKey(instanceid)) { temp = casThumbsKeyList[instanceid]; foundPic = true; } else { if (casThumbsKeyList2.ContainsKey(instanceid)) { temp = casThumbsKeyList2[instanceid]; foundPic = true; } } if (foundPic) { tempImage = Image.FromStream(castdb.GetResourceStream(temp)); try { tempImage.Save(Path.Combine(Application.StartupPath, Path.Combine("cache", meshName + ".png")), System.Drawing.Imaging.ImageFormat.Png); } catch (Exception ex) { } } else { Helpers.logMessageToFile("Couldn't find a match for " + meshName + " (0x" + instanceid.ToString("X16") + ")"); } cast.Close(); //dbpf = null; castdb = null; } else { Helpers.logMessageToFile(@"Can't find sims3root or Thumbnails\CasThumbnails.package"); } //Console.WriteLine("Stopped " + meshName + " at " + DateTime.Now.ToString()); return tempImage; }
private void button9_Click(object sender, EventArgs e) { // Go through the list of DDS files and dump them string s3root = MadScience.Helpers.findSims3Root(); if (s3root != "") { bool hasShownDialog = false; toolStripProgressBar1.Visible = true; toolStripProgressBar1.Minimum = 0; toolStripProgressBar1.Value = 0; toolStripStatusLabel1.Text = "Searching for meshes... please wait"; statusStrip1.Refresh(); Stream fbuild0 = File.Open(Path.Combine(s3root, Helpers.getGameSubPath("\\GameData\\Shared\\Packages\\FullBuild0.package")), FileMode.Open, FileAccess.Read, FileShare.Read); MadScience.Wrappers.Database db = new MadScience.Wrappers.Database(fbuild0, true); toolStripProgressBar1.Maximum = db._Entries.Count; Dictionary<ulong, string> keyNames = new Dictionary<ulong, string>(); long nowTicks = DateTime.Now.Ticks; Console.WriteLine("Started at: " + nowTicks); foreach (MadScience.Wrappers.ResourceKey entry in db._Entries.Keys) { //MadScience.Wrappers.ResourceKey entry = new MadScience.Wrappers.ResourceKey(keyString); //DatabasePackedFile.Entry entry = db.dbpfEntries[i]; if (entry.typeId == (int)0x0166038C) { keyNames = Helpers.getKeyNames(db.GetResourceStream(entry)); break; } } // Get the Mesh links for the first LOD //List<Stream> meshStreams = new List<Stream>(); // Use the VPXY to get the mesh lod Stream vpxyStream = KeyUtils.findKey(casPartSrc.tgi64list[casPartSrc.tgiIndexVPXY], 0); int numFound = 0; folderBrowserDialog1.SelectedPath = ""; if (vpxyStream != null) { VPXYFile vpxyFile = new VPXYFile(vpxyStream); // Get the first VPXY internal link if (vpxyFile.vpxy.linkEntries.Count >= 1) // && vpxyFile.vpxy.linkEntries[0].tgiList.Count >= 1) { for (int p = 0; p < vpxyFile.vpxy.linkEntries.Count; p++) { for (int i = 0; i < vpxyFile.vpxy.linkEntries[p].tgiList.Count; i++) { //meshStreams.Add(KeyUtils.findKey(vpxyFile.vpxy.linkEntries[0].tgiList[i], 0)); //KeyUtils.findKey(vpxyFile.vpxy.linkEntries[0].tgiList[i], 0); ResourceKey entry = vpxyFile.vpxy.linkEntries[p].tgiList[i]; string fileNameToSave = ""; if (keyNames.ContainsKey(entry.instanceId)) { fileNameToSave = keyNames[entry.instanceId]; if (fileNameToSave.Contains("0x") == false) { fileNameToSave += "_0x" + entry.instanceId.ToString("X16"); } } else { fileNameToSave = entry.typeId.ToString("X8") + "_" + entry.groupId.ToString("X8") + "_" + entry.instanceId.ToString("X16"); } Stream output = KeyUtils.findKey(entry, 0); if (!hasShownDialog) { folderBrowserDialog1.Description = "Please select a folder to save the extracted meshes to."; folderBrowserDialog1.ShowDialog(); hasShownDialog = true; } if (folderBrowserDialog1.SelectedPath != "") { string extension = ""; if (entry.typeId == 0x015A1849) { extension = ".simgeom"; } FileStream saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(output, saveFile); saveFile.Close(); numFound++; } output.Close(); } } } if (numFound > 0) { string fileNameToSave2 = ""; ResourceKey entry = casPartSrc.tgi64list[casPartSrc.tgiIndexVPXY]; if (keyNames.ContainsKey(entry.instanceId)) { fileNameToSave2 = keyNames[entry.instanceId]; if (fileNameToSave2.Contains("0x") == false) { fileNameToSave2 += "_0x" + entry.instanceId.ToString("X16"); } } else { fileNameToSave2 = entry.typeId.ToString("X8") + "_" + entry.groupId.ToString("X8") + "_" + entry.instanceId.ToString("X16"); } FileStream saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave2) + ".vpxy", FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(vpxyStream, saveFile, true); saveFile.Close(); } vpxyStream.Close(); } if (debugModeToolStripMenuItem.Checked) { Stream bodyBlendFatStream = KeyUtils.findKey(casPartSrc.tgi64list[casPartSrc.tgiIndexBlendInfoFat].ToString(), 0); Stream bodyBlendFitStream = KeyUtils.findKey(casPartSrc.tgi64list[casPartSrc.tgiIndexBlendInfoFit].ToString(), 0); Stream bodyBlendThinStream = KeyUtils.findKey(casPartSrc.tgi64list[casPartSrc.tgiIndexBlendInfoThin].ToString(), 0); Stream bodyBlendSpecialStream = KeyUtils.findKey(casPartSrc.tgi64list[casPartSrc.tgiIndexBlendInfoSpecial].ToString(), 0); if (!hasShownDialog) { folderBrowserDialog1.Description = "Please select a folder to save the extracted meshes to."; folderBrowserDialog1.ShowDialog(); hasShownDialog = true; } if (folderBrowserDialog1.SelectedPath != "") { string extension = ".bodyblend"; string fileNameToSave = ""; fileNameToSave = txtMeshName.Text + "_fit"; FileStream saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bodyBlendFitStream, saveFile); saveFile.Close(); fileNameToSave = txtMeshName.Text + "_fat"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bodyBlendFatStream, saveFile); saveFile.Close(); fileNameToSave = txtMeshName.Text + "_thin"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bodyBlendThinStream, saveFile); saveFile.Close(); fileNameToSave = txtMeshName.Text + "_special"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bodyBlendSpecialStream, saveFile); saveFile.Close(); // Just grab the one BGEO for now bodyBlendFatStream.Seek(0, SeekOrigin.Begin); FacialBlend fblend = new FacialBlend(bodyBlendFatStream); Stream bgeoStream = KeyUtils.findKey(fblend.blendTgi, 0); bgeoStream.Seek(0, SeekOrigin.Begin); extension = ".blendgeom"; fileNameToSave = txtMeshName.Text + "_fat"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bgeoStream, saveFile); saveFile.Close(); bodyBlendFitStream.Seek(0, SeekOrigin.Begin); fblend = new FacialBlend(bodyBlendFitStream); bgeoStream = KeyUtils.findKey(fblend.blendTgi, 0); bgeoStream.Seek(0, SeekOrigin.Begin); fileNameToSave = txtMeshName.Text + "_fit"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bgeoStream, saveFile); saveFile.Close(); bodyBlendThinStream.Seek(0, SeekOrigin.Begin); fblend = new FacialBlend(bodyBlendThinStream); bgeoStream = KeyUtils.findKey(fblend.blendTgi, 0); bgeoStream.Seek(0, SeekOrigin.Begin); extension = ".blendgeom"; fileNameToSave = txtMeshName.Text + "_thin"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bgeoStream, saveFile); saveFile.Close(); bodyBlendSpecialStream.Seek(0, SeekOrigin.Begin); fblend = new FacialBlend(bodyBlendSpecialStream); bgeoStream = KeyUtils.findKey(fblend.blendTgi, 0); bgeoStream.Seek(0, SeekOrigin.Begin); extension = ".blendgeom"; fileNameToSave = txtMeshName.Text + "_special"; saveFile = new FileStream(Path.Combine(folderBrowserDialog1.SelectedPath, fileNameToSave + extension), FileMode.Create, FileAccess.Write); StreamHelpers.CopyStream(bgeoStream, saveFile); saveFile.Close(); //numFound++; } } toolStripProgressBar1.Value = 0; toolStripProgressBar1.Visible = false; toolStripStatusLabel1.Text = numFound.ToString() + " meshes found"; statusStrip1.Refresh(); fbuild0.Close(); } }
public static bool fixRecursive(Database db) { uint numFixed = 0; // textBox1.Text += "Checking for corrupted TXTC entries... " + Environment.NewLine; for (int i = 0; i < db.dbpf.Entries.Count; i++) { DatabasePackedFile.Entry entry = db.dbpf.Entries[i]; if ((entry.Key.typeId == 0x0) && (entry.Key.groupId == 0x0) && (entry.Key.instanceId == 0x0)) { // Check the first 4 bytes of the stream Stream checkDbpf = db.GetResourceStream(entry.Key); string magic = MadScience.StreamHelpers.ReadStringASCII(checkDbpf, 4); if (magic == "DBPF" || magic == "DBBF") // DBPF & DBBF { db.DeleteResource(entry.Key); numFixed++; } checkDbpf.Close(); } } if (numFixed == 0) { //textBox1.Text += Environment.NewLine; //textBox1.Text += "This file appears OK!"; return false; } else { //this.filesFixed++; //textBox1.Text += Environment.NewLine; //textBox1.Text += "This file had some corrupted TXTCs! They are now fixed."; //textBox1.Text += "Fixed " + filename + Environment.NewLine; //saveToolStripMenuItem.Enabled = true; db.Commit(true); } return true; }
public static bool fixTXTR(Database db) { uint numFixed = 0; // textBox1.Text += "Checking for corrupted TXTC entries... " + Environment.NewLine; for (int i = 0; i < db.dbpf.Entries.Count; i++) { DatabasePackedFile.Entry entry = db.dbpf.Entries[i]; if (entry.Key.typeId == 0x033A1435) { //textBox1.Text += " " + entry.Key.ToString() + Environment.NewLine; // textBox1.Text += " Checking for corrupted TGI offset... "; // Quick and dirty way Stream TXTC = db.GetResourceStream(entry.Key); // Read offset, first 4 bytes after ID StreamHelpers.ReadValueU32(TXTC); uint offset = StreamHelpers.ReadValueU32(TXTC); // textBox1.Text += offset.ToString() + "..."; // Seek to this offset + 8 and read the number there. TXTC.Seek(offset + 8, SeekOrigin.Begin); uint numTGIs = StreamHelpers.ReadValueU8(TXTC); // textBox1.Text += numTGIs.ToString() + " TGIs... "; // Since each TGI is 16 bytes we can calculate how many bytes they are. uint tgiSize = numTGIs * 16; uint tgiOffsetEnd = offset + 8 + 1 + tgiSize; //textBox1.Text += "TGI block end is at " + tgiOffsetEnd.ToString() + "..."; if (tgiOffsetEnd == TXTC.Length) { return false; } else { // Try offset - 1 offset = offset - 1; // Seek to this offset + 8 and read the number there. TXTC.Seek(offset + 8, SeekOrigin.Begin); numTGIs = StreamHelpers.ReadValueU8(TXTC); // textBox1.Text += numTGIs.ToString() + " TGIs... "; // Since each TGI is 16 bytes we can calculate how many bytes they are. tgiSize = numTGIs * 16; tgiOffsetEnd = offset + 8 + 1 + tgiSize; //textBox1.Text += "TGI block end is at " + tgiOffsetEnd.ToString() + "..."; if (tgiOffsetEnd == TXTC.Length) { // textBox1.Text += "Correct!"; // Offset it minus 1 TXTC.Seek(4, SeekOrigin.Begin); StreamHelpers.WriteValueU32(TXTC, offset); MemoryStream newTXTC = new MemoryStream(); StreamHelpers.CopyStream(TXTC, newTXTC, true); db.SetResourceStream(entry.Key, newTXTC); // textBox1.Text += Environment.NewLine; // textBox1.Text += "The above resource has been fixed."; numFixed++; newTXTC.Close(); } else { // textBox1.Text += "Incorrect!"; } } // textBox1.Text += Environment.NewLine; TXTC = null; } } if (numFixed == 0) { //textBox1.Text += Environment.NewLine; //textBox1.Text += "This file appears OK!"; return false; } else { //this.filesFixed++; //textBox1.Text += Environment.NewLine; //textBox1.Text += "This file had some corrupted TXTCs! They are now fixed."; //textBox1.Text += "Fixed " + filename + Environment.NewLine; //saveToolStripMenuItem.Enabled = true; db.Commit(true); } return true; }