public void Save(string filename, Sims3PackFile s3p) { Stream output = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Write); StreamHelpers.WriteValueU32(output, 7); StreamHelpers.WriteStringASCII(output, "TS3Pack"); StreamHelpers.WriteValueU16(output, s3p.UnknownInt); // First pass. // Recalculate all the package file offsets, based on which ones are checked, and remove disabled ones int curOffset = 0; for (int i = 0; i < s3p.PackagedFiles.Count; i++) { if (!s3p.PackagedFiles[i].isDisabled) { s3p.PackagedFiles[i].Offset = curOffset; curOffset += s3p.PackagedFiles[i].Length; if (s3p.PackagedFiles[i].MetaTags.lotThumb.Count > 0) { List <string> tempThumbs = new List <string>(); for (int y = 0; y < s3p.PackagedFiles[i].MetaTags.lotThumb.Count; y++) { for (int z = 0; z < s3p.PackagedFiles.Count; z++) { if (!s3p.PackagedFiles[z].isDisabled && s3p.PackagedFiles[z].Name == s3p.PackagedFiles[i].MetaTags.lotThumb[y] + ".png") { tempThumbs.Add(s3p.PackagedFiles[i].MetaTags.lotThumb[y]); } } } s3p.PackagedFiles[i].MetaTags.lotThumb = tempThumbs; } } } string xml = WriteSims3PackXml(s3p); StreamHelpers.WriteValueS32(output, 0); StreamHelpers.WriteStringUTF8(output, xml); int xmlLength = (int)output.Position - 17; for (int i = 0; i < s3p.PackagedFiles.Count; i++) { if (!s3p.PackagedFiles[i].isDisabled) { StreamHelpers.CopyStream(s3p.PackagedFiles[i].DBPF, output, true); } } output.Seek(4 + 7 + 2, SeekOrigin.Begin); StreamHelpers.WriteValueS32(output, xmlLength); output.Close(); }
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); }