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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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);
        }