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",