예제 #1
0
 public void PreviewFile(string path)
 {
     string ext = Path.GetExtension(path).ToLower();
     TOCFile toc;
     switch (ext)
     {
         case ".toc":
             toc = new TOCFile(path);
             if (toc != null && toc.lines != null)
                 Helpers.FillTreeFast(treeView2, toc.lines);
             break;
         case ".sb":
             string tocpath = Helpers.GetFileNameWithOutExtension(path) + ".toc";
             if (File.Exists(tocpath))
             {
                 toc = new TOCFile(tocpath);
                 if (toc != null && toc.lines != null && toc.lines.Count != 0)
                     foreach (BJSON.Field f in toc.lines[0].fields)
                         if (f.fieldname == "cas" && (bool)f.data)
                         {
                             SBFile sb = new SBFile(path);
                             if (sb != null && sb.lines != null)
                                 Helpers.FillTreeFast(treeView2, sb.lines);
                             return;
                         }
             }
             break;
     }
 }
예제 #2
0
 public void LoadFile(string path)
 {
     this.Text = "SB Tool - " + path;
     toc = new TOCFile(Helpers.GetFileNameWithOutExtension(path) + ".toc");
     if (toc.iscas)
     {
         toolStrip1.Visible = true;
         splitContainer2.BringToFront();
         sb = new SBFile(path);
         RefreshTree();
     }
     else
     {
         toolStrip1.Visible = false;
         tabControl1.BringToFront();
         RefreshBinary();
     }
 }
예제 #3
0
 public void LoadFile(string path)
 {
     initfs = new TOCFile(path);
     list = new List<FileEntry>();
     foreach (BJSON.Entry e in initfs.lines)
         if (e.fields != null && e.fields.Count != 0)
         {
             BJSON.Field file = e.fields[0];
             List<BJSON.Field> data = (List<BJSON.Field>)file.data;
             FileEntry entry = new FileEntry();
             foreach (BJSON.Field f in data)
                 switch (f.fieldname)
                 {
                     case "name":
                         entry.name = (string)f.data;
                         break;
                     case "payload":
                         entry.data = (byte[])f.data;
                         break;
                 }
             list.Add(entry);
         }
     RefreshList();
 }
예제 #4
0
 private void RefreshPreview()
 {
     try
     {
         int n = listBox2.SelectedIndex;
         if (n == -1)
             return;
         status.Text = "Getting header infos from db...";
         Application.DoEvents();
         DBAccess.RESInformation ti = ttprevlist[n];
         DBAccess.BundleInformation buni = DBAccess.GetBundleInformationById(ti.bundlepath)[0];
         DBAccess.TOCInformation toci = DBAccess.GetTocInformationByIndex(buni.tocIndex);
         byte[] resdata = new byte[0];
         if (toci.incas)
         {
             status.Text = "Getting header data from sha1...";
             Application.DoEvents();
             resdata = SHA1Access.GetDataBySha1(Helpers.HexStringToByteArray(ti.sha1));
         }
         else
         {
             status.Text = "Getting header data from binary bundle...";
             Application.DoEvents();
             TOCFile toc = new TOCFile(toci.path);
             byte[] bundledata = toc.ExportBundleDataByPath(buni.bundlepath);
             BinaryBundle b = new BinaryBundle(new MemoryStream(bundledata));
             foreach (BinaryBundle.ResEntry res in b.ResList)
                 if (res._name == ti.resname)
                 {
                     resdata = res._data;
                     break;
                 }
         }
         hb2.ByteProvider = new DynamicByteProvider(resdata);
         status.Text = "Ready";
     }
     catch (Exception ex)
     {
         status.Text = "General error, after state '" + status.Text + "' : " + ex.Message;
     }
 }
