From f18dc3fa31bb7dd8782dfa473d648d80acf12903 Mon Sep 17 00:00:00 2001 From: Ape <155788660+ApeMV@users.noreply.github.com> Date: Fri, 21 Aug 2026 18:44:45 +0200 Subject: [PATCH] v2.0.2 --- AmongUsRevamped.cs | 2 +- Modules/CustomOptionsHolder.cs | 2 - Modules/FixedUpdate.cs | 49 ++++++++++++++--------- Modules/Utils.cs | 21 +++++++++- Patches/ChatPatches.cs | 8 ++-- Patches/DevicePatches.cs | 2 +- Patches/GameStartManagerPatch.cs | 10 +++++ Patches/IntroPatch.cs | 14 +++++-- Patches/JoinAndLeavePatches.cs | 3 +- Patches/OnGameStartedPatch.cs | 26 +++++------- Patches/PlayerControlPatches.cs | 2 +- README.md | 2 +- Resources/Language/Japanese.json | 10 ++++- Resources/Language/SimplifiedChinese.json | 10 ++++- Resources/Language/Spanish.json | 17 +++++--- 15 files changed, 119 insertions(+), 59 deletions(-) diff --git a/AmongUsRevamped.cs b/AmongUsRevamped.cs index 7dc3c9f..9773363 100644 --- a/AmongUsRevamped.cs +++ b/AmongUsRevamped.cs @@ -44,7 +44,7 @@ public partial class Main : BasePlugin public static bool HasArgumentException; public static string CredentialsText; - public const string ModVersion = "v2.0.1"; + public const string ModVersion = "v2.0.2"; public static float GameTimer; public static float AfkTimer; diff --git a/Modules/CustomOptionsHolder.cs b/Modules/CustomOptionsHolder.cs index 81a6981..9863121 100644 --- a/Modules/CustomOptionsHolder.cs +++ b/Modules/CustomOptionsHolder.cs @@ -301,7 +301,6 @@ namespace AmongUsRevamped public static OptionItem SNSChatInGameExtend2; public static OptionItem SNSChatInGameFast; public static OptionItem CrewAutoWinsGameAfter; - public static OptionItem MisfiresToSuicide; public static OptionItem SNSDisableSabotage; public static OptionItem SNSDisableReactor; public static OptionItem SNSDisableOxygen; @@ -476,7 +475,6 @@ namespace AmongUsRevamped .SetParent(SNSChatInGame); SNSChatInGameFast = BooleanOptionItem.Create(70054, Translator.Get("snsChatInGameFast"), false, TabGroup.GamemodeSettings, false) .SetParent(SNSChatInGame); - MisfiresToSuicide = IntegerOptionItem.Create(70055, Translator.Get("misfiresToSuicide"), new(1, 10, 1), 1, TabGroup.GamemodeSettings, false); CrewAutoWinsGameAfter = IntegerOptionItem.Create(70056, Translator.Get("crewAutoWinsGameAfter"), new(60, 600, 10), 300, TabGroup.GamemodeSettings, false) .SetValueFormat(OptionFormat.Seconds); SNSDisableSabotage = BooleanOptionItem.Create(70057, Translator.Get("snsDisableSabotage"), true, TabGroup.GamemodeSettings, false) diff --git a/Modules/FixedUpdate.cs b/Modules/FixedUpdate.cs index f538fe7..755d1ce 100644 --- a/Modules/FixedUpdate.cs +++ b/Modules/FixedUpdate.cs @@ -128,6 +128,7 @@ public static class FixedUpdate if (p.protectedByGuardianId == -1) { p.RpcProtectPlayer(p, p.cosmetics.ColorId); + p.Data.MarkDirty(); } } } @@ -165,12 +166,6 @@ class FixedUpdateInGamePatch private static float t; private static GameObject settingsLabel; - public static bool CanUseKillButton(PlayerControl pc) - { - pc.Data.Role.CanUseKillButton = false; - return false; - } - public static void Postfix(PlayerControl __instance) { if (__instance == null || __instance.PlayerId == 255 || !AmongUsClient.Instance.AmHost) return; @@ -208,13 +203,15 @@ class FixedUpdateInGamePatch break; case 1: // SnS - if (Utils.InGame) return; - if (Main.NormalOptions.KillCooldown != 2.5f) + if (!Utils.InGame) { - Main.NormalOptions.KillCooldown = 2.5f; - Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Shapeshifter, 3, 100); - Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Phantom, 0, 0); - Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Viper, 0, 0); + if (Main.NormalOptions.KillCooldown != 2.5f) + { + Main.NormalOptions.KillCooldown = 2.5f; + Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Shapeshifter, 3, 100); + Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Phantom, 0, 0); + Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Viper, 0, 0); + } } break; @@ -222,18 +219,20 @@ class FixedUpdateInGamePatch break; case 3: // PnS - if (Utils.InGame) return; - if (Main.NormalOptions.KillCooldown != 1f) + if (!Utils.InGame) { - Main.NormalOptions.KillCooldown = 1f; - Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Shapeshifter, 0, 0); - Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Phantom, 3, 100); - Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Viper, 0, 0); + if (Main.NormalOptions.KillCooldown != 1f) + { + Main.NormalOptions.KillCooldown = 1f; + Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Shapeshifter, 0, 0); + Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Phantom, 3, 100); + Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Viper, 0, 0); + } } break; } - if (Utils.InGame && !Utils.IsMeeting && !ExileController.Instance) + if (Utils.InGame && !Utils.IsMeeting && !ExileController.Instance && Main.GameTimer > 6) { // 1 = Shift and Seek if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek && Options.CrewAutoWinsGameAfter.GetInt() != 0 && !Options.NoGameEnd.GetBool()) @@ -260,7 +259,7 @@ class FixedUpdateInGamePatch } } // 3 = Poof and Seek - if (Options.Gamemode.GetValue() == 3 && !Utils.isHideNSeek) + if (Options.Gamemode.GetValue() == 3 && !Utils.isHideNSeek && !Options.NoGameEnd.GetBool()) { if (Main.GameTimer > Options.PNSCrewAutoWinsGameAfter.GetInt()) { @@ -271,6 +270,16 @@ class FixedUpdateInGamePatch NormalGameEndChecker.CheckWinnerText("PnSTimer"); } } + + if ((Options.SNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 1) || (Options.PNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 3)) + { + if (Main.GM.Value && !Utils.IsDead) + { + Logger.Info($" Game Master Successful", "StartGame"); + PlayerControl.LocalPlayer.Exiled(); + PlayerControl.LocalPlayer.RpcSetRole(RoleTypes.CrewmateGhost); + } + } } } } \ No newline at end of file diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 7523fc6..2a4e257 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -38,7 +38,6 @@ public static class Utils public static bool IsFreePlay => AmongUsClient.Instance.NetworkMode == NetworkModes.FreePlay; public static bool IsMeeting => InGame && (MeetingHud.Instance); - public static bool GamePastRoleSelection => Main.GameTimer > 10f; public static bool HandlingGameEnd; public static byte CustomGameOverReason; public static bool CanCallMeetings; @@ -201,6 +200,8 @@ public static class Utils public static void ClearLeftoverData() { + Logger.Info(" Cleared Leftover Data", "Utils"); + RpcSetTasksPatch.GlobalTaskIds = null; HandlingGameEnd = false; OnGameJoinedPatch.AutoStartCheck = false; @@ -217,7 +218,6 @@ public static class Utils NormalGameEndChecker.ImpCheckComplete = false; CreateOptionsPickerPatch.SetDleks2 = false; CanCallMeetings = true; - PlayerControlSetRolePatch.FirstAssign = true; PlayerControlCompleteTaskPatch.playerTasksCompleted.Clear(); PlayerControlCompleteTaskPatch.tasksPerPlayer.Clear(); @@ -227,6 +227,7 @@ public static class Utils OnPlayerJoinedPatch.JoinNum = 0; + PlayerControlSetRolePatch.ProcessedPlayers.Clear(); PlayerControlSetRolePatch.Seekers.Clear(); PlayerControlSetRolePatch.FirstAssign = true; PlayerControlSetRolePatch.manualSeekers.Clear(); @@ -760,4 +761,20 @@ public static class Utils ModeVoteActive = false; }, Options.ModeVoteDuration.GetInt(), "ModePoll"); } + + // As of v2026.8.18, Innersloth bans the host for hacking if the start game button is pressed when any player is not Serialized (or something similar). + // CheckValidData serves as an emergency blockage to prevent this and stop host from being kicked. + public static bool CheckValidData() + { + if (!AmongUsClient.Instance.AmHost) return true; + + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p == null || !p.hasBeenSerialized) + { + return false; + } + } + return true; + } } \ No newline at end of file diff --git a/Patches/ChatPatches.cs b/Patches/ChatPatches.cs index 3567c78..3ad0bbb 100644 --- a/Patches/ChatPatches.cs +++ b/Patches/ChatPatches.cs @@ -525,7 +525,7 @@ internal static class SendChatPatch if (text == "/0kc" || text == "/0killcooldown") { - Utils.ChatCommand(__instance, "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false); + Utils.ChatCommand(__instance, "0 Kill Cooldown:\n\nImpostors have no kill cooldown, and can't kill after a game starts for 5 seconds", "", false); return false; } @@ -559,7 +559,7 @@ internal static class SendChatPatch case 0: if (GameOptionsManager.Instance.CurrentGameOptions.GetFloat(FloatOptionNames.KillCooldown) == 0.01f) { - Utils.ChatCommand(__instance, "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false); + Utils.ChatCommand(__instance, "0 Kill Cooldown:\n\nImpostors have no kill cooldown, and can't kill after a game starts for 5 seconds", "", false); } break; @@ -957,7 +957,7 @@ public static class RPCHandlerPatch if (text == "/0kc" || text == "/0killcooldown") { if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return; - Utils.ModeratorChatCommand("0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false); + Utils.ModeratorChatCommand("0 Kill Cooldown:\n\nImpostors have no kill cooldown, and can't kill after a game starts for 5 seconds", "", false); } if (text == "/sns" || text == "/shiftandseek") { @@ -990,7 +990,7 @@ public static class RPCHandlerPatch case 0: if (GameOptionsManager.Instance.CurrentGameOptions.GetFloat(FloatOptionNames.KillCooldown) == 0.01f) { - Utils.ModeratorChatCommand("0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false); + Utils.ModeratorChatCommand("0 Kill Cooldown:\n\nImpostors have no kill cooldown, and can't kill after a game starts for 5 seconds", "", false); } break; diff --git a/Patches/DevicePatches.cs b/Patches/DevicePatches.cs index 7f13608..05bac97 100644 --- a/Patches/DevicePatches.cs +++ b/Patches/DevicePatches.cs @@ -49,7 +49,7 @@ internal static class DisableDevice public static void FixedUpdate() { - if (!AmongUsClient.Instance.AmHost || ShipStatus.Instance == null || !Utils.GamePastRoleSelection) return; + if (!AmongUsClient.Instance.AmHost || ShipStatus.Instance == null || !OnGameStartPatch.PastStartScreen) return; frame = frame == 5 ? 0 : ++frame; if (frame != 0) return; diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs index a490718..1030ea0 100644 --- a/Patches/GameStartManagerPatch.cs +++ b/Patches/GameStartManagerPatch.cs @@ -20,12 +20,22 @@ public static class GameStartManagerUpdatePatch __instance.MinPlayers = 1; + if (!Utils.CheckValidData()) + { + __instance.StartButton.gameObject.SetActive(false); + } + else if (__instance.startState != GameStartManager.StartingStates.Countdown) + { + __instance.StartButton.gameObject.SetActive(true); + } + if (Main.AutoStart.Value && OnGameJoinedPatch.AutoStartCheck && GameStartManager.InstanceExists && __instance.startState != GameStartManager.StartingStates.Countdown && GameData.Instance?.PlayerCount >= Options.PlayerAutoStart.GetInt()) { __instance.startState = GameStartManager.StartingStates.Countdown; __instance.countDownTimer = Options.AutoStartTimer.GetFloat(); __instance.StartButton.gameObject.SetActive(false); Autostarting = true; + return; } if (__instance.startState == GameStartManager.StartingStates.Countdown) diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index 18e4617..009f8ca 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -39,6 +39,7 @@ internal static class CoShowIntroPatch OptionManager.SyncGameOptions(); p.RpcProtectPlayer(p, p.cosmetics.ColorId); + p.Data.MarkDirty(); Logger.Info($" {p.Data.PlayerName} has been granted a shield for {Options.ShieldFirstDeathDuration.GetInt()}s", "RoleInfo"); } @@ -65,9 +66,16 @@ internal static class CoShowIntroPatch { if (Main.NormalOptions.roleOptions.TryGetRoleOptions(RoleTypes.GuardianAngel, out var GuardianAngelOptions)) { - GuardianAngelOptions.ProtectionDurationSeconds = 10f; + GuardianAngelOptions.ProtectionDurationSeconds = 254f; } OptionManager.SyncGameOptions(); + + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.Data == null || p.Data.IsDead || p.Data.RoleType == RoleTypes.Shapeshifter) continue; + p.RpcProtectPlayer(p, p.cosmetics.ColorId); + p.Data.MarkDirty(); + } if (Options.SNSChatInGameExtend.GetBool()) { @@ -84,7 +92,7 @@ internal static class CoShowIntroPatch if ((GameOptionsManager.Instance.CurrentGameOptions.GetFloat(FloatOptionNames.KillCooldown) == 0.01f)) { - Main.NormalOptions.KillCooldown = 8f; + Main.NormalOptions.KillCooldown = 5f; OptionManager.SyncGameOptions(); _ = new LateTask(() => @@ -98,7 +106,7 @@ internal static class CoShowIntroPatch { if (Options.PNSChatInGame.GetBool()) { - Main.NormalOptions.KillCooldown = 8f; + Main.NormalOptions.KillCooldown = 5f; OptionManager.SyncGameOptions(); _ = new LateTask(() => diff --git a/Patches/JoinAndLeavePatches.cs b/Patches/JoinAndLeavePatches.cs index 00d21b7..8930ffb 100644 --- a/Patches/JoinAndLeavePatches.cs +++ b/Patches/JoinAndLeavePatches.cs @@ -14,7 +14,7 @@ internal static class OnGameJoinedPatch public static bool AutoStartCheck; public static void Postfix() { - Logger.Info(" -------- JOINED GAME --------", "OnGameJoined"); + Logger.Info(" -------- GAME JOINED --------", "OnGameJoined"); if (!AmongUsClient.Instance.AmHost) return; @@ -100,7 +100,6 @@ class OnPlayerJoinedPatch return false; } - static void Postfix([HarmonyArgument(0)] ClientData Client) { Logger.Info($" {Client.PlayerName} / {Client.FriendCode} / {Client.PlatformData.Platform}", "Joined The Game"); diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index 07d5079..c603ff7 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -33,7 +33,7 @@ internal class CoStartGamePatch class PlayerControlSetRolePatch { public static bool FirstAssign; - private static readonly HashSet ProcessedPlayers = new(); + public static readonly HashSet ProcessedPlayers = new(); public static HashSet Seekers = new(); public static HashSet manualSeekers = new(); private static readonly System.Random rand = new System.Random(); @@ -101,16 +101,10 @@ class PlayerControlSetRolePatch else roleType = RoleTypes.Crewmate; } - if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek) - { - if (roleType == RoleTypes.Impostor || roleType == RoleTypes.Phantom || roleType == RoleTypes.Viper) roleType = RoleTypes.Shapeshifter; - } - if (ProcessedPlayers.Count >= PlayerControl.AllPlayerControls.Count) { Seekers.Clear(); - ProcessedPlayers.Clear(); - + FirstAssign = false; Logger.Info(" PCSRP successful", "RoleManaging"); } @@ -136,19 +130,21 @@ internal static class OnGameStartPatch if (MeetingHud.Instance != null) MeetingHud.Instance.RpcClose(); } - if (AmongUsClient.Instance.AmHost && Main.GM.Value) - { - Logger.Info($" Game Master Successful", "StartGame"); - PlayerControl.LocalPlayer.Exiled(); - PlayerControl.LocalPlayer.RpcSetRole(RoleTypes.CrewmateGhost); - } - foreach (var p in PlayerControl.AllPlayerControls) { Utils.StoredRoleText[p.PlayerId] = Utils.GetRoleText(p); } PastStartScreen = true; + + if (AmongUsClient.Instance.AmHost && Main.GM.Value) + { + if ((Options.SNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 1) || (Options.PNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 3)) return; + + Logger.Info($" Game Master Successful", "StartGame"); + PlayerControl.LocalPlayer.Exiled(); + PlayerControl.LocalPlayer.RpcSetRole(RoleTypes.CrewmateGhost); + } } // All Patches below are for the speeded up Chat In Game. diff --git a/Patches/PlayerControlPatches.cs b/Patches/PlayerControlPatches.cs index 69b19a6..d4dac53 100644 --- a/Patches/PlayerControlPatches.cs +++ b/Patches/PlayerControlPatches.cs @@ -197,7 +197,7 @@ class PlayerControlCompleteTaskPatch public static void CalculateTaskWin() { - if (!Utils.GamePastRoleSelection || Utils.isHideNSeek || Options.NoGameEnd.GetBool() || !OnGameStartPatch.PastStartScreen) return; + if (!OnGameStartPatch.PastStartScreen || Utils.isHideNSeek || Options.NoGameEnd.GetBool() || !OnGameStartPatch.PastStartScreen) return; //Logger.Info($" Checking if {GameData.Instance.CompletedTasks} - {ignoredCompletedTasks} >= ({GameData.Instance.TotalTasks} - {ignoredTasks}) * 0.01 * {Options.TaskPercentNeededToWin.GetInt()}", "TaskPatch"); diff --git a/README.md b/README.md index 4fd8647..9dfb1d9 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ **** ‎ -# 🎮 Features (v2.0.1): +# 🎮 Features (v2.0.2): ## ♠️ Client Side settings: - Toggle Game Master (Spectator) diff --git a/Resources/Language/Japanese.json b/Resources/Language/Japanese.json index ac0676e..863931f 100644 --- a/Resources/Language/Japanese.json +++ b/Resources/Language/Japanese.json @@ -341,5 +341,13 @@ "pnsDisableCloseDoor": "PnSのドア閉鎖サボタージュを無効にする", "tabGroupPNS": "Poof and Seek", "badMoveTimeToSuicide": "幻象師が明らかに移動した後、自殺するまでの時間", -"snsImpostorCanVent": "インポスターはベントを使用できる" +"snsImpostorCanVent": "インポスターはベントを使用できる", +"modeVoteDuration": "ゲームモード投票時間", +"snsChatInGameExtendTwo": "ゲーム開始後に拡張情報を送信", +"snsChatInGameFast": "高速会議(実験的+)", +"shieldFirstDeath": "最初に死亡したプレイヤーをシールドで保護", +"shieldFirstDeathDuration": "シールド持続時間", +"snsTwoDesc": "Shift and Seekの拡張説明を送信。", +"modeVoteDesc": "すべてのゲームモードから投票を開始します。", +"automaticModePoll": "再参加後に自動で /gmvote を実行" } diff --git a/Resources/Language/SimplifiedChinese.json b/Resources/Language/SimplifiedChinese.json index 4541a65..6bac251 100644 --- a/Resources/Language/SimplifiedChinese.json +++ b/Resources/Language/SimplifiedChinese.json @@ -328,5 +328,13 @@ "pnsDisableCloseDoor": "禁用 PnS 关门破坏。", "tabGroupPNS": "Poof and Seek", "badMoveTimeToSuicide": "幻象师在明显移动后自杀的时间。", -"snsImpostorCanVent": "内鬼可以使用通风管。" +"snsImpostorCanVent": "内鬼可以使用通风管。", +"modeVoteDuration": "游戏模式投票时长", +"snsChatInGameExtendTwo": "游戏开始后发送扩展信息", +"snsChatInGameFast": "快速会议(实验性+)", +"shieldFirstDeath": "护盾保护第一个死亡的玩家", +"shieldFirstDeathDuration": "护盾持续时间", +"snsTwoDesc": "发送 Shift and Seek 扩展说明。", +"modeVoteDesc": "在所有游戏模式之间发起投票。", +"automaticModePoll": "重新加入后自动执行 /gmvote" } diff --git a/Resources/Language/Spanish.json b/Resources/Language/Spanish.json index 0f9c79d..1bbef40 100644 --- a/Resources/Language/Spanish.json +++ b/Resources/Language/Spanish.json @@ -294,10 +294,17 @@ "moderatorAndAbove": "Moderador o superior", "admin": "Administrador", "onlyYou": "Solo tú", - - "pnsDisableSabotage": "Disable PnS Critical Sabotages", - "pnsDisableCloseDoor": "Disable PnS Door Sabotages", + "pnsDisableSabotage": "Desactivar sabotajes críticos de PnS", + "pnsDisableCloseDoor": "Desactivar sabotajes de puertas de PnS", "tabGroupPNS": "Poof and Seek", - "badMoveTimeToSuicide": "Phantom Suicides After Visibly Moving For", - "snsImpostorCanVent": "Impostors can vent" + "badMoveTimeToSuicide": "El Fantasma se suicida después de moverse visiblemente durante", + "snsImpostorCanVent": "Los impostores pueden usar conductos", + "modeVoteDuration": "Duración de la votación de modo de juego", + "snsChatInGameExtendTwo": "Enviar información ampliada al iniciar la partida", + "snsChatInGameFast": "Reunión más rápida (experimental+)", + "shieldFirstDeath": " Proteger al primer jugador que murió", + "shieldFirstDeathDuration": "Duración de la protección", + "snsTwoDesc": "Enviar la descripción ampliada de Shift and Seek.", + "modeVoteDesc": "Inicia una votación entre todos los modos de juego.", + "automaticModePoll": "/gmvote automático al volver a la sala" }