Update invalid sabotage detections (work in progress)

This commit is contained in:
D1GQ committed 2024-12-06 00:01:26 -06:00
1 parent 4a1551a871
commit 29e0b44385
3 files changed
+155 -148

No files matched your search

+4 -4
View File
@@ -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)
@@ -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<uint, Func<PlayerControl?, ISystemType, MessageReader, byte, bool>> systemHandlers;
private static SabotageSystemType SabotageSystem => ShipStatus.Instance.Systems[SystemTypes.Sabotage].Cast<SabotageSystemType>();
public UpdateSystemHandler()
{
systemHandlers = new Dictionary<uint, Func<PlayerControl?, ISystemType, MessageReader, byte, bool>>
{
{ (uint)SystemTypes.Sabotage, (sender, system, reader, count) => HandleSabotageSystem(sender, system.Cast<SabotageSystemType>(), reader) },
{ (uint)SystemTypes.Ventilation, (sender, system, reader, count) => HandleVentilationSystem(sender, system.Cast<VentilationSystem>(), count) },
{ (uint)SystemTypes.Electrical, (sender, system, reader, count) => HandleSwitchSystem(sender, system.Cast<SwitchSystem>(), count) },
{ (uint)SystemTypes.Comms, (sender, system, reader, count) => HandleCommsSystem(sender, system, count) },
{ (uint)SystemTypes.MushroomMixupSabotage, (sender, system, reader, count) => HandleMushroomMixupSabotageSystem(sender, system.Cast<MushroomMixupSabotageSystem>(), count) },
{ (uint)SystemTypes.Doors, (sender, system, reader, count) => HandleDoorsSystem(sender, system.Cast<DoorsSystemType>(), count) },
{ (uint)SystemTypes.Reactor, (sender, system, reader, count) => HandleReactorSystem(sender, system.Cast<ReactorSystemType>(), count) },
{ (uint)SystemTypes.Laboratory, (sender, system, reader, count) => HandleReactorSystem(sender, system.Cast<ReactorSystemType>(), count) },
{ (uint)SystemTypes.HeliSabotage, (sender, system, reader, count) => HandleHeliSabotageSystem(sender, system.Cast<HeliSabotageSystem>(), count) },
{ (uint)SystemTypes.LifeSupp, (sender, system, reader, count) => HandleLifeSuppSystem(sender, system.Cast<LifeSuppSystemType>(), 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<HqHudSystemType>(out var hqHudSystem))
{
return HandleHqHudSystem(sender, hqHudSystem, count);
}
if (system.TryCast<HudOverrideSystemType>(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;
}
}
-1
View File
@@ -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()}");