From 765ffb92653bac5ad5e204856c4743b9bbfcb64c Mon Sep 17 00:00:00 2001 From: Ape <155788660+ApeMV@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:14:18 +0100 Subject: [PATCH] System Settings pt2 --- HNSRevamped.cs | 8 ++- Modules/CustomOptionsHolder.cs | 22 +++++-- Modules/OptionItem/OptionItem.cs | 1 + Modules/Utils.cs | 107 ++++++++++++++++--------------- Patches/EndGamePatches.cs | 50 +++++++++++++++ Patches/GameOptionsMenuPatch.cs | 8 +-- Patches/GameSettingMenuPatch.cs | 4 +- Patches/KickPlayerPatch.cs | 6 +- Patches/NumberOptionsPatch.cs | 2 +- 9 files changed, 136 insertions(+), 72 deletions(-) create mode 100644 Patches/EndGamePatches.cs diff --git a/HNSRevamped.cs b/HNSRevamped.cs index cdbe9d4..3b5ccc4 100644 --- a/HNSRevamped.cs +++ b/HNSRevamped.cs @@ -1,7 +1,10 @@ -using BepInEx; +global using HarmonyLib; +global using System.Collections.Generic; +global using System.Linq; + +using BepInEx; using BepInEx.Configuration; using BepInEx.Unity.IL2CPP; -using HarmonyLib; namespace HNSRevamped; @@ -13,7 +16,6 @@ public partial class Main : BasePlugin public static BepInEx.Logging.ManualLogSource Logger; public static BasePlugin Instance; - public override void Load() { var handler = HNSRevamped.Logger.Handler("GitVersion"); diff --git a/Modules/CustomOptionsHolder.cs b/Modules/CustomOptionsHolder.cs index c3d49a6..17ec813 100644 --- a/Modules/CustomOptionsHolder.cs +++ b/Modules/CustomOptionsHolder.cs @@ -33,6 +33,10 @@ namespace HNSRevamped public static OptionItem ApplyBanList; public static OptionItem ApplyModeratorList; + public static OptionItem AutoRejoinLobby; + + public static OptionItem NoGameEnd; + //Mod public static OptionItem DisableTasks; @@ -44,19 +48,25 @@ namespace HNSRevamped if (IsLoaded) return; //Main settings - KickLowLevelPlayer = IntegerOptionItem.Create(60050, "KickLowLevelPlayer", new(0, 100, 1), 0, TabGroup.SystemSettings, false) + KickLowLevelPlayer = IntegerOptionItem.Create(60050, "Kick Players Under Level", new(0, 100, 1), 0, TabGroup.SystemSettings, false) .SetValueFormat(OptionFormat.Level) .SetHeader(true); - TempBanLowLevelPlayer = BooleanOptionItem.Create(60051, "TempBanLowLevelPlayer", false, TabGroup.SystemSettings, false) + TempBanLowLevelPlayer = BooleanOptionItem.Create(60051, "Ban Instead Of Kick", false, TabGroup.SystemSettings, false) .SetParent(KickLowLevelPlayer) .SetValueFormat(OptionFormat.Times); - KickInvalidFriendCodes = BooleanOptionItem.Create(60080, "KickInvalidFriendCodes", true, TabGroup.SystemSettings, false); - TempBanInvalidFriendCodes = BooleanOptionItem.Create(60081, "TempBanInvalidFriendCodes", false, TabGroup.SystemSettings, false) + KickInvalidFriendCodes = BooleanOptionItem.Create(60080, "Kick Invalid FriendCodes", true, TabGroup.SystemSettings, false); + TempBanInvalidFriendCodes = BooleanOptionItem.Create(60081, "Ban Instead Of Kick", false, TabGroup.SystemSettings, false) .SetParent(KickInvalidFriendCodes); - ApplyBanList = BooleanOptionItem.Create(60110, "ApplyBanList", true, TabGroup.SystemSettings, true); - ApplyModeratorList = BooleanOptionItem.Create(60120, "ApplyModeratorList", false, TabGroup.SystemSettings, false); + ApplyBanList = BooleanOptionItem.Create(60110, "Apply BanList", true, TabGroup.SystemSettings, true); + ApplyModeratorList = BooleanOptionItem.Create(60120, "Apply ModeratorList", false, TabGroup.SystemSettings, false); + + AutoRejoinLobby = BooleanOptionItem.Create(60210, "Auto Rejoin Lobby", false, TabGroup.SystemSettings, false); + + NoGameEnd = BooleanOptionItem.Create(60380, "No Game End", false, TabGroup.SystemSettings, false) + .SetColor(Color.red) + .SetHeader(true); IsLoaded = true; } diff --git a/Modules/OptionItem/OptionItem.cs b/Modules/OptionItem/OptionItem.cs index 083d12a..826ab56 100644 --- a/Modules/OptionItem/OptionItem.cs +++ b/Modules/OptionItem/OptionItem.cs @@ -215,6 +215,7 @@ namespace HNSRevamped { SystemSettings, ModSettings, + HNSSettings, } diff --git a/Modules/Utils.cs b/Modules/Utils.cs index f9568c4..1a6ba5d 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -17,8 +17,8 @@ using Object = UnityEngine.Object; namespace HNSRevamped; - public static class Utils - { +public static class Utils +{ public static bool isHideNSeek => GameOptionsManager.Instance.CurrentGameOptions.GameMode == GameModes.HideNSeek; public static string ColorString(Color32 color, string str) => $"<#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}>{str}"; @@ -33,66 +33,67 @@ namespace HNSRevamped; return friendCodes.Any(code => code.Contains(friendCode)); } - public static string GetTabName(TabGroup tab) + public static string GetTabName(TabGroup tab) + { + switch (tab) { - switch (tab) - { - case TabGroup.SystemSettings: - return "System Settings"; - case TabGroup.ModSettings: - return "Mod Settings"; - - default: - return ""; - } + case TabGroup.SystemSettings: + return "System Settings"; + case TabGroup.ModSettings: + return "Mod Settings"; + case TabGroup.HNSSettings: + return "HNS Settings"; + default: + return ""; } + } - public static void DestroyTranslator(this GameObject obj) + public static void DestroyTranslator(this GameObject obj) + { + var translator = obj.GetComponent(); + if (translator != null) { - var translator = obj.GetComponent(); - if (translator != null) - { - Object.Destroy(translator); - } + Object.Destroy(translator); } + } - public static void DestroyTranslator(this MonoBehaviour obj) => obj.gameObject.DestroyTranslator(); + public static void DestroyTranslator(this MonoBehaviour obj) => obj.gameObject.DestroyTranslator(); - public static void CustomSettingsChangeMessageLogic(this NotificationPopper notificationPopper, OptionItem optionItem, string text, bool playSound) + public static void CustomSettingsChangeMessageLogic(this NotificationPopper notificationPopper, OptionItem optionItem, string text, bool playSound) + { + if (notificationPopper.lastMessageKey == 10000 + optionItem.Id && notificationPopper.activeMessages.Count > 0) { - if (notificationPopper.lastMessageKey == 10000 + optionItem.Id && notificationPopper.activeMessages.Count > 0) - { - notificationPopper.activeMessages[notificationPopper.activeMessages.Count - 1].UpdateMessage(text); - } - else - { - notificationPopper.lastMessageKey = 10000 + optionItem.Id; - LobbyNotificationMessage settingmessage = Object.Instantiate(notificationPopper.notificationMessageOrigin, Vector3.zero, Quaternion.identity, notificationPopper.transform); - settingmessage.transform.localPosition = new Vector3(0f, 0f, -2f); - settingmessage.SetUp(text, notificationPopper.settingsChangeSprite, notificationPopper.settingsChangeColor, new Action(() => - { - notificationPopper.OnMessageDestroy(settingmessage); - })); - notificationPopper.ShiftMessages(); - notificationPopper.AddMessageToQueue(settingmessage); - } - if (playSound) - { - SoundManager.Instance.PlaySoundImmediate(notificationPopper.settingsChangeSound, false, 1f, 1f, null); - } + notificationPopper.activeMessages[notificationPopper.activeMessages.Count - 1].UpdateMessage(text); } - - public static string GetOptionNameSCM(this OptionItem optionItem) + else { - if (optionItem.Name == "Enable") + notificationPopper.lastMessageKey = 10000 + optionItem.Id; + LobbyNotificationMessage settingmessage = Object.Instantiate(notificationPopper.notificationMessageOrigin, Vector3.zero, Quaternion.identity, notificationPopper.transform); + settingmessage.transform.localPosition = new Vector3(0f, 0f, -2f); + settingmessage.SetUp(text, notificationPopper.settingsChangeSprite, notificationPopper.settingsChangeColor, new Action(() => { - int id = optionItem.Id; - while (id % 10 != 0) - --id; - var optionItem2 = OptionItem.AllOptions.FirstOrDefault(opt => opt.Id == id); - return optionItem2 != null ? optionItem2.GetName() : optionItem.GetName(); - } - else - return optionItem.GetName(); + notificationPopper.OnMessageDestroy(settingmessage); + })); + notificationPopper.ShiftMessages(); + notificationPopper.AddMessageToQueue(settingmessage); } - } \ No newline at end of file + if (playSound) + { + SoundManager.Instance.PlaySoundImmediate(notificationPopper.settingsChangeSound, false, 1f, 1f, null); + } + } + + public static string GetOptionNameSCM(this OptionItem optionItem) + { + if (optionItem.Name == "Enable") + { + int id = optionItem.Id; + while (id % 10 != 0) + --id; + var optionItem2 = OptionItem.AllOptions.FirstOrDefault(opt => opt.Id == id); + return optionItem2 != null ? optionItem2.GetName() : optionItem.GetName(); + } + else + return optionItem.GetName(); + } +} diff --git a/Patches/EndGamePatches.cs b/Patches/EndGamePatches.cs new file mode 100644 index 0000000..c677379 --- /dev/null +++ b/Patches/EndGamePatches.cs @@ -0,0 +1,50 @@ +using AmongUs.Data; +using Hazel; +using InnerNet; +using UnityEngine; + +namespace HNSRevamped; + +[HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.ShowButtons))] +public static class EndGameManagerPatch +{ + public static void Postfix(EndGameManager __instance) + { + EndGameNavigation navigation = __instance.Navigation; + if (!AmongUsClient.Instance.AmHost || __instance == null || navigation == null || !Options.AutoRejoinLobby.GetBool()) return; + navigation.NextGame(); + } +} + +[HarmonyPatch(typeof(LogicGameFlowNormal), nameof(LogicGameFlowNormal.CheckEndCriteria))] +class NormalGameEndChecker +{ + public static bool Prefix() + { + if (Options.NoGameEnd.GetBool()) return false; + else return true; + } +} +[HarmonyPatch(typeof(LogicGameFlowHnS), nameof(LogicGameFlowHnS.CheckEndCriteria))] +class HNSGameEndChecker +{ + public static bool Prefix() + { + if (Options.NoGameEnd.GetBool()) return false; + else return true; + } +} +[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))] +internal class ControllerManagerUpdatePatch +{ + public static void Postfix() + { + if (Input.GetKey(KeyCode.L) && Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Return)) + { + // Instead of a gigantic custom RPC, the game can just be ended in 3 lines of code + MessageWriter writer = AmongUsClient.Instance.StartEndGame(); + writer.Write((byte)GameOverReason.ImpostorDisconnect); + AmongUsClient.Instance.FinishEndGame(writer); + } + } +} \ No newline at end of file diff --git a/Patches/GameOptionsMenuPatch.cs b/Patches/GameOptionsMenuPatch.cs index 8d4a65d..210b93f 100644 --- a/Patches/GameOptionsMenuPatch.cs +++ b/Patches/GameOptionsMenuPatch.cs @@ -11,9 +11,9 @@ namespace HNSRevamped public static class ModGameOptionsMenu { public static int TabIndex = 0; - public static Dictionary OptionList = new(); - public static Dictionary BehaviourList = new(); - public static Dictionary CategoryHeaderList = new(); + public static Il2CppSystem.Collections.Generic.Dictionary OptionList = new(); + public static Il2CppSystem.Collections.Generic.Dictionary BehaviourList = new(); + public static Il2CppSystem.Collections.Generic.Dictionary CategoryHeaderList = new(); } [HarmonyPatch(typeof(GameOptionsMenu))] @@ -26,7 +26,7 @@ namespace HNSRevamped if (__instance.Children == null || __instance.Children.Count == 0) { __instance.MapPicker.gameObject.SetActive(false); - __instance.Children = new List(); + __instance.Children = new Il2CppSystem.Collections.Generic.List(); __instance.CreateSettings(); __instance.cachedData = GameOptionsManager.Instance.CurrentGameOptions; for (int i = 0; i < __instance.Children.Count; i++) diff --git a/Patches/GameSettingMenuPatch.cs b/Patches/GameSettingMenuPatch.cs index 8247120..6ea9aa1 100644 --- a/Patches/GameSettingMenuPatch.cs +++ b/Patches/GameSettingMenuPatch.cs @@ -121,7 +121,9 @@ namespace HNSRevamped case TabGroup.ModSettings: __instance.MenuDescriptionText.text = "Mod Settings"; break; - + case TabGroup.HNSSettings: + __instance.MenuDescriptionText.text = "HNS Settings"; + break; } } } diff --git a/Patches/KickPlayerPatch.cs b/Patches/KickPlayerPatch.cs index d3df023..ab685f7 100644 --- a/Patches/KickPlayerPatch.cs +++ b/Patches/KickPlayerPatch.cs @@ -1,6 +1,4 @@ -using HarmonyLib; -using InnerNet; -using System.Collections.Generic; +using InnerNet; using UnityEngine; // https://github.com/tukasa0001/TownOfHost/blob/main/Patches/ClientPatch.cs @@ -19,7 +17,7 @@ internal class KickPlayerPatch AttemptedKickPlayerList.Add(HashedPuid, 0); else if (AttemptedKickPlayerList[HashedPuid] < 10) { - Logger.Fatal($"Kick player Request too fast! Canceled.", "KickPlayerPatch"); + Logger.Fatal($"Kick player Request was too fast and has been canceled.", "KickPlayerPatch"); return false; } if (ban) BanManager.AddBanPlayer(AmongUsClient.Instance.GetRecentClient(clientId)); diff --git a/Patches/NumberOptionsPatch.cs b/Patches/NumberOptionsPatch.cs index 89d0074..e37f7c8 100644 --- a/Patches/NumberOptionsPatch.cs +++ b/Patches/NumberOptionsPatch.cs @@ -49,4 +49,4 @@ public static class NumberOption_Initialize __instance.ValidRange = new FloatRange(-999f, 999f); } } -} \ No newline at end of file +}