Example #1
0
        public static List <PackFileInfo> DetectDuplicates(List <PackFileInfo> files)
        {
            List <PackFileInfo> newlist = new List <PackFileInfo>(files.Count);

            for (int i = 0; i < files.Count; ++i)
            {
                var npfi = new PackFileInfo(files[i]);
                npfi.DuplicateOf = null;
                for (int j = 0; j < i; ++j)
                {
                    if (files[i].DataStream != null && files[j].DataStream != null)
                    {
                        using (var istr = files[i].DataStream.Duplicate())
                            using (var jstr = files[j].DataStream.Duplicate()) {
                                if (StreamUtils.IsIdentical(istr, jstr))
                                {
                                    npfi.DuplicateOf = (ulong)j;
                                    break;
                                }
                            }
                    }
                }
                newlist.Add(npfi);
            }
            return(newlist);
        }
Example #2
0
		public PackFileInfo(PackFileInfo other) {
			Name = other.Name;
			Length = other.Length;
			RelativePath = other.RelativePath;
			DataStream = other.DataStream != null ? other.DataStream.Duplicate() : null;
			DuplicateOf = other.DuplicateOf;
		}
Example #3
0
        //添加Token
        public PackFileInfo AddToken(List <string> keyWords, string fileID)
        {
            List <byte[]> random = new List <byte[]>();

            byte[]        temp     = null;
            List <string> C        = new List <string>();
            List <string> searched = new List <string>();

            foreach (var item in keyWords)
            {
                //temp = tool.WordToHash(item);
                random.Add(temp);
                string s1 = tool.HmacHash(temp, k1);
                if (history.Contains(s1))
                {
                    searched.Add(s1);
                }
                C.Add(tool.HmacAdd(s1));
            }
            //sort比较器实现
            C.Sort();
            PackFileInfo info = new PackFileInfo();

            info.FileID      = fileID;
            info.historyList = searched;
            info.tokenList   = C;

            return(info);
        }
Example #4
0
 public int AddFile(PackFileInfo info, string filePath)
 {
     rf.Add(info.FileID, info.tokenList);
     foreach (var item in info.historyList)
     {
         rw[item].Add(info.FileID);
     }
     tool.FileAdd(filePath);
     return(1);
 }