예제 #5
0
 public static void AddBundle(int tocid, bool incas, Bundle b, TOCFile.TOCBundleInfoStruct info, SQLiteConnection con)
 {
     Debug.LogLn(" EBX:" + b.ebx.Count + " RES:" + b.res.Count + " CHUNK:" + b.chunk.Count, true);
     SQLCommand("INSERT INTO bundles (tocfile, frostid, offset, size, base, delta) VALUES (" + tocid + ",'" + info.id + "'," + info.offset + ", " + info.size + ", '" + info.isbase + "', '" + info.isdelta + "' )", con);
     int bundleid = (int)GetLastRowId(con);
     TOCInformation toci = GetTocInformationByIndex(tocid);
     var transaction = con.BeginTransaction();
     int counter = 0;
     if (b.ebx != null)
         foreach (Bundle.ebxtype ebx in b.ebx)
             try
             {
                 if (ebx.name != null && ebx.originalSize != null && ebx.size != null)
                 {
                     EBXInformation inf = new EBXInformation();
                     inf.basesha1 = Helpers.ByteArrayToHexString(ebx.baseSha1);
                     inf.bundlepath = b.path;
                     inf.casPatchType = ebx.casPatchType;
                     inf.deltasha1 = Helpers.ByteArrayToHexString(ebx.deltaSha1);
                     inf.ebxname = ebx.name;
                     inf.incas = incas;
                     inf.isbase = info.isbase;
                     inf.isdelta = info.isdelta;
                     if (toci.type == TYPE_BASEGAME)
                         inf.isbasegamefile = true;
                     if (toci.type == TYPE_UPDATE)
                         inf.isDLC = true;
                     if (toci.type == TYPE_PATCH)
                         inf.isPatch = true;
                     inf.offset = info.offset;
                     inf.sha1 = Helpers.ByteArrayToHexString(ebx.Sha1);
                     inf.size = info.size;
                     inf.tocfilepath = toci.path;
                     byte[] data = new byte[0];
                     if (inf.incas)
                         data = SHA1Access.GetDataBySha1(ebx.Sha1, 0x38);
                     else
                     {
                         BinaryBundle bb = null;
                         foreach (AddEBXHelpStruct h in aehelp)
                             if (h.tocpath == inf.tocfilepath && h.bpath == inf.bundlepath)
                             {
                                 bb = h.b;
                                 break;
                             }
                         if (bb == null)
                         {
                             TOCFile toc = new TOCFile(inf.tocfilepath);
                             byte[] bundledata = toc.ExportBundleDataByPath(inf.bundlepath);
                             bb = new BinaryBundle(new MemoryStream(bundledata));
                             AddEBXHelpStruct h = new AddEBXHelpStruct();
                             h.tocpath = inf.tocfilepath;
                             h.bpath = inf.bundlepath;
                             h.b = bb;
                             if (aehelp.Count > 10)
                                 aehelp.RemoveAt(0);
                         }
                         foreach (BinaryBundle.EbxEntry ebx2 in bb.EbxList)
                             if (inf.ebxname == ebx2._name)
                                 data = ebx2._data;
                     }
                     inf.guid = Helpers.ByteArrayToHexString(data, 0x28, 0x10);
                     AddEBXLUTFile(inf, con);
                     if ((counter++) % 100 == 0)
                     {
                         transaction.Commit();
                         transaction = con.BeginTransaction();
                     }
                 }
             }
             catch (Exception ex)
             {
                 throw ex;
             }
     transaction.Commit();
     transaction = con.BeginTransaction();
     if (b.res != null)
         foreach (Bundle.restype res in b.res)
             try
             {
                 if (res.name != null)
                     AddRESFile(res.name, res.SHA1, res.rtype, bundleid, con);
             }
             catch (Exception ex)
             {
                 throw ex;
             }
     transaction.Commit();
     transaction = con.BeginTransaction();
     if (b.chunk != null)
         foreach (Bundle.chunktype chunk in b.chunk)
             try
             {
                 AddChunk(chunk.id, chunk.SHA1, bundleid, con);
             }
             catch (Exception ex)
             {
                 throw ex;
             }
     transaction.Commit();
 }
