diff --git a/Commands/DumpCommand.cs b/Commands/DumpCommand.cs index a7b9fba..b44d71b 100644 --- a/Commands/DumpCommand.cs +++ b/Commands/DumpCommand.cs @@ -18,7 +18,7 @@ internal class DumpCommand : BaseCommand string logFilePath = Path.Combine(BetterDataManager.filePathFolder, "better-log.txt"); string log = File.ReadAllText(logFilePath); string newLog = string.Empty; - string[] logArray = log.Split(new[] { Environment.NewLine }, StringSplitOptions.None); + string[] logArray = log.Split([Environment.NewLine], StringSplitOptions.None); foreach (string text in logArray) { if (text.Contains("[PrivateLog]")) diff --git a/Helpers/Colors.cs b/Helpers/Colors.cs index aa2d54e..2ea1257 100644 --- a/Helpers/Colors.cs +++ b/Helpers/Colors.cs @@ -44,6 +44,13 @@ internal static class Colors /// A hexadecimal string representing the Color32 object. internal static string Color32ToHex(this Color32 color) => $"#{color.r:X2}{color.g:X2}{color.b:X2}{255:X2}"; + /// + /// Converts a Color32 object to a hexadecimal string representation. + /// + /// The Color32 object to convert. + /// A hexadecimal string representing the Color32 object. + internal static string ColorToHex(this Color color) => $"#{color.r:X2}{color.g:X2}{color.b:X2}{255:X2}"; + /// /// Converts a hexadecimal color string to a Color32 object. /// @@ -96,4 +103,7 @@ internal static class Colors return Color.Lerp(colors[segmentIndex], colors[segmentIndex + 1], segmentT); } + + internal static readonly Color CrewmateBlue = new Color32(140, byte.MaxValue, byte.MaxValue, byte.MaxValue); + internal static readonly Color ImpostorRed = new Color32(byte.MaxValue, 25, 25, byte.MaxValue); } \ No newline at end of file diff --git a/Helpers/RoleHelper.cs b/Helpers/RoleHelper.cs index df339f1..746d0fb 100644 --- a/Helpers/RoleHelper.cs +++ b/Helpers/RoleHelper.cs @@ -4,13 +4,37 @@ namespace BetterAmongUs.Helpers; internal static class RoleHelper { - internal static RoleBehaviour? GetBehaviour(this RoleTypes role) => RoleManager.Instance?.AllRoles.FirstOrDefaultIl2Cpp(r => r.Role == role); + private static readonly Lazy> roleLookup = + new(() => + { + var dict = new Dictionary(); + foreach (var r in RoleManager.Instance.AllRoles) + { + dict[r.Role] = r; + } + return dict; + }); + + internal static RoleBehaviour? GetBehaviour(this RoleTypes role) + { + var lookup = roleLookup.Value; + return lookup.TryGetValue(role, out var behaviour) ? behaviour : null; + } internal static bool IsImpostorRole(RoleTypes role) => role.GetBehaviour().TeamType is RoleTeamTypes.Impostor; internal static string GetRoleName(this RoleTypes role) { + if (role is RoleTypes.ImpostorGhost) + { + return RoleTypes.Impostor.GetBehaviour()?.NiceName ?? "???"; + } + else if (role is RoleTypes.CrewmateGhost) + { + return RoleTypes.Crewmate.GetBehaviour()?.NiceName ?? "???"; + } + return role.GetBehaviour()?.NiceName ?? "???"; } diff --git a/Managers/HostManager.cs b/Managers/HostManager.cs index 7834362..e7c599d 100644 --- a/Managers/HostManager.cs +++ b/Managers/HostManager.cs @@ -19,6 +19,7 @@ internal static class HostManager internal static void SyncNames(NameSyncType syncType, float sDelay, int repeat = 1) { + return; if (!GameState.IsHost || !BetterGameSettings.ShowRoleForClients.GetValue()) return; if (syncCoroutine != null && GameData.Instance != null) @@ -46,6 +47,7 @@ internal static class HostManager internal static void SyncNames(NameSyncType syncType) { + return; if (!GameState.IsHost || !BetterGameSettings.ShowRoleForClients.GetValue()) return; StringBuilder sb = new(); @@ -80,7 +82,6 @@ internal static class HostManager player.BetterPlayerControl().NameSetLastFor[target.Data] = newName; RPC.RpcSetNameForTarget(player, newName, target); - Logger.Warning($"Setting {player.BetterData().RealName} name to {newName}, for {target.BetterData().RealName}"); } } } diff --git a/ModInfo.cs b/ModInfo.cs index 58eba65..e37c690 100644 --- a/ModInfo.cs +++ b/ModInfo.cs @@ -4,12 +4,12 @@ internal static class ModInfo { internal static readonly ReleaseTypes ReleaseBuildType = ReleaseTypes.Release; internal const string BetaNum = "0"; - internal const string HotfixNum = "0"; - internal const bool IsHotFix = false; + internal const string HotfixNum = "1"; + internal const bool IsHotFix = true; internal const string PluginName = "BetterAmongUs"; internal const string PluginGuid = "com.ten.betteramongus"; internal const string PluginVersion = "1.3.0"; - internal const string ReleaseDate = "10.19.2025"; // mm/dd/yyyy + internal const string ReleaseDate = "10.24.2025"; // mm/dd/yyyy internal const string Github = "https://github.com/D1GQ/BetterAmongUs-Public"; internal const string Discord = "https://discord.gg/vjYrXpzNAn"; } \ No newline at end of file diff --git a/Mono/PlayerInfoDisplay.cs b/Mono/PlayerInfoDisplay.cs index 0ac19b8..02c8592 100644 --- a/Mono/PlayerInfoDisplay.cs +++ b/Mono/PlayerInfoDisplay.cs @@ -158,12 +158,17 @@ internal class PlayerInfoDisplay : MonoBehaviour if (!_player.IsInShapeshift()) { + if (_player.IsImpostorTeammate()) + newName = newName.ToColor(Colors.ImpostorRed); _player.RawSetName(newName); } else { var targetData = Utils.PlayerDataFromPlayerId(_player.shapeshiftTargetPlayerId); - if (targetData != null) _player.RawSetName(targetData.BetterData()?.RealName ?? targetData.PlayerName); + var name = targetData.BetterData()?.RealName ?? targetData.PlayerName; + if (_player.IsImpostorTeammate()) + name = name.ToColor(Colors.ImpostorRed); + if (targetData != null) _player.RawSetName(name); } UpdateTextIfChanged(_topText, _sbTagTop, ref _lastTopText); @@ -298,7 +303,7 @@ internal class PlayerInfoDisplay : MonoBehaviour if (_player.IsImpostorTeammate() || _player.IsLocalPlayer() || !PlayerControl.LocalPlayer.IsAlive() && !PlayerControl.LocalPlayer.Is(RoleTypes.GuardianAngel)) { - string roleInfo = $"{_player.GetRoleName()}"; + string roleInfo = _player.GetRoleName().ToColor(_player.Data.Role.TeamColor); if (!_player.IsImpostorTeam() && _player.myTasks.Count > 0) { diff --git a/Patches/Gameplay/UI/Settings/GameSettingMenuPatch.cs b/Patches/Gameplay/UI/Settings/GameSettingMenuPatch.cs index 1084812..cd2aa09 100644 --- a/Patches/Gameplay/UI/Settings/GameSettingMenuPatch.cs +++ b/Patches/Gameplay/UI/Settings/GameSettingMenuPatch.cs @@ -63,9 +63,12 @@ internal static class GameSettingMenuPatch BetterGameSettings.UseBanNameList = OptionCheckboxItem.Create(400, BetterSettingsTab, "BetterSetting.Setting.UseBanNameList", true); BetterGameSettings.UseBanWordList = OptionCheckboxItem.Create(500, BetterSettingsTab, "BetterSetting.Setting.UseBanWordList", true); BetterGameSettings.UseBanWordListOnlyLobby = OptionCheckboxItem.Create(1400, BetterSettingsTab, "BetterSetting.Setting.UseBanWordListOnlyLobby", true, BetterGameSettings.UseBanWordList); - OptionDividerItem.Create(BetterSettingsTab); - BetterGameSettings.ShowRoleForClients = OptionCheckboxItem.Create(1700, BetterSettingsTab, "BetterSetting.Setting.ShowRoleForClients", false); - OptionDividerItem.Create(BetterSettingsTab); + + /* + OptionDividerItem.Create(BetterSettingsTab); + BetterGameSettings.ShowRoleForClients = OptionCheckboxItem.Create(1700, BetterSettingsTab, "BetterSetting.Setting.ShowRoleForClients", false); + OptionDividerItem.Create(BetterSettingsTab); + */ } OptionTitleItem.Create(BetterSettingsTab, "BetterSetting.TextHeader.Detections"); @@ -73,12 +76,6 @@ internal static class GameSettingMenuPatch BetterGameSettings.DetectedLevelAbove = OptionIntItem.Create(600, BetterSettingsTab, "BetterSetting.Setting.DetectedLevelAbove", (100, 5000, 5), 200, ("Lv ", "")); BetterGameSettings.DetectCheatClients = OptionCheckboxItem.Create(700, BetterSettingsTab, "BetterSetting.Setting.DetectCheatClients", true); BetterGameSettings.DetectInvalidRPCs = OptionCheckboxItem.Create(800, BetterSettingsTab, "BetterSetting.Setting.DetectInvalidRPCs", true); - - /* - TitleList.Add(new BetterOptionDividerItem().Create(BetterSettingsTab)); - TitleList.Add(new BetterOptionTitleItem().Create(BetterSettingsTab, $"Experimental")); - BetterGameSettings.CancelInvalidSabotage = new BetterOptionCheckboxItem().Create(100000, BetterSettingsTab, "Detect Invalid Sabotages", false); - */ } if (IsPreload || GameState.IsHost) diff --git a/Patches/Managers/RoleManagerPatch.cs b/Patches/Managers/RoleManagerPatch.cs index a844268..3a61285 100644 --- a/Patches/Managers/RoleManagerPatch.cs +++ b/Patches/Managers/RoleManagerPatch.cs @@ -20,10 +20,23 @@ internal static class RoleManagerPatch return clientData?.BetterData()?.IsVerifiedBetterUser != true; }; + [HarmonyPatch(nameof(RoleManager.SetRole))] + [HarmonyPrefix] + private static void RoleManager_Prefix(RoleManager __instance, PlayerControl targetPlayer, RoleTypes roleType) + { + if (RoleManager.IsGhostRole(roleType)) + { + if (!RoleManager.IsGhostRole(targetPlayer.Data.RoleType)) + { + targetPlayer.BetterData().RoleInfo.DeadDisplayRole = targetPlayer.Data.RoleType; + } + } + } + // Better role algorithm [HarmonyPatch(nameof(RoleManager.SelectRoles))] [HarmonyPrefix] - private static bool RoleManager_Prefix(/*RoleManager __instance*/) + private static bool SelectRoles_Prefix(/*RoleManager __instance*/) { if (!GameState.IsHideNSeek) {