Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            Console.WriteLine("DOOMExtract 1.7 by infogram - https://github.com/emoose/DOOMExtract");
            Console.WriteLine();
            if (args.Length <= 0)
            {
                PrintUsage();
                return;
            }

            string indexFilePath = args[0];
            string destFolder    = Path.GetDirectoryName(indexFilePath);

            destFolder = Path.Combine(destFolder, Path.GetFileNameWithoutExtension(indexFilePath));

            bool isRepacking     = false;
            bool isDeleting      = false;
            bool isCreatingPatch = false;
            bool quietMode       = false;

            foreach (var arg in args)
            {
                if (arg == "--quiet")
                {
                    quietMode = true;
                }
            }

            if (args.Length >= 2)
            {
                if (args[1] == "--delete") // deleting
                {
                    isDeleting = true;
                }
                else if (args[1] == "--repack" || args[1] == "--createPatch") // repacking
                {
                    isRepacking     = true;
                    isCreatingPatch = args[1] == "--createPatch";

                    if (args.Length <= 2) // missing the repack folder arg
                    {
                        PrintUsage();
                        return;
                    }

                    destFolder = Path.GetFullPath(args[2]); // use destFolder as the folder where repack files are
                    if (!Directory.Exists(destFolder))
                    {
                        Console.WriteLine((isCreatingPatch ? "Patch" : "Repack") + $" folder \"{destFolder}\" doesn't exist!");
                        return;
                    }
                }
                else
                {
                    destFolder = Path.GetFullPath(args[1]);
                }
            }

            Console.WriteLine($"Loading {indexFilePath}...");
            var index = new DOOMResourceIndex(indexFilePath);

            if (!index.Load())
            {
                Console.WriteLine("Failed to load index file for some reason, is it a valid DOOM index file?");
                return;
            }

            Console.WriteLine($"Index loaded ({index.Entries.Count} files)" + (!quietMode ? ", data file contents:" : ""));

            if (!quietMode)
            {
                var pfis = new Dictionary <int, int>();

                foreach (var entry in index.Entries)
                {
                    if (!pfis.ContainsKey(entry.PatchFileNumber))
                    {
                        pfis.Add(entry.PatchFileNumber, 0);
                    }
                    pfis[entry.PatchFileNumber]++;
                }

                var pfiKeys = pfis.Keys.ToList();
                pfiKeys.Sort();

                int total = 0;
                foreach (var key in pfiKeys)
                {
                    var resName = Path.GetFileName(index.ResourceFilePath(key));
                    Console.WriteLine($"  {resName}: {pfis[key]} files");
                    total += pfis[key];
                }

                Console.WriteLine();
            }

            if (isCreatingPatch)
            {
                // clone old index and increment the patch file number

                byte pfi      = (byte)(index.PatchFileNumber + 1);
                var  destPath = Path.ChangeExtension(index.ResourceFilePath(pfi), ".pindex");
                index.Close();

                if (File.Exists(destPath))
                {
                    File.Delete(destPath); // !!!!
                }
                File.Copy(indexFilePath, destPath);
                indexFilePath = destPath;

                index = new DOOMResourceIndex(destPath);
                if (!index.Load())
                {
                    Console.WriteLine("Copied patch file failed to load? (this should never happen!)");
                    return;
                }
                index.PatchFileNumber = pfi;
            }

            if (isRepacking)
            {
                // REPACK (and patch creation) MODE!!!

                var resFile = index.ResourceFilePath(index.PatchFileNumber);

                Console.WriteLine((isCreatingPatch ? "Creating" : "Repacking") + $" {Path.GetFileName(indexFilePath)} from folder {destFolder}...");

                index.Rebuild(resFile + "_tmp", destFolder, true);
                index.Close();
                if (!File.Exists(resFile + "_tmp"))
                {
                    Console.WriteLine("Failed to create new resource data file!");
                    return;
                }

                if (File.Exists(resFile))
                {
                    File.Delete(resFile);
                }

                File.Move(resFile + "_tmp", resFile);
                Console.WriteLine(isCreatingPatch ? "Patch file created!" : "Repack complete!");
                return;
            }

            if (isDeleting)
            {
                if (args.Length <= 2)
                {
                    PrintUsage();
                    return;
                }

                // DELETE MODE!!
                int deleted = 0;
                for (int i = 2; i < args.Length; i++)
                {
                    var path = args[i].Replace("/", "\\").ToLower();

                    int delIdx = -1;
                    for (int j = 0; j < index.Entries.Count; j++)
                    {
                        if (index.Entries[j].GetFullName().ToLower() == path)
                        {
                            delIdx = j;
                            break;
                        }
                    }

                    if (delIdx == -1)
                    {
                        Console.WriteLine($"Failed to find file {args[i]} in package.");
                    }
                    else
                    {
                        index.Entries.RemoveAt(delIdx);
                        deleted++;
                        Console.WriteLine($"Deleted {args[i]}!");
                    }
                }


                if (deleted > 0)
                {
                    Console.WriteLine("Repacking/rebuilding resources file...");
                    index.Rebuild(index.ResourceFilePath(index.PatchFileNumber) + "_tmp", String.Empty, true);
                    index.Close();
                    File.Delete(index.ResourceFilePath(index.PatchFileNumber));
                    File.Move(index.ResourceFilePath(index.PatchFileNumber) + "_tmp", index.ResourceFilePath(index.PatchFileNumber));
                }
                Console.WriteLine($"Deleted {deleted} files from resources.");
                return;
            }

            // EXTRACT MODE!

            if (!Directory.Exists(destFolder))
            {
                Directory.CreateDirectory(destFolder);
            }

            Console.WriteLine("Extracting contents to:");
            Console.WriteLine("\t" + destFolder);

            var fileIds      = new List <string>();
            int numExtracted = 0;
            int numProcessed = 0;

            foreach (var entry in index.Entries)
            {
                numProcessed++;
                if (entry.Size == 0 && entry.CompressedSize == 0) // blank entry?
                {
                    continue;
                }

                Console.WriteLine($"Extracting {entry.GetFullName()}...");
                Console.WriteLine($"    id: {entry.ID}, type: {entry.FileType}, size: {entry.Size} ({entry.CompressedSize} bytes compressed)");
                Console.WriteLine($"    source: {Path.GetFileName(index.ResourceFilePath(entry.PatchFileNumber))}");

                var destFilePath = Path.Combine(destFolder, entry.GetFullName());
                if (entry.FileType != "file")
                {
                    destFilePath += ";" + entry.FileType;
                }

                var destFileFolder = Path.GetDirectoryName(destFilePath);

                if (!Directory.Exists(destFileFolder))
                {
                    Directory.CreateDirectory(destFileFolder);
                }

                using (FileStream fs = File.OpenWrite(destFilePath))
                    index.CopyEntryDataToStream(entry, fs);

                Console.WriteLine($"--------------({numProcessed}/{index.Entries.Count})--------------");
                fileIds.Add(entry.GetFullName() + "=" + entry.ID);
                numExtracted++;
            }

            if (fileIds.Count > 0)
            {
                var idFile = Path.Combine(destFolder, "fileIds.txt");
                if (File.Exists(idFile))
                {
                    File.Delete(idFile);
                }
                File.WriteAllLines(idFile, fileIds.ToArray());
            }

            Console.WriteLine($"Extraction complete! Extracted {numExtracted} files.");
        }
Ejemplo n.º 2
0
 public DOOMResourceEntry(DOOMResourceIndex index)
 {
     _index = index;
 }