public void TestBSPWrite() { using var ms = new MemoryStream(); using var binaryWriter = new BinaryWriter(ms); // Read and then write the BSP to the memory stream var reader = FileReader.OpenStream("testdata/map.bsp"); var bsp1 = new BSP(reader); reader.Dispose(); bsp1.WriteBSP(binaryWriter); binaryWriter.Flush(); ms.Seek(0, SeekOrigin.Begin); // Now read the BSP again from the memory stream, we can then compare them to make sure the write went correct reader = new BinaryReader(ms); var bsp2 = new BSP(reader); reader.Dispose(); var gl1 = (GameLump)bsp1.Lumps[(int)LumpType.GameLump]; var gl2 = (GameLump)bsp2.Lumps[(int)LumpType.GameLump]; Assert.Equal(gl1.LumpItems, gl2.LumpItems); var pak1 = (PakfileLump)bsp1.Lumps[(int)LumpType.Pakfile]; var pak2 = (PakfileLump)bsp2.Lumps[(int)LumpType.Pakfile]; Assert.Equal(pak1.Data, pak2.Data); }
/// <summary> /// Performs the lump extraction. Assumes that the options have been validated. /// </summary> /// <param name="opts">The lump extraction options</param> /// <exception cref="ArgumentException">Thrown if opts.BSPPath is not a file path</exception> /// <exception cref="LumpEmptyException">Thrown if the specified lump is already empty</exception> public static void ExtractLump(Options opts) { var lumpIndex = opts.LumpIndex; var bspFolder = Path.GetDirectoryName(opts.BSPPath); var bspName = Path.GetFileNameWithoutExtension(opts.BSPPath); if (bspFolder == null || bspName == null || Directory.Exists(opts.BSPPath)) { throw new ArgumentException("Invalid BSP path specified"); } // Read BSP Console.WriteLine("Reading and parsing BSP"); var bsp = new BSP(opts.BSPPath); if (bsp.Lumps[lumpIndex].Data.Length <= 1) { throw new LumpEmptyException(); } // True if we will modify the original BSP var willModify = !opts.DontClear; // Backup original BSP if (opts.MakeBackup && willModify) { Console.WriteLine("Saving BSP backup"); var backupBSPPath = Path.Combine(bspFolder, $"{bspName}.bsp.orig"); File.Move(opts.BSPPath, backupBSPPath); } // Write lump if (!opts.DontExtract) { Console.WriteLine("Writing .lmp file"); var lmpPath = Path.Combine(bspFolder, $"{bspName}_l_{lumpIndex}.lmp"); bsp.WriteLMP(lmpPath, lumpIndex); } // Clear lump if (!opts.DontClear) { Console.WriteLine("Clearing lump"); bsp.Lumps[lumpIndex].Clear(); } // Clear lump and write new BSP if (willModify) { Console.WriteLine("Writing to original file"); bsp.WriteBSP(opts.BSPPath); } Console.WriteLine("Done"); }
public static void PackFiles(Options opts, IReadOnlyCollection <string> files) { Console.WriteLine($"Found {files.Count} files matching the filter."); Console.WriteLine($"Reading from {Path.GetFileName(opts.BSPPath)}"); var bsp = new BSP(opts.BSPPath); var pakLump = (PakfileLump)bsp.Lumps[(int)LumpType.Pakfile]; var archive = pakLump.OpenArchiveStream(ZipArchiveMode.Update); var i = 0; foreach (var file in files) { if (i % 50 == 0) { Console.WriteLine($"{i}/{files.Count} Zipping files..."); } var relPath = ToRelativePath(file, opts.ContentPath); var entry = archive.GetEntry(relPath); if (entry != null) { Console.WriteLine($"{relPath} already packed, overwriting..."); } else { entry = archive.CreateEntry(relPath, CompressionLevel.NoCompression); } using var entryWriter = entry.Open(); using var fileReader = File.Open(file, FileMode.Open, FileAccess.Read); fileReader.CopyTo(entryWriter); i++; } pakLump.CloseArchiveStream(); Console.WriteLine($"Writing to {Path.GetFileName(opts.BSPPath)}"); bsp.WriteBSP(opts.BSPPath); Console.WriteLine("Done!"); }
public void TestBSPFileWrite() { string fileName = Path.GetTempPath() + Guid.NewGuid() + ".bsp"; // Read BSP and then write to a temp file var reader = FileReader.OpenStream("testdata/map.bsp"); var bsp1 = new BSP(reader); reader.Dispose(); bsp1.WriteBSP(fileName); // Re-open the temp file and do basic consistency check using var fs = File.Open(fileName, FileMode.Open, FileAccess.Read); using var reader2 = new BinaryReader(fs); var bsp2 = new BSP(reader2); reader2.Dispose(); Assert.Equal(bsp1.Version, bsp2.Version); File.Delete(fileName); }
public void TestClearLump() { // Read BSP, clear lump, write BSP, read again, confirm lump is cleared var reader = FileReader.OpenStream("testdata/map.bsp"); var bsp = new BSP(reader); var lump = bsp.Lumps[(int)LumpType.Entities]; var lumpSize = lump.Data.Length; lump.Clear(); using var ms = new MemoryStream(); using var writer = new BinaryWriter(ms); bsp.WriteBSP(writer); writer.Flush(); ms.Seek(0, SeekOrigin.Begin); using var reader2 = new BinaryReader(ms); var bsp2 = new BSP(reader2); Assert.Single(bsp2.Lumps[(int)LumpType.Entities].Data); }