From 294b5df4d934ac5657cbed03f78fa6597141ed22 Mon Sep 17 00:00:00 2001 From: Ape <155788660+ApeMV@users.noreply.github.com> Date: Wed, 21 Jan 2026 22:17:29 +0100 Subject: [PATCH] Send intercontinental missile to hackers & some other stuff --- AmongUsRevamped.cs | 2 +- Modules/CustomOptionsHolder.cs | 70 +++++++++-- Modules/EACR.cs | 204 +++++++++++++++++++++++++++++++ Modules/Hotkeys.cs | 4 +- Modules/OptionItem/OptionItem.cs | 1 + Modules/Utils.cs | 3 + Patches/CredentialsPatch.cs | 13 ++ Patches/EndGamePatches.cs | 3 +- Patches/GameSettingMenuPatch.cs | 9 +- Patches/SabotagePatches.cs | 25 +++- 10 files changed, 315 insertions(+), 19 deletions(-) create mode 100644 Modules/EACR.cs diff --git a/AmongUsRevamped.cs b/AmongUsRevamped.cs index 7e11c33..7d67f1f 100644 --- a/AmongUsRevamped.cs +++ b/AmongUsRevamped.cs @@ -35,7 +35,7 @@ public partial class Main : BasePlugin public static NormalGameOptionsV10 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null; public static bool HasArgumentException; public static string CredentialsText; - public const string ModVersion = "v1.3.2"; + public const string ModVersion = "v1.3.3"; public static float GameTimer; diff --git a/Modules/CustomOptionsHolder.cs b/Modules/CustomOptionsHolder.cs index a4a0e67..c3cfd34 100644 --- a/Modules/CustomOptionsHolder.cs +++ b/Modules/CustomOptionsHolder.cs @@ -21,6 +21,28 @@ namespace AmongUsRevamped taskOptionsLoad.Wait(); } + public static class CL + { + public static Color32 Hex(string hex) + { + if (hex.StartsWith("#")) + hex = hex.Substring(1); + + if (hex.Length == 3) + { + hex = $"{hex[0]}{hex[0]}{hex[1]}{hex[1]}{hex[2]}{hex[2]}"; + } + + if (hex.Length != 6) + throw new System.ArgumentException("Hex color must be 6 or 3 characters long."); + + byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber); + byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber); + byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber); + + return new Color32(r, g, b, 255); + } +} public const int PresetId = 0; private static readonly string[] presets = @@ -70,12 +92,14 @@ namespace AmongUsRevamped public static OptionItem AllowFortegreen; public static OptionItem NoGameEnd; - //Mod + //Gameplay + public static OptionItem TabGroupGameplayGeneral; public static OptionItem DisableSabotage; public static OptionItem DisableCloseDoor; public static OptionItem DisableReport; + public static OptionItem TabGroupTasks; public static OptionItem OverrideTaskSettings; public static OptionItem AllPlayersSameTasks; @@ -201,6 +225,13 @@ namespace AmongUsRevamped public static OptionItem SpeedrunSettingsOverride; public static OptionItem GameAutoEndsAfter; + // Roles + public static OptionItem TabGroupCrewmate; + + public static OptionItem TabGroupNeutral; + public static OptionItem JesterPerc; + + public static OptionItem TabGroupImpostor; public static bool IsLoaded = false; @@ -254,6 +285,24 @@ namespace AmongUsRevamped NoGameEnd = BooleanOptionItem.Create(60383, "No Game End", false, TabGroup.SystemSettings, false) .SetColor(Color.red); + + + + // Custom role settings + TabGroupCrewmate = TextOptionItem.Create(100000, "Crewmate Roles", TabGroup.CustomRoleSettings) + .SetColor(CL.Hex("#8cffff")); + + TabGroupNeutral = TextOptionItem.Create(101000, "Neutral Roles", TabGroup.CustomRoleSettings) + .SetColor(CL.Hex("#FFFF99")); + JesterPerc = IntegerOptionItem.Create(101001, "PLACEHOLDER", new(0, 100, 5), 0, TabGroup.CustomRoleSettings, false) + .SetValueFormat(OptionFormat.Percent) + .SetColor(CL.Hex("#ec62a5")); + + TabGroupImpostor = TextOptionItem.Create(102000, "Impostor Roles", TabGroup.CustomRoleSettings) + .SetColor(CL.Hex("#ff1919")); + + + // Gamemode Settings TabGroupHNS = TextOptionItem.Create(70000, "Hide and Seek", TabGroup.GamemodeSettings) .SetColor(Color.green); @@ -282,23 +331,22 @@ namespace AmongUsRevamped // Gameplay Settings + TabGroupGameplayGeneral = TextOptionItem.Create(60564, "General", TabGroup.ModSettings) + .SetColor(Color.blue); DisableSabotage = BooleanOptionItem.Create(60565, "Disable Critical Sabotages", false, TabGroup.ModSettings, false) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)) - .SetHeader(true); + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableCloseDoor = BooleanOptionItem.Create(60566, "Disable Door Sabotages", false, TabGroup.ModSettings, false) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableReport = BooleanOptionItem.Create(60520, "Disable Body Reports", false, TabGroup.ModSettings, false) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); - - OverrideTaskSettings = BooleanOptionItem.Create(22998, "<#ffd>Ove<#ffb>rri<#ff9>de T<#ffb>ask <#ffd>Set<#ffb>tin<#ff9>gs", false, TabGroup.ModSettings, false) - .SetColor(new Color32(239, 89, 175, byte.MaxValue)) - .SetHeader(true); - - AllPlayersSameTasks = BooleanOptionItem.Create(22999, "Everyone has same tasks", false, TabGroup.ModSettings, false) - .SetColor(new Color32(255, 255, 153, byte.MaxValue)) - .SetParent(OverrideTaskSettings); + TabGroupTasks = TextOptionItem.Create(22997, "Tasks", TabGroup.ModSettings) + .SetColor(Color.yellow); + AllPlayersSameTasks = BooleanOptionItem.Create(22998, "Everyone has same tasks", false, TabGroup.ModSettings, false) + .SetColor(new Color32(255, 255, 153, byte.MaxValue)); + OverrideTaskSettings = BooleanOptionItem.Create(22999, "<#ffd>Di<#ffb>sa<#ff9>bl<#ffb>e T<#ffd>as<#ffb>ks", false, TabGroup.ModSettings, false) + .SetColor(new Color32(239, 89, 175, byte.MaxValue)); DisableMiraTasks = BooleanOptionItem.Create(23000, "Disable Mira HQ Tasks", false, TabGroup.ModSettings, false) .SetColor(new Color32(173, 216, 230, byte.MaxValue)) diff --git a/Modules/EACR.cs b/Modules/EACR.cs new file mode 100644 index 0000000..a840b27 --- /dev/null +++ b/Modules/EACR.cs @@ -0,0 +1,204 @@ +using Hazel; +using System; +using UnityEngine; + +namespace AmongUsRevamped; + +internal class EACR +{ + public static bool PlayerControlReceiveRpc(PlayerControl pc, byte callId, MessageReader reader) + { + if (!AmongUsClient.Instance.AmHost) return false; + if (pc == null || reader == null) return false; + + try + { + MessageReader sr = MessageReader.Get(reader); + var rpc = (RpcCalls)callId; + switch (rpc) + { + case RpcCalls.StartMeeting: + { + AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true); + Logger.SendInGame($"{pc.Data.PlayerName} was banned for being calling an invalid meeting (cheating)"); + Logger.Info($" {pc.Data.PlayerName} was banned for being calling an invalid meeting (cheating)", "EACR"); + return true; + } + } + switch (callId) + { + case 101: // Aum Chat + try + { + var firstString = sr.ReadString(); + var secondString = sr.ReadString(); + sr.ReadInt32(); + + var flag = string.IsNullOrEmpty(firstString) && string.IsNullOrEmpty(secondString); + + if (!flag) + { + AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true); + Logger.SendInGame($"{pc.Data.PlayerName} was banned for AUM chat CallId (cheating)"); + Logger.Info($" {pc.Data.PlayerName} was banned for AUM chat CallId (cheating)", "EACR"); + return true; + } + } + catch + { + + } + break; + case unchecked((byte)42069): // 85 AUM + try + { + var aumid = sr.ReadByte(); + + if (aumid == pc.PlayerId) + { + AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true); + Logger.SendInGame($"{pc.Data.PlayerName} was banned for AUM CallId (cheating)"); + Logger.Info($" {pc.Data.PlayerName} was banned for AUM CallId (cheating)", "EACR"); + return true; + } + } + catch + { + + } + break; + case 119: // KN Chat + try + { + var firstString = sr.ReadString(); + var secondString = sr.ReadString(); + sr.ReadInt32(); + + var flag = string.IsNullOrEmpty(firstString) && string.IsNullOrEmpty(secondString); + + if (!flag) + { + AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true); + Logger.SendInGame($"{pc.Data.PlayerName} was banned for KN chat CallId (cheating)"); + Logger.Info($" {pc.Data.PlayerName} was banned for KN chat CallId (cheating)", "EACR"); + return true; + } + } + catch + { + + } + break; + case 250: // KN + if (sr.BytesRemaining == 0) + { + AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true); + Logger.SendInGame($"{pc.Data.PlayerName} was banned for KN CallId (cheating)"); + Logger.Info($" {pc.Data.PlayerName} was banned for KN CallId (cheating)", "EACR"); + return true; + } + break; + case unchecked((byte)420): // 164 Sicko + if (sr.BytesRemaining == 0) + { + AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true); + Logger.SendInGame($"{pc.Data.PlayerName} was banned for Sickomenu RPC (cheating)"); + Logger.Info($" {pc.Data.PlayerName} was banned for Sickomenu RPC (cheating)", "EACR"); + return true; + } + break; + } + } + catch (Exception e) + { + Logger.Exception(e, "EACR"); + } + return false; + } + public static bool RpcUpdateSystemCheck(PlayerControl player, SystemTypes systemType, byte amount) + { + var Mapid = Utils.GetActiveMapId(); + + if (!AmongUsClient.Instance.AmHost) + { + return false; + } + + if (player == null) + { + Logger.Warn("PlayerControl is null", "EACR-RpcUpdateSystemCheck"); + return true; + } + + if (systemType == SystemTypes.Sabotage) + { + if (!player.Data.Role.IsImpostor && !player.isNew) + { + AmongUsClient.Instance.KickPlayer(player.Data.ClientId, true); + Logger.SendInGame($"{player.Data.PlayerName} was banned for invalid sabotage (cheating)"); + Logger.Info($" {player.Data.PlayerName} was banned for invalid sabotage", "EACR"); + } + } + else if (systemType == SystemTypes.LifeSupp) + { + if (Mapid != 0 && Mapid != 1 && Mapid != 3) goto YesCheat; + else if (amount != 64 && amount != 65) goto YesCheat; + } + else if (systemType == SystemTypes.Comms) + { + if (amount == 0) + { + if (Mapid == 1 || Mapid == 5) goto YesCheat; + } + else if (amount == 64 || amount == 65 || amount == 32 || amount == 33 || amount == 16 || amount == 17) + { + if (!(Mapid == 1 || Mapid == 5)) goto YesCheat; + } + else goto YesCheat; + } + else if (systemType == SystemTypes.Electrical) + { + if (Mapid == 5) goto YesCheat; + if (amount >= 5) + { + goto YesCheat; + } + } + else if (systemType == SystemTypes.Laboratory) + { + if (Mapid != 2) goto YesCheat; + else if (!(amount == 64 || amount == 65 || amount == 32 || amount == 33)) goto YesCheat; + } + else if (systemType == SystemTypes.Reactor) + { + if (Mapid == 2 || Mapid == 4) goto YesCheat; + else if (!(amount == 64 || amount == 65 || amount == 32 || amount == 33)) goto YesCheat; + } + else if (systemType == SystemTypes.HeliSabotage) + { + if (Mapid != 4) goto YesCheat; + else if (!(amount == 64 || amount == 65 || amount == 16 || amount == 17 || amount == 32 || amount == 33)) goto YesCheat; + } + else if (systemType == SystemTypes.MushroomMixupSabotage) + { + goto YesCheat; + } + + if (Utils.IsMeeting && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) + { + Logger.SendInGame($"{player.Data.PlayerName} might have called an invalid sabotage (cheating)"); + Logger.Info($" {player.Data.PlayerName} might have called an invalid sabotage (cheating)", "EACR"); + return true; + } + + return false; + + YesCheat: + { + AmongUsClient.Instance.KickPlayer(player.Data.ClientId, true); + Logger.SendInGame($"{player.Data.PlayerName} was banned for an invalid sabotage (cheating)"); + Logger.Info($" {player.Data.PlayerName} was banned for an invalid sabotage", "EACR"); + return true; + } + } +} \ No newline at end of file diff --git a/Modules/Hotkeys.cs b/Modules/Hotkeys.cs index 02b4fa7..d35d48a 100644 --- a/Modules/Hotkeys.cs +++ b/Modules/Hotkeys.cs @@ -10,7 +10,9 @@ internal class Hotkeys { public static void Postfix() { + // I don't know which psychopath would use right keys, but I know someday, someone will complain bool Shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); + bool Ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); bool Enter = Input.GetKeyDown(KeyCode.Return); if (Input.GetKey(KeyCode.L) && Shift && Enter) @@ -39,7 +41,7 @@ internal class Hotkeys if ((!AmongUsClient.Instance.IsGameStarted || !Utils.IsOnlineGame) && Utils.CanMove && PlayerControl.LocalPlayer.Collider != null) { - PlayerControl.LocalPlayer.Collider.enabled = !Input.GetKey(KeyCode.LeftControl); + PlayerControl.LocalPlayer.Collider.enabled = !Ctrl; } if (Input.GetKeyDown(KeyCode.C) && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening && Utils.IsLobby) diff --git a/Modules/OptionItem/OptionItem.cs b/Modules/OptionItem/OptionItem.cs index 27374a7..6bec10f 100644 --- a/Modules/OptionItem/OptionItem.cs +++ b/Modules/OptionItem/OptionItem.cs @@ -214,6 +214,7 @@ namespace AmongUsRevamped public enum TabGroup { SystemSettings, + CustomRoleSettings, ModSettings, GamemodeSettings, diff --git a/Modules/Utils.cs b/Modules/Utils.cs index a2e0f77..824f5ac 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -46,6 +46,7 @@ public static class Utils public static string ColorString(Color32 color, string str) => $"<#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}>{str}"; public static string ColorToHex(Color32 color) => $"#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}"; + public static byte GetActiveMapId() => GameOptionsManager.Instance.CurrentGameOptions.MapId; public static bool IsPlayerModerator(string friendCode) { @@ -79,6 +80,8 @@ public static class Utils { case TabGroup.SystemSettings: return "System Settings"; + case TabGroup.CustomRoleSettings: + return "Custom Roles"; case TabGroup.ModSettings: return "Gameplay Settings"; case TabGroup.GamemodeSettings: diff --git a/Patches/CredentialsPatch.cs b/Patches/CredentialsPatch.cs index a44c136..5ce6815 100644 --- a/Patches/CredentialsPatch.cs +++ b/Patches/CredentialsPatch.cs @@ -182,6 +182,19 @@ public static class MainMenuManagerStartPatch bg.SetActive(false); } + var leftPanel = GameObject.Find("LeftPanel"); + if (leftPanel != null) + { + leftPanel.gameObject.GetComponent().enabled = false; + } + + var div = GameObject.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/Divider"); + if (div != null) + { + div.SetActive(false); + } + + Transform tintTrans = __instance.transform.Find("MainUI/Tint"); var tint = tintTrans.gameObject; if (tint != null) diff --git a/Patches/EndGamePatches.cs b/Patches/EndGamePatches.cs index 02d241e..e4f1429 100644 --- a/Patches/EndGamePatches.cs +++ b/Patches/EndGamePatches.cs @@ -10,6 +10,7 @@ public static class EndGameManagerPatch { public static void Postfix(EndGameManager __instance) { + Logger.Info(" -------- GAME ENDED --------", "EndGame"); Utils.ClearLeftoverData(); EndGameNavigation navigation = __instance.Navigation; @@ -54,8 +55,6 @@ class NormalGameEndChecker { LastWinReason = $"ā˜… Impostors win! (Sabotage)\n\nImpostors:\nā˜…" + string.Join("\nā˜…", imps.Select(p => p.Data.PlayerName)); } - - Logger.Info(" -------- GAME ENDED --------", "EndGame"); return true; } } diff --git a/Patches/GameSettingMenuPatch.cs b/Patches/GameSettingMenuPatch.cs index d12337a..bbcff23 100644 --- a/Patches/GameSettingMenuPatch.cs +++ b/Patches/GameSettingMenuPatch.cs @@ -114,13 +114,16 @@ namespace AmongUsRevamped switch ((TabGroup)(tabNum - 3)) { case TabGroup.SystemSettings: - __instance.MenuDescriptionText.text = "Quality settings to improve comfort and testing"; + __instance.MenuDescriptionText.text = "Quality settings to improve comfort and testing."; + break; + case TabGroup.CustomRoleSettings: + __instance.MenuDescriptionText.text = "Custom Role enabling and settings."; break; case TabGroup.ModSettings: - __instance.MenuDescriptionText.text = "Gameplay Settings to improve the in-game experience"; + __instance.MenuDescriptionText.text = "Gameplay Settings to improve the in-game experience."; break; case TabGroup.GamemodeSettings: - __instance.MenuDescriptionText.text = "Situational settings to apply for specific gamemodes"; + __instance.MenuDescriptionText.text = "Situational settings to apply for specific gamemodes."; break; } } diff --git a/Patches/SabotagePatches.cs b/Patches/SabotagePatches.cs index d460374..457dd14 100644 --- a/Patches/SabotagePatches.cs +++ b/Patches/SabotagePatches.cs @@ -4,7 +4,7 @@ using UnityEngine; namespace AmongUsRevamped; -[HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] // SetInitialSabotageCooldown - set sabotage cooldown in start game +[HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] public static class SabotageSystemTypeRepairDamagePatch { private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) @@ -45,4 +45,27 @@ class ShipStatusCloseDoorsPatch } else return true; } +} + +[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.UpdateSystem), typeof(SystemTypes), typeof(PlayerControl), typeof(MessageReader))] +public static class MessageReaderUpdateSystemPatch +{ + public static bool Prefix(ShipStatus __instance, [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] MessageReader reader) + { + if (systemType is + SystemTypes.Ventilation + or SystemTypes.Security + or SystemTypes.Decontamination + or SystemTypes.Decontamination2 + or SystemTypes.Decontamination3 + or SystemTypes.MedBay) return true; + + var amount = MessageReader.Get(reader).ReadByte(); + if (EACR.RpcUpdateSystemCheck(player, systemType, amount)) + { + Logger.Info("EACR patched Sabotage RPC", "MessageReaderUpdateSystemPatch"); + return false; + } + else return true; + } } \ No newline at end of file