예제 #1
0
        public static int Execute(List <string> argumentsGiven)
        {
            if (!argumentsGiven.Contains("start"))
            {
                Console.WriteLine("Include \"start\" in the arguments to confirm execution!");
                Console.WriteLine("Other arguments to enable specific file types:");
                Console.WriteLine("  comptoe     Tales Compressor files");
                Console.WriteLine("  TXMdetect   Try and autodetect Tales texture TXM/TXV pairs even if their file extensions are different");
                Console.WriteLine("  DRpak       Dangan Ronpa PAK files");
                Console.WriteLine("Usage of these parameters could break unrelated files, be careful.");
                return(-1);
            }


            Queue <FileStruct> queue = new Queue <FileStruct>();

            Console.WriteLine("Adding all files and folders recursively...");
            EnqueueDirectoryRecursively(queue, System.Environment.CurrentDirectory);

            bool AllowComptoe = argumentsGiven.Contains("comptoe");
            bool DetectTxmTxv = argumentsGiven.Contains("TXMdetect");
            bool AllowDrPak   = argumentsGiven.Contains("DRpak");

            while (queue.Count > 0)
            {
                FileStruct fstr = queue.Dequeue();
                Console.WriteLine(fstr.Filename);
                string f = System.IO.Path.GetFullPath(fstr.Filename);
                string prog, args;

                if (!System.IO.File.Exists(f))
                {
                    continue;
                }

                try {
                    bool isMaybeVesperiaStyleTexture;
                    isMaybeVesperiaStyleTexture = f.EndsWith(".TXV");
                    if (isMaybeVesperiaStyleTexture)
                    {
                        string txm = f.Substring(0, f.Length - 1) + "M";
                        string txv = f;
                        Tales.Vesperia.Texture.Decode.Extract(txm, txv, f + ".ext");
                    }

                    using (FileStream fs = new FileStream(f, FileMode.Open)) {
                        long filesize   = fs.Length;
                        int  firstbyte  = fs.ReadByte();
                        int  secondbyte = fs.ReadByte();
                        int  thirdbyte  = fs.ReadByte();
                        int  fourthbyte = fs.ReadByte();
                        int  fifthbyte  = fs.ReadByte();

                        bool HasBeenProcessed = false;

                        // maybe a comptoe file
                        if (AllowComptoe)
                        {
                            if (firstbyte == 0x01 || firstbyte == 0x03)
                            {
                                uint maybefilesizeBigEndian = ((uint)secondbyte) << 24 | ((uint)thirdbyte) << 16 | ((uint)fourthbyte) << 8 | (uint)fifthbyte;
                                uint maybefilesizeLitEndian = ((uint)fifthbyte) << 24 | ((uint)fourthbyte) << 16 | ((uint)thirdbyte) << 8 | (uint)secondbyte;
                                if ((maybefilesizeBigEndian == filesize) ||
                                    (maybefilesizeLitEndian + 9 == filesize))
                                {
                                    int  b6 = fs.ReadByte();
                                    int  b7 = fs.ReadByte();
                                    int  b8 = fs.ReadByte();
                                    int  b9 = fs.ReadByte();
                                    uint uncompressedfilesizeBigEndian = ((uint)b6) << 24 | ((uint)b7) << 16 | ((uint)b8) << 8 | (uint)b9;
                                    uint uncompressedfilesizeLitEndian = ((uint)b6) | ((uint)b7) << 8 | ((uint)b8) << 16 | ((uint)b9) << 24;
                                    fs.Close();
                                    prog = "comptoe";
                                    args = "-d \"" + f + "\" \"" + f + ".d\"";
                                    Console.WriteLine();
                                    Console.WriteLine(prog + " " + args);
                                    try {
                                        if (ExternalProgramExecution.RunProgramSynchronous(prog, new string[] { "-d", f, f + ".d" }).StdOut.EndsWith("Success"))
                                        {
                                            queue.Enqueue(new FileStruct(f + ".d", fstr.Indirection));
                                            FileInfo decInfo = new FileInfo(f + ".d");
                                            if ((decInfo.Length == uncompressedfilesizeBigEndian) || (decInfo.Length == uncompressedfilesizeLitEndian))
                                            {
                                                System.IO.File.Delete(f);
                                                HasBeenProcessed = true;
                                            }
                                            else
                                            {
                                                Console.WriteLine("Uncompressed comptoe Filesize does not match!");
                                            }
                                        }
                                        else
                                        {
                                            Console.WriteLine("comptoe decompression failure");
                                        }
                                    } catch (Exception ex) {
                                        Console.WriteLine("comptoe failure: " + ex.ToString());
                                    }
                                }
                                else
                                {
                                    Console.WriteLine();
                                    Console.WriteLine(f);
                                    Console.WriteLine("Suspected comptoe, but compressed Filesize does not match!");

                                    Console.WriteLine();
                                    Console.WriteLine("Tales.Abyss.PKF.Split.SplitPkf " + f);
                                    fs.Close();
                                    if (Tales.Abyss.PKF.Split.SplitPkf(System.IO.File.ReadAllBytes(f), f + ".ex"))
                                    {
                                        EnqueueDirectoryRecursively(queue, f + ".ex");
                                        System.IO.File.Delete(f);
                                        HasBeenProcessed = true;
                                    }
                                }
                            }
                        }

                        if (firstbyte == (int)'T')
                        {
                            if (secondbyte == (int)'L' && thirdbyte == (int)'Z' && fourthbyte == (int)'C')
                            {
                                fs.Close();
                                List <string> tlzcargs = new List <string>();
                                tlzcargs.Add("-d");
                                tlzcargs.Add(f);
                                tlzcargs.Add(f + ".dec");
                                Console.WriteLine();
                                Console.WriteLine("tlzc -d \"" + f + "\" \"" + f + ".dec\"");
                                if (HyoutaTools.Tales.tlzc.tlzcmain.Execute(tlzcargs) == 0)
                                {
                                    queue.Enqueue(new FileStruct(f + ".dec", fstr.Indirection));
                                    System.IO.File.Delete(f);
                                    HasBeenProcessed = true;
                                }
                            }
                        }

                        if (firstbyte == (int)'F')
                        {
                            if (secondbyte == (int)'P' && thirdbyte == (int)'S' && fourthbyte == (int)'4')
                            {
                                fs.Close();
                                prog = "tovfps4e";
                                args = "\"" + f + "\"";
                                Console.WriteLine();
                                Console.WriteLine(prog + " " + args);

                                var fps4 = new Tales.Vesperia.FPS4.FPS4(f);
                                fps4.Extract(f + ".ext");
                                fps4.Close();

                                EnqueueDirectoryRecursively(queue, f + ".ext");
                                System.IO.File.Delete(f);
                                HasBeenProcessed = true;
                            }

                            if (secondbyte == (int)'P' && thirdbyte == (int)'S' && fourthbyte == (int)'2')
                            {
                                fs.Close();
                                Console.WriteLine();
                                Console.WriteLine("Tales.Abyss.FPS2.Extract " + f);
                                List <string> argList = new List <string>(1);
                                argList.Add(f);
                                if (0 == Tales.Abyss.FPS2.Program.Execute(argList))
                                {
                                    EnqueueDirectoryRecursively(queue, f + ".ext");
                                    System.IO.File.Delete(f);
                                    HasBeenProcessed = true;
                                }
                            }
                            if (secondbyte == (int)'P' && thirdbyte == (int)'S' && fourthbyte == (int)'3')
                            {
                                fs.Close();
                                Console.WriteLine();
                                Console.WriteLine("Tales.Abyss.FPS3.Extract " + f);
                                List <string> argList = new List <string>(1);
                                argList.Add(f);
                                if (0 == Tales.Abyss.FPS3.Program.Execute(argList))
                                {
                                    EnqueueDirectoryRecursively(queue, f + ".ext");
                                    System.IO.File.Delete(f);
                                    HasBeenProcessed = true;
                                }
                            }
                        }

                        string fname = System.IO.Path.GetFileName(f);
                        if (DetectTxmTxv &&
                            (firstbyte == 0x00 && secondbyte == 0x02 && thirdbyte == 0x00 && fourthbyte == 0x00 &&
                             !isMaybeVesperiaStyleTexture &&
                             !(fname.EndsWith(".TXM") || fname.EndsWith(".TXV")))
                            )
                        {
                            FileStruct nextfile = queue.Peek();
                            fs.Close();

                            string txm = f + ".TXM";
                            string txv = f + ".TXV";

                            Console.WriteLine("ren " + f + " " + txm);
                            Console.WriteLine("ren " + nextfile.Filename + " " + txv);
                            System.IO.File.Move(f, txm);
                            System.IO.File.Move(nextfile.Filename, txv);

                            queue.Enqueue(new FileStruct(txv, fstr.Indirection));

                            HasBeenProcessed = true;
                        }


                        if (firstbyte == 0x4D)
                        {
                            if (secondbyte == 0x49 && thirdbyte == 0x47 && fourthbyte == 0x2E)
                            {
                                fs.Close();
                                Console.WriteLine();
                                Console.WriteLine("GimToPng " + f);
                                List <string> converted = PSP.GIM.GimToPng.GimToPng.ConvertGimFileToPngFiles(f);

                                if (converted != null && converted.Count > 0)
                                {
                                    System.IO.File.Delete(f);
                                    HasBeenProcessed = true;
                                }
                            }
                        }
                        if (firstbyte == 'O' && secondbyte == 'M' && thirdbyte == 'G' && fourthbyte == 0x2E)
                        {
                            fs.Close();
                            f = RenameToWithExtension(f, ".gmo");
                            HasBeenProcessed = true;
                        }

                        if (firstbyte == 'L' && secondbyte == 'L' && thirdbyte == 'F' && fourthbyte == 'S')
                        {
                            fs.Close();
                            f = RenameToWithExtension(f, ".llfs");
                            HasBeenProcessed = true;
                        }

                        if (AllowDrPak)
                        {
                            if (f.ToLowerInvariant().EndsWith(".pak") || (secondbyte < 0x10 && thirdbyte == 0x00 && fourthbyte == 0x00))
                            {
                                // could maybe possibly be a PAK file who knows
                                bool drpaksuccess = false;
                                try {
                                    fs.Position = 0;
                                    DanganRonpa.Pak.Program.Extract(fs, f + ".ex");
                                    fs.Close();
                                    drpaksuccess = true;
                                } catch (Exception ex) {
                                    Console.WriteLine("Extracting " + f + " as DanganRonpa PAK file failed: " + ex.ToString());
                                }

                                if (drpaksuccess)
                                {
                                    EnqueueDirectoryRecursively(queue, f + ".ex");
                                    System.IO.File.Delete(f);
                                    HasBeenProcessed = true;
                                }
                            }
                        }

                        if (firstbyte == 0x1F && secondbyte == 0x8B && thirdbyte == 0x08)
                        {
                            // gzip compressed file
                            GZip.GZipHandler.Extract(fs, f + ".dec");
                            queue.Enqueue(new FileStruct(f + ".dec", fstr.Indirection));
                            fs.Close();
                            System.IO.File.Delete(f);
                            HasBeenProcessed = true;
                        }

                        if (!HasBeenProcessed)
                        {
                            Console.WriteLine("Nothing found to process " + f + ", leaving alone.");
                        }
                    }
                } catch (FileNotFoundException) { } catch (Exception ex) {
                    Console.WriteLine(ex.ToString());
                }
            }
            return(0);
        }
