void Decode(string filePath, string xmlName, string outputPath) { if (string.IsNullOrWhiteSpace(outputPath)) { outputPath = Path.GetDirectoryName(filePath); } if (!Directory.Exists(outputPath)) { Console.WriteLine("Error: The output path doesn't exist or is inaccessible: {0}", outputPath); return; } string xml_filename = Path.Combine(outputPath, xmlName) + kNameExtension; string bin_filename = filePath; MegaloModel.MegaloScriptModelTagElementStreamFlags model_stream_flags; bool ignore_write_predicates = false; DecodeParseSwitches(mSwitches, out model_stream_flags, ref ignore_write_predicates); KBlam.RuntimeData.Variants.GameEngineVariant gev = null; if (DecodeVariantBlf(bin_filename, out gev)) { DecodeSaveVariant(gev, xml_filename, model_stream_flags, ignore_write_predicates); } }
void DecodeSaveVariant(KBlam.RuntimeData.Variants.GameEngineVariant gev, string xmlFilename, MegaloModel.MegaloScriptModelTagElementStreamFlags modelStreamFlags, bool ignoreWritePredicates) { var megalo_variant = gev.TryGetMegaloVariant(); if (megalo_variant != null) { megalo_variant.TagElementStreamSerializeFlags = KBlam.RuntimeData.Variants.GameEngineMegaloVariantTagElementStreamFlags.UseStringTableNames | KBlam.RuntimeData.Variants.GameEngineMegaloVariantTagElementStreamFlags.UseUserOptionNames; megalo_variant.EngineDefinition.TagElementStreamSerializeFlags = modelStreamFlags; } using (var xml = IO.XmlElementStream.CreateForWrite("GameVariant")) { xml.StreamMode = FileAccess.Write; xml.IgnoreWritePredicates = ignoreWritePredicates; gev.Serialize(xml); using (var sw = new System.IO.StreamWriter(xmlFilename, false, System.Text.Encoding.UTF8)) xml.Document.Save(sw); } }
protected override void ReverseEngineerInputFile(string inputFile, string outputFile) { KBlam.RuntimeData.Variants.GameEngineVariant gev = null; if (DecodeVariantBlf(inputFile, out gev)) { DecodeSaveVariant(gev, outputFile); } }
bool EncodeVariantBlf(string filePath, KBlam.RuntimeData.Variants.GameEngineVariant gev) { bool result = true; using (var dst_fs = File.Open(filePath, System.IO.FileMode.Open, FileAccess.Write)) result = EncodeVariantBlob(dst_fs, gev); return(result); }
protected override void ReverseEngineerInputFile(string inputFile, string outputFile) { bool success = true; KBlam.RuntimeData.Variants.GameEngineVariant gev = null; success = success && EncodeLoadVariant(inputFile, out gev); success = success && EncodeVariantPreprocess(gev, outputFile); success = success && EncodeVariantBlf(outputFile, gev); }
bool EncodeVariantBlob(FileStream fs, KBlam.RuntimeData.Variants.GameEngineVariant gev) { var megalo_variant = gev.TryGetMegaloVariant(); var blf_result = KBlam.Blob.Transport.BlobChunkVerificationResultInfo.ValidResult; long blffile_length = KBlam.Blob.GameEngineVariantBlob.GetBlfFileLength(mGameBuildAndTarget); using (var blf = new KBlam.Blob.Transport.BlobTransportStream()) { blf.GameTarget = mGameBuildAndTarget; var blob_system = mRequiredSystems.BlobSystemRef.System; if (fs.Length < blffile_length) { fs.SetLength(blffile_length); } blf_result = blf.OpenForWrite(fs, mFileOffset, blffile_length); if (blf_result.IsValid) { blf.UnderlyingStream.StreamMode = FileAccess.Write; int engine_version_to_write = mEngineVersion; if (megalo_variant != null) { if (megalo_variant.EngineVersion <= 0) { megalo_variant.EngineVersion = engine_version_to_write; } else { engine_version_to_write = megalo_variant.EngineVersion; } } var chdr = (KBlam.Blob.ContentHeaderBlob)blob_system.CreateObject(mGameBuildAndTarget, KBlam.Blob.WellKnownBlob.ContentHeader); chdr.ChangeData(gev.Variant.BaseVariant.Header, engine_version_to_write); var mpvr = (KBlam.Blob.GameEngineVariantBlob)blob_system.CreateObject(mGameBuildAndTarget, KBlam.Blob.WellKnownBlob.GameVariant); mpvr.ChangeData(gev); blf_result = blf.WriteChunksSansAuthentication(chdr, mpvr); } } if (blf_result.IsInvalid) { Console.WriteLine("Error: Failed to encode variant file{0}{1}", System.Environment.NewLine, blf_result.BuildErrorMessage()); } return(blf_result.IsValid); }
bool DecodeVariantBlob(FileStream fs, out KBlam.RuntimeData.Variants.GameEngineVariant gev) { gev = null; KBlam.Blob.GameEngineVariantBlob gevb = null; var blf_result = KBlam.Blob.Transport.BlobChunkVerificationResultInfo.ValidResult; long blffile_length = KBlam.Blob.GameEngineVariantBlob.GetBlfFileLength(mGameBuildAndTarget); using (var blf = new KBlam.Blob.Transport.BlobTransportStream()) { blf.GameTarget = mGameBuildAndTarget; var blob_system = mGameEngineBlobSystemRef.System; blf_result = blf.OpenRange(fs, mFileOffset, mFileOffset + blffile_length, FileAccess.Read); if (blf_result.IsValid) { blf.UnderlyingStream.StreamMode = FileAccess.Read; IEnumerable <KBlam.Blob.BlobObject> objects; blf_result = blf.EnumerateChunks(blob_system, out objects); if (blf_result.IsValid) { gevb = (from bo in objects where bo is KBlam.Blob.GameEngineVariantBlob select bo).FirstOrDefault() as KBlam.Blob.GameEngineVariantBlob; } } } if (blf_result.IsInvalid) { Console.WriteLine("Error: Failed to decode variant file{0}{1}", System.Environment.NewLine, blf_result.BuildErrorMessage()); } else if (gevb == null) { Console.WriteLine("Error: Not a game variant file"); } else if (KBlam.Blob.GameEngineVariantBlob.RequireValidHashes && gevb.InvalidData) { Console.WriteLine("Error: Game variant file's bitstream is corrupt"); } else { gev = gevb.Data; } return(blf_result.IsValid); }
void Encode(string filePath, string xmlName, string outputPath) { EncodeSwitches switches; EncodeParseSwitches(mSwitches, out switches); bool create_output_dir_and_file = (switches & EncodeSwitches.CreateVariantFile) != 0; if (string.IsNullOrWhiteSpace(outputPath)) { outputPath = Path.GetDirectoryName(filePath); } if (!Directory.Exists(outputPath) && !create_output_dir_and_file) { Console.WriteLine("Error: The output path doesn't exist or is inaccessible: {0}", outputPath); return; } string xml_filename = filePath; string bin_filename = Path.Combine(outputPath, xmlName) + kGvarExtension; if (!File.Exists(xml_filename)) { Console.WriteLine("Error: input variant xml does not exist in {0}", xml_filename); return; } bool success = true; KBlam.RuntimeData.Variants.GameEngineVariant gev = null; success = success && EncodeLoadVariant(xml_filename, out gev); success = success && EncodeVariantPreprocess(switches, gev, bin_filename); success = success && EncodeVariantBlf(bin_filename, gev); if (!success && create_output_dir_and_file && File.Exists(bin_filename)) { File.Delete(bin_filename); } }
bool EncodeLoadVariant(string xmlFilename, out KBlam.RuntimeData.Variants.GameEngineVariant ev) { ev = new KBlam.RuntimeData.Variants.GameEngineVariant(mGameBuildAndTarget.Build); bool result = true; using (var xml = new IO.XmlElementStream(xmlFilename)) { xml.InitializeAtRootElement(); xml.StreamMode = FileAccess.Read; ev.Serialize(xml); } if (ev.GameBuild != mGameBuildAndTarget.Build) { Console.WriteLine("Error: {0}'s game parameter '{1}' differs from what you gave me. Weak sauce", xmlFilename, ev.GameBuild); result = false; } return(result); }
bool DecodeVariantBlf(string filePath, out KBlam.RuntimeData.Variants.GameEngineVariant gev) { gev = null; bool result = true; using (var dst_fs = File.Open(filePath, System.IO.FileMode.Open, FileAccess.Read)) { long blffile_length = KBlam.Blob.GameEngineVariantBlob.GetBlfFileLength(mGameBuildAndTarget); if (dst_fs.Length < (mFileOffset + blffile_length)) { Console.WriteLine("Error: not enough data starting at offset 0x{0} to be a variant we support", mFileOffset.ToString("X8")); result = false; } else { result = DecodeVariantBlob(dst_fs, out gev); } } return(result); }
bool EncodeVariantPreprocess( KBlam.RuntimeData.Variants.GameEngineVariant gev, string filePath) { var mv = gev.TryGetMegaloVariant(); if (mv == null) { return(true); } if (mClearTitleUpdateData) { mv.ClearTitleUpdateData(); } if (mClearWeaponTuning) { mv.ClearWeaponTunings(); } // #TODO_MGLO: AddAllTeams return(true); }
bool EncodeVariantPreprocess(EncodeSwitches switches, KBlam.RuntimeData.Variants.GameEngineVariant gev, string filePath) { const string k_teams_xml_filename = @"Games\Halo4\Definitions\VariantGameTeams.xml"; var mv = gev.TryGetMegaloVariant(); #region CreateVariantFile if ((switches & EncodeSwitches.CreateVariantFile) != 0) { string dir = Path.GetDirectoryName(filePath); if (!Directory.Exists(dir)) { Console.WriteLine("Error: The directory for the game file doesn't exist or is inaccessible: {0}", dir); return(false); } using (var fs = File.Create(filePath)) { fs.SetLength(KBlam.Blob.GameEngineVariantBlob.GetBlfFileLength(mGameBuildAndTarget)); } } else if (!File.Exists(filePath)) { Console.WriteLine("Error: Output game file does not exist"); return(false); } #endregion #region ClearWeaponTuning if ((switches & EncodeSwitches.ClearWeaponTuning) != 0 && mv != null) { mv.ClearWeaponTunings(); } #endregion #region AddAllTeams if ((switches & EncodeSwitches.AddAllTeams) != 0 && mGameBuildAndTarget.Build.IsWithinSameBranch(KBlam.Engine.EngineRegistry.EngineBranchHalo4)) { var bv = gev.Variant.BaseVariant; foreach (var team in bv.TeamOptions.Teams) { team.NameString.Clear(); } if (File.Exists(k_teams_xml_filename)) { using (var xml = new IO.XmlElementStream(k_teams_xml_filename, System.IO.FileAccess.Read)) { xml.InitializeAtRootElement(); xml.StreamMode = System.IO.FileAccess.Read; var team_xml_game = KBlam.Engine.EngineBuildHandle.None; KBlam.Engine.EngineBuildHandle.Serialize(xml, ref team_xml_game); if (team_xml_game.IsWithinSameBranch(KBlam.Engine.EngineRegistry.EngineBranchHalo4)) { bv.TeamOptions.SerializeTeams(xml); } else { Console.WriteLine("Warning: Teams xml is not for this game, not modifying variant's team data"); } } } else { Console.WriteLine("Warning: Teams xml not found, not modifying variant's team data"); } } #endregion if (mv == null) { return(true); } #region sanity check category name #if false string megalo_category_name; if (mv != null && mCornbread == false && mCategoryIndexToName.TryGetValue(mv.EngineCategory, out megalo_category_name)) { if (mv.CategoryString.Count == 0) { mv.CategoryString.Add(megalo_category_name); } else if (mv.CategoryString[0].English != megalo_category_name) { mv.CategoryString[0].Set(megalo_category_name); } } else if (mv != null && mCornbread == false) { Console.WriteLine("Warning: Invalid Megalo category data {0}, defaulting", mv.EngineCategory); mv.BaseVariant.Header.EngineCategoryIndex = mv.EngineCategory = kCommunityCategoryIndex; if (mv.CategoryString.Count == 0) { mv.CategoryString.Add(kCommunityCategory); } else { mv.CategoryString[0].Set(kCommunityCategory); } } #endif #endregion #region watermark #if false if (mv != null) { var mv_h4 = mv as KBlam.Games.Halo4.RuntimeData.Variants.GameEngineMegaloVariantHalo4; if (mv_h4 != null) { const string k_water_mark = "Halomods in your pods!"; if (mv_h4.IntroDescriptionString.Count == 0) { mv_h4.IntroDescriptionString.Add(k_water_mark); } else { mv_h4.IntroDescriptionString[0].Set(k_water_mark); } } } #endif #endregion return(true); }