public static Image makePatternThumb(patternDetails pattern, Wrappers.Database db) { Image temp = null; if (pattern.type == "HSV") { DdsFileTypePlugin.DdsFile ddsP = new DdsFileTypePlugin.DdsFile(); Colours.HSVColor channel1Color = new Colours.HSVColor(); Colours.HSVColor channel2Color = new Colours.HSVColor(); Colours.HSVColor channel3Color = new Colours.HSVColor(); Colours.HSVColor backColor = new Colours.HSVColor(Convert.ToDouble(pattern.HBg, CultureInfo.InvariantCulture) * 360, Convert.ToDouble(pattern.SBg, CultureInfo.InvariantCulture), Convert.ToDouble(pattern.VBg, CultureInfo.InvariantCulture)); bool[] channelsEnabled = new bool[3]; if (pattern.ChannelEnabled[0] != null && pattern.ChannelEnabled[0].ToLower() == "true") { channel1Color = new Colours.HSVColor(Convert.ToDouble(pattern.H[0], CultureInfo.InvariantCulture) * 360, Convert.ToDouble(pattern.S[0], CultureInfo.InvariantCulture), Convert.ToDouble(pattern.V[0], CultureInfo.InvariantCulture)); channelsEnabled[0] = true; } if (pattern.ChannelEnabled[1] != null && pattern.ChannelEnabled[1].ToLower() == "true") { channel2Color = new Colours.HSVColor(Convert.ToDouble(pattern.H[1], CultureInfo.InvariantCulture) * 360, Convert.ToDouble(pattern.S[1], CultureInfo.InvariantCulture), Convert.ToDouble(pattern.V[1], CultureInfo.InvariantCulture)); channelsEnabled[1] = true; } if (pattern.ChannelEnabled[2] != null && pattern.ChannelEnabled[2].ToLower() == "true") { channel3Color = new Colours.HSVColor(Convert.ToDouble(pattern.H[2], CultureInfo.InvariantCulture) * 360, Convert.ToDouble(pattern.S[2], CultureInfo.InvariantCulture), Convert.ToDouble(pattern.V[2], CultureInfo.InvariantCulture)); channelsEnabled[2] = true; } if (isEmptyMask(pattern.rgbmask)) { if (db != null) { temp = Patterns.createHSVPattern(KeyUtils.findKey(new Wrappers.ResourceKey(pattern.BackgroundImage), 2, db), backColor); } else { temp = Patterns.createHSVPattern(KeyUtils.findKey(pattern.BackgroundImage), backColor); } } else { if (db != null) { temp = Patterns.createHSVPattern(KeyUtils.findKey(new Wrappers.ResourceKey(pattern.BackgroundImage), 2, db), KeyUtils.findKey(new Wrappers.ResourceKey(pattern.rgbmask), 2, db), backColor, KeyUtils.findKey(new MadScience.Wrappers.ResourceKey(makeKey(pattern.Channel[0])), 0, db), KeyUtils.findKey(new Wrappers.ResourceKey(makeKey(pattern.Channel[1])), 0, db), KeyUtils.findKey(new Wrappers.ResourceKey(makeKey(pattern.Channel[2])), 0, db), channel1Color, channel2Color, channel3Color, channelsEnabled); } else { temp = Patterns.createHSVPattern(KeyUtils.findKey(pattern.BackgroundImage), KeyUtils.findKey(pattern.rgbmask), backColor, KeyUtils.findKey(makeKey(pattern.Channel[0])), KeyUtils.findKey(makeKey(pattern.Channel[1])), KeyUtils.findKey(makeKey(pattern.Channel[2])), channel1Color, channel2Color, channel3Color, channelsEnabled); } } } else if (pattern.type == "Coloured") { DdsFileTypePlugin.DdsFile ddsP = new DdsFileTypePlugin.DdsFile(); Color bgColor = Colours.convertColour(pattern.ColorP[0], true); if (bgColor == Color.Empty) { bgColor = Color.Black; } if (pattern.isCustom) { // We need this in here becuase findKey only searches the game files and any local DDS files - it // doesn't search custom packages if (File.Exists(pattern.customFilename)) { Stream patternThumb = KeyUtils.searchForKey(pattern.rgbmask, pattern.customFilename); if (!StreamHelpers.isValidStream(patternThumb)) { patternThumb = KeyUtils.searchForKey(pattern.BackgroundImage, pattern.customFilename); } if (StreamHelpers.isValidStream(patternThumb)) { ddsP.Load(patternThumb); } patternThumb.Close(); } } else { if (db != null) { ddsP.Load(KeyUtils.findKey(new Wrappers.ResourceKey(pattern.rgbmask), 2, db)); } else { ddsP.Load(KeyUtils.findKey(pattern.rgbmask)); } } temp = ddsP.Image(bgColor, Colours.convertColour(pattern.ColorP[1], true), Colours.convertColour(pattern.ColorP[2], true), Colours.convertColour(pattern.ColorP[3], true), Colours.convertColour(pattern.ColorP[4], true)); } else if (pattern.type == "solidColor") { temp = new Bitmap(256, 256); using (Graphics g = Graphics.FromImage(temp)) { g.FillRectangle(new SolidBrush(Colours.convertColour(pattern.Color)), 0, 0, 256, 256); } } return(temp); }
public static List <Stream> findKey(List <MadScience.Wrappers.ResourceKey> resourceKeys, int fullBuildNum, MadScience.Wrappers.Database db) { List <Stream> tempChunks = new List <Stream>(); // Add one Stream per keyName, even if null for (int i = 0; i < resourceKeys.Count; i++) { tempChunks.Add(new MemoryStream()); } // Check local files first if (Helpers.localFiles.Count > 0) { for (int i = 0; i < resourceKeys.Count; i++) { if (Helpers.localFiles.ContainsKey(resourceKeys[i].ToString())) { Stream blah = File.OpenRead((string)Helpers.localFiles[resourceKeys[i].ToString()]); StreamHelpers.CopyStream(blah, tempChunks[i]); tempChunks[i].Seek(0, SeekOrigin.Begin); blah.Close(); } } } //check current package if (!String.IsNullOrEmpty(Helpers.currentPackageFile)) { Stream localPackage = File.Open(Helpers.currentPackageFile, FileMode.Open, FileAccess.Read, FileShare.Read); MadScience.Wrappers.Database localDb = new MadScience.Wrappers.Database(localPackage, true); for (int i = 0; i < resourceKeys.Count; i++) { if (tempChunks[i].Length == 0) { try { tempChunks[i] = localDb.GetResourceStream(resourceKeys[i]); } catch (System.Collections.Generic.KeyNotFoundException) { //Helpers.logMessageToFile(ex.Message); } catch (Exception) { //Helpers.logMessageToFile(ex.Message); } } } localPackage.Close(); } //check global packages foreach (string filename in Helpers.globalPackageFiles) { if (!String.IsNullOrEmpty(filename)) { using (Stream localPackage = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { MadScience.Wrappers.Database localDb = new MadScience.Wrappers.Database(localPackage, true); for (int i = 0; i < resourceKeys.Count; i++) { if (tempChunks[i].Length == 0) { try { tempChunks[i] = localDb.GetResourceStream(resourceKeys[i]); } catch (System.Collections.Generic.KeyNotFoundException) { //Helpers.logMessageToFile(ex.Message); } catch (Exception) { //Helpers.logMessageToFile(ex.Message); } } } localPackage.Close(); } } } // If input stream isn't null then we use that, otherwise open the fullbuild we want... Stream input = Stream.Null; bool closeDb = false; if (db == null) { closeDb = true; try { input = File.OpenRead(Path.Combine(Helpers.findSims3Root(), Helpers.getGameSubPath("\\GameData\\Shared\\Packages\\FullBuild" + fullBuildNum.ToString() + ".package"))); db = new MadScience.Wrappers.Database(input, true); } catch (Exception) { return(tempChunks); } } for (int i = 0; i < resourceKeys.Count; i++) { if (tempChunks[i].Length == 0) { //keyName tKey = new keyName(resourceKeys[i]); try { tempChunks[i] = db.GetResourceStream(resourceKeys[i]); } catch (System.Collections.Generic.KeyNotFoundException) { //Helpers.logMessageToFile(ex.Message); } catch (Exception) { //Helpers.logMessageToFile(ex.Message); } } } if (closeDb) { input.Close(); } return(tempChunks); }
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); }
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); }