From 623f812e2addeca7444c5c89b332ecf3fea09588 Mon Sep 17 00:00:00 2001 From: Toby Gebhart Date: Thu, 20 Apr 2023 23:48:22 -0500 Subject: [PATCH 1/5] Initial checkin of olmod integration with tracker for challenge mode --- GameMod/CMTracker/Models/LeaderboardEntry.cs | 11 ++ GameMod/CMTracker/Models/Run.cs | 26 +++ GameMod/CMTracker/Models/StatPlayer.cs | 10 ++ GameMod/CMTracker/Models/StatRobot.cs | 11 ++ GameMod/CMTracker/Platform.cs | 165 +++++++++++++++++++ GameMod/CMTracker/PostRun.cs | 132 +++++++++++++++ GameMod/GameMod.csproj | 6 + 7 files changed, 361 insertions(+) create mode 100644 GameMod/CMTracker/Models/LeaderboardEntry.cs create mode 100644 GameMod/CMTracker/Models/Run.cs create mode 100644 GameMod/CMTracker/Models/StatPlayer.cs create mode 100644 GameMod/CMTracker/Models/StatRobot.cs create mode 100644 GameMod/CMTracker/Platform.cs create mode 100644 GameMod/CMTracker/PostRun.cs diff --git a/GameMod/CMTracker/Models/LeaderboardEntry.cs b/GameMod/CMTracker/Models/LeaderboardEntry.cs new file mode 100644 index 00000000..ebe63d60 --- /dev/null +++ b/GameMod/CMTracker/Models/LeaderboardEntry.cs @@ -0,0 +1,11 @@ +namespace GameMod.CMTracker.Models +{ + public class LeaderboardEntry + { + public int FavoriteWeaponId { get; set; } + public float AliveTime { get; set; } + public int RobotsDestroyed { get; set; } + public string PilotName { get; set; } + public int Score { get; set; } + } +} \ No newline at end of file diff --git a/GameMod/CMTracker/Models/Run.cs b/GameMod/CMTracker/Models/Run.cs new file mode 100644 index 00000000..a6ce45ff --- /dev/null +++ b/GameMod/CMTracker/Models/Run.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + +namespace GameMod.CMTracker.Models +{ + public class Run + { + public string PilotName { get; set; } + public string PlayerId { get; set; } + public string LevelName { get; set; } + public string LevelHash { get; set; } + public int KillerId { get; set; } + public int FavoriteWeaponId { get; set; } + public int DifficultyLevelId { get; set; } + public int ModeId { get; set; } + public int RobotsDestroyed { get; set; } + public float AliveTime { get; set; } + public int Score { get; set; } + public float SmashDamage { get; set; } + public int SmashKills { get; set; } + public float AutoOpDamage { get; set; } + public int AutoOpKills { get; set; } + public float SelfDamage { get; set; } + public List StatsRobot { get; set; } + public List StatsPlayer { get; set; } + } +} \ No newline at end of file diff --git a/GameMod/CMTracker/Models/StatPlayer.cs b/GameMod/CMTracker/Models/StatPlayer.cs new file mode 100644 index 00000000..739638e4 --- /dev/null +++ b/GameMod/CMTracker/Models/StatPlayer.cs @@ -0,0 +1,10 @@ +namespace GameMod.CMTracker.Models +{ + public class StatPlayer + { + public int WeaponTypeId { get; set; } + public bool IsPrimary { get; set; } + public float DamageDealt { get; set; } + public int NumKilled { get; set; } + } +} \ No newline at end of file diff --git a/GameMod/CMTracker/Models/StatRobot.cs b/GameMod/CMTracker/Models/StatRobot.cs new file mode 100644 index 00000000..8c238bc7 --- /dev/null +++ b/GameMod/CMTracker/Models/StatRobot.cs @@ -0,0 +1,11 @@ +namespace GameMod.CMTracker.Models +{ + public class StatRobot + { + public int EnemyTypeId { get; set; } + public bool IsSuper { get; set; } + public float DamageReceived { get; set; } + public float DamageDealt { get; set; } + public int NumKilled { get; set; } + } +} \ No newline at end of file diff --git a/GameMod/CMTracker/Platform.cs b/GameMod/CMTracker/Platform.cs new file mode 100644 index 00000000..e37cecff --- /dev/null +++ b/GameMod/CMTracker/Platform.cs @@ -0,0 +1,165 @@ +using HarmonyLib; +using Newtonsoft.Json; +using Overload; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Networking; + +namespace GameMod.CMTracker +{ + [HarmonyPatch(typeof(Platform), "Init")] + internal static class CMTracker_Platform_Init + { + static void Postfix() + { + AccessTools.Field(typeof(Platform), "CloudProvider").SetValue(null, 4); + } + } + + [HarmonyPatch(typeof(Platform), "UserName", MethodType.Getter)] + public static class CMTracker_Platform_UserName + { + static void Postfix(ref string __result) + { + __result = PilotManager.PilotName; + } + } + + [HarmonyPatch(typeof(Platform), "PlatformName", MethodType.Getter)] + public static class CMTracker_Platform_PlatformName + { + public static void Postfix(ref string __result) + { + __result = "OLMOD"; + } + } + + [HarmonyPatch(typeof(Platform), "StatsAvailable", MethodType.Getter)] + static class CMTracker_Platform_PlatformStatsAvailable + { + public static void Postfix(ref bool __result) + { + __result = true; + } + } + + [HarmonyPatch(typeof(Platform), "GetLeaderboardData")] + static class CMTracker_Platform_GetLeaderboardData + { + public static void Postfix(ref LeaderboardEntry[] __result, out int leaderboard_length, out int user_index, out Platform.LeaderboardDataState result) + { + user_index = -1; + leaderboard_length = 0; + + if (m_download_state == DownloadState.NoLeaderboard) + { + result = Platform.LeaderboardDataState.NoLeaderboard; + __result = null; + return; + } + if (m_download_state == DownloadState.RetryFromStart) + { + m_request_start = 1; + try + { + Platform.RequestChallengeLeaderboardData(MenuManager.ChallengeMission.DisplayName, MenuManager.m_leaderboard_challenge_countdown, MenuManager.m_leaderboard_difficulty, 1, m_request_num_entries - 1, false); + m_download_state = DownloadState.WaitingForData; + result = Platform.LeaderboardDataState.Waiting; + } + catch (Exception ex) + { + Debug.Log($"Error requesting olmod leaderboard entries: {ex.Message}"); + m_download_state = DownloadState.NoLeaderboard; + result = Platform.LeaderboardDataState.NoLeaderboard; + } + __result = null; + return; + } + if (m_download_state != DownloadState.HaveData) + { + result = Platform.LeaderboardDataState.Waiting; + __result = null; + return; + } + + LeaderboardEntry[] array = new LeaderboardEntry[m_entries.Length]; + for (int i = 0; i < m_entries.Length; i++) + { + if (m_entries[i].m_name == null) + { + m_entries[i].m_name = "m_name here"; + m_entries[i].m_rank = i + 1; + } + array[i] = m_entries[i]; + } + leaderboard_length = m_entries.Length; + result = Platform.LeaderboardDataState.HaveData; + __result = array; + } + + public static DownloadState m_download_state = DownloadState.RetryFromStart; + public static int m_request_start; + public static int m_request_num_entries = 0; + public static int m_leaderboard_length = 0; + public static LeaderboardEntry[] m_entries; + + public enum DownloadState + { + WaitingForData, + NoLeaderboard, + RetryFromStart, + HaveData + } + } + + [HarmonyPatch(typeof(Platform), "RequestChallengeLeaderboardData")] + public static class CMRequestChallengeLeaderboardData + { + public static CloudDataYield Postfix(CloudDataYield __result, string level_name, bool submode, int difficulty_level, int range_start, int num_entries, bool friends) + { + var levelHash = MenuManager.ChallengeMission.IsLevelAnAddon(MenuManager.m_leaderboard_level_num) + ? MenuManager.ChallengeMission.GetAddOnLevelIdStringHash(MenuManager.m_leaderboard_level_num) + : MenuManager.ChallengeMission.GetLevelFileName(MenuManager.m_leaderboard_level_num) + ":STOCK"; + CMTracker_Platform_GetLeaderboardData.m_download_state = CMTracker_Platform_GetLeaderboardData.DownloadState.WaitingForData; + GameManager.m_gm.StartCoroutine(DownloadLeaderboard(level_name, levelHash, Convert.ToInt32(submode), difficulty_level)); + CloudDataYield cdy = new CloudDataYield(() => CMTracker_Platform_GetLeaderboardData.m_download_state != CMTracker_Platform_GetLeaderboardData.DownloadState.HaveData && + CMTracker_Platform_GetLeaderboardData.m_download_state != CMTracker_Platform_GetLeaderboardData.DownloadState.NoLeaderboard); + + __result = cdy; + return null; + } + + static IEnumerator DownloadLeaderboard(string levelName, string levelHash, int modeId, int difficultyLevelId) + { + var url = $"{Config.Settings.Value("trackerBaseUrl")}/api/challengemodeleaderboard?levelHash={UnityWebRequest.EscapeURL(levelHash)}&difficultyLevelId={difficultyLevelId}&modeId={modeId}"; + + UnityWebRequest www = UnityWebRequest.Get(url); + yield return www.SendWebRequest(); + + if (www.isNetworkError || www.isHttpError) + { + Debug.Log($"DownloadLeaderboard Error: {www.error}"); + } + else + { + List results = JsonConvert.DeserializeObject>(www.downloadHandler.text); + + CMTracker_Platform_GetLeaderboardData.m_entries = results.Select(x => new LeaderboardEntry + { + m_data_is_valid = true, + m_favorite_weapon = x.FavoriteWeaponId, + m_game_time = (int)Math.Round(x.AliveTime), + m_kills = x.RobotsDestroyed, + m_name = x.PilotName, + m_rank = 1, + m_score = x.Score, + m_time_stamp = DateTime.Now + }).ToArray(); + CMTracker_Platform_GetLeaderboardData.m_download_state = CMTracker_Platform_GetLeaderboardData.DownloadState.HaveData; + } + } + } +} \ No newline at end of file diff --git a/GameMod/CMTracker/PostRun.cs b/GameMod/CMTracker/PostRun.cs new file mode 100644 index 00000000..07ddd6a1 --- /dev/null +++ b/GameMod/CMTracker/PostRun.cs @@ -0,0 +1,132 @@ +using GameMod.CMTracker.Models; +using HarmonyLib; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using Overload; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.Networking; + +namespace GameMod.CMTracker +{ + [HarmonyPatch(typeof(Overload.GameplayManager), "DoneLevel")] + internal class CMTracker_PostRun_GameplayManager_DoneLevel + { + static void Postfix(GameplayManager.DoneReason reason) + { + if (GameplayManager.IsChallengeMode && GameplayManager.m_level_info.Mission.FileName != "_EDITOR" && (int)ChallengeManager.ChallengeRobotsDestroyed > 0) + { + string url = $"{Config.Settings.Value("trackerBaseUrl")}/api/challengemoderun"; + Post(url, GetTrackerPost()); + } + } + + private static void Post(string url, Models.Run cmRun) + { + var request = new UnityWebRequest(url) + { + uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes( + JsonConvert.SerializeObject(cmRun, new JsonSerializerSettings() + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }))), + downloadHandler = new DownloadHandlerBuffer(), + method = UnityWebRequest.kHttpVerbPOST + }; + request.SetRequestHeader("Content-Type", "application/json"); + GameManager.m_gm.StartCoroutine(RequestCoroutine(request.SendWebRequest())); + } + + private static IEnumerator RequestCoroutine(UnityWebRequestAsyncOperation op) + { + yield return op; + } + + private static Models.Run GetTrackerPost() + { + var request = new Models.Run + { + PilotName = PilotManager.PilotName, + PlayerId = PlayerPrefs.GetString("UserID"), + RobotsDestroyed = (int)ChallengeManager.ChallengeRobotsDestroyed, + AliveTime = GameplayManager.AliveTime, + Score = (int)ChallengeManager.ChallengeScore, + LevelName = GameplayManager.Level.DisplayName, + LevelHash = GameplayManager.Level.IsAddOn ? GameplayManager.Level.GetAddOnLevelIdStringHash() : GameplayManager.Level.FileName + ":STOCK", + ModeId = Convert.ToInt32(ChallengeManager.CountdownMode), + FavoriteWeaponId = GameplayManager.MostDamagingWeapon(), + DifficultyLevelId = (int)GameplayManager.DifficultyLevel, + KillerId = GameplayManager.m_stats_player_killer, + SmashDamage = GameplayManager.m_robot_cumulative_damage_by_other_type[0], + SmashKills = GameplayManager.m_other_killer[0], + AutoOpDamage = GameplayManager.m_robot_cumulative_damage_by_other_type[1], + AutoOpKills = GameplayManager.m_other_killer[1], + SelfDamage = GameplayManager.m_stats_player_self_damage, + StatsRobot = new List(), + StatsPlayer = new List() + }; + + var enemyTypes = Enum.GetNames(typeof(EnemyType)); + for (int i = 0; i < GameplayManager.m_player_cumulative_damage_by_robot_type.Length; i++) + { + if (GameplayManager.m_player_cumulative_damage_by_robot_type[i] != 0) + { + request.StatsRobot.Add(new StatRobot + { + EnemyTypeId = i, + IsSuper = false, + DamageReceived = GameplayManager.m_player_cumulative_damage_by_robot_type[i], + DamageDealt = 0, + NumKilled = GameplayManager.m_robots_killed.Count(x => x.robot_type == (EnemyType)i) + }); + } + + if (GameplayManager.m_player_cumulative_damage_by_super_robot_type[i] != 0) + { + request.StatsRobot.Add(new StatRobot + { + EnemyTypeId = i, + IsSuper = true, + DamageReceived = GameplayManager.m_player_cumulative_damage_by_super_robot_type[i], + DamageDealt = 0, + NumKilled = GameplayManager.m_super_robots_killed.Count(x => x.robot_type == (EnemyType)i) + }); + } + } + + for (int i = 0; i < 8; i++) + { + if (GameplayManager.m_robot_cumulative_damage_by_weapon_type[i] != 0 || GameplayManager.m_weapon_killer[i] != 0) + { + request.StatsPlayer.Add(new StatPlayer + { + IsPrimary = true, + WeaponTypeId = i, + DamageDealt = GameplayManager.m_robot_cumulative_damage_by_weapon_type[i], + NumKilled = GameplayManager.m_weapon_killer[i] + }); + } + } + + for (int i = 0; i < 8; i++) + { + if (GameplayManager.m_robot_cumulative_damage_by_missile_type[i] != 0 || GameplayManager.m_missile_killer[i] != 0) + { + request.StatsPlayer.Add(new StatPlayer + { + IsPrimary = false, + WeaponTypeId = i, + DamageDealt = GameplayManager.m_robot_cumulative_damage_by_missile_type[i], + NumKilled = GameplayManager.m_missile_killer[i] + }); + } + } + + return request; + } + } +} \ No newline at end of file diff --git a/GameMod/GameMod.csproj b/GameMod/GameMod.csproj index 60257134..2d946c77 100644 --- a/GameMod/GameMod.csproj +++ b/GameMod/GameMod.csproj @@ -104,6 +104,12 @@ + + + + + + From 4110c1a734fce7bec79d8ef1d411f1a0990a4309 Mon Sep 17 00:00:00 2001 From: Toby Gebhart Date: Fri, 21 Apr 2023 19:35:52 -0500 Subject: [PATCH 2/5] Don't need PlayerId --- GameMod/CMTracker/Models/Run.cs | 1 - GameMod/CMTracker/Platform.cs | 2 +- GameMod/CMTracker/PostRun.cs | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/GameMod/CMTracker/Models/Run.cs b/GameMod/CMTracker/Models/Run.cs index a6ce45ff..f51e4e16 100644 --- a/GameMod/CMTracker/Models/Run.cs +++ b/GameMod/CMTracker/Models/Run.cs @@ -5,7 +5,6 @@ namespace GameMod.CMTracker.Models public class Run { public string PilotName { get; set; } - public string PlayerId { get; set; } public string LevelName { get; set; } public string LevelHash { get; set; } public int KillerId { get; set; } diff --git a/GameMod/CMTracker/Platform.cs b/GameMod/CMTracker/Platform.cs index e37cecff..d2dfea24 100644 --- a/GameMod/CMTracker/Platform.cs +++ b/GameMod/CMTracker/Platform.cs @@ -134,7 +134,7 @@ public static CloudDataYield Postfix(CloudDataYield __result, string level_name, static IEnumerator DownloadLeaderboard(string levelName, string levelHash, int modeId, int difficultyLevelId) { - var url = $"{Config.Settings.Value("trackerBaseUrl")}/api/challengemodeleaderboard?levelHash={UnityWebRequest.EscapeURL(levelHash)}&difficultyLevelId={difficultyLevelId}&modeId={modeId}"; + var url = $"{Config.Settings.Value("trackerBaseUrl")}/api/challengemodeleaderboard?levelHash={levelHash}&difficultyLevelId={difficultyLevelId}&modeId={modeId}"; UnityWebRequest www = UnityWebRequest.Get(url); yield return www.SendWebRequest(); diff --git a/GameMod/CMTracker/PostRun.cs b/GameMod/CMTracker/PostRun.cs index 07ddd6a1..536decc8 100644 --- a/GameMod/CMTracker/PostRun.cs +++ b/GameMod/CMTracker/PostRun.cs @@ -51,7 +51,6 @@ private static Models.Run GetTrackerPost() var request = new Models.Run { PilotName = PilotManager.PilotName, - PlayerId = PlayerPrefs.GetString("UserID"), RobotsDestroyed = (int)ChallengeManager.ChallengeRobotsDestroyed, AliveTime = GameplayManager.AliveTime, Score = (int)ChallengeManager.ChallengeScore, From e551f6ace7978b45f0ad70c9d2d59a60b023aa63 Mon Sep 17 00:00:00 2001 From: Toby Gebhart Date: Fri, 21 Apr 2023 20:25:06 -0500 Subject: [PATCH 3/5] Remove "Offline" error message from leaderboards --- GameMod/CMTracker/Platform.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/GameMod/CMTracker/Platform.cs b/GameMod/CMTracker/Platform.cs index d2dfea24..f2744e1a 100644 --- a/GameMod/CMTracker/Platform.cs +++ b/GameMod/CMTracker/Platform.cs @@ -11,7 +11,7 @@ namespace GameMod.CMTracker { [HarmonyPatch(typeof(Platform), "Init")] - internal static class CMTracker_Platform_Init + internal class CMTracker_Platform_Init { static void Postfix() { @@ -20,7 +20,7 @@ static void Postfix() } [HarmonyPatch(typeof(Platform), "UserName", MethodType.Getter)] - public static class CMTracker_Platform_UserName + internal class CMTracker_Platform_UserName { static void Postfix(ref string __result) { @@ -29,7 +29,7 @@ static void Postfix(ref string __result) } [HarmonyPatch(typeof(Platform), "PlatformName", MethodType.Getter)] - public static class CMTracker_Platform_PlatformName + internal class CMTracker_Platform_PlatformName { public static void Postfix(ref string __result) { @@ -38,7 +38,7 @@ public static void Postfix(ref string __result) } [HarmonyPatch(typeof(Platform), "StatsAvailable", MethodType.Getter)] - static class CMTracker_Platform_PlatformStatsAvailable + internal class CMTracker_Platform_PlatformStatsAvailable { public static void Postfix(ref bool __result) { @@ -46,8 +46,17 @@ public static void Postfix(ref bool __result) } } + [HarmonyPatch(typeof(Platform), "OnlineErrorMessage", MethodType.Getter)] + internal class CMTracker_Platform_OnlineErrorMessage + { + public static void Postfix(ref string __result) + { + __result = null; + } + } + [HarmonyPatch(typeof(Platform), "GetLeaderboardData")] - static class CMTracker_Platform_GetLeaderboardData + internal class CMTracker_Platform_GetLeaderboardData { public static void Postfix(ref LeaderboardEntry[] __result, out int leaderboard_length, out int user_index, out Platform.LeaderboardDataState result) { @@ -116,7 +125,7 @@ public enum DownloadState } [HarmonyPatch(typeof(Platform), "RequestChallengeLeaderboardData")] - public static class CMRequestChallengeLeaderboardData + internal static class CMRequestChallengeLeaderboardData { public static CloudDataYield Postfix(CloudDataYield __result, string level_name, bool submode, int difficulty_level, int range_start, int num_entries, bool friends) { From b78371c449bc9fe26a4352960fd01aeb4798e3d8 Mon Sep 17 00:00:00 2001 From: Toby Gebhart Date: Mon, 24 Apr 2023 12:44:36 -0500 Subject: [PATCH 4/5] Change source of PlayerId to use Unity's PlayerPrefs class directly (h/t luponix) --- GameMod/CMTracker/Models/Run.cs | 1 + GameMod/CMTracker/PostRun.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/GameMod/CMTracker/Models/Run.cs b/GameMod/CMTracker/Models/Run.cs index f51e4e16..2680f538 100644 --- a/GameMod/CMTracker/Models/Run.cs +++ b/GameMod/CMTracker/Models/Run.cs @@ -4,6 +4,7 @@ namespace GameMod.CMTracker.Models { public class Run { + public string PlayerId { get; set; } public string PilotName { get; set; } public string LevelName { get; set; } public string LevelHash { get; set; } diff --git a/GameMod/CMTracker/PostRun.cs b/GameMod/CMTracker/PostRun.cs index 536decc8..41d55c5f 100644 --- a/GameMod/CMTracker/PostRun.cs +++ b/GameMod/CMTracker/PostRun.cs @@ -50,6 +50,7 @@ private static Models.Run GetTrackerPost() { var request = new Models.Run { + PlayerId = PlayerPrefs.GetString("UserID"), PilotName = PilotManager.PilotName, RobotsDestroyed = (int)ChallengeManager.ChallengeRobotsDestroyed, AliveTime = GameplayManager.AliveTime, From dca8248cc83beab986eaa11d8c62cf0e174ac242 Mon Sep 17 00:00:00 2001 From: Toby Gebhart Date: Mon, 24 Apr 2023 19:24:26 -0500 Subject: [PATCH 5/5] Add checkbox option in CM menu for user's preference to not display detailed CM run information on public tracker --- GameMod/CMTracker/Menu.cs | 74 +++++++++++++++++++++++++++++++++ GameMod/CMTracker/Models/Run.cs | 1 + GameMod/CMTracker/PostRun.cs | 1 + GameMod/MPSetup.cs | 2 + 4 files changed, 78 insertions(+) create mode 100644 GameMod/CMTracker/Menu.cs diff --git a/GameMod/CMTracker/Menu.cs b/GameMod/CMTracker/Menu.cs new file mode 100644 index 00000000..92076c10 --- /dev/null +++ b/GameMod/CMTracker/Menu.cs @@ -0,0 +1,74 @@ +using HarmonyLib; +using Overload; +using System.Collections.Generic; +using System.Reflection.Emit; +using UnityEngine; + +namespace GameMod.CMTracker +{ + class CMTracker + { + public static bool mms_cm_runs_visible_in_tracker = false; + } + + [HarmonyPatch(typeof(UIElement), "DrawChallengeLevelSelectMenu")] + class CMTracker_Menu_UIElement_DrawChallengeLevelSelectMenu + { + + private static void PatchMenu(UIElement uie, Vector2 position) + { + uie.SelectAndDrawCheckboxItem("SUBMIT RESULTS TO PUBLIC TRACKER", position, 7, CMTracker.mms_cm_runs_visible_in_tracker, false, 1f, -1); + } + + private static IEnumerable Transpiler(IEnumerable codes) + { + // Skip from float num = 137f; to end of method, not applicable to olmod + bool skip = false; + foreach (var code in codes) + { + if (code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 137f) + skip = true; + + if (skip) + continue; + + yield return code; + } + + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldloc_0); + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(CMTracker_Menu_UIElement_DrawChallengeLevelSelectMenu), "PatchMenu")); + yield return new CodeInstruction(OpCodes.Ret); + } + } + + [HarmonyPatch(typeof(MenuManager), "ChallengeLevelSelectUpdate")] + internal class CMTracker_Menu_MenuManager_ChallengeLevelSelectUpdate + { + private static int PatchMenu() + { + if (UIManager.m_menu_selection == 7) + { + CMTracker.mms_cm_runs_visible_in_tracker = !CMTracker.mms_cm_runs_visible_in_tracker; + MenuManager.PlaySelectSound(); + return UIManager.m_menu_selection; + } + + // ilcode represented differently in Harmony than dnSpy, we need to return something other than UIManager.m_menu_selection to hit CreateNewGame branch + return 99; + } + + private static IEnumerable Transpiler(IEnumerable codes) + { + foreach (var code in codes) + { + if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 97) + { + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(CMTracker_Menu_MenuManager_ChallengeLevelSelectUpdate), "PatchMenu")); + continue; + } + yield return code; + } + } + } +} diff --git a/GameMod/CMTracker/Models/Run.cs b/GameMod/CMTracker/Models/Run.cs index 2680f538..ca367fad 100644 --- a/GameMod/CMTracker/Models/Run.cs +++ b/GameMod/CMTracker/Models/Run.cs @@ -6,6 +6,7 @@ public class Run { public string PlayerId { get; set; } public string PilotName { get; set; } + public bool DisplayOnTracker { get; set; } public string LevelName { get; set; } public string LevelHash { get; set; } public int KillerId { get; set; } diff --git a/GameMod/CMTracker/PostRun.cs b/GameMod/CMTracker/PostRun.cs index 41d55c5f..5f763c56 100644 --- a/GameMod/CMTracker/PostRun.cs +++ b/GameMod/CMTracker/PostRun.cs @@ -52,6 +52,7 @@ private static Models.Run GetTrackerPost() { PlayerId = PlayerPrefs.GetString("UserID"), PilotName = PilotManager.PilotName, + DisplayOnTracker = CMTracker.mms_cm_runs_visible_in_tracker, RobotsDestroyed = (int)ChallengeManager.ChallengeRobotsDestroyed, AliveTime = GameplayManager.AliveTime, Score = (int)ChallengeManager.ChallengeScore, diff --git a/GameMod/MPSetup.cs b/GameMod/MPSetup.cs index cbd46382..af72dad0 100644 --- a/GameMod/MPSetup.cs +++ b/GameMod/MPSetup.cs @@ -294,6 +294,7 @@ static void Postfix(string filename) FramerateLimiter.target_framerate = ModPrefs.GetInt("TARGET_FRAMERATE", 0); Menus.mms_collision_mesh = ModPrefs.GetInt("MP_COLLIDER_MESH", 0); + CMTracker.CMTracker.mms_cm_runs_visible_in_tracker = ModPrefs.GetBool("CM_RUNS_VISIBLE_IN_TRACKER", true); } else // for compatibility with old olmod, no need to add new settings { @@ -385,6 +386,7 @@ private static void Prefix(string filename) ModPrefs.SetBool("MP_AUDIOTAUNT_SHOW_FREQUENCYBAND", MPAudioTaunts.AClient.display_audio_spectrum); ModPrefs.SetInt("TARGET_FRAMERATE", FramerateLimiter.target_framerate); ModPrefs.SetInt("MP_COLLIDER_MESH", Menus.mms_collision_mesh); + ModPrefs.SetBool("CM_RUNS_VISIBLE_IN_TRACKER", CMTracker.CMTracker.mms_cm_runs_visible_in_tracker); ModPrefs.Flush(filename + "mod"); }