예제 #6
0
        private static void ScanTOCsForBundles()
        {
            Debug.LogLn("Saving bundles into db...");
            SQLiteConnection con = GetConnection();
            con.Open();
            SQLiteDataReader reader = getAll("tocfiles", con);
            StringBuilder sb = new StringBuilder();
            List<string> files = new List<string>();
            List<int> fileids = new List<int>();
            while (reader.Read())
            {
                fileids.Add(reader.GetInt32(0));
                files.Add(reader.GetString(1));
            }
            int counter = 0;
            Stopwatch sp = new Stopwatch();
            sp.Start();
            foreach (string file in files)
            {
                counter++;
                Debug.LogLn("Opening " + file + " ...");
                TOCFile tocfile = new TOCFile(file);
                int counter2 = 0;

                foreach (TOCFile.TOCBundleInfoStruct info in tocfile.bundles)
                {
                    counter2++;
                    Bundle b;
                    string pathsb = Helpers.GetFileNameWithOutExtension(file) + ".sb";
                    FileStream fs = new FileStream(pathsb, FileMode.Open, FileAccess.Read);
                    fs.Seek(0, SeekOrigin.End);
                    long filesize = fs.Position;
                    if (info.offset > filesize)
                    {
                        fs.Close();
                        continue;
                    }
                    fs.Seek(info.offset, 0);
                    byte[] buff = new byte[info.size];
                    fs.Read(buff, 0, info.size);
                    if (tocfile.iscas)
                    {
                        if (buff[0] != 0x82)
                            continue;
                        List<BJSON.Entry> list = new List<BJSON.Entry>();
                        BJSON.ReadEntries(new MemoryStream(buff), list);
                        b = Bundle.Create(list[0]);
                    }
                    else
                    {
                        uint magic = BitConverter.ToUInt32(buff, 4);
                        if (magic != 0xd58e799d)
                            continue;
                        b = Bundle.Create(buff, true);
                    }
                    string log = " adding bundle: " + (counter2) + "/" + tocfile.bundles.Count + " ";
                    if (info.isbase) log += "ISBASEG ";
                    if (info.isdelta) log += "ISDELTA ";
                    log += "ID: " + info.id;
                    Debug.Log(log, true);
                    AddBundle(fileids[counter - 1], tocfile.iscas, b, info, con);
                }
                counter2 = 0;
                var transaction = con.BeginTransaction();
                foreach (TOCFile.TOCChunkInfoStruct info in tocfile.chunks)
                {
                    AddGlobalChunk(fileids[counter - 1], info.id, info.sha1, info.offset, info.size, con);
                    Debug.LogLn(" adding chunk: " + (counter2) + "/" + tocfile.chunks.Count + " " + Helpers.ByteArrayToHexString(info.id), counter2 % 1000 == 0);
                    if (counter2 % 1000 == 0)
                    {
                        transaction.Commit();
                        transaction = con.BeginTransaction();
                    }
                    counter2++;
                }
                transaction.Commit();
                long elapsed = sp.ElapsedMilliseconds;
                long ETA = ((elapsed / counter) * files.Count);
                TimeSpan ETAt = TimeSpan.FromMilliseconds(ETA);
                Debug.LogLn((counter) + "/" + files.Count + " files done." + " - Elapsed: " + sp.Elapsed.ToString() + " ETA: " + ETAt.ToString());
            }
            con.Close();
        }
