private static void AlignCellChildren( BinaryReadStream mutaReader, MutagenWriter writer) { writer.Write(mutaReader.ReadSpan(4, readSafe: false)); var storage = new Dictionary <int, ReadOnlyMemorySlice <byte> >(); for (int i = 0; i < 3; i++) { mutaReader.Position += 4; var subLen = mutaReader.ReadInt32(); mutaReader.Position += 4; var subGrupType = mutaReader.ReadInt32(); mutaReader.Position -= 16; if (!writer.MetaData.Constants.GroupConstants.Cell.SubTypes.Contains(subGrupType)) { i = 3; // end loop continue; } storage[subGrupType] = mutaReader.ReadMemory(subLen, readSafe: true); } foreach (var item in writer.MetaData.Constants.GroupConstants.Cell.SubTypes) { if (storage.TryGetValue(item, out var content)) { writer.Write(content); } } }
public async Task Setup() { // Load Settings System.Console.WriteLine("Running in directory: " + Directory.GetCurrentDirectory()); FilePath settingsPath = "../../../../TestingSettings.xml"; System.Console.WriteLine("Settings path: " + settingsPath); Settings = JsonConvert.DeserializeObject <TestingSettings>(File.ReadAllText(settingsPath.Path)); System.Console.WriteLine("Target settings: " + Settings.ToString()); var passthroughSettings = new PassthroughTestParams() { NicknameSuffix = null, PassthroughSettings = Settings.PassthroughSettings, GameRelease = GameRelease.Oblivion, Target = new Target() { Path = $"Oblivion.esm", Do = true, }, }; var passthrough = new OblivionPassthroughTest(passthroughSettings); (TempFolder TempFolder, Test Test) = passthrough.SetupProcessedFiles(); using var tmp = TempFolder; await Test.Start(); using (var stream = new BinaryReadStream(passthrough.ProcessedPath(ProcessedFilesFolder))) { stream.Position = 0xCF614B; PathGridBytes = stream.ReadBytes(0x14C7); } PathGridReader = new MutagenMemoryReadStream(PathGridBytes, new ParsingBundle(GameRelease.Oblivion, masterReferences: null)); }
public static async Task OblivionESM_GroupMask_Export(TestingSettings settings, Target target) { var mod = OblivionMod.CreateFromBinary( new ModPath( Mutagen.Bethesda.Oblivion.Constants.Oblivion, Path.Combine(settings.DataFolderLocations.Oblivion, target.Path))); using var tmp = new TempFolder("Mutagen_Oblivion_Binary_GroupMask_Export"); var oblivionOutputPath = Path.Combine(tmp.Dir.Path, TestingConstants.OBLIVION_ESM); mod.WriteToBinary( oblivionOutputPath, importMask: new GroupMask() { Npcs = true }); var fileLocs = RecordLocator.GetFileLocations(oblivionOutputPath, GameRelease.Oblivion); using var reader = new BinaryReadStream(oblivionOutputPath); foreach (var rec in fileLocs.ListedRecords.Keys) { reader.Position = rec; var t = HeaderTranslation.ReadNextRecordType(reader); if (!t.Equals(Oblivion.Internals.RecordTypes.NPC_)) { throw new ArgumentException("Exported a non-NPC record."); } } }
public BinaryReadStream GetBinaryReadStream(int length, bool loaded = true) { var ret = new BinaryReadStream( new MemoryStream(GetByteArray(length)), bufferSize: BUFFER_SIZE); if (loaded) { ret.LoadPosition(); } return(ret); }
private static void DoTest <T>(int streamCapacity, T expected, Action <BinaryWriter> write, Func <IBinaryReadStream, T> read) { using var ms = new MemoryStream(streamCapacity); using var bw = new BinaryWriter(ms); using var br = new BinaryReadStream(ms, isLittleEndian: false); write(bw); ms.Position = 0; var actual = read(br); Assert.Equal(expected, actual); Assert.Equal(ms.Length, ms.Position); }
public static PexFile CreateFromStream(Stream stream, GameCategory gameCategory) { using var br = new BinaryReadStream(stream, isLittleEndian: !gameCategory.IsBigEndian()); //https://en.uesp.net/wiki/Skyrim_Mod:Compiled_Script_File_Format var pexFile = new PexFile(gameCategory); Read(pexFile, br); if (stream.Position != stream.Length) { throw new InvalidDataException("Finished reading but end of the stream was not reached! " + $"Current position: {stream.Position} " + $"Stream length: {stream.Length} " + $"Missing: {stream.Length - stream.Position}"); } return(pexFile); }
private static void AlignCellChildren( BinaryReadStream mutaReader, MutagenWriter writer) { writer.Write(mutaReader.ReadSpan(4, readSafe: false)); var storage = new Dictionary <GroupTypeEnum, ReadOnlyMemorySlice <byte> >(); for (int i = 0; i < 3; i++) { mutaReader.Position += 4; var subLen = mutaReader.ReadInt32(); mutaReader.Position += 4; var subGrupType = (GroupTypeEnum)mutaReader.ReadUInt32(); mutaReader.Position -= 16; switch (subGrupType) { case GroupTypeEnum.CellPersistentChildren: case GroupTypeEnum.CellTemporaryChildren: case GroupTypeEnum.CellVisibleDistantChildren: break; default: i = 3; // end loop continue; } storage[subGrupType] = mutaReader.ReadMemory(subLen, readSafe: true); } if (storage.TryGetValue(GroupTypeEnum.CellPersistentChildren, out var content)) { writer.Write(content); } if (storage.TryGetValue(GroupTypeEnum.CellTemporaryChildren, out content)) { writer.Write(content); } if (storage.TryGetValue(GroupTypeEnum.CellVisibleDistantChildren, out content)) { writer.Write(content); } }
public static void Align( ModPath inputPath, FilePath outputPath, GameRelease gameMode, AlignmentRules alignmentRules, DirectoryPath temp) { var interest = new RecordInterest(alignmentRules.Alignments.Keys) { EmptyMeansInterested = false }; // Always interested in parent record types interest.InterestingTypes.Add("CELL"); interest.InterestingTypes.Add("WRLD"); var fileLocs = RecordLocator.GetLocations(inputPath, gameMode, interest); if (gameMode == GameRelease.Oblivion) { var alignedMajorRecordsFile = new ModPath(inputPath.ModKey, Path.Combine(temp, "alignedRules")); using (var inputStream = new MutagenBinaryReadStream(inputPath, gameMode)) { using var writer = new MutagenWriter(new FileStream(alignedMajorRecordsFile, FileMode.Create), gameMode); AlignMajorRecordsByRules(inputStream, writer, alignmentRules, fileLocs); } var alignedGroupsFile = new ModPath(inputPath.ModKey, Path.Combine(temp, "alignedGroups")); using (var inputStream = new MutagenBinaryReadStream(alignedMajorRecordsFile, gameMode)) { using var writer = new MutagenWriter(new FileStream(alignedGroupsFile, FileMode.Create), gameMode); AlignGroupsByRules(inputStream, writer, alignmentRules, fileLocs); } fileLocs = RecordLocator.GetLocations(alignedGroupsFile, gameMode, interest); var alignedCellsFile = new ModPath(inputPath.ModKey, Path.Combine(temp, "alignedCells")); using (var mutaReader = new BinaryReadStream(alignedGroupsFile)) { using var writer = new MutagenWriter(alignedCellsFile, gameMode); foreach (var grup in fileLocs.GrupLocations.Keys) { if (grup <= mutaReader.Position) { continue; } var noRecordLength = grup - mutaReader.Position; mutaReader.WriteTo(writer.BaseStream, (int)noRecordLength); // If complete overall, return if (mutaReader.Complete) { break; } mutaReader.WriteTo(writer.BaseStream, 12); var grupType = mutaReader.ReadInt32(); writer.Write(grupType); if (writer.MetaData.Constants.GroupConstants.Cell.TopGroupType == grupType) { AlignCellChildren(mutaReader, writer); } } mutaReader.WriteTo(writer.BaseStream, checked ((int)mutaReader.Remaining)); } fileLocs = RecordLocator.GetLocations(alignedCellsFile, gameMode, interest); using (var mutaReader = new MutagenBinaryReadStream(alignedCellsFile, gameMode)) { using var writer = new MutagenWriter(outputPath.Path, gameMode); foreach (var grup in fileLocs.GrupLocations.Keys) { if (grup <= mutaReader.Position) { continue; } var noRecordLength = grup - mutaReader.Position; mutaReader.WriteTo(writer.BaseStream, (int)noRecordLength); // If complete overall, return if (mutaReader.Complete) { break; } mutaReader.WriteTo(writer.BaseStream, 12); var grupType = mutaReader.ReadInt32(); writer.Write(grupType); if (writer.MetaData.Constants.GroupConstants.World.TopGroupType == grupType) { AlignWorldChildren(mutaReader, writer); } } mutaReader.WriteTo(writer.BaseStream, checked ((int)mutaReader.Remaining)); } } else { var alignedMajorRecordsFile = new ModPath(inputPath.ModKey, Path.Combine(temp, "alignedRules")); using (var inputStream = new MutagenBinaryReadStream(inputPath, gameMode)) { using var writer = new MutagenWriter(alignedMajorRecordsFile, gameMode); AlignMajorRecordsByRules(inputStream, writer, alignmentRules, fileLocs); } var alignedGroupsFile = Path.Combine(temp, "alignedGroups"); using (var inputStream = new MutagenBinaryReadStream(alignedMajorRecordsFile, gameMode)) { using var writer = new MutagenWriter(new FileStream(outputPath.Path, FileMode.Create), gameMode); AlignGroupsByRules(inputStream, writer, alignmentRules, fileLocs); } } }
public static void Align( ModPath inputPath, FilePath outputPath, GameRelease release, AlignmentRules alignmentRules, TempFolder?temp = null) { var interest = new RecordInterest(alignmentRules.Alignments.Keys) { EmptyMeansInterested = false }; var parsingBundle = new ParsingBundle(GameConstants.Get(release), MasterReferenceReader.FromPath(inputPath, release)); var fileLocs = RecordLocator.GetFileLocations(inputPath.Path, release, interest); temp ??= new TempFolder(); using (temp) { var alignedMajorRecordsFile = Path.Combine(temp.Dir.Path, "alignedRules"); using (var inputStream = new MutagenBinaryReadStream(inputPath.Path, parsingBundle)) { using var writer = new MutagenWriter(new FileStream(alignedMajorRecordsFile, FileMode.Create), release); AlignMajorRecordsByRules(inputStream, writer, alignmentRules, fileLocs); } var alignedGroupsFile = Path.Combine(temp.Dir.Path, "alignedGroups"); using (var inputStream = new MutagenBinaryReadStream(alignedMajorRecordsFile, parsingBundle)) { using var writer = new MutagenWriter(new FileStream(alignedGroupsFile, FileMode.Create), release); AlignGroupsByRules(inputStream, writer, alignmentRules, fileLocs); } fileLocs = RecordLocator.GetFileLocations(alignedGroupsFile, release, interest); var alignedCellsFile = Path.Combine(temp.Dir.Path, "alignedCells"); using (var mutaReader = new BinaryReadStream(alignedGroupsFile)) { using var writer = new MutagenWriter(alignedCellsFile, release); foreach (var grup in fileLocs.GrupLocations) { if (grup <= mutaReader.Position) { continue; } var noRecordLength = grup - mutaReader.Position; mutaReader.WriteTo(writer.BaseStream, (int)noRecordLength); // If complete overall, return if (mutaReader.Complete) { break; } mutaReader.WriteTo(writer.BaseStream, 12); var grupType = (GroupTypeEnum)mutaReader.ReadUInt32(); writer.Write((int)grupType); switch (grupType) { case GroupTypeEnum.CellChildren: AlignCellChildren(mutaReader, writer); break; default: break; } } mutaReader.WriteTo(writer.BaseStream, checked ((int)mutaReader.Remaining)); } fileLocs = RecordLocator.GetFileLocations(alignedCellsFile, release, interest); using (var mutaReader = new MutagenBinaryReadStream(alignedCellsFile, parsingBundle)) { using var writer = new MutagenWriter(outputPath.Path, GameConstants.Get(release)); foreach (var grup in fileLocs.GrupLocations) { if (grup <= mutaReader.Position) { continue; } var noRecordLength = grup - mutaReader.Position; mutaReader.WriteTo(writer.BaseStream, (int)noRecordLength); // If complete overall, return if (mutaReader.Complete) { break; } mutaReader.WriteTo(writer.BaseStream, 12); var grupType = (GroupTypeEnum)mutaReader.ReadUInt32(); writer.Write((int)grupType); switch (grupType) { case GroupTypeEnum.WorldChildren: AlignWorldChildren(mutaReader, writer); break; default: break; } } mutaReader.WriteTo(writer.BaseStream, checked ((int)mutaReader.Remaining)); } } }