From 88006b31f934c79a9866e8dea48d524ee8d41404 Mon Sep 17 00:00:00 2001 From: D1GQ Date: Thu, 25 Jun 2026 15:30:46 -0500 Subject: [PATCH] Add settings for rpc rate limiting --- src/Managers/NetworkManager.cs | 14 ++++++---- src/Modules/AntiCheat/BetterAntiCheat.cs | 4 +-- src/Mono/Extended/ExtendedPlayerInfo.cs | 27 +++++++++---------- .../Gameplay/UI/Settings/GameSettingsPatch.cs | 10 ++++--- src/Resources/Lang/en_US.json | 4 ++- src/build/Generated/TranslationStrings.cs | 14 ++++++++-- 6 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/Managers/NetworkManager.cs b/src/Managers/NetworkManager.cs index deb1d88..22be91b 100644 --- a/src/Managers/NetworkManager.cs +++ b/src/Managers/NetworkManager.cs @@ -5,6 +5,7 @@ using BetterAmongUs.Modules; using BetterAmongUs.Modules.AntiCheat; using BetterAmongUs.Mono.Extended; using BetterAmongUs.Network; +using BetterAmongUs.Patches.Gameplay.UI.Settings; using BetterAmongUs.Structs; using BetterAmongUs.Utilities; using HarmonyLib; @@ -454,10 +455,10 @@ internal static class NetworkManager /// private static bool PlayerRpc(PlayerControl player, byte callId, MessageReader reader) { - if (player.ExtendedData() != null) + if (player.ExtendedData() != null && BetterGameSettings.RpcRateLimiting.GetBool()) { player.ExtendedData().AntiCheatInfo.RPCSentPS++; - if (player.ExtendedData().AntiCheatInfo.RPCSentPS >= ExtendedAntiCheatInfo.MAX_RPC_SENT) + if (player.ExtendedData().AntiCheatInfo.RPCSentPS >= BetterGameSettings.RpcRateLimit.GetInt()) { return false; } @@ -496,10 +497,13 @@ internal static class NetworkManager [HarmonyPrefix] internal static bool ShipStatus_UpdateSystem_Prefix(SystemTypes systemType, PlayerControl player, MessageReader msgReader) { - player.ExtendedData().AntiCheatInfo.RPCSentPS++; - if (player.ExtendedData().AntiCheatInfo.RPCSentPS >= ExtendedAntiCheatInfo.MAX_RPC_SENT) + if (BetterGameSettings.RpcRateLimiting.GetBool()) { - return false; + player.ExtendedData().AntiCheatInfo.RPCSentPS++; + if (player.ExtendedData().AntiCheatInfo.RPCSentPS >= BetterGameSettings.RpcRateLimit.GetInt()) + { + return false; + } } if (BetterAntiCheat.RpcUpdateSystemCheck(player, systemType, msgReader) != true) return false; diff --git a/src/Modules/AntiCheat/BetterAntiCheat.cs b/src/Modules/AntiCheat/BetterAntiCheat.cs index 19fe679..fa41b3a 100644 --- a/src/Modules/AntiCheat/BetterAntiCheat.cs +++ b/src/Modules/AntiCheat/BetterAntiCheat.cs @@ -109,7 +109,7 @@ internal static class BetterAntiCheat return; if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || - !BetterGameSettings.DetectInvalidRPCs.GetBool()) + !BetterGameSettings.DetectInvalidRpcs.GetBool()) return; if (player == null) @@ -138,7 +138,7 @@ internal static class BetterAntiCheat try { if (player == null || player.Data == null) return true; - if (!IsEnabled || !BAUConfigs.AntiCheat.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || !BetterGameSettings.DetectInvalidRPCs.GetBool()) return true; + if (!IsEnabled || !BAUConfigs.AntiCheat.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || !BetterGameSettings.DetectInvalidRpcs.GetBool()) return true; if (player.IsLocalPlayer() && player.IsHost()) return true; MessageReader reader = MessageReader.Get(oldReader); diff --git a/src/Mono/Extended/ExtendedPlayerInfo.cs b/src/Mono/Extended/ExtendedPlayerInfo.cs index 50bd60b..6670c2f 100644 --- a/src/Mono/Extended/ExtendedPlayerInfo.cs +++ b/src/Mono/Extended/ExtendedPlayerInfo.cs @@ -4,6 +4,7 @@ using BetterAmongUs.Generated; using BetterAmongUs.Managers; using BetterAmongUs.Modules; using BetterAmongUs.Modules.Support; +using BetterAmongUs.Patches.Gameplay.UI.Settings; using BetterAmongUs.Utilities; using HarmonyLib; using Hazel; @@ -79,17 +80,20 @@ internal sealed class ExtendedPlayerInfo : MonoBehaviour, IMonoExtension 0) { - bool flag = BaseMono.IsCheater(); - - if (AntiCheatInfo.RPCSentPS >= ExtendedAntiCheatInfo.MAX_RPC_SENT && !flag) + if (BetterGameSettings.RpcRateLimiting.GetBool()) { - BetterNotificationManager.NotifyCheat( - BaseMono.Object, - TranslationStrings.AntiCheat_Reason_RPCSentPS.LocalizedString, - TranslationStrings.AntiCheat_UnauthorizedAction.LocalizedString - ); + bool flag = BaseMono.IsCheater(); - Logger_.LogCheat($"{BaseMono.Object.ExtendedData().RealName} {AntiCheatInfo.RPCSentPS} Sent."); + if (AntiCheatInfo.RPCSentPS >= BetterGameSettings.RpcRateLimit.GetInt() && !flag) + { + BetterNotificationManager.NotifyCheat( + BaseMono.Object, + TranslationStrings.AntiCheat_Reason_RPCSentPS.LocalizedString, + TranslationStrings.AntiCheat_UnauthorizedAction.LocalizedString + ); + + Logger_.LogCheat($"{BaseMono.Object.ExtendedData().RealName} {AntiCheatInfo.RPCSentPS} Sent."); + } } timeAccumulator += time; @@ -184,11 +188,6 @@ internal sealed class ExtendedPlayerInfo : MonoBehaviour, IMonoExtension internal sealed class ExtendedAntiCheatInfo { - /// - /// Maximum allowed RPCs per second. - /// - internal const int MAX_RPC_SENT = 50; - /// /// Gets or sets whether the player is banned by anti-cheat. /// diff --git a/src/Patches/Gameplay/UI/Settings/GameSettingsPatch.cs b/src/Patches/Gameplay/UI/Settings/GameSettingsPatch.cs index 88efe1e..85c77e7 100644 --- a/src/Patches/Gameplay/UI/Settings/GameSettingsPatch.cs +++ b/src/Patches/Gameplay/UI/Settings/GameSettingsPatch.cs @@ -22,7 +22,9 @@ internal sealed class BetterGameSettings internal static OptionCheckboxItem? KickLevel; internal static OptionIntItem? KickLevelBelow; internal static OptionCheckboxItem? DetectCheatClients; - internal static OptionCheckboxItem? DetectInvalidRPCs; + internal static OptionCheckboxItem? DetectInvalidRpcs; + internal static OptionCheckboxItem? RpcRateLimiting; + internal static OptionIntItem? RpcRateLimit; internal static OptionStringItem? RoleRandomizer; @@ -49,7 +51,7 @@ internal static class GameSettingsPatch // Creates all custom game settings and organizes them in tabs internal static void SetupSettings(bool IsPreload = false) { - // Note: Use 2000 next ID + // Note: Use 2200 next ID // Create main settings tab BetterSettingsTab = OptionTab.Create(3, TranslationStrings.BetterSetting, TranslationStrings.BetterSetting_Description, Color.green); @@ -83,7 +85,9 @@ internal static class GameSettingsPatch BetterGameSettings.KickLevel = OptionCheckboxItem.Create(1900, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_KickLevel, false); BetterGameSettings.KickLevelBelow = OptionIntItem.Create(1700, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_KickLevelBelow, (0, 10000, 1), 0, ("Lv ", ""), BetterGameSettings.KickLevel); BetterGameSettings.DetectCheatClients = OptionCheckboxItem.Create(700, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_DetectCheatClients, true); - BetterGameSettings.DetectInvalidRPCs = OptionCheckboxItem.Create(800, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_DetectInvalidRPCs, true); + BetterGameSettings.DetectInvalidRpcs = OptionCheckboxItem.Create(800, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_DetectInvalidRpcs, true); + BetterGameSettings.RpcRateLimiting = OptionCheckboxItem.Create(2000, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_RpcRateLimiting, true); + BetterGameSettings.RpcRateLimit = OptionIntItem.Create(2100, BetterSettingsTab, TranslationStrings.BetterSetting_Setting_RateLimit, (25, 1000, 1), 50, ("", " PS"), BetterGameSettings.RpcRateLimiting); } // Role algorithm settings diff --git a/src/Resources/Lang/en_US.json b/src/Resources/Lang/en_US.json index 3060cff..210d95b 100644 --- a/src/Resources/Lang/en_US.json +++ b/src/Resources/Lang/en_US.json @@ -95,7 +95,9 @@ "BetterSetting.Setting.KickLevel": "Kick player levels", "BetterSetting.Setting.KickLevelBelow": "Kick player level below", "BetterSetting.Setting.DetectCheatClients": "Detect cheat clients", - "BetterSetting.Setting.DetectInvalidRPCs": "Detect invalid RPCs", + "BetterSetting.Setting.DetectInvalidRpcs": "Detect invalid Rpcs", + "BetterSetting.Setting.RpcRateLimiting": "Rpc Rate Limiting", + "BetterSetting.Setting.RateLimit": "Rate Limit", "BetterSetting.Setting.RoleRandomizer": "Randomizer", "BetterSetting.Setting.DesyncRoles": "Desync roles to other clients", "BetterSetting.Setting.DisableSabotagesForDead": "Disable sabotages for dead", diff --git a/src/build/Generated/TranslationStrings.cs b/src/build/Generated/TranslationStrings.cs index b3c4219..c4a4479 100644 --- a/src/build/Generated/TranslationStrings.cs +++ b/src/build/Generated/TranslationStrings.cs @@ -469,9 +469,19 @@ public static class TranslationStrings public static readonly TranslationString BetterSetting_Setting_DetectCheatClients = new("BetterSetting.Setting.DetectCheatClients"); /// - /// Base Translation: Detect invalid RPCs + /// Base Translation: Detect invalid Rpcs /// - public static readonly TranslationString BetterSetting_Setting_DetectInvalidRPCs = new("BetterSetting.Setting.DetectInvalidRPCs"); + public static readonly TranslationString BetterSetting_Setting_DetectInvalidRpcs = new("BetterSetting.Setting.DetectInvalidRpcs"); + + /// + /// Base Translation: Rpc Rate Limiting + /// + public static readonly TranslationString BetterSetting_Setting_RpcRateLimiting = new("BetterSetting.Setting.RpcRateLimiting"); + + /// + /// Base Translation: Rate Limit + /// + public static readonly TranslationString BetterSetting_Setting_RateLimit = new("BetterSetting.Setting.RateLimit"); /// /// Base Translation: Randomizer