예제 #7
0
 public static void AddEBXLUTFile(EBXInformation ebx, SQLiteConnection con)
 {
     string ftype = "b";
     if (ebx.isDLC)
         ftype = "u";
     if (ebx.isPatch)
         ftype = "p";
     string guid = "";
     byte[] data = new byte[0];
     if (ebx.incas)
         data = SHA1Access.GetDataBySha1(Helpers.HexStringToByteArray(ebx.sha1));
     else
     {
         BinaryBundle b  = null;
         foreach(AddEBXHelpStruct h in aehelp)
             if (h.tocpath == ebx.tocfilepath && h.bpath == ebx.bundlepath)
             {
                 b = h.b;
                 break;
             }
         if (b == null)
         {
             TOCFile toc = new TOCFile(ebx.tocfilepath);
             byte[] bundledata = toc.ExportBundleDataByPath(ebx.bundlepath);
             b = new BinaryBundle(new MemoryStream(bundledata));
             AddEBXHelpStruct h = new AddEBXHelpStruct();
             h.tocpath = ebx.tocfilepath;
             h.bpath = ebx.bundlepath;
             h.b = b;
             if (aehelp.Count > 10)
                 aehelp.RemoveAt(0);
         }
         foreach (BinaryBundle.EbxEntry ebx2 in b.EbxList)
             if (ebx.ebxname == ebx2._name)
                 data = ebx2._data;
     }
     guid = Helpers.ByteArrayToHexString(data, 0x28, 0x10);
     SQLCommand("INSERT INTO ebxlut (path,sha1,basesha1,deltasha1,casptype,guid,bundlepath,offset,size,isbase,isdelta,tocpath,incas,filetype) VALUES ('"
         + ebx.ebxname.Replace("'","''") + "','"
         + ebx.sha1 + "','"
         + ebx.basesha1 + "','"
         + ebx.deltasha1 + "',"
         + ebx.casPatchType + ",'"
         + guid + "','"
         + ebx.bundlepath + "',"
         + ebx.offset + ","
         + ebx.size + ",'"
         + ebx.isbase + "','"
         + ebx.isdelta + "','"
         + ebx.tocfilepath + "','"
         + ebx.incas + "','"
         + ftype + "')", con);
 }
예제 #8
0
 public static void AddTOCFile(string path, string type, SQLiteConnection con)
 {
     string md5 = Helpers.ByteArrayToHexString(Helpers.ComputeHash(path));
     Debug.LogLn(" MD5: " + md5 + " Filename: " + Path.GetFileName(path));
     TOCFile toc = new TOCFile(path);
     bool incas = false;
     foreach (BJSON.Field f1 in toc.lines[0].fields)
         if (f1.fieldname == "cas")
             incas = (bool)f1.data;
     SQLCommand("INSERT INTO tocfiles (path, md5, incas, type) VALUES ('" + path + "', '" + md5 + "','" + incas + "','" + type + "')", con);
 }
예제 #9
0
 public void UpdateTOC(TOCFile toc)
 {
     string path = toc.MyPath;
     path = path.ToLower().Replace(".toc",".sb");
     if (!toc.iscas)
         return;
     SBFile sb = new SBFile(path);
     BJSON.Entry root = sb.lines[0];
     BJSON.Field bundles = root.FindField("bundles");
     BJSON.Entry tocroot = toc.lines[0];
     BJSON.Field tocbundles = tocroot.FindField("bundles");
     foreach (BJSON.Entry bun in (List<BJSON.Entry>)bundles.data)
     {
         BJSON.Field f = bun.FindField("path");
         string bunpath = (string)f.data;
         foreach (BJSON.Entry tocbun in (List<BJSON.Entry>)tocbundles.data)
         {
             BJSON.Field f2 = tocbun.FindField("id");
             string bunpath2 = (string)f2.data;
             if (bunpath == bunpath2)
             {
                 BJSON.Field offset = tocbun.FindField("offset");
                 offset.data = BitConverter.GetBytes(bun.offset);
                 MemoryStream m = new MemoryStream();
                 BJSON.WriteEntry(m, bun);
                 string p = Path.GetDirectoryName(path);
                 File.WriteAllBytes(p + "\\" + Path.GetFileName(bunpath) + ".bin", m.ToArray());
                 BJSON.Field size = tocbun.FindField("size");
                 size.data = BitConverter.GetBytes((uint)m.Length);
             }
         }
     }
     toc.Save();
     DbgPrint("  TOC file offsets updated.");
 }
