private void importToolStripMenuItem_Click(object sender, EventArgs e) { if (mod == null) return; OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.DAIMWV|*.DAIMWV"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Mod mi = new Mod(); mi.Load(d.FileName); foreach (Mod.ModJob mj in mi.jobs) mod.jobs.Add(mj); mod.CreateHeader(); RefreshMe(); MessageBox.Show("Done."); } }
private void createSingleModToolStripMenuItem_Click(object sender, EventArgs e) { int n = listBox1.SelectedIndex; if (n == -1) return; MessageBox.Show("Please select replacement texture (same size)"); OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.dds|*.dds"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { byte[] data = File.ReadAllBytes(d.FileName); MessageBox.Show("Please select mod save location"); SaveFileDialog d2 = new SaveFileDialog(); d2.Filter = "*.DAIMWV|*.DAIMWV"; if (d2.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Mod mod = new Mod(); mod.jobs = new List<Mod.ModJob>(); Mod.ModJob mj = new Mod.ModJob(); mj.type = 0; mj.bundlePaths = new List<string>(); mj.tocPaths = new List<string>(); int plen = GlobalStuff.FindSetting("gamepath").Length; DBAccess.BundleInformation buni = bil[n]; DBAccess.TextureInformation ti = new DBAccess.TextureInformation(); foreach (DBAccess.TextureInformation t in til) if (t.bundleIndex == buni.index) ti = t; DBAccess.TOCInformation toci = DBAccess.GetTocInformationByIndex(buni.tocIndex); mj.respath = ti.name; mj.bundlePaths.Add(buni.bundlepath); mj.tocPaths.Add(toci.path.Substring(plen, toci.path.Length - plen)); MemoryStream m = new MemoryStream(); m.Write(data, 0x80, data.Length - 0x80); mj.data = m.ToArray(); mod.jobs.Add(mj); mod.Save(d2.FileName); MessageBox.Show("Done."); } } }
private void createForAllDupsModToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("Please select replacement texture (same size)"); OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.dds|*.dds"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { byte[] data = File.ReadAllBytes(d.FileName); MessageBox.Show("Please select mod save location"); SaveFileDialog d2 = new SaveFileDialog(); d2.Filter = "*.DAIMWV|*.DAIMWV"; if (d2.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Mod mod = new Mod(); mod.jobs = new List<Mod.ModJob>(); Mod.ModJob mj = new Mod.ModJob(); mj.type = 0; mj.bundlePaths = new List<string>(); mj.tocPaths = new List<string>(); int plen = GlobalStuff.FindSetting("gamepath").Length; bool skip = false; for (int i = 0; i < bil.Length; i++) { DBAccess.BundleInformation buni = bil[i]; DBAccess.TextureInformation ti = new DBAccess.TextureInformation(); foreach (DBAccess.TextureInformation t in til) if (t.bundleIndex == buni.index) ti = t; DBAccess.TOCInformation toci = DBAccess.GetTocInformationByIndex(buni.tocIndex); mj.respath = ti.name; skip = false; foreach (string p in mj.bundlePaths) if (p == buni.bundlepath) { skip = true; break; } if (!skip) mj.bundlePaths.Add(buni.bundlepath); string tpath = toci.path.Substring(plen, toci.path.Length - plen); skip = false; foreach (string p in mj.tocPaths) if (p == tpath) { skip = true; break; } if (tpath.ToLower().Contains("\\patch\\")) skip = true; if (!skip) mj.tocPaths.Add(tpath); } MemoryStream m = new MemoryStream(); m.Write(data, 0x80, data.Length - 0x80); mj.data = m.ToArray(); mod.jobs.Add(mj); mod.Save(d2.FileName); MessageBox.Show("Done."); } } }
private void createSingleModToolStripMenuItem_Click(object sender, EventArgs e) { int n = listBox2.SelectedIndex; if (n == -1) return; MessageBox.Show("Please select replacement data"); OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.bin|*.bin"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { byte[] data = File.ReadAllBytes(d.FileName); MessageBox.Show("Please select mod save location"); SaveFileDialog d2 = new SaveFileDialog(); d2.Filter = "*.DAIMWV|*.DAIMWV"; if (d2.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Mod mod = new Mod(); mod.jobs = new List<Mod.ModJob>(); Mod.ModJob mj = new Mod.ModJob(); mj.type = 1; mj.bundlePaths = new List<string>(); mj.tocPaths = new List<string>(); int plen = GlobalStuff.FindSetting("gamepath").Length; DBAccess.RESInformation resi = ttprevlist[n]; mj.respath = resi.resname; mj.bundlePaths.Add(resi.bundlepath); mj.tocPaths.Add(resi.tocfilepath.Substring(plen)); MemoryStream m = new MemoryStream(); m.Write(data, 0x80, data.Length - 0x80); mj.data = m.ToArray(); mj.restype = types[toolStripComboBox1.SelectedIndex]; mod.jobs.Add(mj); mod.Save(d2.FileName); MessageBox.Show("Done."); } } }
private void createForAllDupsModToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("Please select replacement data"); OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.bin|*.bin"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Mod mod = new Mod(); mod.jobs = new List<Mod.ModJob>(); Mod.ModJob mj = new Mod.ModJob(); mj.data = File.ReadAllBytes(d.FileName); MessageBox.Show("Please select mod save location"); SaveFileDialog d2 = new SaveFileDialog(); d2.Filter = "*.DAIMWV|*.DAIMWV"; if (d2.ShowDialog() == System.Windows.Forms.DialogResult.OK) { int plen = GlobalStuff.FindSetting("gamepath").Length; mj.type = 1; mj.bundlePaths = new List<string>(); mj.tocPaths = new List<string>(); bool skip = false; for (int i = 0; i < ttprevlist.Count; i++) { DBAccess.RESInformation resi = ttprevlist[i]; mj.respath = resi.resname; skip = false; foreach (string p in mj.bundlePaths) if (p == resi.bundlepath) { skip = true; break; } if (!skip) mj.bundlePaths.Add(resi.bundlepath); skip = false; foreach (string p in mj.tocPaths) if (p == resi.tocfilepath.Substring(plen)) { skip = true; break; } if (!skip && !resi.tocfilepath.ToLower().Contains("\\patch\\")) mj.tocPaths.Add(resi.tocfilepath.Substring(plen)); } mj.restype = types[toolStripComboBox1.SelectedIndex]; mod.jobs.Add(mj); mod.Save(d2.FileName); MessageBox.Show("Done."); } } }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.DAIMWV|*.DAIMWV"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { mod = new Mod(); mod.Load(d.FileName); RefreshMe(); } }
public void RunTextureResJob(Mod.ModJob mj, string tocpath, byte[] newsha1, int newcompressedsize) { DbgPrint("Loading : " + tocpath); TOCFile toc = null; if (!tocpath.ToLower().StartsWith("update")) toc = new TOCFile(outputPath + tocpath); else toc = new TOCFile(outputPath + Helpers.SkipSubFolder(tocpath, 2)); //walk through affected bundles if (toc.iscas) foreach (string bpath in mj.bundlePaths) RunTextureResJobOnBundle(mj, toc, tocpath, newsha1, bpath, newcompressedsize); else foreach (string bpath in mj.bundlePaths) RunTextureResJobOnBundleBinary(mj, toc, tocpath, bpath); UpdateTOC(toc); }
public void RunTextureResJobOnBundle(Mod.ModJob mj, TOCFile toc, string tocpath, byte[] newsha1, string bpath, int newcompressedsize) { GC.Collect(); int count = 0; int index = -1; foreach (TOCFile.TOCBundleInfoStruct buni in toc.bundles) if (count++ > -1 && bpath == buni.id) { DbgPrint(" Found bundle : " + bpath); index = count - 1; break; } //if bundle found if (index != -1) { if (!toc.iscas) { DbgPrint(" Warning: binary bundles not supported yet, skipping!"); return; } //find out if base or delta BJSON.Entry root = toc.lines[0]; BJSON.Field bundles = root.FindField("bundles"); BJSON.Entry bun = ((List<BJSON.Entry>)bundles.data)[index]; BJSON.Field isDeltaField = bun.FindField("delta"); BJSON.Field isBaseField = bun.FindField("base"); //if is base, copy from base, make delta and recompile if (isBaseField != null && (bool)isBaseField.data == true) if (!ImportBundleFromBase(toc, tocpath, index, bpath)) return; //check if already is in sb if (isDeltaField != null && (bool)isDeltaField.data == true) DbgPrint(" Its already a delta"); DbgPrint(" Updating SB file with new SHA1...");//yeah, pretty much string SBpath = outputPath + Path.GetDirectoryName(tocpath) + "\\" + Path.GetFileNameWithoutExtension(tocpath) + ".sb"; SBFile sb = new SBFile(SBpath); root = sb.lines[0]; bundles = root.FindField("bundles"); List<BJSON.Entry> bundle_list =(List<BJSON.Entry>)bundles.data; //find right bundle for (int i = 0; i < bundle_list.Count; i++) { bun = bundle_list[i]; BJSON.Field ebx = bun.FindField("ebx"); BJSON.Field res = bun.FindField("res"); BJSON.Field chunks = bun.FindField("chunks"); BJSON.Field path = bun.FindField("path"); if (!(path != null && (string)path.data == bpath) || res == null || chunks == null) continue; bool found = false; byte[] chunkidbuff = new byte[16]; byte[] newchunkid = new byte[16]; //find right res entry List<BJSON.Entry> res_list = (List<BJSON.Entry>)res.data; for (int j = 0; j < res_list.Count; j++) { BJSON.Entry res_e = res_list[j]; BJSON.Field f_sha1 = res_e.FindField("sha1"); BJSON.Field f_name = res_e.FindField("name"); BJSON.Field f_size = res_e.FindField("size"); BJSON.Field f_osize = res_e.FindField("originalSize"); BJSON.Field f_casPatchType = res_e.FindField("casPatchType"); if (f_name != null && (string)f_name.data == mj.respath && f_sha1 != null) { //get res data and extract chunk id byte[] sha1buff = (byte[])f_sha1.data; DbgPrint(" Found res sha1 : " + Helpers.ByteArrayToHexString(sha1buff)); byte[] resdata = SHA1Access.GetDataBySha1(sha1buff); if (resdata.Length == 0) { DbgPrint(" Error: cant find res data, skipping!"); break; } for (int k = 0; k < 16; k++) chunkidbuff[k] = resdata[k + 0x1C]; DbgPrint(" Found chunk id : " + Helpers.ByteArrayToHexString(chunkidbuff)); newchunkid = Guid.NewGuid().ToByteArray(); DbgPrint(" Creating new chunk id : " + Helpers.ByteArrayToHexString(newchunkid)); for (int k = 0; k < 16; k++) resdata[k + 0x1C] = newchunkid[k]; int newrescompsize = 0; byte[] newressha1 = CreateCASContainer(resdata, out newrescompsize, " "); DbgPrint(" Creating new res sha1 : " + Helpers.ByteArrayToHexString(newressha1)); f_sha1.data = newressha1; DbgPrint(" Updating res size : " + resdata.Length); f_size.data = BitConverter.GetBytes((long)newrescompsize); f_osize.data = BitConverter.GetBytes((long)resdata.Length); if (f_casPatchType != null) { if (BitConverter.ToInt32((byte[])f_casPatchType.data, 0) != 1) { DbgPrint(" CasPatchType: found and set to 1!"); f_casPatchType.data = BitConverter.GetBytes((int)1); } else DbgPrint(" CasPatchType: found and is fine!"); } else { f_casPatchType = new BJSON.Field(); f_casPatchType.fieldname = "casPatchType"; f_casPatchType.type = 8; f_casPatchType.data = BitConverter.GetBytes((int)1); res_e.fields.Add(f_casPatchType); DbgPrint(" CasPatchType: added and set to 1!"); } found = true; } } if (!found) { DbgPrint(" Error: cant find res, skipping!"); break; } found = false; //find right chunk entry List<BJSON.Entry> chunk_list = (List<BJSON.Entry>)chunks.data; for (int j = 0; j < chunk_list.Count; j++) { BJSON.Entry chunk_e = chunk_list[j]; BJSON.Field f_id = chunk_e.FindField("id"); BJSON.Field f_size = chunk_e.FindField("size"); BJSON.Field f_rangeStart = chunk_e.FindField("rangeStart"); BJSON.Field f_rangeEnd = chunk_e.FindField("rangeEnd"); BJSON.Field f_logicalOffset = chunk_e.FindField("logicalOffset"); BJSON.Field f_logicalSize = chunk_e.FindField("logicalSize"); BJSON.Field f2_sha1 = chunk_e.FindField("sha1"); BJSON.Field f_casPatchType2 = chunk_e.FindField("casPatchType"); if (f_id != null && Helpers.ByteArrayCompare((byte[])f_id.data, chunkidbuff)) { DbgPrint(" Found chunk"); f_id.data = newchunkid; found = true; if (f_casPatchType2 != null) { if (BitConverter.ToInt32((byte[])f_casPatchType2.data, 0) != 1) { DbgPrint(" CasPatchType: found and set to 1!"); f_casPatchType2.data = BitConverter.GetBytes((int)1); } else DbgPrint(" CasPatchType: found and is fine!"); } else { f_casPatchType2 = new BJSON.Field(); f_casPatchType2.fieldname = "casPatchType"; f_casPatchType2.type = 8; f_casPatchType2.data = BitConverter.GetBytes((int)1); chunk_e.fields.Add(f_casPatchType2); DbgPrint(" CasPatchType: added and set to 1!"); } f_size.data = BitConverter.GetBytes(newcompressedsize); if (f_rangeStart != null) f_rangeStart.data = BitConverter.GetBytes((int)0); if (f_rangeEnd != null) f_rangeEnd.data = BitConverter.GetBytes(newcompressedsize); if (f_logicalOffset != null) f_logicalOffset.data = BitConverter.GetBytes((int)0); if (f_logicalSize != null) f_logicalSize.data = BitConverter.GetBytes(mj.data.Length); f2_sha1.data = newsha1; DbgPrint(" Updated chunk size : " + mj.data.Length); CalcTotalSize(bun); sb.Save(); found = true; DbgPrint(" Replaced chunk sha1 and saved SB file"); DbgPrint(" Job successfull!"); break; } } if (!found) DbgPrint(" Error: Could not find Chunk by id"); } } }
public void RunTextureJob(Mod.ModJob mj) { DbgPrint("Running Texture Replacement Job for: " + mj.respath); //Check Toc Files List<string> reducedTocPaths = new List<string>(); bool found = false; foreach (string p in mj.tocPaths) { found = false; for (int i = 0; i < reducedTocPaths.Count; i++) if (p == reducedTocPaths[i]) { found = true; break; } if (!found) reducedTocPaths.Add(p); } mj.tocPaths = reducedTocPaths; List<string> reducedBundlePaths = new List<string>(); foreach (string p in mj.bundlePaths) { found = false; for (int i = 0; i < reducedBundlePaths.Count; i++) if (p == reducedBundlePaths[i]) { found = true; break; } if (!found) reducedBundlePaths.Add(p); } mj.bundlePaths = reducedBundlePaths; foreach (string tocpath in mj.tocPaths) { if (tocpath.ToLower().Contains("\\patch\\")) continue; DbgPrint("Checking for : " + tocpath); if (!tocpath.ToLower().StartsWith("update")) { if (!File.Exists(outputPath + tocpath)) { string from = GlobalStuff.FindSetting("gamepath") + tocpath; string to = outputPath + tocpath; Directory.CreateDirectory(Path.GetDirectoryName(to) + "\\"); DbgPrint("TOC file not found, copying from base!"); try { File.Copy(from, to); } catch (Exception) { DbgPrint("Error: TOC file not found, can not copy from base!\n Tried to copy from:\n\t" + from + "\n to:\n\t" + to); return; } from = GlobalStuff.FindSetting("gamepath") + tocpath.ToLower().Replace(".toc",".sb"); to = outputPath + tocpath.ToLower().Replace(".toc", ".sb"); Directory.CreateDirectory(Path.GetDirectoryName(to) + "\\"); try { File.Copy(from, to); } catch (Exception) { DbgPrint("Error: SB file not found, can not copy from base!\n Tried to copy from:\n\t" + from + "\n to:\n\t" + to); return; } DbgPrint("Fixing layout.toc..."); TOCFile toc = new TOCFile(outputPath + "Data\\layout.toc"); BJSON.Entry root = toc.lines[0]; BJSON.Field sbun = root.FindField("superBundles"); List<BJSON.Entry> list = (List<BJSON.Entry>)sbun.data; BJSON.Entry ne = new BJSON.Entry(); ne.type = 0x82; ne.fields = new List<BJSON.Field>(); ne.fields.Add(new BJSON.Field(7, "name", tocpath.Replace(".toc", ""))); ne.fields.Add(new BJSON.Field(6, "delta", true)); list.Add(ne); sbun.data = list; toc.Save(); DbgPrint("SuperBundle added"); } } else { if (!File.Exists(outputPath + Helpers.SkipSubFolder(tocpath, 2))) { string from = GlobalStuff.FindSetting("gamepath") + tocpath; string to = outputPath + Helpers.SkipSubFolder(tocpath, 2); Directory.CreateDirectory(Path.GetDirectoryName(to) + "\\"); DbgPrint("TOC file not found, copying from base!"); try { File.Copy(from, to); } catch (Exception) { DbgPrint("Error: TOC file not found, can not copy from base!\n Tried to copy from:\n\t" + from + "\n to:\n\t" + to); return; } from = GlobalStuff.FindSetting("gamepath") + tocpath.ToLower().Replace(".toc", ".sb"); to = outputPath + Helpers.SkipSubFolder(tocpath, 2).ToLower().Replace(".toc", ".sb"); Directory.CreateDirectory(Path.GetDirectoryName(to) + "\\"); try { File.Copy(from, to); } catch (Exception) { DbgPrint("Error: SB file not found, can not copy from base!\n Tried to copy from:\n\t" + from + "\n to:\n\t" + to); return; } DbgPrint("Fixing layout.toc..."); TOCFile toc = new TOCFile(outputPath + "Data\\layout.toc"); BJSON.Entry root = toc.lines[0]; BJSON.Field sbun = root.FindField("superBundles"); List<BJSON.Entry> list = (List<BJSON.Entry>)sbun.data; BJSON.Entry ne = new BJSON.Entry(); ne.type = 0x82; ne.fields = new List<BJSON.Field>(); ne.fields.Add(new BJSON.Field(7, "name", Helpers.SkipSubFolder(tocpath, 2).Replace(".toc", ""))); ne.fields.Add(new BJSON.Field(6, "delta", true)); list.Add(ne); sbun.data = list; toc.Save(); DbgPrint("SuperBundle added"); } } } DbgPrint("All found."); //create cas data int newcompressedsize = 0; byte[] newsha1 = CreateCASContainer(mj.data, out newcompressedsize); if (newsha1.Length != 0x14) { DbgPrint("Error: could not create CAS data, aborting!"); return; } //walk through affected toc files foreach (string tocpath in mj.tocPaths) RunTextureResJob(mj, tocpath, newsha1, newcompressedsize); }
public void RunRessourceJobOnBundle(Mod.ModJob mj, TOCFile toc, string tocpath, byte[] newsha1, string bpath, int newcompressedsize) { GC.Collect(); int count = 0; int index = -1; foreach (TOCFile.TOCBundleInfoStruct buni in toc.bundles) if (count++ > -1 && bpath.ToLower() == buni.id.ToLower()) { DbgPrint(" Found bundle : " + bpath); index = count - 1; break; } //if bundle found if (index != -1) { if (!toc.iscas) { DbgPrint(" Warning: binary bundles not supported yet, skipping!"); return; } //find out if base or delta BJSON.Entry root = toc.lines[0]; BJSON.Field bundles = root.FindField("bundles"); BJSON.Entry bun = ((List<BJSON.Entry>)bundles.data)[index]; BJSON.Field isDeltaField = bun.FindField("delta"); BJSON.Field isBaseField = bun.FindField("base"); //if is base, copy from base, make delta and recompile if (isBaseField != null && (bool)isBaseField.data == true) if (!ImportBundleFromBase(toc, tocpath, index, bpath)) return; //check if already is in sb if (isDeltaField != null && (bool)isDeltaField.data == true) DbgPrint(" Its already a delta"); DbgPrint(" Updating SB file with new SHA1...");//yeah, pretty much string SBpath = outputPath + Path.GetDirectoryName(tocpath) + "\\" + Path.GetFileNameWithoutExtension(tocpath) + ".sb"; SBFile sb = new SBFile(SBpath); root = sb.lines[0]; bundles = root.FindField("bundles"); List<BJSON.Entry> bundle_list = (List<BJSON.Entry>)bundles.data; //find right bundle for (int i = 0; i < bundle_list.Count; i++) { bun = bundle_list[i]; BJSON.Field ebx = bun.FindField("ebx"); BJSON.Field res = bun.FindField("res"); BJSON.Field path = bun.FindField("path"); if (!(path != null && ((string)path.data).ToLower() == bpath.ToLower()) || res == null) continue; bool found = false; //find right res entry List<BJSON.Entry> res_list = (List<BJSON.Entry>)res.data; for (int j = 0; j < res_list.Count; j++) { BJSON.Entry res_e = res_list[j]; BJSON.Field f_sha1 = res_e.FindField("sha1"); BJSON.Field f_name = res_e.FindField("name"); BJSON.Field f_size = res_e.FindField("size"); BJSON.Field f_osize = res_e.FindField("originalSize"); BJSON.Field f_casPatchType = res_e.FindField("casPatchType"); if (f_name != null && ((string)f_name.data).ToLower() == mj.respath.ToLower() && f_sha1 != null) { //get res data byte[] sha1buff = (byte[])f_sha1.data; DbgPrint(" Found res sha1 : " + Helpers.ByteArrayToHexString(sha1buff)); f_sha1.data = newsha1; DbgPrint(" Replaced res sha1 with : " + Helpers.ByteArrayToHexString(newsha1)); DbgPrint(" Updating res size : " + mj.data.Length); f_size.data = BitConverter.GetBytes((long)newcompressedsize); f_osize.data = BitConverter.GetBytes((long)mj.data.Length); if (f_casPatchType != null) { if (BitConverter.ToInt32((byte[])f_casPatchType.data, 0) != 1) { DbgPrint(" CasPatchType: found and set to 1!"); f_casPatchType.data = BitConverter.GetBytes((int)1); } else DbgPrint(" CasPatchType: found and is fine!"); } else { f_casPatchType = new BJSON.Field(); f_casPatchType.fieldname = "casPatchType"; f_casPatchType.type = 8; f_casPatchType.data = BitConverter.GetBytes((int)1); res_e.fields.Add(f_casPatchType); DbgPrint(" CasPatchType: added and set to 1!"); } CalcTotalSize(bun); sb.Save(); DbgPrint(" Job successfull!"); found = true; } } if (!found) { DbgPrint(" cant find res, adding it!"); BJSON.Entry newres = new BJSON.Entry(); newres.type = 0x82; newres.fields = new List<BJSON.Field>(); newres.fields.Add(new BJSON.Field(7, "name", mj.respath)); newres.fields.Add(new BJSON.Field(0x10, "sha1", newsha1)); newres.fields.Add(new BJSON.Field(9, "size", BitConverter.GetBytes((long)newcompressedsize))); newres.fields.Add(new BJSON.Field(9, "originalSize", BitConverter.GetBytes((long)mj.data.Length))); newres.fields.Add(new BJSON.Field(0x8, "resType", Helpers.HexStringToByteArray(mj.restype))); newres.fields.Add(new BJSON.Field(0x13, "resMeta", new byte[0x10])); newres.fields.Add(new BJSON.Field(9, "resRid", BitConverter.GetBytes((long)0))); newres.fields.Add(new BJSON.Field(8, "casPatchType", BitConverter.GetBytes((int)1))); ((List<BJSON.Entry>)res.data).Add(newres); CalcTotalSize(bun); sb.Save(); DbgPrint(" Job successfull!"); break; } } } }
public void RunBinaryResJob(Mod.ModJob mj) { DbgPrint("Running Binary Ressource Replacement Job for: " + mj.respath); //Check Toc Files List<string> reducedTocPaths = new List<string>(); bool found = false; foreach (string p in mj.tocPaths) { found = false; for (int i = 0; i < reducedTocPaths.Count; i++) if (p == reducedTocPaths[i]) { found = true; break; } if (!found) reducedTocPaths.Add(p); } mj.tocPaths = reducedTocPaths; List<string> reducedBundlePaths = new List<string>(); foreach (string p in mj.bundlePaths) { found = false; for (int i = 0; i < reducedBundlePaths.Count; i++) if (p == reducedBundlePaths[i]) { found = true; break; } if (!found) reducedBundlePaths.Add(p); } mj.bundlePaths = reducedBundlePaths; foreach (string tocpath in mj.tocPaths) { if (tocpath.ToLower().Contains("\\patch\\")) continue; DbgPrint("Checking for : " + tocpath); if (!tocpath.ToLower().StartsWith("update")) { if (!File.Exists(outputPath + tocpath)) { DbgPrint("Error: TOC file not found, aborting!"); return; } } else { if (!File.Exists(outputPath + Helpers.SkipSubFolder(tocpath, 2))) { DbgPrint("Error: TOC file not found, aborting!"); return; } } } DbgPrint("All found."); //create cas data int newcompressedsize = 0; byte[] newsha1 = CreateCASContainer(mj.data, out newcompressedsize); if (newsha1.Length != 0x14) { DbgPrint("Error: could not create CAS data, aborting!"); return; } //walk through affected toc files foreach (string tocpath in mj.tocPaths) if (!tocpath.ToLower().Contains("\\patch\\")) RunRessourceJob(mj, tocpath, newsha1, newcompressedsize); }
private void toolStripButton3_Click(object sender, EventArgs e) { if (textBox2.Text == "") return; mod = new Mod(); mod.Load(textBox2.Text); panel2.BringToFront(); }
public void RunTextureResJobOnBundleBinary(Mod.ModJob mj, TOCFile toc, string tocpath, string bpath) { GC.Collect(); int count = 0; int index = -1; foreach (TOCFile.TOCBundleInfoStruct buni in toc.bundles) if (count++ > -1 && bpath.ToLower() == buni.id.ToLower()) { DbgPrint(" Found bundle : " + bpath); index = count - 1; break; } //if bundle found if (index != -1) { //find out if base, delta or nothing BJSON.Entry root = toc.lines[0]; BJSON.Field bundles = root.FindField("bundles"); BJSON.Entry bun = ((List<BJSON.Entry>)bundles.data)[index]; BJSON.Field isDeltaField = bun.FindField("delta"); BJSON.Field isBaseField = bun.FindField("base"); //if has base or delta prop, still from patch if (isBaseField != null) if (!ImportBundleBinaryFromBase(toc, tocpath, bpath)) return; toc = new TOCFile(toc.MyPath);//reload toc byte[] bundledataraw = toc.ExportBundleDataByPath(bpath); uint test = BitConverter.ToUInt32(bundledataraw, 4); if (test != 0xD58E799D) { DbgPrint(" Its a real delta bundle, importing from base..."); if (!ImportBundleBinaryFromBase(toc, tocpath, bpath, false)) return; toc.Save(); toc = new TOCFile(toc.MyPath);//reload toc } DbgPrint(" Updating SB file with new data..."); bundledataraw = toc.ExportBundleDataByPath(bpath); BinaryBundle bundle = new BinaryBundle(new MemoryStream(bundledataraw)); bool found = false; byte[] chunkidbuff = new byte[16]; byte[] newchunkid = new byte[16]; //find right res entry for (int j = 0; j < bundle.ResList.Count; j++) if (bundle.ResList[j]._name.ToLower() == mj.respath.ToLower()) { //get res data and extract chunk id for (int k = 0; k < 16; k++) chunkidbuff[k] = bundle.ResList[j]._data[k + 0x1C]; DbgPrint(" Found chunk id : " + Helpers.ByteArrayToHexString(chunkidbuff)); newchunkid = Guid.NewGuid().ToByteArray(); DbgPrint(" Creating new chunk id : " + Helpers.ByteArrayToHexString(newchunkid)); for (int k = 0; k < 16; k++) bundle.ResList[j]._data[k + 0x1C] = newchunkid[k]; found = true; } if (!found) { DbgPrint(" Error: cant find res, skipping!"); return; } found = false; //find right chunk entry MemoryStream m3 = new MemoryStream(); Helpers.WriteLEInt(m3, BitConverter.ToInt32(chunkidbuff, 0)); Helpers.WriteLEUShort(m3, BitConverter.ToUInt16(chunkidbuff, 4)); Helpers.WriteLEUShort(m3, BitConverter.ToUInt16(chunkidbuff, 6)); m3.Write(chunkidbuff, 8, 8); byte[] chunkidswapped = m3.ToArray(); for (int j = 0; j < bundle.ChunkList.Count; j++) if (Helpers.ByteArrayCompare(bundle.ChunkList[j].id, chunkidswapped)) { DbgPrint(" Found chunk"); found = true; BinaryBundle.ChunkEntry chunk = bundle.ChunkList[j]; m3 = new MemoryStream(); Helpers.WriteLEInt(m3, BitConverter.ToInt32(newchunkid, 0)); Helpers.WriteLEUShort(m3, BitConverter.ToUInt16(newchunkid, 4)); Helpers.WriteLEUShort(m3, BitConverter.ToUInt16(newchunkid, 6)); m3.Write(newchunkid, 8, 8); chunk.id = m3.ToArray(); chunk._data = mj.data; bundle.ChunkList[j] = chunk; break; } if (!found) { DbgPrint(" Error: Could not find Chunk by id"); return; } DbgPrint(" Recompiling bundle..."); MemoryStream m = new MemoryStream(); bundle.Save(m); DbgPrint(" Recompiling sb..."); MemoryStream m2 = new MemoryStream(); List<BJSON.Entry> list = ((List<BJSON.Entry>)bundles.data); foreach (TOCFile.TOCBundleInfoStruct buni in toc.bundles) if (!buni.isbase) { byte[] buff = new byte[0]; if (bpath.ToLower() != buni.id.ToLower()) buff = toc.ExportBundleDataByPath(buni.id); else buff = m.ToArray(); for (int i = 0; i < list.Count; i++) if ((string)list[i].FindField("id").data == buni.id) { BJSON.Entry e = list[i]; BJSON.Field f = e.fields[e.FindFieldIndex("offset")]; f.data = BitConverter.GetBytes(m2.Position); e.fields[e.FindFieldIndex("offset")] = f; f = e.fields[e.FindFieldIndex("size")]; f.data = BitConverter.GetBytes(buff.Length); e.fields[e.FindFieldIndex("size")] = f; list[i] = e; break; } m2.Write(buff, 0, buff.Length); } bundles.data = list; root.fields[root.FindFieldIndex("bundles")] = bundles; toc.lines[0] = root; DbgPrint(" Updating TOC..."); toc.Save(); toc = new TOCFile(toc.MyPath);//reload toc DbgPrint(" Saving sb..."); if (tocpath.ToLower().Contains("update")) File.WriteAllBytes(outputPath + Helpers.SkipSubFolder(tocpath.ToLower().Replace(".toc", ".sb"), 2), m2.ToArray()); else File.WriteAllBytes(outputPath + tocpath.ToLower().Replace(".toc", ".sb"), m2.ToArray()); DbgPrint(" Job successfull!"); } }