private static void Read(PexFile file, IBinaryReadStream br) { var magic = br.ReadUInt32(); if (magic != PexMagic) { throw new InvalidDataException($"File does not have fast code! Magic does not match {PexMagic:x8} is {magic:x8}"); } file.MajorVersion = br.ReadUInt8(); file.MinorVersion = br.ReadUInt8(); file.GameId = br.ReadUInt16(); file.CompilationTime = br.ReadUInt64().ToDateTime(); file.SourceFileName = br.ReadPrependedString(2); file.Username = br.ReadPrependedString(2); file.MachineName = br.ReadPrependedString(2); var stringsCount = br.ReadUInt16(); var bundle = new PexParseMeta( file._gameCategory, br, new Dictionary <ushort, string>()); for (var i = 0; i < stringsCount; i++) { bundle.Strings.Add((ushort)i, br.ReadPrependedString(2)); } var hasDebugInfo = bundle.Reader.ReadUInt8() == 1; if (hasDebugInfo) { file.DebugInfo = Mutagen.Bethesda.Pex.DebugInfo.Create(bundle); } var userFlagCount = br.ReadUInt16(); for (var i = 0; i < userFlagCount; i++) { var str = bundle.ReadString(); file.UserFlags[br.ReadUInt8()] = str; } var objectCount = br.ReadUInt16(); for (var i = 0; i < objectCount; i++) { var pexObject = PexObject.Create(bundle); file.Objects.Add(pexObject); } }
/// <summary> /// Write to a .pex file. /// </summary> /// <param name="pexFile">The pex file to write.</param> /// <param name="outputPath">Output path.</param> /// <param name="gameCategory">Game Category of the pex file.</param> public static void WritePexFile(this PexFile pexFile, string outputPath, GameCategory gameCategory) { var dirName = Path.GetDirectoryName(outputPath); Directory.CreateDirectory(dirName ?? string.Empty); if (File.Exists(outputPath)) { File.Delete(outputPath); } using var fs = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); using var bw = new PexWriter(fs, Encoding.UTF8, gameCategory.IsBigEndian()); pexFile.Write(bw); }
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); }