예제 #10
0
 private void openSingleToolStripMenuItem_Click(object sender, EventArgs e)
 {
     OpenFileDialog d = new OpenFileDialog();
     d.Filter = "*.toc|*.toc";
     if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
     {
         toc = new TOCFile(d.FileName);
         RefreshTree();
         this.Text = "TOC Tool - " + d.FileName;
     }
 }
예제 #11
0
 private void RefreshPreview()
 {
     try
     {
         int n = listBox2.SelectedIndex;
         if (n == -1)
             return;
         statustextures.Text = "Getting header infos from db...";
         Application.DoEvents();
         hb3.ByteProvider = new DynamicByteProvider(new byte[0]);
         hb3.BringToFront();
         if (!Directory.Exists("tmp"))
             Directory.CreateDirectory("tmp");
         if (File.Exists("tmp\\tmp.dds"))
             File.Delete("tmp\\tmp.dds");
         DBAccess.TextureInformation ti = ttprevlist[n];
         DBAccess.BundleInformation buni = DBAccess.GetBundleInformationByIndex(ti.bundleIndex);
         DBAccess.TOCInformation toci = DBAccess.GetTocInformationByIndex(buni.tocIndex);
         byte[] resdata = new byte[0];
         if (toci.incas)
         {
             statustextures.Text = "Getting header data from sha1...";
             Application.DoEvents();
             resdata = SHA1Access.GetDataBySha1(ti.sha1);
         }
         else
         {
             statustextures.Text = "Getting header data from binary bundle...";
             Application.DoEvents();
             TOCFile toc = new TOCFile(toci.path);
             byte[] bundledata = toc.ExportBundleDataByPath(buni.bundlepath);
             BinaryBundle b = new BinaryBundle(new MemoryStream(bundledata));
             foreach (BinaryBundle.ResEntry res in b.ResList)
                 if (res._name == ti.name)
                 {
                     resdata = res._data;
                     break;
                 }
         }
         hb2.ByteProvider = new DynamicByteProvider(resdata);
         statustextures.Text = "Getting texture infos from db...";
         Application.DoEvents();
         TextureMetaResource tmr = new TextureMetaResource(resdata);
         DBAccess.ChunkInformation ci = DBAccess.GetChunkInformationById(tmr.chunkid);
         if (ci.bundleIndex == -1)
             throw new Exception("no chunk info found in db");
         DBAccess.BundleInformation buni2 = DBAccess.GetBundleInformationByIndex(ci.bundleIndex);
         DBAccess.TOCInformation toci2 = DBAccess.GetTocInformationByIndex(buni2.tocIndex);
         byte[] texdata = new byte[0];
         if (toci2.incas)
         {
             statustextures.Text = "Getting texture data from sha1...";
             Application.DoEvents();
             texdata = SHA1Access.GetDataBySha1(ci.sha1);
         }
         else
         {
             statustextures.Text = "Getting texture data from binary bundle...";
             Application.DoEvents();
             TOCFile toc = new TOCFile(toci2.path);
             byte[] bundledata = toc.ExportBundleDataByPath(buni2.bundlepath);
             BinaryBundle b = new BinaryBundle(new MemoryStream(bundledata));
             foreach (BinaryBundle.ChunkEntry chunk in b.ChunkList)
                 if (Helpers.MatchByteArray(chunk.id, ci.id))
                 {
                     texdata = chunk._data;
                     break;
                 }
         }
         if (toolStripButton16.Checked)
         {
             hb3.ByteProvider = new DynamicByteProvider(texdata);
             hb3.BringToFront();
         }
         else
         {
             statustextures.Text = "Making Preview...";
             Application.DoEvents();
             MemoryStream m = new MemoryStream();
             tmr.WriteTextureHeader(m);
             m.Write(texdata, 0, texdata.Length);
             File.WriteAllBytes("tmp\\tmp.dds", m.ToArray());
             try
             {
                 pb1.Image = DevIL.DevIL.LoadBitmap("tmp\\tmp.dds");
                 pb1.BringToFront();
             }
             catch (Exception)
             {
                 statustextures.Text = "Error loading dds, after state '" + statustextures.Text + "'";
                 hb3.ByteProvider = new DynamicByteProvider(texdata);
                 hb3.BringToFront();
             }
         }
         statustextures.Text = "Ready";
     }
     catch (Exception)
     {
         statustextures.Text = "General error, after state '" + statustextures.Text + "'";
     }
 }