예제 #2
0
        public override async Task <ResultType> Run(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ResultType.Cancelled);
            }

            JobStatus = VideoJobStatus.Running;
            if ((VideoInfo as YoutubeVideoInfo) == null)
            {
                Status = "Retrieving video info...";
                bool wantCookies = Notes != null && Notes.Contains("cookies");
                var  result      = await Youtube.RetrieveVideo(VideoInfo.VideoId, VideoInfo.Username, wantCookies);

                switch (result.result)
                {
                case Youtube.RetrieveVideoResult.Success:
                    VideoInfo = result.info;
                    break;

                case Youtube.RetrieveVideoResult.ParseFailure:
                    // this seems to happen randomly from time to time, just retry later
                    return(ResultType.TemporarilyUnavailable);

                default:
                    return(ResultType.Failure);
                }
            }

            string filenameWithoutExtension = "youtube_" + VideoInfo.Username + "_" + VideoInfo.VideoTimestamp.ToString("yyyy-MM-dd") + "_" + VideoInfo.VideoId;
            string filename     = filenameWithoutExtension + ".mkv";
            string tempFolder   = Path.Combine(Util.TempFolderPath, filenameWithoutExtension);
            string tempFilepath = Path.Combine(tempFolder, filename);

            {
                if (!await Util.FileExists(tempFilepath))
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(ResultType.Cancelled);
                    }

                    Directory.CreateDirectory(tempFolder);
                    Status = "Running youtube-dl...";
                    await StallWrite(tempFilepath, 0, cancellationToken);                       // don't know expected filesize, so hope we have a sensible value in minimum free space

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(ResultType.Cancelled);
                    }
                    List <string> args = new List <string>()
                    {
                        "-f", "bestvideo[height<=?1080]+bestaudio/best",
                        "-o", tempFilepath,
                        "--merge-output-format", "mkv",
                        "--no-color",
                        "--abort-on-error",
                        "--abort-on-unavailable-fragment",
                        "--no-sponsorblock",
                    };
                    string limit = Util.YoutubeSpeedLimit;
                    if (limit != "")
                    {
                        args.Add("--rate-limit");
                        args.Add(limit);
                    }
                    bool wantCookies = Notes != null && Notes.Contains("cookies");
                    if (wantCookies)
                    {
                        args.Add("--cookies");
                        args.Add(@"d:\cookies.txt");
                    }
                    bool nokill = Notes != null && Notes.Contains("nokill");
                    args.Add("https://www.youtube.com/watch?v=" + VideoInfo.VideoId);
                    var data = await ExternalProgramExecution.RunProgram(
                        @"yt-dlp", args.ToArray(), youtubeSpeedWorkaround : !nokill,
                        stdoutCallbacks : new System.Diagnostics.DataReceivedEventHandler[1] {
                        (sender, received) => {
                            if (!String.IsNullOrEmpty(received.Data))
                            {
                                Status = received.Data;
                            }
                        }
                    }
                        );
                }

                string finalFilename = GenerateOutputFilename();
                string finalFilepath = Path.Combine(Util.TargetFolderPath, finalFilename);
                if (File.Exists(finalFilepath))
                {
                    throw new Exception("File exists: " + finalFilepath);
                }

                Status = "Waiting for free disk IO slot to move...";
                try {
                    await Util.ExpensiveDiskIOSemaphore.WaitAsync(cancellationToken);
                } catch (OperationCanceledException) {
                    return(ResultType.Cancelled);
                }
                try {
                    // sanity check
                    Status = "Sanity check on downloaded video...";
                    TimeSpan actualVideoLength   = (await FFMpegUtil.Probe(tempFilepath)).Duration;
                    TimeSpan expectedVideoLength = VideoInfo.VideoLength;
                    if (actualVideoLength.Subtract(expectedVideoLength).Duration() > TimeSpan.FromSeconds(5))
                    {
                        // if difference is bigger than 5 seconds something is off, report
                        Status = "Large time difference between expected (" + expectedVideoLength.ToString() + ") and actual (" + actualVideoLength.ToString() + "), stopping.";
                        return(ResultType.Failure);
                    }

                    Status = "Moving...";
                    await Task.Run(() => Util.MoveFileOverwrite(tempFilepath, finalFilepath));

                    await Task.Run(() => Directory.Delete(tempFolder));
                } finally {
                    Util.ExpensiveDiskIOSemaphore.Release();
                }
            }

            Status    = "Done!";
            JobStatus = VideoJobStatus.Finished;
            return(ResultType.Success);
        }