diff --git a/Modules/AntiCheat/RPCHandler.cs b/Modules/AntiCheat/RPCHandler.cs index ad521da..18a2ff0 100644 --- a/Modules/AntiCheat/RPCHandler.cs +++ b/Modules/AntiCheat/RPCHandler.cs @@ -51,10 +51,10 @@ public abstract class RPCHandler try { if (handlerFlag == HandlerFlag.Handle) handler.Handle(sender, MessageReader.Get(reader)); - if (handlerFlag == HandlerFlag.AntiCheatCheck) handler.HandleAntiCheatCheck(sender, MessageReader.Get(reader)); - if (handlerFlag == HandlerFlag.AntiCheatCancel) cancel = !handler.HandleAntiCheatCancel(sender, MessageReader.Get(reader)); - if (handlerFlag == HandlerFlag.AntiCheat) handler.HandleAntiCheat(sender, MessageReader.Get(reader)); - if (handlerFlag == HandlerFlag.BetterHost) cancel = !handler.BetterHandle(sender, MessageReader.Get(reader)); + else if (handlerFlag == HandlerFlag.AntiCheatCheck) handler.HandleAntiCheatCheck(sender, MessageReader.Get(reader)); + else if (handlerFlag == HandlerFlag.AntiCheatCancel) cancel = !handler.HandleAntiCheatCancel(sender, MessageReader.Get(reader)); + else if (handlerFlag == HandlerFlag.AntiCheat) handler.HandleAntiCheat(sender, MessageReader.Get(reader)); + else if (handlerFlag == HandlerFlag.BetterHost) cancel = !handler.BetterHandle(sender, MessageReader.Get(reader)); if (!(cancel)) break; } catch (Exception ex) diff --git a/Modules/AntiCheat/RPCHandlers/UpdateSystemHandler.cs b/Modules/AntiCheat/RPCHandlers/UpdateSystemHandler.cs index 1d38628..26923f3 100644 --- a/Modules/AntiCheat/RPCHandlers/UpdateSystemHandler.cs +++ b/Modules/AntiCheat/RPCHandlers/UpdateSystemHandler.cs @@ -1,5 +1,4 @@ using BetterAmongUs.Helpers; -using BetterAmongUs.Patches; using Hazel; namespace BetterAmongUs.Modules.AntiCheat; @@ -9,155 +8,164 @@ public class UpdateSystemHandler : RPCHandler public override byte CallId => (byte)RpcCalls.UpdateSystem; public SystemTypes CatchedSystemType; + + private readonly Dictionary> systemHandlers; + + private static SabotageSystemType SabotageSystem => ShipStatus.Instance.Systems[SystemTypes.Sabotage].Cast(); + + public UpdateSystemHandler() + { + systemHandlers = new Dictionary> + { + { (uint)SystemTypes.Sabotage, (sender, system, reader, count) => HandleSabotageSystem(sender, system.Cast(), reader) }, + { (uint)SystemTypes.Ventilation, (sender, system, reader, count) => HandleVentilationSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.Electrical, (sender, system, reader, count) => HandleSwitchSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.Comms, (sender, system, reader, count) => HandleCommsSystem(sender, system, count) }, + { (uint)SystemTypes.MushroomMixupSabotage, (sender, system, reader, count) => HandleMushroomMixupSabotageSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.Doors, (sender, system, reader, count) => HandleDoorsSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.Reactor, (sender, system, reader, count) => HandleReactorSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.Laboratory, (sender, system, reader, count) => HandleReactorSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.HeliSabotage, (sender, system, reader, count) => HandleHeliSabotageSystem(sender, system.Cast(), count) }, + { (uint)SystemTypes.LifeSupp, (sender, system, reader, count) => HandleLifeSuppSystem(sender, system.Cast(), count) } + }; + } + public override bool HandleAntiCheatCancel(PlayerControl? sender, MessageReader reader) { - byte amount = reader.ReadByte(); - byte hostNum = 128; // Only host should ever send this number - byte singleFixNum = 0; - byte minLightNum = 0; - byte MaxLightNum = 4; - byte fixNum = 16; // 16 and 17 - byte openPanelNum = 64; // 64 and 65 - byte closePanelNum = 32; // 32 and 33 + MessageReader oldReader = MessageReader.Get(reader); + byte count = reader.ReadByte(); - // Set fixing status - if (Utils.SystemTypeIsSabotage(CatchedSystemType)) + Logger.InGame($"{Enum.GetName(CatchedSystemType)}"); + + if (ShipStatus.Instance.Systems.TryGetValue(CatchedSystemType, out ISystemType system)) { - if (amount == openPanelNum && !sender.BetterData().AntiCheatInfo.IsFixingPanelSabotage) + uint systemKey = (uint)CatchedSystemType; + + if (systemHandlers.TryGetValue(systemKey, out var handler)) { - sender.BetterData().AntiCheatInfo.OpenSabotageNum = 1; - } - else if (amount == openPanelNum + 1 && !sender.BetterData().AntiCheatInfo.IsFixingPanelSabotage) - { - sender.BetterData().AntiCheatInfo.OpenSabotageNum = 2; - } - - if (amount == closePanelNum && sender.BetterData().AntiCheatInfo.OpenSabotageNum == 1) - { - sender.BetterData().AntiCheatInfo.OpenSabotageNum = 0; - } - else if (amount == closePanelNum + 1 && sender.BetterData().AntiCheatInfo.OpenSabotageNum == 2) - { - sender.BetterData().AntiCheatInfo.OpenSabotageNum = 0; - } - } - - if (!GameState.IsHost || PlayerControl.LocalPlayer == null || sender == null || sender.IsLocalPlayer() || sender.BetterData().IsBetterHost || !BAUAntiCheat.IsEnabled || !Main.AntiCheat.Value - || GameState.IsBetterHostLobby && !GameState.IsHost || !BetterGameSettings.DetectInvalidRPCs.GetBool()) return true; - - if (!BetterGameSettings.CancelInvalidSabotage.GetBool()) - return true; - - // Single Fix: 0 - // Lights: 0-1-2-3-4 - // Fix 1: 16 - // Fix 2: 17 - // Panel 1: Open/Hold 64 - Close/Release 32 - // Panel 2: Open/Hold 65 - Close/Release 33 - // Host: 128 - - // Activate sabotage - if (CatchedSystemType == SystemTypes.Sabotage) - { - SystemTypes SaboType = (SystemTypes)amount; - - if (!sender.IsImpostorTeam() || GameState.IsAnySabotageActive() || !Utils.SystemTypeIsSabotage(SaboType) - || GameState.SkeldIsActive && ShipStatus.Instance.AllDoors.Any(door => !door.IsOpen)) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(SaboType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(SaboType)}: {!player.IsImpostorTeam()} || {GameStates.IsAnySabotageActive()} " + - $"|| {!Utils.SystemTypeIsSabotage(SaboType)}"); - */ - return false; - } - } - - // Fix sabotage - else if (Utils.SystemTypeIsSabotage(CatchedSystemType)) - { - if (amount == hostNum && !sender.IsHost()) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {amount == hostNum} && {!player.IsHost()}"); - */ - return false; - } - - if (!GameState.IsSystemActive(CatchedSystemType)) - { - if (CatchedSystemType is SystemTypes.Electrical) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {systemType is SystemTypes.Electrical}"); - */ - } - - return false; - } - - if (sender.BetterData().AntiCheatInfo.IsFixingPanelSabotage) - { - if (sender.BetterData().AntiCheatInfo.OpenSabotageNum == 0) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {player.BetterData().AntiCheatInfo.OpenSabotageNum == 0}"); - */ - return false; - } - - if (amount == openPanelNum && amount == openPanelNum + 1) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {amount == openPanelNum} && {amount == openPanelNum + 1}"); - */ - return false; - } - - if (sender.BetterData().AntiCheatInfo.OpenSabotageNum == 1 && amount == openPanelNum + 1 - || sender.BetterData().AntiCheatInfo.OpenSabotageNum == 2 && amount == openPanelNum) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {player.BetterData().AntiCheatInfo.OpenSabotageNum == 1} && {amount == openPanelNum + 1} " + - $"|| {player.BetterData().AntiCheatInfo.OpenSabotageNum == 2} && {amount == openPanelNum}"); - */ - return false; - } - } - else - { - if (amount != fixNum && amount != fixNum + 1 - && amount != closePanelNum && amount != closePanelNum + 1 - && amount > MaxLightNum) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {amount != fixNum} && {amount != fixNum + 1}" + - $" && {amount != closePanelNum} && {amount != closePanelNum + 1}" + - $" && {amount > MaxLightNum}"); - */ - return false; - } - - if (CatchedSystemType == SystemTypes.Electrical) - { - if (amount > MaxLightNum) - { - /* - BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName(systemType)}"); - Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName(systemType)}: {amount > MaxLightNum}"); - */ - return false; - } - } + return handler.Invoke(sender, system, oldReader, count); } } return true; } -} + + private static bool HandleSabotageSystem(PlayerControl? sender, SabotageSystemType sabotageSystem, MessageReader reader) + { + byte count = reader.ReadByte(); + + if (!sender.IsImpostorTeam()) + { + return false; + } + + if (sabotageSystem.Timer > 0f) + { + return false; + } + + return true; + } + + private static bool HandleVentilationSystem(PlayerControl? sender, VentilationSystem ventilationSystem, byte count) + { + + return true; + } + + private static bool HandleSwitchSystem(PlayerControl? sender, SwitchSystem switchSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleCommsSystem(PlayerControl? sender, ISystemType system, byte count) + { + if (system == null) return false; + + if (system.TryCast(out var hqHudSystem)) + { + return HandleHqHudSystem(sender, hqHudSystem, count); + } + if (system.TryCast(out var HudOverrideSystem)) + { + return HandleHudOverrideSystem(sender, HudOverrideSystem, count); + } + + return true; + } + + private static bool HandleHqHudSystem(PlayerControl? sender, HqHudSystemType hqHudSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleHudOverrideSystem(PlayerControl? sender, HudOverrideSystemType hudOverrideSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleMushroomMixupSabotageSystem(PlayerControl? sender, MushroomMixupSabotageSystem mushroomMixupSabotage, byte count) + { + if (count == 1) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleDoorsSystem(PlayerControl? sender, DoorsSystemType doorsSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleReactorSystem(PlayerControl? sender, ReactorSystemType reactorSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleHeliSabotageSystem(PlayerControl? sender, HeliSabotageSystem heliSabotageSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } + + private static bool HandleLifeSuppSystem(PlayerControl? sender, LifeSuppSystemType lifeSuppSystem, byte count) + { + if (count == 128) // Direct sabotage call from client, which is not possible, only the host should have this count when HandleSabotageSystem it's called + { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/Modules/RPC.cs b/Modules/RPC.cs index 5ff7064..b1d0514 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -80,7 +80,6 @@ public static class MessageReaderUpdateSystemPatch { public static bool Prefix(/*ShipStatus __instance,*/ [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] MessageReader reader) { - if (GameState.IsHideNSeek) return false; if (BAUAntiCheat.RpcUpdateSystemCheck(player, systemType, reader) != true) { Logger.LogCheat($"RPC canceled by Anti-Cheat: {Enum.GetName(typeof(SystemTypes), (int)systemType)} - {MessageReader.Get(reader).ReadByte()}");