예제 #12
0
 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!");
     }
 }
예제 #13
0
 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);
 }
예제 #14
0
 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");
         }
     }
 }
예제 #15
0
 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);
 }
예제 #16
0
 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;
             }
         }
     }
 }
예제 #17
0
 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;
 }
예제 #18
0
 private void opnSingleToolStripMenuItem_Click(object sender, EventArgs e)
 {
     OpenFileDialog d = new OpenFileDialog();
     d.Filter = "*.toc|*.toc";
     if(d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
     {
         toc = new TOCFile(d.FileName);
         SelectForDeletion = new List<bool>();
         SelectForReplacement = new List<string>();
         SelectForDuplication = new List<bool>();
         foreach (TOCFile.TOCBundleInfoStruct b in toc.bundles)
         {
             SelectForDeletion.Add(false);
             SelectForReplacement.Add(null);
             SelectForDuplication.Add(false);
         }
         RefreshMe();
         rtb2.Text = "";
     }
 }
예제 #19
0
 private void CompareTocs(string file1, string file2)
 {
     TOCFile toc1 = new TOCFile(file1);
     TOCFile toc2 = new TOCFile(file2);
     foreach (TOCFile.TOCBundleInfoStruct b in toc1.bundles)
     {
         TOCFile.TOCBundleInfoStruct b2 = new TOCFile.TOCBundleInfoStruct();
         b2.id = "";
         foreach(TOCFile.TOCBundleInfoStruct compare in toc2.bundles)
             if (b.id == compare.id)
             {
                 b2 = compare;
                 break;
             }
         if (b2.id == "")
         {
             P(" E:bundle not found in compare file - " + b.id);
             continue;
         }
         StringBuilder sb = new StringBuilder();
         sb.Append(" D:bundle " + b.id + "\n");
         if (b.isbase != b2.isbase)
             sb.AppendFormat(" -base is different ({0}) vs ({1})\n",b.isbase,b2.isbase);
         if (b.isdelta != b2.isdelta)
             sb.AppendFormat(" -delta is different ({0}) vs ({1})\n",b.isdelta,b2.isdelta);
         if (b.size != b2.size)
             sb.AppendFormat(" -size is different ({0}) vs ({1})\n",b.size, b2.size);
         if ((b.isbase != b2.isbase) || (b.isdelta != b2.isdelta) || (b.size != b2.size))
             P(sb.ToString());
     }
     if (!file1.ToLower().Contains("chunk"))
     foreach (TOCFile.TOCChunkInfoStruct b in toc1.chunks)
     {
         TOCFile.TOCChunkInfoStruct b2 = new TOCFile.TOCChunkInfoStruct();
         b2.id = new byte[0];
         foreach (TOCFile.TOCChunkInfoStruct compare in toc2.chunks)
             if (Helpers.ByteArrayCompare(b.id, compare.id))
             {
                 b2 = compare;
                 break;
             }
         if (b2.id.Length == 0)
         {
             P(" E:chunk not found in compare file - " + Helpers.ByteArrayToHexString(b.id));
             continue;
         }
         StringBuilder sb = new StringBuilder();
         sb.Append(" D:chunk " + Helpers.ByteArrayToHexString(b.id) + "\n");
         if (b.sha1 != null && Helpers.ByteArrayCompare(b.sha1,b2.sha1))
             sb.AppendFormat(" -sha1 is different ({0}) vs ({1})\n", Helpers.ByteArrayToHexString(b.sha1), Helpers.ByteArrayToHexString(b2.sha1));
         if (b.offset != b2.offset)
             sb.AppendFormat(" -offset is different ({0}) vs ({1})\n", b.offset, b2.offset);
         if (b.size != b2.size)
             sb.AppendFormat(" -size is different ({0}) vs ({1})\n", b.size, b2.size);
         if ((b.sha1 != null && Helpers.ByteArrayCompare(b.sha1, b2.sha1)) || (b.offset != b2.offset) || (b.size != b2.size))
             P(sb.ToString());
     }
     CompareSB(file1.ToLower().Replace(".toc", ".sb"), file2.ToLower().Replace(".toc", ".sb"));
 }
예제 #20
0
 private void treeView3_AfterSelect(object sender, TreeViewEventArgs e)
 {
     TreeNode t = treeView3.SelectedNode;
     if (t == null || t.Nodes == null || t.Nodes.Count != 0)
         return;
     string path = Helpers.GetPathFromNode(t, "/");
     for (int i = 0; i < tblist.Count; i++)
         if (path.Contains(tblist[i].bundlepath))
         {
             DBAccess.BundleInformation bi = tblist[i];
             if (bi.isbase)
                 return;
             TOCFile toc = new TOCFile(bi.filepath);
             byte[] data = toc.ExportBundleDataByPath(bi.bundlepath);
             Bundle b = null;
             if (bi.incas)
             {
                 List<BJSON.Entry> tmp = new List<BJSON.Entry>();
                 BJSON.ReadEntries(new MemoryStream(data), tmp);
                 b = Bundle.Create(tmp[0]);
             }
             else
                 b = Bundle.Create(data, true);
             if (b == null)
                 return;
             if (b.ebx == null)
                 b.ebx = new List<Bundle.ebxtype>();
             if (b.res == null)
                 b.res = new List<Bundle.restype>();
             if (b.chunk == null)
                 b.chunk = new List<Bundle.chunktype>();
             int total = b.ebx.Count + b.res.Count + b.chunk.Count;
             StringBuilder sb = new StringBuilder();
             sb.AppendFormat("Total count : {0}\n", total);
             sb.AppendFormat("EBX count   : {0}\n", b.ebx.Count);
             sb.AppendFormat("RES count   : {0}\n", b.res.Count);
             sb.AppendFormat("CHUNK count : {0}\n", b.chunk.Count);
             rtb1.Text = sb.ToString();
             DBAccess.BundleInformation[] dupBun = DBAccess.GetBundleInformationById(bi.bundlepath);
             listBox3.Items.Clear();
             int count = 0;
             int l = GlobalStuff.FindSetting("gamepath").Length;
             foreach (DBAccess.BundleInformation dup in dupBun)
             {
                 DBAccess.TOCInformation ti = DBAccess.GetTocInformationByIndex(dup.tocIndex);
                 listBox3.Items.Add((count++) + " : " + ti.path.Substring(l, ti.path.Length - l) + " -> Delta:" + dup.isdelta + " Base:" + dup.isbase);
             }
         }
 }
예제 #21
0
 public bool ImportBundleBinaryFromBase(TOCFile toc, string tocpath, string bpath, bool isbase = true)
 {
     if(isbase)
         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 ttocpath = tocpath;
     if (tocpath.ToLower().Contains("update"))
         ttocpath = Helpers.SkipSubFolder(tocpath, 2);
     string oldSBpath = outputPath + Path.GetDirectoryName(ttocpath) + "\\" + Path.GetFileNameWithoutExtension(ttocpath) + ".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_id = b.FindField("id");
         BJSON.Field f_offset = b.FindField("offset");
         BJSON.Field f_size = b.FindField("size");
         BJSON.Field f_isBase = b.FindField("base");
         BJSON.Field f_isDelta = b.FindField("delta");
         //if not our target and not copied from base, copy from old SB
         if (((string)f_id.data).ToLower() != bpath && 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 (((string)f_id.data).ToLower() == bpath)
         {
             f_offset.data = BitConverter.GetBytes(glob_off);
             f_size.data = BitConverter.GetBytes(buff.Length);
             if (f_isBase != null)
                 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);
     oldSB.Write(newSB.ToArray(), 0, (int)newSB.Length);
     oldSB.Close();
     DbgPrint("  Recompiling TOC...");
     toc.Save();
     DbgPrint("  Bundle imported");
     return true;
 }
예제 #22
0
 private void RefreshPreview()
 {
     try
     {
         int n = listBox2.SelectedIndex;
         if (n == -1)
             return;
         status.Text = "Getting header infos from db...";
         Application.DoEvents();
         DBAccess.RESInformation ti = ttprevlist[n];
         DBAccess.BundleInformation buni = DBAccess.GetBundleInformationById(ti.bundlepath)[0];
         DBAccess.TOCInformation toci = DBAccess.GetTocInformationByIndex(buni.tocIndex);
         BinaryBundle b = new BinaryBundle();
         byte[] resdata = new byte[0];
         if (toci.incas)
         {
             status.Text = "Getting header data from sha1...";
             Application.DoEvents();
             resdata = SHA1Access.GetDataBySha1(Helpers.HexStringToByteArray(ti.sha1));
         }
         else
         {
             status.Text = "Getting header data from binary bundle...";
             Application.DoEvents();
             TOCFile toc = new TOCFile(toci.path);
             byte[] bundledata = toc.ExportBundleDataByPath(buni.bundlepath);
             b = new BinaryBundle(new MemoryStream(bundledata));
             foreach (BinaryBundle.ResEntry res in b.ResList)
                 if (res._name == ti.resname)
                 {
                     resdata = res._data;
                     break;
                 }
         }
         hb2.ByteProvider = new DynamicByteProvider(resdata);
         Mesh mesh = new Mesh(new MemoryStream(resdata));
         foreach (Mesh.MeshLOD lod in mesh.header.LODs)
         {
             byte[] id = lod.ChunkID;
             byte[] data = new byte[0];
             if (toci.incas)
             {
                 DBAccess.ChunkInformation ci = DBAccess.GetChunkInformationById(id);
                 if (ci.sha1 == null)
                     continue;
                 data = SHA1Access.GetDataBySha1(ci.sha1);
             }
             else
             {
                 byte t = id[0];
                 id[0] = id[3];
                 id[3] = t;
                 t = id[1];
                 id[1] = id[2];
                 id[2] = t;
                 t = id[6];
                 id[6] = id[7];
                 id[7] = t;
                 t = id[4];
                 id[4] = id[5];
                 id[5] = t;
                 foreach (BinaryBundle.ChunkEntry c in b.ChunkList)
                     if (Helpers.ByteArrayCompare(id, c.id))
                         data = c._data;
                 if (data.Length == 0)
                 {
                     DBAccess.ChunkInformation ci = DBAccess.GetChunkInformationById(id);
                     if (ci.sha1 == null)
                         continue;
                     data = SHA1Access.GetDataBySha1(ci.sha1);
                 }
             }
             mesh.LoadChunkData(lod, new MemoryStream(data));
         }
         MeshRenderObject mro = new MeshRenderObject(mesh);
         renderer.list.Clear();
         renderer.list.Add(mro);
         renderer.worldoffset = -mro.center;
         renderer.CamDistance = mro.min.Length() + mro.max.Length();
         status.Text = "Ready";
     }
     catch (Exception ex)
     {
         status.Text = "General error, after state '" + status.Text + "' : " + ex.Message;
     }
 }
예제 #23
0
 private void toolStripMenuItem3_Click(object sender, EventArgs e)
 {
     OpenFileDialog d = new OpenFileDialog();
     d.Filter = "*.bundle|*.bundle";
     if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
     {
         toc = null;
         toolStrip1.Visible = true;
         splitContainer2.BringToFront();
         MemoryStream m = new MemoryStream(File.ReadAllBytes(d.FileName));
         binBundle = new BinaryBundle(m);
         tabControl1.BringToFront();
         RefreshBinary();
         RefreshBinaryBundle();
         return;
     }
 }