Example #5
0
        public static int Pack(List <string> args)
        {
            if (args.Count < 2)
            {
                PrintPackUsage();
                return(-1);
            }

            string dir           = null;
            string outName       = null;
            string outHeaderName = null;

            ushort?bitmask            = null;
            uint?  alignment          = null;
            uint?  alignmentFirstFile = null;
            bool   orderByExtension   = false;
            bool   includeSubdirs     = false;
            bool   littleEndian       = false;
            string originalFps4       = null;
            string metadata           = null;
            string comment            = null;
            uint   multiplier         = 1;

            try {
                for (int i = 0; i < args.Count; ++i)
                {
                    switch (args[i])
                    {
                    case "-a":
                        alignment = HexUtils.ParseDecOrHex(args[++i]);
                        break;

                    case "--firstalign":
                        alignmentFirstFile = HexUtils.ParseDecOrHex(args[++i]);
                        break;

                    case "-b":
                        bitmask = (ushort)HexUtils.ParseDecOrHex(args[++i]);
                        break;

                    case "-l":
                        littleEndian = true;
                        break;

                    case "-m":
                        metadata = args[++i];
                        break;

                    case "-c":
                        comment = UnEscape(args[++i]);
                        break;

                    case "-e":
                        orderByExtension = true;
                        break;

                    case "-s":
                        includeSubdirs = true;
                        break;

                    case "-h":
                        outHeaderName = args[++i];
                        break;

                    case "-o":
                        originalFps4 = args[++i];
                        break;

                    case "--multiplier":
                        multiplier = HexUtils.ParseDecOrHex(args[++i]);
                        break;

                    default:
                        if (dir == null)
                        {
                            dir = args[i];
                        }
                        else if (outName == null)
                        {
                            outName = args[i];
                        }
                        else
                        {
                            PrintPackUsage(); return(-1);
                        }
                        break;
                    }
                }
            } catch (IndexOutOfRangeException) {
                PrintPackUsage();
                return(-1);
            }

            if (dir == null || outName == null)
            {
                PrintPackUsage();
                return(-1);
            }

            FPS4 fps4;

            if (originalFps4 != null)
            {
                fps4 = new FPS4(originalFps4, printProgressToConsole: true);
            }
            else
            {
                fps4 = new FPS4();
            }

            if (bitmask != null)
            {
                fps4.ContentBitmask = new ContentInfo((ushort)bitmask);
            }
            if (alignment != null)
            {
                fps4.Alignment = (uint)alignment;
            }
            if (littleEndian)
            {
                fps4.Endian = EndianUtils.Endianness.LittleEndian;
            }
            if (comment != null)
            {
                fps4.ArchiveName = comment;
            }

            string[] files;
            if (includeSubdirs)
            {
                files = System.IO.Directory.GetFiles(dir, "*", System.IO.SearchOption.AllDirectories);
            }
            else
            {
                files = System.IO.Directory.GetFiles(dir);
            }

            if (orderByExtension)
            {
                files = files.OrderBy(x => x.Split('.').Last()).ToArray();
            }

            Stream outStream       = new FileStream(outName, FileMode.Create);
            Stream outHeaderStream = outHeaderName == null ? null : new FileStream(outHeaderName, FileMode.Create);

            List <PackFileInfo> packFileInfos = new List <PackFileInfo>(files.Length);

            foreach (var file in files)
            {
                var fi = new System.IO.FileInfo(file);
                var p  = new PackFileInfo();
                p.Name   = fi.Name;
                p.Length = fi.Length;
                if (metadata.Contains('p'))
                {
                    try {
                        p.RelativePath = FPS4.GetRelativePath(outHeaderName == null ? outName : outHeaderName, fi.FullName);
                    } catch (Exception) { }
                }
                p.DataStream = new DuplicatableFileStream(file);
                packFileInfos.Add(p);
            }


            try {
                FPS4.Pack(
                    packFileInfos,
                    outStream,
                    fps4.ContentBitmask,
                    fps4.Endian,
                    fps4.Unknown2,
                    originalFps4 != null ? new System.IO.FileStream(originalFps4, System.IO.FileMode.Open) : null,
                    fps4.ArchiveName,
                    fps4.FirstFileStart,
                    fps4.Alignment,
                    outputHeaderStream: outHeaderStream,
                    metadata: metadata,
                    alignmentFirstFile: alignmentFirstFile,
                    fileLocationMultiplier: multiplier,
                    printProgressToConsole: true
                    );
            } finally {
                outStream.Close();
                if (outHeaderStream != null)
                {
                    outHeaderStream.Close();
                }
            }

            return(0);
        }
