Advertisement
Guest User

Untitled

a guest
Oct 8th, 2015
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 18.21 KB | None | 0 0
  1.  public void RunTextureJob(Mod.ModJob mj)
  2.         {
  3.             //Check Toc Files
  4.             foreach (string tocpath in mj.tocPaths)
  5.             {
  6.                 DbgPrint("Checking for : " + tocpath);
  7.                 if (!File.Exists(outputPath + tocpath))
  8.                 {
  9.                     DbgPrint("Error: TOC file not found, aborting!");
  10.                     return;
  11.                 }
  12.             }
  13.             //walk through affected toc files
  14.             foreach (string tocpath in mj.tocPaths)
  15.             {
  16.                 //check if incas
  17.                 DbgPrint("Loading : " + tocpath);
  18.                 TOCFile toc = new TOCFile(outputPath + tocpath);
  19.                 if(!toc.iscas )
  20.                 {
  21.                     DbgPrint("Error: TOC is not saving in CAS, skipping!");
  22.                     continue;
  23.                 }
  24.                 //walk through affected bundles
  25.                 foreach (string bpath in mj.bundlePaths)
  26.                 {
  27.                     int count = 0;
  28.                     int index = -1;
  29.                     foreach (TOCFile.TOCBundleInfoStruct buni in toc.bundles)
  30.                         if (count++ > -1 && bpath == buni.id)
  31.                         {
  32.                             DbgPrint(" Found bundle : " + bpath);
  33.                             index = count - 1;
  34.                             break;
  35.                         }
  36.                     //if bundle found
  37.                     if (index != -1)
  38.                     {
  39.                         //find out if base or delta
  40.                         BJSON.Entry root = toc.lines[0];
  41.                         BJSON.Field bundles = root.fields[0];
  42.                         BJSON.Entry bun = ((List<BJSON.Entry>)bundles.data)[index];
  43.                         BJSON.Field isDeltaField = null;
  44.                         BJSON.Field isBaseField = null;
  45.                         foreach (BJSON.Field f in bun.fields)
  46.                             switch (f.fieldname)
  47.                             {
  48.                                 case "base":
  49.                                     isBaseField = f;
  50.                                     break;
  51.                                 case "delta":
  52.                                     isDeltaField = f;
  53.                                     break;
  54.                             }
  55.                         //if is base, copy from base, make delta and recompile
  56.                         if (isBaseField != null && (bool)isBaseField.data == true)
  57.                         {
  58.                             DbgPrint("  Its a base reference! Copying in from base...");
  59.                             //Find base toc
  60.                             string basepath = GlobalStuff.FindSetting("gamepath");
  61.                             if (!File.Exists(basepath + tocpath))
  62.                             {
  63.                                 DbgPrint("Error: base TOC file not found, skipping!");
  64.                                 continue;
  65.                             }
  66.                             TOCFile otoc = new TOCFile(basepath + tocpath);
  67.                             //get base bundle data
  68.                             byte[] buff = otoc.ExportBundleDataByPath(bpath);
  69.                             if (buff.Length == 0)
  70.                             {
  71.                                 DbgPrint("Error: base bundle not found, skipping!");
  72.                                 continue;
  73.                             }
  74.                             //get old sb file
  75.                             string oldSBpath = outputPath + Path.GetDirectoryName(tocpath) + "\\" + Path.GetFileNameWithoutExtension(tocpath) + ".sb";
  76.                             if (!File.Exists(oldSBpath))
  77.                             {
  78.                                 DbgPrint("Error: patch SB file not found, skipping!");
  79.                                 continue;
  80.                             }
  81.                             DbgPrint("  Got copy, recompiling...");
  82.                             //recompiling new sb in memory
  83.                             MemoryStream newSB = new MemoryStream();
  84.                             FileStream oldSB = new FileStream(oldSBpath, FileMode.Open, FileAccess.Read);
  85.                             long glob_off = 0;
  86.                             count = ((List<BJSON.Entry>)bundles.data).Count();
  87.                             DbgPrint("  Recompiling SB...");
  88.                             //put one bundle after another that is not base as defined in toc
  89.                             for (int i = 0; i < count; i++)
  90.                             {
  91.                                 //get entry infos
  92.                                 BJSON.Entry b = ((List<BJSON.Entry>)bundles.data)[i];
  93.                                 BJSON.Field f_offset = null;
  94.                                 BJSON.Field f_size = null;
  95.                                 BJSON.Field f_isBase = null;
  96.                                 foreach (BJSON.Field f in b.fields)
  97.                                     switch (f.fieldname)
  98.                                     {
  99.                                         case "offset":
  100.                                             f_offset = f;
  101.                                             break;
  102.                                         case "size":
  103.                                             f_size = f;
  104.                                             break;
  105.                                         case "base":
  106.                                             f_isBase = f;
  107.                                             break;
  108.                                     }
  109.                                 //if not our target and not copied from base, copy from old SB
  110.                                 if (i != index && f_isBase == null)
  111.                                 {
  112.                                     int size = BitConverter.ToInt32((byte[])f_size.data, 0);
  113.                                     CopyFileStream(oldSB, newSB, BitConverter.ToInt64((byte[])f_offset.data, 0), size);
  114.                                     f_offset.data = BitConverter.GetBytes(glob_off);
  115.                                     glob_off += size;
  116.                                 }
  117.                                 //if target, replace data, make delta
  118.                                 if (i == index)
  119.                                 {
  120.                                     f_offset.data = BitConverter.GetBytes(glob_off);
  121.                                     f_size.data = BitConverter.GetBytes(buff.Length);
  122.                                     f_isBase.fieldname = "delta";
  123.                                     newSB.Write(buff, 0, buff.Length);
  124.                                     glob_off += buff.Length;
  125.                                 }
  126.                             }
  127.                             oldSB.Close();
  128.                             //rebuilding new SB
  129.                             oldSB = new FileStream(oldSBpath, FileMode.Create, FileAccess.Write);
  130.                             //creating bundle header field
  131.                             MemoryStream t = new MemoryStream();
  132.                             Helpers.WriteLEB128(t, (int)newSB.Length);
  133.                             newSB.WriteByte(0);
  134.                             int varsize = (int)t.Length;
  135.                             //add root entry
  136.                             oldSB.WriteByte(0x82);
  137.                             Helpers.WriteLEB128(oldSB, varsize + 9 + (int)newSB.Length);
  138.                             byte[] buff2 = { 0x01, 0x62, 0x75, 0x6E, 0x64, 0x6C, 0x65, 0x73, 0x00 };
  139.                             oldSB.Write(buff2, 0, 9);
  140.                             oldSB.Write(t.ToArray(), 0, varsize);
  141.                             //header done, grab header offset and put all bundles
  142.                             int rel_off = (int)oldSB.Position;
  143.                             oldSB.Write(newSB.ToArray(), 0, (int)newSB.Length);
  144.                             oldSB.Close();
  145.                             DbgPrint("  Recompiling TOC...");
  146.                             //correct offsets in toc by new adding header offset
  147.                             count = ((List<BJSON.Entry>)bundles.data).Count();
  148.                             for (int i = 0; i < count; i++)
  149.                             {
  150.                                 BJSON.Entry b = ((List<BJSON.Entry>)bundles.data)[i];
  151.                                 BJSON.Field f_offset = null;
  152.                                 BJSON.Field f_isBase = null;
  153.                                 foreach (BJSON.Field f in b.fields)
  154.                                     switch (f.fieldname)
  155.                                     {
  156.                                         case "offset":
  157.                                             f_offset = f;
  158.                                             break;
  159.                                         case "base":
  160.                                             f_isBase = f;
  161.                                             break;
  162.                                     }
  163.                                 //if is in sb file, update
  164.                                 if (f_isBase == null)
  165.                                 {
  166.                                     long off = BitConverter.ToInt64((byte[])f_offset.data, 0);
  167.                                     off += rel_off;
  168.                                     f_offset.data = BitConverter.GetBytes(off);
  169.                                 }
  170.                             }
  171.                             toc.Save();
  172.                             DbgPrint("  Bundle imported");
  173.                         }
  174.                         //check if already is in sb
  175.                         if (isDeltaField != null && (bool)isDeltaField.data == true)
  176.                         {
  177.                             DbgPrint("  Its already a delta");
  178.                         }
  179.                         //generating cas data
  180.                         DbgPrint("  Creating CAS container for new data");
  181.                         byte[] data = CASFile.MakeHeaderAndContainer(mj.data);
  182.                         DbgPrint("  Finding free CAS...");
  183.                         int casindex = 99;
  184.                         FileStream fs;
  185.                         long pos;
  186.                         while (File.Exists(outputPath + "Data\\cas_" + casindex.ToString("D2") + ".cas"))
  187.                         {
  188.                             fs = new FileStream(outputPath + "Data\\cas_" + casindex.ToString("D2") + ".cas", FileMode.Open, FileAccess.Read);
  189.                             fs.Seek(0, SeekOrigin.End);
  190.                             pos = fs.Position;
  191.                             fs.Close();
  192.                             if (pos < 0x70000000)
  193.                                 break;
  194.                             casindex--;
  195.                         }
  196.                         string caspath = outputPath + "Data\\cas_" + casindex.ToString("D2") + ".cas";
  197.                         if (!File.Exists(caspath))
  198.                             File.WriteAllBytes(caspath, new byte[0]);
  199.                         DbgPrint("  Choosing : cas_" + casindex.ToString("D2") + ".cas");
  200.                         fs = new FileStream(caspath, FileMode.Open, FileAccess.Read);
  201.                         //get new offset
  202.                         fs.Seek(0, SeekOrigin.End);
  203.                         pos = fs.Position;
  204.                         fs.Close();
  205.                         fs = new FileStream(caspath, FileMode.Append, FileAccess.Write);
  206.                         fs.Write(data, 0, data.Length);
  207.                         fs.Close();
  208.                         //creating new CAT entry with new SHA1
  209.                         DbgPrint("  Appended Data, updating CAT file...");
  210.                         if (!File.Exists(outputPath + "Data\\cas.cat"))
  211.                         {
  212.                             DbgPrint("Error: cant find CAT file, skipping!");
  213.                             continue;
  214.                         }
  215.                         fs = new FileStream(outputPath + "Data\\cas.cat", FileMode.Append, FileAccess.Write);
  216.                         fs.Write(data, 4, 0x14);
  217.                         byte[] newsha1 = new byte[0x14];
  218.                         for (int i = 0; i < 0x14; i++)
  219.                             newsha1[i] = data[i + 4];
  220.                         fs.Write(BitConverter.GetBytes((int)pos + 0x20), 0, 4);
  221.                         fs.Write(BitConverter.GetBytes((int)data.Length - 0x20), 0, 4);
  222.                         fs.Write(BitConverter.GetBytes(casindex), 0, 4);
  223.                         fs.Close();
  224.                         DbgPrint("  Updating SB file with new SHA1...");//yeah, pretty much
  225.                         string SBpath = outputPath + Path.GetDirectoryName(tocpath) + "\\" + Path.GetFileNameWithoutExtension(tocpath) + ".sb";
  226.                         SBFile sb = new SBFile(SBpath);
  227.                         root = sb.lines[0];
  228.                         bundles = root.fields[0];
  229.                         count = ((List<BJSON.Entry>)bundles.data).Count;
  230.                         //find right bundle
  231.                         for (int i = 0; i < count; i++)
  232.                         {
  233.                             bun = ((List<BJSON.Entry>)bundles.data)[i];
  234.                             bool found = false;
  235.                             BJSON.Field res = null;
  236.                             BJSON.Field chunks = null;
  237.                             foreach (BJSON.Field f in bun.fields)
  238.                                 if (f.fieldname == "path" && ((string)f.data) == bpath)
  239.                                     found = true;
  240.                                 else
  241.                                     switch (f.fieldname)
  242.                                     {
  243.                                         case "res":
  244.                                             res = f;
  245.                                             break;
  246.                                         case "chunks":
  247.                                             chunks = f;
  248.                                             break;
  249.                                     }
  250.                             if (!found || res == null || chunks == null)
  251.                                 continue;
  252.                             //find right res entry
  253.                             foreach (BJSON.Entry res_e in ((List<BJSON.Entry>)res.data))
  254.                             {
  255.                                 bool found2 = false;
  256.                                 BJSON.Field f_sha1 = null;
  257.                                 foreach (BJSON.Field f2 in res_e.fields)
  258.                                     switch (f2.fieldname)
  259.                                     {
  260.                                         case "name":
  261.                                             if (((string)f2.data) == mj.respath)
  262.                                                 found2 = true;
  263.                                             break;
  264.                                         case "sha1":
  265.                                             f_sha1 = f2;
  266.                                             break;
  267.                                     }
  268.                                 if (found2 && f_sha1 != null)
  269.                                 {
  270.                                     //get res data and extract chunk id
  271.                                     byte[] sha1buff = (byte[])f_sha1.data;
  272.                                     DbgPrint("  Found res sha1 : " + Helpers.ByteArrayToHexString(sha1buff));
  273.                                     byte[] resdata = SHA1Access.GetDataBySha1(sha1buff);
  274.                                     if (resdata.Length == 0)
  275.                                     {
  276.                                         DbgPrint("  Error: cant find res data, skipping!");
  277.                                         break;
  278.                                     }
  279.                                     byte[] chunkidbuff = new byte[16];
  280.                                     for (int j = 0; j < 16; j++)
  281.                                         chunkidbuff[j] = resdata[j + 0x1C];
  282.                                     DbgPrint("  Found chunk id : " + Helpers.ByteArrayToHexString(chunkidbuff));
  283.                                     List<BJSON.Entry> chunklist = (List<BJSON.Entry>)chunks.data;
  284.                                     bool replaced = false;
  285.                                     //find right chunk by id
  286.                                     for (int j = 0; j < chunklist.Count; j++)
  287.                                     {
  288.                                         bool found3 = false;
  289.                                         BJSON.Field f2_sha1 = null;
  290.                                         foreach (BJSON.Field f3 in chunklist[j].fields)
  291.                                             switch (f3.fieldname)
  292.                                             {
  293.                                                 case "id":
  294.                                                     if (Helpers.ByteArrayCompare((byte[])f3.data, chunkidbuff))
  295.                                                         found3 = true;
  296.                                                     break;
  297.                                                 case "sha1":
  298.                                                     f2_sha1 = f3;
  299.                                                     break;
  300.                                             }
  301.                                         //patch in new sha1
  302.                                         if (found3 && f2_sha1 != null)
  303.                                         {
  304.                                             f2_sha1.data = newsha1;
  305.                                             sb.Save();
  306.                                             replaced = true;
  307.                                             DbgPrint("  Replaced chunk sha1 and saved SB file");
  308.                                             DbgPrint("  Job successfull!");
  309.                                             break;
  310.                                         }
  311.                                     }
  312.                                     if (!replaced)
  313.                                     {
  314.                                         DbgPrint("  Error: Could not find Chunk by id");
  315.                                     }
  316.                                 }
  317.                             }
  318.                         }
  319.                     }
  320.                     else
  321.                     {
  322.                         DbgPrint(" Error: could find bundle " + bpath);
  323.                     }
  324.                 }
  325.             }
  326.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement