コード例 #1
0
ファイル: ModRunner.cs プロジェクト: tirnoney/DAIToolsWV
 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;
             }
         }
     }
 }
コード例 #2
0
ファイル: ModRunner.cs プロジェクト: tirnoney/DAIToolsWV
 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");
         }
     }
 }
コード例 #3
0
ファイル: ModRunner.cs プロジェクト: tirnoney/DAIToolsWV
 public bool ImportBundleFromBase(TOCFile toc, string tocpath, int index, string bpath)
 {
     DbgPrint("  Its a base reference! Copying in from base...");
     //Find base toc
     string basepath = GlobalStuff.FindSetting("gamepath");
     if (!File.Exists(basepath + tocpath))
     {
         DbgPrint("Error: base TOC file not found, skipping!");
         return false;
     }
     TOCFile otoc = new TOCFile(basepath + tocpath);
     //get base bundle data
     byte[] buff = otoc.ExportBundleDataByPath(bpath);
     if (buff.Length == 0)
     {
         DbgPrint("Error: base bundle not found, skipping!");
         return false;
     }
     //get old sb file
     string oldSBpath = outputPath + Path.GetDirectoryName(tocpath) + "\\" + Path.GetFileNameWithoutExtension(tocpath) + ".sb";
     if (!File.Exists(oldSBpath))
     {
         DbgPrint("Error: patch SB file not found, skipping!");
         return false;
     }
     DbgPrint("  Got copy, recompiling...");
     //recompiling new sb in memory
     MemoryStream newSB = new MemoryStream();
     FileStream oldSB = new FileStream(oldSBpath, FileMode.Open, FileAccess.Read);
     long glob_off = 0;
     BJSON.Entry root = toc.lines[0];
     BJSON.Field bundles = root.fields[0];
     int count = ((List<BJSON.Entry>)bundles.data).Count();
     DbgPrint("  Recompiling SB...");
     //put one bundle after another that is not base as defined in toc
     for (int i = 0; i < count; i++)
     {
         //get entry infos
         BJSON.Entry b = ((List<BJSON.Entry>)bundles.data)[i];
         BJSON.Field f_offset = b.FindField("offset");
         BJSON.Field f_size = b.FindField("size");
         BJSON.Field f_isBase = b.FindField("base");
         //if not our target and not copied from base, copy from old SB
         if (i != index && f_isBase == null)
         {
             int size = BitConverter.ToInt32((byte[])f_size.data, 0);
             CopyFileStream(oldSB, newSB, BitConverter.ToInt64((byte[])f_offset.data, 0), size);
             f_offset.data = BitConverter.GetBytes(glob_off);
             glob_off += size;
         }
         //if target, replace data, make delta
         if (i == index)
         {
             f_offset.data = BitConverter.GetBytes(glob_off);
             f_size.data = BitConverter.GetBytes(buff.Length);
             f_isBase.fieldname = "delta";
             newSB.Write(buff, 0, buff.Length);
             glob_off += buff.Length;
         }
     }
     oldSB.Close();
     //rebuilding new SB
     oldSB = new FileStream(oldSBpath, FileMode.Create, FileAccess.Write);
     //creating bundle header field
     MemoryStream t = new MemoryStream();
     Helpers.WriteLEB128(t, (int)newSB.Length);
     newSB.WriteByte(0);
     int varsize = (int)t.Length;
     //add root entry
     oldSB.WriteByte(0x82);
     Helpers.WriteLEB128(oldSB, varsize + 9 + (int)newSB.Length);
     byte[] buff2 = { 0x01, 0x62, 0x75, 0x6E, 0x64, 0x6C, 0x65, 0x73, 0x00 };
     oldSB.Write(buff2, 0, 9);
     oldSB.Write(t.ToArray(), 0, varsize);
     //header done, grab header offset and put all bundles
     int rel_off = (int)oldSB.Position;
     oldSB.Write(newSB.ToArray(), 0, (int)newSB.Length);
     oldSB.Close();
     //removing idata
     DbgPrint("  removing idata...");
     SBFile sb = new SBFile(oldSBpath);
     BJSON.Entry newroot = sb.lines[0];
     BJSON.Field newbundles = newroot.FindField("bundles");
     List<BJSON.Entry> newbun_list = (List<BJSON.Entry>)newbundles.data;
     for (int i = 0; i < newbun_list.Count; i++)
     {
         BJSON.Field f_res = newbun_list[i].FindField("res");
         List<BJSON.Entry> newres_list = (List<BJSON.Entry>)f_res.data;
         for (int j = 0; j < newres_list.Count; j++)
             newres_list[j].RemoveField("idata");
     }
     sb.Save();
     DbgPrint("  Recompiling TOC...");
     //correct offsets in toc by new adding header offset
     count = ((List<BJSON.Entry>)bundles.data).Count();
     for (int i = 0; i < count; i++)
     {
         BJSON.Entry b = ((List<BJSON.Entry>)bundles.data)[i];
         BJSON.Field f_offset = b.FindField("offset");
         BJSON.Field f_isBase = b.FindField("base");
         //if is in sb file, update
         if (f_isBase == null)
         {
             long off = BitConverter.ToInt64((byte[])f_offset.data, 0);
             off += rel_off;
             f_offset.data = BitConverter.GetBytes(off);
         }
     }
     toc.Save();
     DbgPrint("  Bundle imported");
     return true;
 }