Example #6
0
        private static void GenerateUndubRoot(string datadir, string voicedir, string outdir, UndubVersion undubVersion)
        {
            Console.WriteLine(string.Format("processing {0}", "rootR.cpk"));
            var    datastream  = new DuplicatableFileStream(Path.Combine(datadir, "rootR.cpk"));
            var    voicestream = new DuplicatableFileStream(Path.Combine(voicedir, "rootR.cpk"));
            var    datacpk     = new HyoutaTools.Tales.CPK.CpkContainer(datastream.Duplicate());
            var    voicecpk    = new HyoutaTools.Tales.CPK.CpkContainer(voicestream);
            string outfile     = Path.Combine(outdir, "rootR.cpk");
            var    builder     = new HyoutaTools.Tales.CPK.CpkBuilder(datastream.Duplicate());

            // audio containers: we can direct-copy these, no need to un/repack
            foreach (string name in new string[] { "RTS.nub", "VOBTL.nub", "VOBTLETC.nub", "VOCHT.nub", "VOSCE01.nub", "VOSCE02.nub", "VOSCE03.nub", "VOSCE04.nub", "VOSCE05.nub", "VOSCE06.nub", "VOSCE07.nub", "VOSCE08.nub", "VOSCE09.nub", "VOSCE15.nub", "VOSCE16.nub" })
            {
                string subdir  = "snd/strpck";
                string subpath = subdir + "/" + name;
                Console.WriteLine(string.Format("injecting {0}", subpath));
                var subfile = builder.Files.Where(x => x.Directory == subdir && x.Name == name).First();
                ReplaceFile(subfile, voicecpk.GetChildByName(subpath).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose());
            }

            // skits: for all of these unpack them (FPS4 containers), copy over file with index 1, repack
            // some of them are mistimed now because of altered timing for english skits, this could be refined...
            for (long i = 0; i < datacpk.toc_entries; ++i)
            {
                var entry = datacpk.GetEntryByIndex(i);
                if (entry != null && entry.dir_name == "chat/chd" && entry.file_name.EndsWith(".chd") && entry.file_name != "debug_02.chd")
                {
                    // for EU undub also exclude CHT_PR*.chd because those files are not on the EU disc (they look unused on US too...)
                    if (!(undubVersion == UndubVersion.JpVoicesToEu && entry.file_name.StartsWith("CHT_PR")))
                    {
                        string subpath = entry.dir_name + "/" + entry.file_name;
                        Console.WriteLine(string.Format("injecting {0}", subpath));
                        var skitstreamen = datacpk.GetChildByIndex(i).AsFile.DataStream;
                        var skitstreamjp = voicecpk.GetChildByName(subpath).AsFile.DataStream;
                        var fps4en       = new FPS4(skitstreamen);
                        var fps4jp       = new FPS4(skitstreamjp);

                        List <PackFileInfo> packFileInfos = new List <PackFileInfo>(fps4en.Files.Count - 1);
                        for (int j = 0; j < fps4en.Files.Count - 1; ++j)
                        {
                            var pf = new PackFileInfo();
                            pf.Name = fps4en.Files[j].FileName;
                            if (j == 1)
                            {
                                pf.DataStream = fps4jp.GetChildByIndex(j).AsFile.DataStream.Duplicate();
                            }
                            else
                            {
                                pf.DataStream = fps4en.GetChildByIndex(j).AsFile.DataStream.Duplicate();
                            }
                            pf.Length = pf.DataStream.Length;
                            packFileInfos.Add(pf);
                        }
                        packFileInfos = FPS4.DetectDuplicates(packFileInfos);
                        MemoryStream newfps4stream = new MemoryStream();
                        FPS4.Pack(packFileInfos, newfps4stream, fps4en.ContentBitmask, EndianUtils.Endianness.BigEndian, fps4en.Unknown2, null, fps4en.ArchiveName, fps4en.FirstFileStart, 0x20);
                        newfps4stream.Position = 0;

                        var subfile = builder.Files.Where(x => x.Directory == entry.dir_name && x.Name == entry.file_name).First();
                        ReplaceFile(subfile, newfps4stream.CopyToByteArrayStreamAndDispose(), true);
                    }
                }
            }

            // post-battle skits/quotes
            for (long i = 0; i < datacpk.toc_entries; ++i)
            {
                var entry = datacpk.GetEntryByIndex(i);
                if (entry != null && entry.dir_name == "btl/acf" && (
                        (entry.file_name.StartsWith("skt") && entry.file_name.EndsWith(".acf") && entry.file_name != "skt000.acf") ||
                        (entry.file_name.StartsWith("vav") && entry.file_name.EndsWith(".acf") && entry.file_name != "vav000.acf")
                        ))
                {
                    string subpath = entry.dir_name + "/" + entry.file_name;
                    Console.WriteLine(string.Format("injecting {0}", subpath));
                    var subfile = builder.Files.Where(x => x.Directory == entry.dir_name && x.Name == entry.file_name).First();
                    ReplaceFile(subfile, voicecpk.GetChildByName(subpath).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose());
                }
            }

            CreateDirectory(outdir);
            WriteCpk(outfile, builder);
        }