From eb44df4c5694cc28d7f321f586efe92cfccc417f Mon Sep 17 00:00:00 2001 From: D1GQ Date: Thu, 19 Mar 2026 15:13:28 -0500 Subject: [PATCH] Add detections to ModMenuCrew and clean up tag handling --- src/Data/BetterDataManager.cs | 9 +++ src/Data/Json/BetterDataFile.cs | 53 ++++++++++++++- src/Enums/CustomRPC.cs | 17 ++++- src/Helpers/Colors.cs | 21 ++++-- src/Modules/AntiCheat/BetterAntiCheat.cs | 6 ++ .../RPCHandlers/Cheats/AUMChatHandler.cs | 67 ++++++++++++------- .../RPCHandlers/Cheats/AUMHandler.cs | 18 ++++- .../RPCHandlers/Cheats/KillNetworkHandler.cs | 19 +++--- .../Cheats/ModMenuCrewChatHandler.cs | 56 ++++++++++++++++ .../RPCHandlers/Cheats/SickoHandler.cs | 19 +++--- src/Mono/MeetingInfoDisplay.cs | 33 ++------- src/Mono/PlayerInfoDisplay.cs | 52 +++----------- src/Patches/Gameplay/UI/Chat/ChatPatch.cs | 12 ++-- src/Resources/Lang/en_US.json | 4 +- 14 files changed, 252 insertions(+), 134 deletions(-) create mode 100644 src/Modules/AntiCheat/RPCHandlers/Cheats/ModMenuCrewChatHandler.cs diff --git a/src/Data/BetterDataManager.cs b/src/Data/BetterDataManager.cs index 00a52ae..76d1bfe 100644 --- a/src/Data/BetterDataManager.cs +++ b/src/Data/BetterDataManager.cs @@ -306,6 +306,14 @@ internal static class BetterDataManager didFind = true; } } + foreach (var info in BetterDataFile.MMCData.ToArray()) + { + if (info.PlayerName.Replace(' ', '_') == identifier || info.HashPuid == identifier || info.FriendCode == identifier) + { + BetterDataFile.MMCData.Remove(info); + didFind = true; + } + } if (didFind) { @@ -324,6 +332,7 @@ internal static class BetterDataManager BetterDataFile.SickoData.Clear(); BetterDataFile.AUMData.Clear(); BetterDataFile.KNData.Clear(); + BetterDataFile.MMCData.Clear(); BetterDataFile.Save(); } } \ No newline at end of file diff --git a/src/Data/Json/BetterDataFile.cs b/src/Data/Json/BetterDataFile.cs index 39dc53c..49b3653 100644 --- a/src/Data/Json/BetterDataFile.cs +++ b/src/Data/Json/BetterDataFile.cs @@ -1,4 +1,6 @@ -using BetterAmongUs.Structs; +using BetterAmongUs.Helpers; +using BetterAmongUs.Modules; +using BetterAmongUs.Structs; using System.Text.Json.Serialization; namespace BetterAmongUs.Data.Json; @@ -34,10 +36,49 @@ internal sealed class BetterDataFile : AbstractJsonFile /// True if saving was successful, false otherwise. internal override bool Save() { - AllCheatData = [.. CheatData, .. SickoData, .. AUMData, .. KNData]; + AllCheatData = [.. CheatData, .. SickoData, .. AUMData, .. KNData, .. MMCData]; return base.Save(); } + /// + /// Attempts to get cheat information for the specified player. + /// + /// The player information to check. + /// When this method returns, contains the title and hex color if cheat info is found; otherwise, empty strings. + /// True if cheat information was found for the player; otherwise, false. + internal bool TryGetCheatInfo(NetworkedPlayerInfo data, out (string title, string hexColor) info) + { + info = ("", ""); + + if (SickoData.Any(info => info.CheckPlayerData(data))) + { + info = (Translator.GetString("Player.SickoUser"), Colors.SickoHexColor); + return true; + } + else if (AUMData.Any(info => info.CheckPlayerData(data))) + { + info = (Translator.GetString("Player.AUMUser"), Colors.AUMHexColor); + return true; + } + else if (KNData.Any(info => info.CheckPlayerData(data))) + { + info = (Translator.GetString("Player.KNUser"), Colors.KNHexColor); + return true; + } + else if (MMCData.Any(info => info.CheckPlayerData(data))) + { + info = (Translator.GetString("Player.MMCUser"), Colors.MMCHexColor); + return true; + } + else if (CheatData.Any(info => info.CheckPlayerData(data))) + { + info = (Translator.GetString("Player.FlaggedPlayer"), Colors.CheaterHexColor); + return true; + } + + return false; + } + /// /// Checks if player data matches any known cheat entries. /// @@ -101,8 +142,14 @@ internal sealed class BetterDataFile : AbstractJsonFile public HashSet AUMData { get; set; } = []; /// - /// Gets or sets the collection of KN cheat user data. + /// Gets or sets the collection of Kill Network cheat user data. /// [JsonPropertyName("knData")] public HashSet KNData { get; set; } = []; + + /// + /// Gets or sets the collection of Mod Menu Crew cheat user data. + /// + [JsonPropertyName("mmcData")] + public HashSet MMCData { get; set; } = []; } \ No newline at end of file diff --git a/src/Enums/CustomRPC.cs b/src/Enums/CustomRPC.cs index b3acff2..2550517 100644 --- a/src/Enums/CustomRPC.cs +++ b/src/Enums/CustomRPC.cs @@ -5,6 +5,10 @@ /// internal enum CustomRPC : int { + // ======================================== + // Known Cheat RPCS + // ======================================== + // Cheat RPC's /// /// RPC identifier for Sicko cheat detection. @@ -31,19 +35,28 @@ internal enum CustomRPC : int /// KillNetworkChat = 119, + /// + /// RPC identifier for ModMenuCrew chat communication. + /// + ModMenuCrewChat = 201, + // ======================================== + // BAU RPCS + // ======================================== // Better Among Us /// /// Legacy RPC for BetterAmongUs checks (currently unused). /// LegacyBetterCheck = 150, // Unused + /// /// RPC for sending a shared secret to another player. /// - SendSecretToPlayer, + SendSecretToPlayer = 151, + /// /// RPC for checking the hash of a shared secret received from another player. /// - CheckSecretHashFromPlayer, + CheckSecretHashFromPlayer = 152, } \ No newline at end of file diff --git a/src/Helpers/Colors.cs b/src/Helpers/Colors.cs index ce2a5d3..db53287 100644 --- a/src/Helpers/Colors.cs +++ b/src/Helpers/Colors.cs @@ -7,18 +7,22 @@ namespace BetterAmongUs.Helpers; /// internal static class Colors { - // Convert a string to a colored string using a Unity Color object /// - /// Converts the provided string into a colored string by wrapping it with a - /// tag using the Unity Color object. The Unity Color is automatically - /// converted to its hexadecimal representation before being applied to the string. + /// Converts the provided string into a colored string. /// /// The string to be colored. /// The Unity Color object representing the desired color. /// A string wrapped in a color tag, displaying the string in the specified Unity color. internal static string ToColor(this string str, Color color) => $"<{Color32ToHex(color)}>{str}"; - // Modify the alpha value of an existing color + /// + /// Converts the provided string into a colored string. + /// + /// The string to be colored. + /// The Hex Color representing the desired color. + /// A string wrapped in a color tag, displaying the string in the specified hex color. + internal static string ToColor(this string str, string hex) => $"<{hex}>{str}"; + /// /// Returns a new color that preserves the RGB (Red, Green, Blue) values of the /// original color, but applies a new alpha (opacity) value from the provided new color. @@ -29,7 +33,6 @@ internal static class Colors /// A new color with the same RGB values as the original color, but with the new alpha value. internal static Color ToColor(this Color oldColor, Color newColor) => new(newColor.r, newColor.g, newColor.b, oldColor.a); - // Set a new alpha value while keeping the original RGB values /// /// Creates and returns a new color with the same RGB values as the original color, /// but with the specified alpha (transparency) value. This method is useful for @@ -136,4 +139,10 @@ internal static class Colors /// Standard impostor red color. /// internal static readonly Color ImpostorRed = new Color32(byte.MaxValue, 25, 25, byte.MaxValue); + + internal static readonly string SickoHexColor = "#00f583"; + internal static readonly string AUMHexColor = "#4f0000"; + internal static readonly string KNHexColor = "#8731e7"; + internal static readonly string MMCHexColor = "#9c8200"; + internal static readonly string CheaterHexColor = "#fc0000"; } \ No newline at end of file diff --git a/src/Modules/AntiCheat/BetterAntiCheat.cs b/src/Modules/AntiCheat/BetterAntiCheat.cs index 004b293..1eafd1e 100644 --- a/src/Modules/AntiCheat/BetterAntiCheat.cs +++ b/src/Modules/AntiCheat/BetterAntiCheat.cs @@ -61,6 +61,12 @@ internal static class BetterAntiCheat string kickMessage = string.Format(Translator.GetString("AntiCheat.KickMessage"), Translator.GetString("AntiCheat.ByAntiCheat"), reason); player.Kick(true, kickMessage, true); } + else if (BetterDataManager.BetterDataFile.MMCData.Any(info => info.CheckPlayerData(player.Data))) + { + string reason = Translator.GetString("AntiCheat.Reason.MMCUser"); + string kickMessage = string.Format(Translator.GetString("AntiCheat.KickMessage"), Translator.GetString("AntiCheat.ByAntiCheat"), reason); + player.Kick(true, kickMessage, true); + } else if (BetterDataManager.BetterDataFile.CheatData.Any(info => info.CheckPlayerData(player.Data))) { string reason = Translator.GetString("AntiCheat.Reason.KnownCheater"); diff --git a/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMChatHandler.cs b/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMChatHandler.cs index d4d1fa4..6b31226 100644 --- a/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMChatHandler.cs +++ b/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMChatHandler.cs @@ -19,33 +19,52 @@ internal sealed class AUMChatHandler : RPCHandler internal override void HandleCheatRpcCheck(PlayerControl? sender, MessageReader reader) { - var nameString = reader.ReadString(); - var msgString = reader.ReadString(); - var colorId = reader.ReadInt32(); - - var flag3 = sender.BetterData().AntiCheatInfo.AUMChats.Count > 0 && sender.BetterData().AntiCheatInfo.AUMChats.Last() == msgString; - if (!flag3) + try { - Utils.AddChatPrivate($"{msgString}", overrideName: $"AUM Chat - {sender.GetPlayerNameAndColor()}"); - sender.BetterData().AntiCheatInfo.AUMChats.Add(msgString); + var nameString = reader.ReadString(); + var msgString = reader.ReadString(); + var colorId = reader.ReadInt32(); + + var flag3 = sender.BetterData().AntiCheatInfo.AUMChats.Count > 0 && sender.BetterData().AntiCheatInfo.AUMChats.Last() == msgString; + if (!flag3) + { + Utils.AddChatPrivate($"{msgString}", overrideName: $"AUM Chat - {sender.GetPlayerNameAndColor()}"); + sender.BetterData().AntiCheatInfo.AUMChats.Add(msgString); + } + + Logger_.Log($"{sender.Data.PlayerName} -> {msgString}", "AUMChatLog"); + + if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) + return; + + if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) + return; + + var flag = string.IsNullOrEmpty(nameString) && string.IsNullOrEmpty(msgString); + + if (!flag && !BetterDataManager.BetterDataFile.AUMData.Any(info => info.CheckPlayerData(sender.Data))) + { + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.AUMData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "AUM Chat RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.AUM"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); + } } - - Logger_.Log($"{sender.Data.PlayerName} -> {msgString}", "AUMChatLog"); - - if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) - return; - - if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) - return; - - var flag = string.IsNullOrEmpty(nameString) && string.IsNullOrEmpty(msgString); - - if (!flag && !BetterDataManager.BetterDataFile.AUMData.Any(info => info.CheckPlayerData(sender.Data))) + catch { - sender.ReportPlayer(ReportReasons.Cheating_Hacking); - BetterDataManager.BetterDataFile.AUMData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "AUM Chat RPC")); - BetterDataManager.BetterDataFile.Save(); - BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.AUM"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); + if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) + return; + + if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) + return; + + if (!BetterDataManager.BetterDataFile.AUMData.Any(info => info.CheckPlayerData(sender.Data))) + { + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.AUMData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "AUM Chat RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.AUM"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); + } } } } \ No newline at end of file diff --git a/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMHandler.cs b/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMHandler.cs index 3b52127..ec33203 100644 --- a/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMHandler.cs +++ b/src/Modules/AntiCheat/RPCHandlers/Cheats/AUMHandler.cs @@ -19,7 +19,13 @@ internal sealed class AUMHandler : RPCHandler internal override void HandleCheatRpcCheck(PlayerControl? sender, MessageReader reader) { - if (BAUConfigs.AntiCheat.Value && !BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) && BetterGameSettings.DetectCheatClients.GetBool()) + if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) + return; + + if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) + return; + + try { var aumid = reader.ReadByte(); @@ -34,5 +40,15 @@ internal sealed class AUMHandler : RPCHandler } } } + catch + { + if (!BetterDataManager.BetterDataFile.AUMData.Any(info => info.CheckPlayerData(sender.Data))) + { + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.AUMData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "AUM RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.AUM"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); + } + } } } \ No newline at end of file diff --git a/src/Modules/AntiCheat/RPCHandlers/Cheats/KillNetworkHandler.cs b/src/Modules/AntiCheat/RPCHandlers/Cheats/KillNetworkHandler.cs index e9d0c58..3351e1b 100644 --- a/src/Modules/AntiCheat/RPCHandlers/Cheats/KillNetworkHandler.cs +++ b/src/Modules/AntiCheat/RPCHandlers/Cheats/KillNetworkHandler.cs @@ -19,15 +19,18 @@ internal sealed class KillNetworkHandler : RPCHandler internal override void HandleCheatRpcCheck(PlayerControl? sender, MessageReader reader) { - if (BAUConfigs.AntiCheat.Value && !BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) && BetterGameSettings.DetectCheatClients.GetBool()) + if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) + return; + + if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) + return; + + if (!BetterDataManager.BetterDataFile.KNData.Any(info => info.CheckPlayerData(sender.Data))) { - if (!BetterDataManager.BetterDataFile.KNData.Any(info => info.CheckPlayerData(sender.Data))) - { - sender.ReportPlayer(ReportReasons.Cheating_Hacking); - BetterDataManager.BetterDataFile.KNData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "KillNetwork RPC")); - BetterDataManager.BetterDataFile.Save(); - BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.KN"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); - } + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.KNData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "KillNetwork RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.KN"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); } } } \ No newline at end of file diff --git a/src/Modules/AntiCheat/RPCHandlers/Cheats/ModMenuCrewChatHandler.cs b/src/Modules/AntiCheat/RPCHandlers/Cheats/ModMenuCrewChatHandler.cs new file mode 100644 index 0000000..e77d530 --- /dev/null +++ b/src/Modules/AntiCheat/RPCHandlers/Cheats/ModMenuCrewChatHandler.cs @@ -0,0 +1,56 @@ +using BetterAmongUs.Attributes; +using BetterAmongUs.Data; +using BetterAmongUs.Data.Config; +using BetterAmongUs.Enums; +using BetterAmongUs.Helpers; +using BetterAmongUs.Managers; +using BetterAmongUs.Modules.Support; +using BetterAmongUs.Mono; +using BetterAmongUs.Patches.Gameplay.UI.Settings; +using Hazel; +using InnerNet; + +namespace BetterAmongUs.Modules.AntiCheat; + +[RegisterRPCHandler] +internal sealed class ModMenuCrewChatHandler : RPCHandler +{ + internal override byte CallId => unchecked((byte)CustomRPC.ModMenuCrewChat); + + internal override void HandleCheatRpcCheck(PlayerControl? sender, MessageReader reader) + { + if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) + return; + + if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) + return; + + try + { + var tag = reader.ReadByte(); + var senderId = reader.ReadPackedInt32(); + var senderName = reader.ReadString(); + var content = reader.ReadString(); + var timestamp = reader.ReadUInt64(); + var type = reader.ReadByte(); + + if (!BetterDataManager.BetterDataFile.MMCData.Any(info => info.CheckPlayerData(sender.Data))) + { + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.MMCData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "ModMenuCrew Chat RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.MMCC"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); + } + } + catch + { + if (!BetterDataManager.BetterDataFile.MMCData.Any(info => info.CheckPlayerData(sender.Data))) + { + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.MMCData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "ModMenuCrew Chat RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.MMCC"), Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); + } + } + } +} \ No newline at end of file diff --git a/src/Modules/AntiCheat/RPCHandlers/Cheats/SickoHandler.cs b/src/Modules/AntiCheat/RPCHandlers/Cheats/SickoHandler.cs index 2b50b4e..f9ccc92 100644 --- a/src/Modules/AntiCheat/RPCHandlers/Cheats/SickoHandler.cs +++ b/src/Modules/AntiCheat/RPCHandlers/Cheats/SickoHandler.cs @@ -19,15 +19,18 @@ internal sealed class SickoHandler : RPCHandler internal override void HandleCheatRpcCheck(PlayerControl? sender, MessageReader reader) { - if (BAUConfigs.AntiCheat.Value && !BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) && BetterGameSettings.DetectCheatClients.GetBool()) + if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) + return; + + if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) + return; + + if (reader.BytesRemaining == 0 && !BetterDataManager.BetterDataFile.SickoData.Any(info => info.CheckPlayerData(sender.Data))) { - if (reader.BytesRemaining == 0 && !BetterDataManager.BetterDataFile.SickoData.Any(info => info.CheckPlayerData(sender.Data))) - { - sender.ReportPlayer(ReportReasons.Cheating_Hacking); - BetterDataManager.BetterDataFile.SickoData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "Sicko RPC")); - BetterDataManager.BetterDataFile.Save(); - BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.Sicko"), newText: Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); - } + sender.ReportPlayer(ReportReasons.Cheating_Hacking); + BetterDataManager.BetterDataFile.SickoData.Add(new(sender?.BetterData().RealName ?? sender.Data.PlayerName, sender.GetHashPuid(), sender.Data.FriendCode, "Sicko RPC")); + BetterDataManager.BetterDataFile.Save(); + BetterNotificationManager.NotifyCheat(sender, Translator.GetString("AntiCheat.Cheat.Sicko"), newText: Translator.GetString("AntiCheat.HasBeenDetectedWithCheat2")); } } } \ No newline at end of file diff --git a/src/Mono/MeetingInfoDisplay.cs b/src/Mono/MeetingInfoDisplay.cs index e11cfbc..60e664b 100644 --- a/src/Mono/MeetingInfoDisplay.cs +++ b/src/Mono/MeetingInfoDisplay.cs @@ -2,7 +2,6 @@ using BetterAmongUs.Data; using BetterAmongUs.Helpers; using BetterAmongUs.Modules; -using BetterAmongUs.Structs; using Il2CppInterop.Runtime.Attributes; using System.Text; using TMPro; @@ -33,10 +32,6 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay /// private class CachedTranslations { - internal readonly string SickoUser = Translator.GetString("Player.SickoUser"); - internal readonly string AUMUser = Translator.GetString("Player.AUMUser"); - internal readonly string KNUser = Translator.GetString("Player.KNUser"); - internal readonly string KnownCheater = Translator.GetString("Player.KnownCheater"); internal readonly string DisconnectLeft = Translator.GetString("DisconnectReasonMeeting.Left"); internal readonly string DisconnectAntiCheat = Translator.GetString("DisconnectReasonMeeting.AntiCheat"); internal readonly string DisconnectBanned = Translator.GetString("DisconnectReasonMeeting.Banned"); @@ -177,14 +172,10 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay if (_player.Data == null) return; - if (ContainsPlayerData(BetterDataManager.BetterDataFile.SickoData, _player.Data)) - sbTag.Append($"{_cachedTranslations.SickoUser}+++"); - else if (ContainsPlayerData(BetterDataManager.BetterDataFile.AUMData, _player.Data)) - sbTag.Append($"{_cachedTranslations.AUMUser}+++"); - else if (ContainsPlayerData(BetterDataManager.BetterDataFile.KNData, _player.Data)) - sbTag.Append($"{_cachedTranslations.KNUser}+++"); - else if (ContainsPlayerData(BetterDataManager.BetterDataFile.CheatData, _player.Data)) - sbTag.Append($"{_cachedTranslations.KnownCheater}+++"); + if (BetterDataManager.BetterDataFile.TryGetCheatInfo(_player.Data, out var info)) + { + sbTag.Append(info.title.ToColor(info.hexColor) + "+++"); + } } /// @@ -283,22 +274,6 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay } } - /// - /// Checks if player data exists in a HashSet of UserInfo. - /// - /// HashSet of UserInfo to check. - /// Player data to look for. - /// True if player data exists in the HashSet. - private static bool ContainsPlayerData(HashSet dataList, NetworkedPlayerInfo playerData) - { - foreach (var info in dataList) - { - if (info.CheckPlayerData(playerData)) - return true; - } - return false; - } - /// /// Updates display for disconnected players. /// diff --git a/src/Mono/PlayerInfoDisplay.cs b/src/Mono/PlayerInfoDisplay.cs index 87985ed..517216b 100644 --- a/src/Mono/PlayerInfoDisplay.cs +++ b/src/Mono/PlayerInfoDisplay.cs @@ -5,7 +5,6 @@ using BetterAmongUs.Data.Config; using BetterAmongUs.Helpers; using BetterAmongUs.Modules; using BetterAmongUs.Patches.Gameplay.UI.Settings; -using BetterAmongUs.Structs; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using System.Text; @@ -45,10 +44,11 @@ internal class PlayerInfoDisplay : MonoBehaviour /// private static readonly Dictionary _cachedColors = new() { - ["#00f583"] = Utils.HexToColor32("#00f583"), - ["#4f0000"] = Utils.HexToColor32("#4f0000"), - ["#fc0000"] = Utils.HexToColor32("#fc0000"), - ["#8731e7"] = Utils.HexToColor32("#8731e7") + [Colors.SickoHexColor] = Utils.HexToColor32(Colors.SickoHexColor), + [Colors.AUMHexColor] = Utils.HexToColor32(Colors.AUMHexColor), + [Colors.KNHexColor] = Utils.HexToColor32(Colors.KNHexColor), + [Colors.MMCHexColor] = Utils.HexToColor32(Colors.MMCHexColor), + [Colors.CheaterHexColor] = Utils.HexToColor32(Colors.CheaterHexColor) }; /// @@ -59,10 +59,6 @@ internal class PlayerInfoDisplay : MonoBehaviour internal readonly string Loading = Translator.GetString("Player.Loading"); internal readonly string PlatformHidden = Translator.GetString("Player.PlatformHidden"); internal readonly string NoFriendCode = Translator.GetString("Player.NoFriendCode"); - internal readonly string SickoUser = Translator.GetString("Player.SickoUser"); - internal readonly string AUMUser = Translator.GetString("Player.AUMUser"); - internal readonly string KNUser = Translator.GetString("Player.KNUser"); - internal readonly string KnownCheater = Translator.GetString("Player.KnownCheater"); internal readonly string BetterUser = Translator.GetString("Player.BetterUser"); } @@ -361,25 +357,10 @@ internal class PlayerInfoDisplay : MonoBehaviour var color = _player.cosmetics.currentBodySprite.BodySprite.material.GetColor("_OutlineColor"); - if (ContainsPlayerData(BetterDataManager.BetterDataFile.SickoData, _player.Data)) + if (BetterDataManager.BetterDataFile.TryGetCheatInfo(_player.Data, out var info)) { - sbTag.Append($"{_cachedTranslations.SickoUser}+++"); - _player.SetOutlineByHex(true, "#00f583"); - } - else if (ContainsPlayerData(BetterDataManager.BetterDataFile.AUMData, _player.Data)) - { - sbTag.Append($"{_cachedTranslations.AUMUser}+++"); - _player.SetOutlineByHex(true, "#4f0000"); - } - else if (ContainsPlayerData(BetterDataManager.BetterDataFile.KNData, _player.Data)) - { - sbTag.Append($"{_cachedTranslations.KNUser}+++"); - _player.SetOutlineByHex(true, "#8731e7"); - } - else if (ContainsPlayerData(BetterDataManager.BetterDataFile.CheatData, _player.Data)) - { - sbTag.Append($"{_cachedTranslations.KnownCheater}+++"); - _player.SetOutlineByHex(true, "#fc0000"); + sbTag.Append(info.title.ToColor(info.hexColor) + "+++"); + _player.SetOutlineByHex(true, info.hexColor); } else if (_cachedColors.Any(kvp => color == kvp.Value)) { @@ -387,23 +368,6 @@ internal class PlayerInfoDisplay : MonoBehaviour } } - /// - /// Checks if player data exists in a HashSet of UserInfo. - /// - /// HashSet of UserInfo to check. - /// Player data to look for. - /// True if player data exists in the HashSet. - [HideFromIl2Cpp] - private static bool ContainsPlayerData(HashSet dataList, NetworkedPlayerInfo playerData) - { - foreach (var info in dataList) - { - if (info.CheckPlayerData(playerData)) - return true; - } - return false; - } - /// /// Sets lobby specific information. /// diff --git a/src/Patches/Gameplay/UI/Chat/ChatPatch.cs b/src/Patches/Gameplay/UI/Chat/ChatPatch.cs index 622520d..10c5071 100644 --- a/src/Patches/Gameplay/UI/Chat/ChatPatch.cs +++ b/src/Patches/Gameplay/UI/Chat/ChatPatch.cs @@ -179,14 +179,10 @@ internal static class ChatPatch } // Show mod-specific tags based on player data - if (BetterDataManager.BetterDataFile.SickoData.Any(info => info.CheckPlayerData(sourcePlayer.Data))) - sbTag.Append($"{Translator.GetString("Player.SickoUser")}+++"); - else if (BetterDataManager.BetterDataFile.AUMData.Any(info => info.CheckPlayerData(sourcePlayer.Data))) - sbTag.Append($"{Translator.GetString("Player.AUMUser")}+++"); - else if (BetterDataManager.BetterDataFile.KNData.Any(info => info.CheckPlayerData(sourcePlayer.Data))) - sbTag.Append($"{Translator.GetString("Player.KNUser")}+++"); - else if (BetterDataManager.BetterDataFile.CheatData.Any(info => info.CheckPlayerData(sourcePlayer.Data))) - sbTag.Append($"{Translator.GetString("Player.KnownCheater")}+++"); + if (BetterDataManager.BetterDataFile.TryGetCheatInfo(sourcePlayer.Data, out var info)) + { + sbTag.Append(info.title.ToColor(info.hexColor) + "+++"); + } } // Hide roles from alive players (unless same team) diff --git a/src/Resources/Lang/en_US.json b/src/Resources/Lang/en_US.json index 0302e5f..ab4d12a 100644 --- a/src/Resources/Lang/en_US.json +++ b/src/Resources/Lang/en_US.json @@ -28,7 +28,8 @@ "Player.SickoUser": "Sicko User", "Player.AUMUser": "AUM User", "Player.KNUser": "KN User", - "Player.KnownCheater": "Flagged Player", + "Player.MMCUser": "MMC User", + "Player.FlaggedPlayer": "Flagged Player", "DisconnectReason.Left": "{0} Left the game!", "DisconnectReason.Disconnect": "{0} Disconnected!", @@ -129,6 +130,7 @@ "AntiCheat.Cheat.AUM": "AUM", "AntiCheat.Cheat.KN": "Kill Network", "AntiCheat.Cheat.KNC": "KN Chat", + "AntiCheat.Cheat.MMCC": "MMC Chat", "AntiCheat.Reason.InvalidFriendCode": "Invalid Friend Code", "AntiCheat.Reason.PlatformSpoofer": "Platform Spoofer", "AntiCheat.Reason.RPCSentPS": "RPC Spam",