static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Error - please specify a texture list (.txt), or a PRS/PVM/GVM archive."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } string filePath = args[0]; bool IsPRS = false; if (args.Length > 1 && args[1] == "-prs") { IsPRS = true; } string directoryName = Path.GetDirectoryName(filePath); string extension = Path.GetExtension(filePath).ToLowerInvariant(); switch (extension) { case ".txt": string archiveName = Path.GetFileNameWithoutExtension(filePath); if (File.Exists(filePath)) { List <string> textureNames = new List <string>(File.ReadAllLines(filePath).Where(a => !string.IsNullOrEmpty(a))); ArchiveBase pvmArchive; string ext = Path.GetExtension(textureNames[0]).ToLowerInvariant(); if (textureNames.Any(a => !Path.GetExtension(a).Equals(ext, StringComparison.OrdinalIgnoreCase))) { Console.WriteLine("Cannot create archive from mixed file types."); return; } switch (ext) { case ".pvr": pvmArchive = new PvmArchive(); break; case ".gvr": pvmArchive = new GvmArchive(); break; default: Console.WriteLine("Unknown file type \"{0}\".", ext); return; } using (Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create)) { ArchiveWriter pvmWriter = pvmArchive.Create(pvmStream); // Reading in textures foreach (string tex in textureNames) { pvmWriter.CreateEntryFromFile(Path.Combine(directoryName, Path.ChangeExtension(tex, ".pvr"))); } pvmWriter.Flush(); } if (IsPRS == true) { byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".pvm")); pvmdata = FraGag.Compression.Prs.Compress(pvmdata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), pvmdata); File.Delete(Path.ChangeExtension(filePath, ".pvm")); } Console.WriteLine("Archive was compiled successfully!"); } else // error, supplied path is invalid { Console.WriteLine("Supplied archive/texture list does not exist!"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } break; case ".prs": case ".pvm": case ".gvm": string path = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(filePath)); Directory.CreateDirectory(path); byte[] filedata = File.ReadAllBytes(filePath); using (TextWriter texList = File.CreateText(Path.Combine(path, Path.ChangeExtension(filePath, ".txt")))) { try { ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filePath); if (extension == ".prs") { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); if (!pvmfile.Is(pvmdata, filePath)) { pvmfile = new GvmArchive(); } ArchiveReader pvmReader = pvmfile.Open(pvmdata); foreach (ArchiveEntry file in pvmReader.Entries) { texList.WriteLine(file.Name); pvmReader.ExtractToFile(file, Path.Combine(path, file.Name)); } Console.WriteLine("Archive extracted!"); } catch { Console.WriteLine("Exception thrown. Canceling conversion."); Directory.Delete(path, true); throw; } } break; default: Console.WriteLine("Unknown extension \"{0}\".", extension); break; } }
private void Run(Settings settings, ProgressDialog dialog) { // Setup some stuff for the progress dialog int numFilesAdded = 0; string description = String.Format("Processing {0}", Path.GetFileName(settings.OutFilename)); dialog.ReportProgress(0, description); // For some archives, the file needs to be a specific format. As such, // they may be rejected when trying to add them. We'll store such files in // this list to let the user know they could not be added. List <string> FilesNotAdded = new List <string>(); // Create the stream we are going to write the archive to Stream destination; if (settings.CompressionFormat == CompressionFormat.Unknown) { // We are not compression the archive. Write directly to the destination destination = File.Create(settings.OutFilename); } else { // We are compressing the archive. Write to a memory stream first. destination = new MemoryStream(); } // Create the archive ArchiveWriter archive = Archive.Create(destination, settings.ArchiveFormat); // Set archive settings if (settings.WriterSettingsControl != null) { settings.WriterSettingsControl.SetModuleSettings(archive); } // Add the file added event handler the archive archive.FileAdded += delegate(object sender, EventArgs e) { numFilesAdded++; //if (numFilesAdded == archive.NumberOfFiles) if (numFilesAdded == archive.Entries.Count) { dialog.ReportProgress(100, "Finishing up"); } else { dialog.ReportProgress(numFilesAdded * 100 / archive.Entries.Count, description + "\n\n" + String.Format("Adding {0} ({1:N0} of {2:N0})", Path.GetFileName(settings.FileEntries[numFilesAdded].SourceFile), numFilesAdded + 1, archive.Entries.Count)); } }; // Add the files to the archive. We're going to do this in a try catch since // sometimes an exception may be thrown (namely if the archive cannot contain // the file the user is trying to add) foreach (FileEntry entry in settings.FileEntries) { try { archive.CreateEntryFromFile(entry.SourceFile, entry.FilenameInArchive); } catch (CannotAddFileToArchiveException) { FilesNotAdded.Add(entry.SourceFile); } } // If filesNotAdded is not empty, then show a message to the user // and ask them if they want to continue if (FilesNotAdded.Count > 0) { if (new FilesNotAddedDialog(FilesNotAdded).ShowDialog() != DialogResult.Yes) { destination.Close(); return; } } if (archive.Entries.Count == 1) { dialog.Description = description + "\n\n" + String.Format("Adding {0}", Path.GetFileName(settings.FileEntries[numFilesAdded].SourceFile)); } else { dialog.Description = description + "\n\n" + String.Format("Adding {0} ({1:N0} of {2:N0})", Path.GetFileName(settings.FileEntries[numFilesAdded].SourceFile), numFilesAdded + 1, archive.Entries.Count); } archive.Flush(); // Do we want to compress this archive? if (settings.CompressionFormat != CompressionFormat.Unknown) { destination.Position = 0; using (FileStream outStream = File.Create(settings.OutFilename)) { Compression.Compress(destination, outStream, settings.CompressionFormat); } } destination.Close(); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("ArchiveTool is a command line tool to manipulate PVM, GVM and PRS archives.\n"); Console.WriteLine("Usage:\n"); Console.WriteLine("Extracting a PVM/GVM/PRS archive:\nArchiveTool file.pvm\nIf the archive is PRS compressed, it will be decompressed first.\nIf the archive contains textures, the program will produce a folder with all PVR/GVR textures and a texture list.\nThe texture list is a text file with each line containing a texture file name.\n"); Console.WriteLine("Creating a PVM/GVM:\nArchiveTool texturelist.txt\nThe program will produce a PVM or GVM archive from a texture list.\nThe textures must be in the same folder as the texture list.\n"); Console.WriteLine("Creating a PRS compressed PVM/GVM:\nArchiveTool texturelist.txt -prs\nSame as the previous option but the PVM/GVM file will be PRS compressed.\n"); Console.WriteLine("Creating a PRS compressed binary:\nArchiveTool file.bin\nA PRS archive will be created from the file.\nFile extension must be .BIN for this option to work.\n"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } string filePath = args[0]; bool IsPRS = false; bool IsGVM = false; bool IsBIN = false; if (args.Length > 1 && args[1] == "-prs") { IsPRS = true; } string directoryName = Path.GetDirectoryName(filePath); string extension = Path.GetExtension(filePath).ToLowerInvariant(); if (!File.Exists(filePath)) { Console.WriteLine("Supplied archive/texture list does not exist!"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } switch (extension) { case ".bin": byte[] bindata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".bin")); bindata = FraGag.Compression.Prs.Compress(bindata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), bindata); Console.WriteLine("PRS archive was compiled successfully!"); break; case ".txt": string archiveName = Path.GetFileNameWithoutExtension(filePath); List <string> textureNames = new List <string>(File.ReadAllLines(filePath).Where(a => !string.IsNullOrEmpty(a))); ArchiveBase pvmArchive; string ext = Path.GetExtension(textureNames[0]).ToLowerInvariant(); if (textureNames.Any(a => !Path.GetExtension(a).Equals(ext, StringComparison.OrdinalIgnoreCase))) { Console.WriteLine("Cannot create archive from mixed file types."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } switch (ext) { case ".pvr": pvmArchive = new PvmArchive(); break; case ".gvr": pvmArchive = new GvmArchive(); IsGVM = true; break; default: Console.WriteLine("Unknown file type \"{0}\".", ext); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } if (!IsGVM) { ext = ".pvm"; } else { ext = ".gvm"; } using (Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ext), FileMode.Create)) { ArchiveWriter pvmWriter = pvmArchive.Create(pvmStream); // Reading in textures foreach (string tex in textureNames) { if (!IsGVM) { pvmWriter.CreateEntryFromFile(Path.Combine(directoryName, Path.ChangeExtension(tex, ".pvr"))); } else { pvmWriter.CreateEntryFromFile(Path.Combine(directoryName, Path.ChangeExtension(tex, ".gvr"))); } } pvmWriter.Flush(); } if (IsPRS) { byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ext)); pvmdata = FraGag.Compression.Prs.Compress(pvmdata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), pvmdata); File.Delete(Path.ChangeExtension(filePath, ext)); } Console.WriteLine("Archive was compiled successfully!"); break; case ".prs": case ".pvm": case ".gvm": string path = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(filePath)); Directory.CreateDirectory(path); byte[] filedata = File.ReadAllBytes(filePath); using (TextWriter texList = File.CreateText(Path.Combine(path, Path.ChangeExtension(filePath, ".txt")))) { try { ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filePath); if (extension == ".prs") { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); MemoryStream stream = new MemoryStream(pvmdata); if (!PvmArchive.Identify(stream)) { pvmfile = new GvmArchive(); if (!GvmArchive.Identify(stream)) { File.WriteAllBytes(Path.ChangeExtension(filePath, ".bin"), pvmdata); IsBIN = true; Console.WriteLine("PRS archive extracted!"); } } if (!IsBIN) { ArchiveReader pvmReader = pvmfile.Open(pvmdata); foreach (ArchiveEntry file in pvmReader.Entries) { texList.WriteLine(file.Name); pvmReader.ExtractToFile(file, Path.Combine(path, file.Name)); } Console.WriteLine("Archive extracted!"); } } catch { Console.WriteLine("Exception thrown. Canceling conversion."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); Directory.Delete(path, true); throw; } } if (IsBIN) { File.Delete(Path.Combine(path, Path.ChangeExtension(filePath, ".txt"))); Directory.Delete(path, true); } break; default: Console.WriteLine("Unknown extension \"{0}\".", extension); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); break; } }