示例#1
0
        public void PatchPartition(string folder, string partition)
        {
            if (!InitializePartition(partition))
            {
                return;
            }

            var resource = LS.TryGetValue(partition);

            if (resource == null)
            {
                return;
            }

            Console.WriteLine($"------{partition}------");
            foreach (string key in Files.Keys)
            {
                string filepath = $"{folder}/{key}";
                if (File.Exists(filepath))
                {
                    Console.WriteLine($"Patch: {key}");
                    var tpl   = Files[key];
                    var rsobj = tpl.Item2;

                    int    index = RF.ResourceEntries.IndexOf(rsobj);
                    byte[] data  = File.ReadAllBytes(filepath);
                    byte[] cmp   = Util.Compress(data);
                    using (FileStream stream = File.Open(DTFiles[tpl.Item1.DTIndex], FileMode.Open))
                    {
                        // Overwrite existing data
                        stream.Seek(tpl.Item1.DTOffset + rsobj.OffInPack, SeekOrigin.Begin);
                        for (int i = 0; i < rsobj.CmpSize; i++)
                        {
                            stream.WriteByte(0xCC);
                        }

                        // Get how much space we have to work with
                        stream.Seek(tpl.Item1.DTOffset + rsobj.OffInPack, SeekOrigin.Begin);
                        int len = 0;
                        while (stream.ReadByte() == 0xCC)
                        {
                            len++;
                        }

                        // If the new file is within range, write the new data
                        stream.Seek(tpl.Item1.DTOffset + rsobj.OffInPack, SeekOrigin.Begin);
                        if (cmp.Length <= len)
                        {
                            stream.Write(cmp, 0, cmp.Length);
                        }
                    }

                    rsobj.DecSize = data.Length;
                    rsobj.CmpSize = cmp.Length;
                    RF[index]     = rsobj;
                }
            }
            RF.UpdateEntries();
            RF.WorkingSource.Close();
            byte[] resbytes = RF.GetBytes();
            using (var stream = File.Open(DTFiles[resource.DTIndex], FileMode.Open))
            {
                stream.Seek(resource.DTOffset, SeekOrigin.Begin);
                stream.Write(resbytes, 0, resbytes.Length);
            }
            resource.Size = resbytes.Length;
            LS.TrySetValue(partition, resource);
            LS.UpdateEntries();
        }
示例#2
0
        public void BuildPartitions(string folder)
        {
            if (DTFiles == null)
            {
                return;
            }

            FileStream dtstrm   = File.Create("dt_rebuild");
            string     tmpfile  = Path.GetTempFileName();
            FileStream packstrm = File.Create(tmpfile);

            foreach (string str in Directory.EnumerateDirectories(folder))
            {
                if (!str.Contains("data"))
                {
                    return;
                }

                string partition = "resource";
                if (str.Contains("("))
                {
                    partition += str.Substring(str.IndexOf("("));
                }

                var rf = new RFFile();

                LSEntry curPacked = null;
                int     pad       = 0;
                string  packKey   = "";
                foreach (string key in Files.Keys)
                {
                    Console.WriteLine(key);
                    var tpl = Files[key];
                    if (tpl.Item2.Packed)
                    {
                        if (curPacked != null)
                        {
                            int aligned = (int)packstrm.Position.RoundUp(0x10) + 0x60;
                            while (packstrm.Position < aligned)
                            {
                                packstrm.WriteByte(0xBB);
                            }
                            curPacked.Size = (int)packstrm.Length;
                            LS.TrySetValue(packKey, curPacked);

                            packstrm.WriteTo(dtstrm);
                            packstrm.Close();
                            packstrm = File.Open(tmpfile, FileMode.Truncate);
                        }
                        curPacked          = tpl.Item1;
                        packKey            = key;
                        curPacked.DTOffset = (uint)dtstrm.Position;
                        var data = File.ReadAllBytes($"{folder}/{key}");
                        for (pad = 0; pad < data.Length && data[pad] == 0xCC; pad++)
                        {
                            packstrm.WriteByte(0xCC);
                        }
                    }
                    else if (!tpl.Item2.EntryString.EndsWith("/"))
                    {
                        var           filedata = File.ReadAllBytes($"{folder}/{key}");
                        var           cmp      = Util.Compress(filedata);
                        ResourceEntry rsobj    = tpl.Item2;
                        int           rIndex   = RF.ResourceEntries.IndexOf(rsobj);

                        rsobj.OffInPack = (uint)packstrm.Position;
                        rsobj.CmpSize   = cmp.Length;
                        rsobj.DecSize   = filedata.Length;
                        RF[rIndex]      = rsobj;
                        packstrm.Write(cmp, 0, cmp.Length);

                        int aligned = (int)packstrm.Position.RoundUp(0x10) + 0x20;
                        while (packstrm.Position % 0x10 > 0)
                        {
                            packstrm.WriteByte(0xCC);
                        }
                    }
                }
                if (curPacked != null)
                {
                    curPacked.Size = (int)packstrm.Length;
                    LS.TrySetValue(packKey, curPacked);
                    packstrm.WriteTo(dtstrm);
                }
                RF.UpdateEntries();


                byte[] full     = RF.GetBytes();
                var    resource = LS.TryGetValue(partition);
                resource.DTOffset = (uint)dtstrm.Position;
                dtstrm.Write(full, 0, full.Length);
                resource.Size = full.Length;
                LS.TrySetValue(partition, resource);
                LS.UpdateEntries();
                dtstrm.Close();
                packstrm.Close();
            }
        }