A lot of code cleanup, with null checks and guards

This commit is contained in:
D1GQ committed 2026-03-17 22:18:29 -05:00
1 parent 22dcff9b59
commit 01c951f990
79 files changed
+631 -359

No files matched your search

+4 -2
View File
@@ -146,7 +146,8 @@ internal class BAUPlugin : BasePlugin
/// </summary>
private void OnChainloaderFinished()
{
if (!BAUModdedSupportEvents.InvokeAll_OnBAULoad(this)) return;
if (!BAUModdedSupportEvents.InvokeAll_OnBAULoad(this))
return;
BAUModdedSupportFlags.Initialize();
GithubAPI.Connect();
@@ -214,7 +215,8 @@ internal class BAUPlugin : BasePlugin
/// Gets the persistent data path for Among Us.
/// </summary>
/// <returns>The persistent data path string.</returns>
internal static string GetDataPathToAmongUs() => Application.persistentDataPath;
internal static string GetDataPathToAmongUs()
=> Application.persistentDataPath;
/// <summary>
/// Gets the game installation path for Among Us.
+3 -6
View File
@@ -12,7 +12,7 @@ internal sealed class AllCommandsCommand : BaseCommand
internal override void Run()
{
BaseCommand?[] allNormalCommands = allCommands.Where(cmd => cmd.Type == CommandType.Normal && cmd.ShowCommand()).ToArray();
BaseCommand[] allNormalCommands = allCommands.Where(cmd => cmd.Type == CommandType.Normal && cmd.ShowCommand()).ToArray();
string list;
var open = "<color=#858585>┌──────── </color>";
var mid = "<color=#858585>├ </color>";
@@ -21,12 +21,9 @@ internal sealed class AllCommandsCommand : BaseCommand
if (allNormalCommands.Length > 0)
{
for (int i = 0; i < allNormalCommands.Length; i++)
foreach (var command in allNormalCommands)
{
if (i < allNormalCommands.Length)
{
list += $"\n{mid}<color=#e0b700><b>{ChatCommandsPatch.CommandPrefix}{allNormalCommands[i].Name}</b></color> <size=65%><color=#735e00>{allNormalCommands[i].Description}.</color></size>";
}
list += $"\n{mid}<color=#e0b700><b>{ChatCommandsPatch.CommandPrefix}{command.Name}</b></color> <size=65%><color=#735e00>{command.Description}.</color></size>";
}
}
+4 -3
View File
@@ -5,12 +5,12 @@
/// </summary>
/// <param name="command">The command this argument belongs to.</param>
/// <param name="argInfo">Information about the argument.</param>
internal abstract class BaseArgument(BaseCommand? command, string argInfo)
internal abstract class BaseArgument(BaseCommand command, string argInfo)
{
/// <summary>
/// Gets the command this argument belongs to.
/// </summary>
internal BaseCommand? Command { get; } = command;
internal BaseCommand Command { get; } = command;
/// <summary>
/// Gets information about the argument.
@@ -36,5 +36,6 @@ internal abstract class BaseArgument(BaseCommand? command, string argInfo)
/// Gets the closest suggestion for the current argument value.
/// </summary>
/// <returns>The closest matching suggestion, or empty string if none found.</returns>
internal string GetClosestSuggestion() => ArgSuggestions.FirstOrDefault(name => name.StartsWith(Arg, StringComparison.OrdinalIgnoreCase)) ?? string.Empty;
internal string GetClosestSuggestion() =>
ArgSuggestions.FirstOrDefault(name => name.StartsWith(Arg, StringComparison.OrdinalIgnoreCase)) ?? string.Empty;
}
+1 -1
View File
@@ -5,7 +5,7 @@
/// </summary>
/// <param name="command">The command this argument belongs to.</param>
/// <param name="argInfo">Information about the argument (default: "{bool}").</param>
internal sealed class BoolArgument(BaseCommand? command, string argInfo = "{bool}") : BaseArgument(command, argInfo)
internal sealed class BoolArgument(BaseCommand command, string argInfo = "{bool}") : BaseArgument(command, argInfo)
{
/// <summary>
/// Gets the boolean argument suggestions for auto-completion.
+1 -1
View File
@@ -7,7 +7,7 @@ namespace BetterAmongUs.Commands.Arguments;
/// </summary>
/// <param name="command">The command this argument belongs to.</param>
/// <param name="argInfo">Information about the argument (default: "{player}").</param>
internal sealed class PlayerArgument(BaseCommand? command, string argInfo = "{player}") : BaseArgument(command, argInfo)
internal sealed class PlayerArgument(BaseCommand command, string argInfo = "{player}") : BaseArgument(command, argInfo)
{
/// <summary>
/// Gets the player argument suggestions for auto-completion.
+1 -1
View File
@@ -5,7 +5,7 @@
/// </summary>
/// <param name="command">The command this argument belongs to.</param>
/// <param name="argInfo">Information about the argument (default: "{String}").</param>
internal sealed class StringArgument(BaseCommand? command, string argInfo = "{String}") : BaseArgument(command, argInfo)
internal sealed class StringArgument(BaseCommand command, string argInfo = "{String}") : BaseArgument(command, argInfo)
{
// This class inherits the basic string argument functionality from BaseArgument
// and can be extended with string-specific parsing or validation if needed.
+1 -1
View File
@@ -13,7 +13,7 @@ internal abstract class BaseCommand
/// <summary>
/// Gets an array of all registered commands.
/// </summary>
internal static readonly BaseCommand?[] allCommands = [.. RegisterCommandAttribute.Instances];
internal static readonly BaseCommand[] allCommands = [.. RegisterCommandAttribute.Instances];
/// <summary>
/// Gets the type of the command.
+2 -1
View File
@@ -9,7 +9,8 @@ internal sealed class DumpCommand : BaseCommand
{
internal override string Name => "dump";
internal override string Description => "Dump the entire log to the user's desktop";
internal override bool ShowCommand() => !ModInfo.Starlight;
internal override bool ShowCommand() =>
!ModInfo.Starlight;
internal override bool CanRunCommand(out string reason)
{
+2 -1
View File
@@ -8,7 +8,8 @@ internal sealed class EndGameCommand : BaseCommand
{
internal override string Name => "endgame";
internal override string Description => "Force end the game";
internal override bool ShowCommand() => GameState.IsHost && !GameState.IsLobby && !GameState.IsFreePlay;
internal override bool ShowCommand() =>
GameState.IsHost && !GameState.IsLobby && !GameState.IsFreePlay;
internal override void Run()
{
GameManager.Instance.RpcEndGame(GameOverReason.ImpostorDisconnect, false);
+7 -7
View File
@@ -22,17 +22,17 @@ internal sealed class KickCommand : BaseCommand
}
public KickCommand()
{
playerArgument = new PlayerArgument(this);
boolArgument = new BoolArgument(this, "{ban}");
Arguments = [playerArgument, boolArgument];
_playerArgument = new PlayerArgument(this);
_boolArgument = new BoolArgument(this, "{ban}");
Arguments = [_playerArgument, _boolArgument];
}
private PlayerArgument playerArgument { get; }
private BoolArgument boolArgument { get; }
private readonly PlayerArgument _playerArgument;
private readonly BoolArgument _boolArgument;
internal override void Run()
{
var player = playerArgument.TryGetTarget();
var isBan = boolArgument.GetBool();
var player = _playerArgument.TryGetTarget();
var isBan = _boolArgument.GetBool();
if (player != null && isBan != null && !player.IsHost())
{
player.Kick((bool)isBan);
+11 -11
View File
@@ -1,6 +1,6 @@
using BetterAmongUs.Commands.Arguments;
using BetterAmongUs.Attributes;
using BetterAmongUs.Commands.Arguments;
using BetterAmongUs.Helpers;
using BetterAmongUs.Attributes;
using System.Text;
namespace BetterAmongUs.Commands;
@@ -13,26 +13,26 @@ internal sealed class PlayerInfoCommand : BaseCommand
public PlayerInfoCommand()
{
playerArgument = new PlayerArgument(this);
Arguments = [playerArgument];
_playerArgument = new PlayerArgument(this);
Arguments = [_playerArgument];
}
private PlayerArgument playerArgument { get; }
private readonly PlayerArgument _playerArgument;
internal override void Run()
{
var player = playerArgument.TryGetTarget();
if (player != null)
var player = _playerArgument.TryGetTarget();
if (player?.Data != null)
{
StringBuilder sb = new();
var hexColor = Utils.Color32ToHex(Palette.PlayerColors[player.CurrentOutfit.ColorId]);
var format1 = "┌ •";
var format2 = "├ •";
var format3 = "└ •";
sb.Append($"<size=150%><color={hexColor}><b>{player?.Data?.PlayerName}</color> Info:</b></size>\n");
sb.Append($"{format1} <color=#c1c1c1>ID: {player?.Data?.PlayerId}</color>\n");
sb.Append($"{format2} <color=#c1c1c1>HashPUID: {Utils.GetHashStr($"{player?.Data?.Puid}")}</color>\n");
sb.Append($"<size=150%><color={hexColor}><b>{player.Data.PlayerName}</color> Info:</b></size>\n");
sb.Append($"{format1} <color=#c1c1c1>ID: {player.Data.PlayerId}</color>\n");
sb.Append($"{format2} <color=#c1c1c1>HashPUID: {Utils.GetHashStr($"{player.Data.Puid}")}</color>\n");
sb.Append($"{format2} <color=#c1c1c1>Platform: {Utils.GetPlatformName(player)}</color>\n");
sb.Append($"{format3} <color=#c1c1c1>FriendCode: {player?.Data?.FriendCode}</color>");
sb.Append($"{format3} <color=#c1c1c1>FriendCode: {player.Data.FriendCode}</color>");
CommandResultText(sb.ToString());
}
}
+8 -6
View File
@@ -1,5 +1,5 @@
using BetterAmongUs.Helpers;
using BetterAmongUs.Attributes;
using BetterAmongUs.Attributes;
using BetterAmongUs.Helpers;
using System.Text;
namespace BetterAmongUs.Commands;
@@ -15,12 +15,14 @@ internal sealed class PlayersInfoCommand : BaseCommand
StringBuilder sb = new();
foreach (PlayerControl player in BAUPlugin.AllPlayerControls.Where(player => !player.isDummy))
{
if (player?.Data == null) continue;
var hexColor = Utils.Color32ToHex(Palette.PlayerColors[player.CurrentOutfit.ColorId]);
sb.Append($"<color={hexColor}><b>{player?.Data?.PlayerName}</color> Info:</b>\n");
sb.Append($"<color=#c1c1c1>{player?.Data?.PlayerId}</color> - ");
sb.Append($"<color=#c1c1c1>{Utils.GetHashStr($"{player?.Data?.Puid}")}</color> - ");
sb.Append($"<color={hexColor}><b>{player.Data.PlayerName}</color> Info:</b>\n");
sb.Append($"<color=#c1c1c1>{player.Data.PlayerId}</color> - ");
sb.Append($"<color=#c1c1c1>{Utils.GetHashStr($"{player.Data.Puid}")}</color> - ");
sb.Append($"<color=#c1c1c1>{Utils.GetPlatformName(player)}</color> - ");
sb.Append($"<color=#c1c1c1>{player?.Data?.FriendCode}</color>");
sb.Append($"<color=#c1c1c1>{player.Data.FriendCode}</color>");
sb.Append("\n\n");
}
CommandResultText(sb.ToString());
+8 -8
View File
@@ -1,7 +1,7 @@
using BetterAmongUs.Commands.Arguments;
using BetterAmongUs.Attributes;
using BetterAmongUs.Commands.Arguments;
using BetterAmongUs.Data;
using BetterAmongUs.Helpers;
using BetterAmongUs.Attributes;
namespace BetterAmongUs.Commands;
@@ -13,26 +13,26 @@ internal sealed class RemovePlayerCommand : BaseCommand
public RemovePlayerCommand()
{
identifierArgument = new StringArgument(this, "{identifier}")
_identifierArgument = new StringArgument(this, "{identifier}")
{
GetArgSuggestions = () =>
BetterDataManager.BetterDataFile.AllCheatData
.SelectMany(info => new[] { info.HashPuid.Replace(' ', '_'), info.FriendCode.Replace(' ', '_'), info.PlayerName.Replace(' ', '_') })
.ToArray()
};
Arguments = [identifierArgument];
Arguments = [_identifierArgument];
}
private StringArgument identifierArgument { get; }
private readonly StringArgument _identifierArgument;
internal override void Run()
{
if (BetterDataManager.RemovePlayer(identifierArgument.Arg) == true)
if (BetterDataManager.RemovePlayer(_identifierArgument.Arg) == true)
{
Utils.AddChatPrivate($"{identifierArgument.Arg} successfully removed from local <color=#4f92ff>Anti-Cheat</color> data!");
Utils.AddChatPrivate($"{_identifierArgument.Arg} successfully removed from local <color=#4f92ff>Anti-Cheat</color> data!");
}
else
{
Utils.AddChatPrivate($"{identifierArgument.Arg} Could not find player data from identifier");
Utils.AddChatPrivate($"{_identifierArgument.Arg} Could not find player data from identifier");
}
}
}
+6 -5
View File
@@ -13,17 +13,18 @@ internal sealed class SetPrefixCommand : BaseCommand
internal SetPrefixCommand()
{
prefixArgument = new StringArgument(this, "{prefix}");
Arguments = [prefixArgument];
_prefixArgument = new StringArgument(this, "{prefix}");
Arguments = [_prefixArgument];
}
private StringArgument? prefixArgument { get; }
private readonly StringArgument _prefixArgument;
internal override bool ShowCommand() => !BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Force_BAU_Command_Prefix);
internal override bool ShowCommand() =>
!BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Force_BAU_Command_Prefix);
internal override void Run()
{
var oldPrefix = BAUConfigs.CommandPrefix.Value;
var prefix = prefixArgument.Arg.ToCharArray()?.First().ToString();
var prefix = _prefixArgument.Arg.ToCharArray()?.First().ToString();
if (!string.IsNullOrEmpty(prefix))
{
BAUConfigs.CommandPrefix.Value = prefix;
+1 -1
View File
@@ -57,7 +57,7 @@ internal static class BetterDataManager
/// <summary>
/// Current compressed settings file path.
/// </summary>
internal static string SettingsFile => Path.Combine(filePathFolderSettings, $"Preset-{BAUConfigs.SettingsPreset?.Value ?? 0}.dat");
internal static string SettingsFile => Path.Combine(filePathFolderSettings, $"Preset-{BAUConfigs.SettingsPreset.Value}.dat");
/// <summary>
/// File containing banned player identifiers.
+16 -16
View File
@@ -11,82 +11,82 @@ internal static class BAUConfigs
/// <summary>
/// Gets the configuration entry for anti-cheat setting.
/// </summary>
internal static BAUConfigEntry<bool>? AntiCheat { get; } = new("Better Options", "AntiCheat", true);
internal static BAUConfigEntry<bool> AntiCheat { get; } = new("Better Options", "AntiCheat", true);
/// <summary>
/// Gets the configuration entry for sending Better RPC setting.
/// </summary>
internal static BAUConfigEntry<bool>? SendBetterRpc { get; } = new("Better Options", "SendBetterRpc", true);
internal static BAUConfigEntry<bool> SendBetterRpc { get; } = new("Better Options", "SendBetterRpc", true);
/// <summary>
/// Gets the configuration entry for better notifications setting.
/// </summary>
internal static BAUConfigEntry<bool>? BetterNotifications { get; } = new("Better Options", "BetterNotifications", true);
internal static BAUConfigEntry<bool> BetterNotifications { get; } = new("Better Options", "BetterNotifications", true);
/// <summary>
/// Gets the configuration entry for force own language setting.
/// </summary>
internal static BAUConfigEntry<bool>? ForceOwnLanguage { get; } = new("Better Options", "ForceOwnLanguage", false);
internal static BAUConfigEntry<bool> ForceOwnLanguage { get; } = new("Better Options", "ForceOwnLanguage", false);
/// <summary>
/// Gets the configuration entry for chat dark mode setting.
/// </summary>
internal static BAUConfigEntry<bool>? ChatDarkMode { get; } = new("Better Options", "ChatDarkMode", true);
internal static BAUConfigEntry<bool> ChatDarkMode { get; } = new("Better Options", "ChatDarkMode", true);
/// <summary>
/// Gets the configuration entry for chat in gameplay setting.
/// </summary>
internal static BAUConfigEntry<bool>? ChatInGameplay { get; } = new("Better Options", "ChatInGameplay", true);
internal static BAUConfigEntry<bool> ChatInGameplay { get; } = new("Better Options", "ChatInGameplay", true);
/// <summary>
/// Gets the configuration entry for lobby player info setting.
/// </summary>
internal static BAUConfigEntry<bool>? LobbyPlayerInfo { get; } = new("Better Options", "LobbyPlayerInfo", true);
internal static BAUConfigEntry<bool> LobbyPlayerInfo { get; } = new("Better Options", "LobbyPlayerInfo", true);
/// <summary>
/// Gets the configuration entry for disable lobby theme setting.
/// </summary>
internal static BAUConfigEntry<bool>? DisableLobbyTheme { get; } = new("Better Options", "DisableLobbyTheme", true);
internal static BAUConfigEntry<bool> DisableLobbyTheme { get; } = new("Better Options", "DisableLobbyTheme", true);
/// <summary>
/// Gets the configuration entry for unlock FPS setting.
/// </summary>
internal static BAUConfigEntry<bool>? UnlockFPS { get; } = new("Better Options", "UnlockFPS", false);
internal static BAUConfigEntry<bool> UnlockFPS { get; } = new("Better Options", "UnlockFPS", false);
/// <summary>
/// Gets the configuration entry for show FPS setting.
/// </summary>
internal static BAUConfigEntry<bool>? ShowFPS { get; } = new("Better Options", "ShowFPS", false);
internal static BAUConfigEntry<bool> ShowFPS { get; } = new("Better Options", "ShowFPS", false);
/// <summary>
/// Gets the configuration entry for minimap icons setting.
/// </summary>
internal static BAUConfigEntry<bool>? MinimapIcons { get; } = new("Better Options", "MinimapIcons", true);
internal static BAUConfigEntry<bool> MinimapIcons { get; } = new("Better Options", "MinimapIcons", true);
/// <summary>
/// Gets the configuration entry for vent color groups setting.
/// </summary>
internal static BAUConfigEntry<bool>? VentColorGroups { get; } = new("Better Options", "VentColorGroups", true);
internal static BAUConfigEntry<bool> VentColorGroups { get; } = new("Better Options", "VentColorGroups", true);
/// <summary>
/// Gets the configuration entry for command prefix setting.
/// </summary>
internal static BAUConfigEntry<string>? CommandPrefix { get; } = new("Mod", "CommandPrefix", "/");
internal static BAUConfigEntry<string> CommandPrefix { get; } = new("Mod", "CommandPrefix", "/");
/// <summary>
/// Gets the configuration entry for private only lobby setting.
/// </summary>
internal static BAUConfigEntry<bool>? PrivateOnlyLobby { get; } = new("Mod", "PrivateOnlyLobby", false);
internal static BAUConfigEntry<bool> PrivateOnlyLobby { get; } = new("Mod", "PrivateOnlyLobby", false);
/// <summary>
/// Gets the configuration entry for favorite color setting.
/// </summary>
internal static BAUConfigEntry<int>? FavoriteColor { get; } = new("Mod", "FavoriteColor", -1);
internal static BAUConfigEntry<int> FavoriteColor { get; } = new("Mod", "FavoriteColor", -1);
/// <summary>
/// Gets the configuration entry for the settings preset.
/// </summary>
internal static BAUConfigEntry<int>? SettingsPreset { get; } = new("Mod", "SettingsPreset", 0);
internal static BAUConfigEntry<int> SettingsPreset { get; } = new("Mod", "SettingsPreset", 0);
/// <summary>
/// Loads configuration options from BepInEx config file.
+3 -1
View File
@@ -32,7 +32,9 @@ internal abstract class AbstractJsonFile
/// </summary>
internal virtual void Init()
{
if (_hasInit) return;
if (_hasInit)
return;
_hasInit = true;
if (!IsFileValid())
+2 -1
View File
@@ -43,7 +43,8 @@ internal sealed class BetterDataFile : AbstractJsonFile
/// </summary>
/// <param name="data">The player information to check.</param>
/// <returns>True if the player matches a cheat entry, false otherwise.</returns>
internal bool CheckPlayerData(NetworkedPlayerInfo data) => CheckPlayerDataWithReason(data).check;
internal bool CheckPlayerData(NetworkedPlayerInfo data) =>
CheckPlayerDataWithReason(data).check;
/// <summary>
/// Checks if player data matches any known cheat entries and provides a reason if found.
+7 -3
View File
@@ -37,14 +37,16 @@ internal sealed class OutfitData
/// Gets the outfit data for the currently selected preset.
/// </summary>
/// <returns>The outfit data for the current preset.</returns>
internal static OutfitData GetOutfitData() => BetterDataManager.BetterDataFile.OutfitData.ElementAt(BetterDataManager.BetterDataFile.SelectedOutfitPreset);
internal static OutfitData GetOutfitData() =>
BetterDataManager.BetterDataFile.OutfitData.ElementAt(BetterDataManager.BetterDataFile.SelectedOutfitPreset);
/// <summary>
/// Gets the outfit data for a specific preset index.
/// </summary>
/// <param name="index">The index of the preset to retrieve.</param>
/// <returns>The outfit data for the specified preset.</returns>
internal static OutfitData GetOutfitData(int index) => BetterDataManager.BetterDataFile.OutfitData.ElementAt(index);
internal static OutfitData GetOutfitData(int index) =>
BetterDataManager.BetterDataFile.OutfitData.ElementAt(index);
private static bool ignoreChange;
@@ -57,7 +59,9 @@ internal sealed class OutfitData
var Save = () =>
{
if (ignoreChange) return;
if (ignoreChange)
return;
GetOutfitData().SetFromData();
BetterDataManager.BetterDataFile.Save();
};
+7 -4
View File
@@ -16,10 +16,13 @@ internal sealed class AppearReplayEvent : IReplayEvent<(int playerId, bool anima
public void Play()
{
var player = Utils.PlayerFromPlayerId(EventData.playerId);
if (player?.Data.RoleType is RoleTypes.Phantom)
{
player?.SetRoleInvisibility(false, EventData.animate, true);
}
if (player == null)
return;
if (player.Data.RoleType != RoleTypes.Phantom)
return;
player.SetRoleInvisibility(false, EventData.animate, true);
}
public void Record(PlayerControl player, bool animate)
+7 -1
View File
@@ -15,8 +15,14 @@ internal sealed class MurderReplayEvent : IReplayEvent<(int killerId, int target
public void Play()
{
var killer = Utils.PlayerFromPlayerId(EventData.killerId);
if (killer == null)
return;
var target = Utils.PlayerFromPlayerId(EventData.targetId);
killer?.MurderPlayer(target, MurderResultFlags.Succeeded);
if (target == null)
return;
killer.MurderPlayer(target, MurderResultFlags.Succeeded);
}
public void Record(PlayerControl killer, PlayerControl target)
+10 -4
View File
@@ -16,11 +16,17 @@ internal sealed class ProtectReplayEvent : IReplayEvent<(int playerId, int targe
public void Play()
{
var player = Utils.PlayerFromPlayerId(EventData.playerId);
if (player == null)
return;
var target = Utils.PlayerFromPlayerId(EventData.targetId);
if (player?.Data.RoleType is RoleTypes.GuardianAngel)
{
player?.ProtectPlayer(target, player.Data.DefaultOutfit.ColorId);
}
if (target == null)
return;
if (player.Data.RoleType != RoleTypes.GuardianAngel)
return;
player.ProtectPlayer(target, player.Data.DefaultOutfit.ColorId);
}
public void Record(PlayerControl player, PlayerControl target)
@@ -16,11 +16,17 @@ internal sealed class ShapeshiftReplayEvent : IReplayEvent<(int playerId, int ta
public void Play()
{
var player = Utils.PlayerFromPlayerId(EventData.playerId);
if (player == null)
return;
var target = Utils.PlayerFromPlayerId(EventData.targetId);
if (player?.Data.RoleType is RoleTypes.Shapeshifter)
{
player?.Shapeshift(target, EventData.animate);
}
if (target == null)
return;
if (player.Data.RoleType != RoleTypes.Shapeshifter)
return;
player.Shapeshift(target, EventData.animate);
}
public void Record(PlayerControl killer, PlayerControl target, bool animate)
@@ -15,10 +15,13 @@ internal sealed class UpdateSystemReplayEvent : IReplayEvent<(byte systemType, i
public void Play()
{
var player = Utils.PlayerFromPlayerId(EventData.playerId);
if (player != null)
{
ShipStatus.Instance?.UpdateSystem((SystemTypes)EventData.systemType, player, EventData.amount);
}
if (player == null)
return;
if (ShipStatus.Instance == null)
return;
ShipStatus.Instance?.UpdateSystem((SystemTypes)EventData.systemType, player, EventData.amount);
}
public void Record(SystemTypes system, PlayerControl player, byte amount)
+7 -4
View File
@@ -16,10 +16,13 @@ internal sealed class VanishReplayEvent : IReplayEvent<int>
public void Play()
{
var player = Utils.PlayerFromPlayerId(EventData);
if (player?.Data.RoleType is RoleTypes.Phantom)
{
player?.SetRoleInvisibility(true, true, true);
}
if (player == null)
return;
if (player.Data.RoleType != RoleTypes.Phantom)
return;
player.SetRoleInvisibility(true, true, true);
}
public void Record(PlayerControl player)
+3 -1
View File
@@ -184,7 +184,9 @@ internal sealed class SharedSecretExchange
/// </summary>
internal void ClearData()
{
if (HasBeenCleared) return;
if (HasBeenCleared)
return;
HasBeenCleared = true;
publicKey = [];
tempKey = 0;
+4 -2
View File
@@ -15,7 +15,8 @@ internal static class Il2CppExtensions
/// <param name="action">The action to perform on each element.</param>
internal static void ForEachIl2Cpp<T>(this Il2CppSystem.Collections.Generic.IEnumerable<T> source, Action<T> action)
{
if (source == null || action == null) return;
if (source == null || action == null)
return;
var list = new Il2CppSystem.Collections.Generic.List<T>(source);
for (int i = 0; i < list.Count; i++)
@@ -54,7 +55,8 @@ internal static class Il2CppExtensions
/// <param name="action">The action to perform on each element.</param>
internal static void ForEachIl2Cpp<T>(this Il2CppSystem.Collections.Generic.List<T> source, Action<T> action)
{
if (source == null || action == null) return;
if (source == null || action == null)
return;
// Direct iteration - no conversion needed!
for (int i = 0; i < source.Count; i++)
+8 -4
View File
@@ -24,7 +24,8 @@ internal static class Logger_
{
try
{
if (hostOnly && !GameState.IsHost) return;
if (hostOnly && !GameState.IsHost)
return;
string mark = $"{DateTime.Now:HH:mm} [BetterLog][{tag}]";
string logFilePath = Path.Combine(BetterDataManager.filePathFolder, "better-log.txt");
@@ -163,7 +164,8 @@ internal static class Logger_
/// <param name="hostOnly">Whether to log only when the client is host.</param>
internal static void InGame(string info, bool hostOnly = false)
{
if (hostOnly && !GameState.IsHost) return;
if (hostOnly && !GameState.IsHost)
return;
if (HudManager.InstanceExists) HudManager.Instance.Notifier.AddDisconnectMessage(info);
Log(info, "InGame", hostOnly: hostOnly);
@@ -179,7 +181,8 @@ internal static class Logger_
{
try
{
if (hostOnly && !GameState.IsHost) return;
if (hostOnly && !GameState.IsHost)
return;
string mark = $"{DateTime.Now:HH:mm} [BetterLog][PrivateLog][{tag}]";
string logFilePath = Path.Combine(BetterDataManager.filePathFolder, "better-log.txt");
@@ -208,7 +211,8 @@ internal class CustomLogListener : ILogListener
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if (eventArgs.Source.SourceName.ToLower().Contains("unity")
|| eventArgs.Source.SourceName.ToLower().Contains("betteramongus")) return;
|| eventArgs.Source.SourceName.ToLower().Contains("betteramongus"))
return;
if (eventArgs.Level is LogLevel.None or LogLevel.Info)
{
+6 -3
View File
@@ -127,7 +127,8 @@ internal static class ObjectHelper
/// <param name="avoidGoName">Names of GameObjects to skip when applying colors.</param>
internal static void SetUIColors(this GameObject go, Color? color = null, Func<SpriteRenderer, bool>? check = null, params string[] avoidGoName)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Theme)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Theme))
return;
var sprites = go.GetComponentsInChildren<SpriteRenderer>(true);
foreach (var sprite in sprites)
@@ -145,7 +146,8 @@ internal static class ObjectHelper
/// <param name="color">The color to blend (defaults to green if null).</param>
internal static void AddColor(SpriteRenderer sprite, Color? color = null)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Theme)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Theme))
return;
color ??= Color.green;
sprite.color = (sprite.color * 0.6f) + ((Color)color * 0.5f);
@@ -159,7 +161,8 @@ internal static class ObjectHelper
internal static void SetLayers(this GameObject go, string layerName)
{
int layer = LayerMask.NameToLayer(layerName);
if (layer == -1) return;
if (layer == -1)
return;
Transform[] allChildren = go.GetComponentsInChildren<Transform>(true);
foreach (Transform child in allChildren)
+20 -8
View File
@@ -26,7 +26,9 @@ internal static class PlayerControlHelper
foreach (var client in AmongUsClient.Instance.allClients)
{
if (client?.Character?.PlayerId == player.PlayerId)
if (client?.Character == null) continue;
if (client.Character.PlayerId == player.PlayerId)
return client;
}
return null;
@@ -46,7 +48,8 @@ internal static class PlayerControlHelper
/// <returns>The colored player name string.</returns>
internal static string GetPlayerNameAndColor(this PlayerControl player)
{
if (player?.Data == null) return string.Empty;
if (player?.Data == null)
return string.Empty;
try
{
@@ -72,8 +75,11 @@ internal static class PlayerControlHelper
return true;
}
if (player.cosmetics?.nameText == null)
return false;
string loading = Translator.GetString("Player.Loading");
string? nameText = player.cosmetics?.nameText?.text;
string nameText = player.cosmetics.nameText.text;
if (nameText == "???" || nameText == "Player" || nameText == loading ||
string.IsNullOrEmpty(nameText) ||
@@ -188,7 +194,8 @@ internal static class PlayerControlHelper
/// <returns>The vent ID, or -1 if not in a vent.</returns>
internal static int GetPlayerVentId(this PlayerControl player)
{
if (player == null) return -1;
if (player == null)
return -1;
if (!(ShipStatus.Instance.Systems.TryGetValue(SystemTypes.Ventilation, out var systemType) &&
systemType.TryCast<VentilationSystem>() is VentilationSystem ventilationSystem))
@@ -202,21 +209,24 @@ internal static class PlayerControlHelper
/// </summary>
/// <param name="player">The player to get the position for.</param>
/// <returns>The player's position as a Vector2.</returns>
internal static Vector2 GetCustomPosition(this PlayerControl player) => new(player.transform.position.x, player.transform.position.y);
internal static Vector2 GetCustomPosition(this PlayerControl player) =>
player.transform.position;
/// <summary>
/// Checks if a player is alive.
/// </summary>
/// <param name="player">The player to check.</param>
/// <returns>True if the player is alive.</returns>
internal static bool IsAlive(this PlayerControl player) => player?.Data != null && !player.Data.IsDead;
internal static bool IsAlive(this PlayerControl player) =>
player?.Data != null && !player.Data.IsDead;
/// <summary>
/// Checks if a player is in a vent.
/// </summary>
/// <param name="player">The player to check.</param>
/// <returns>True if the player is in a vent.</returns>
internal static bool IsInVent(this PlayerControl player) => player != null && (player.inVent || player.walkingToVent || player.MyPhysics?.Animations?.IsPlayingEnterVentAnimation() == true);
internal static bool IsInVent(this PlayerControl player) =>
player != null && (player.inVent || player.walkingToVent || player.MyPhysics?.Animations?.IsPlayingEnterVentAnimation() == true);
/// <summary>
/// Gets the role name of a player.
@@ -362,7 +372,9 @@ internal static class PlayerControlHelper
/// <returns>The hashed PUID string.</returns>
internal static string GetHashPuid(this NetworkedPlayerInfo data)
{
if (data?.Puid == null) return "";
if (data?.Puid == null)
return "";
return Utils.GetHashStr(data.Puid);
}
+10 -4
View File
@@ -155,13 +155,16 @@ internal static class Utils
/// <param name="setRight">Whether to align the message to the right side.</param>
internal static void AddChatPrivate(string text, string overrideName = "", bool setRight = false)
{
if (!GameState.IsInGame) return;
if (!GameState.IsInGame)
return;
var chat = HudManager.Instance?.Chat;
if (chat == null) return;
if (chat == null)
return;
var data = PlayerControl.LocalPlayer?.Data;
if (data == null) return;
if (data == null)
return;
var pooledBubble = chat.GetPooledBubble();
var messageName = $"<color=#ffffff><b>(<color=#00ff44>{Translator.GetString("SystemMessage")}</color>)</b>" + ChatPatch.COMMAND_POSTFIX_ID;
@@ -233,7 +236,10 @@ internal static class Utils
/// <returns>The hashed PUID string.</returns>
internal static string GetHashPuid(PlayerControl player)
{
return player?.Data?.Puid == null ? "" : GetHashStr(player.Data.Puid);
if (player?.Data?.Puid == null)
return "";
return GetHashStr(player.Data.Puid);
}
/// <summary>
+118 -45
View File
@@ -15,13 +15,71 @@ namespace BetterAmongUs.Managers;
/// </summary>
internal static class BetterNotificationManager
{
internal static GameObject? BAUNotificationManagerObj;
internal static TextMeshPro? NameText;
internal static TextMeshPro? TextArea => BAUNotificationManagerObj.transform.Find("Sizer/ChatText (TMP)").GetComponent<TextMeshPro>();
internal static Dictionary<string, float> NotifyQueue = [];
internal static float showTime = 0f;
private static GameObject? BAUNotificationManagerObj;
private static TextMeshPro? NameText;
private static TextMeshPro? TextArea;
private readonly static Dictionary<string, float> NotifyQueue = [];
private static float showTime = 0f;
private static Camera? localCamera;
internal static bool Notifying = false;
private static bool Notifying = false;
/// <summary>
/// Initializes the BetterNotificationManager by creating and configuring a cloned instance of the game's chat notification system.
/// </summary>
internal static void Init()
{
if (BAUNotificationManagerObj == null)
{
var ChatNotifications = HudManager.Instance.Chat.chatNotification;
if (ChatNotifications != null)
{
ChatNotifications.timeOnScreen = 1f;
ChatNotifications.gameObject.SetActive(true);
// Clone chat notification system for BAU notifications
GameObject BAUNotification = UnityEngine.Object.Instantiate(ChatNotifications.gameObject);
BAUNotification.name = "BAUNotification";
BAUNotification.GetComponent<ChatNotification>().DestroyMono();
// Remove unnecessary elements from the clone
GameObject.Find($"{BAUNotification.name}/Sizer/PoolablePlayer").DestroyObj();
GameObject.Find($"{BAUNotification.name}/Sizer/ColorText").DestroyObj();
// Position notification at bottom-left corner
BAUNotification.GetComponent<AspectPosition>().DistanceFromEdge = new Vector3(-1.57f, 5.3f, -15f);
GameObject.Find($"{BAUNotification.name}/Sizer/NameText").transform.localPosition = new Vector3(-3.3192f, -0.0105f);
// Cache TextMeshPro component for text updates
NameText = GameObject.Find($"{BAUNotification.name}/Sizer/NameText").GetComponent<TextMeshPro>();
UnityEngine.Object.DontDestroyOnLoad(BAUNotification);
BAUNotificationManagerObj = BAUNotification;
BAUNotification.SetActive(false);
// Reset original chat notification settings
ChatNotifications.timeOnScreen = 0f;
ChatNotifications.gameObject.SetActive(false);
// Configure text wrapping for multi-line notifications
TextArea = BAUNotificationManagerObj.transform.Find("Sizer/ChatText (TMP)").GetComponent<TextMeshPro>();
TextArea.enableWordWrapping = true;
TextArea.m_firstOverflowCharacterIndex = 0;
TextArea.overflowMode = TextOverflowModes.Overflow;
}
}
}
/// <summary>
/// Cleans up and destroys the notification manager.
/// </summary>
internal static void Detach()
{
NotifyQueue.Clear();
if (BAUNotificationManagerObj == null)
return;
BAUNotificationManagerObj.DestroyObj();
}
/// <summary>
/// Displays a notification message in-game.
@@ -30,25 +88,27 @@ internal static class BetterNotificationManager
/// <param name="Time">The duration in seconds to show the notification.</param>
internal static void Notify(string text, float Time = 5f)
{
if (!BAUConfigs.BetterNotifications.Value) return;
if (!BAUConfigs.BetterNotifications.Value)
return;
if (BAUNotificationManagerObj != null)
if (BAUNotificationManagerObj == null)
return;
if (Notifying)
{
if (Notifying)
{
if (text == BAUNotificationManagerObj.transform.Find("Sizer/ChatText (TMP)").GetComponent<TextMeshPro>().text)
return;
NotifyQueue[text] = Time;
if (text == TextArea.text)
return;
}
showTime = Time;
BAUNotificationManagerObj.SetActive(true);
NameText.text = $"<color=#00ff44>{Translator.GetString("SystemNotification")}</color>";
TextArea.text = text;
SoundManager.Instance.PlaySound(HudManager.Instance.TaskCompleteSound, false, 1f);
Notifying = true;
NotifyQueue[text] = Time;
return;
}
showTime = Time;
BAUNotificationManagerObj.SetActive(true);
NameText.text = $"<color=#00ff44>{Translator.GetString("SystemNotification")}</color>";
TextArea.text = text;
SoundManager.Instance.PlaySound(HudManager.Instance.TaskCompleteSound, false, 1f);
Notifying = true;
}
/// <summary>
@@ -115,42 +175,55 @@ internal static class BetterNotificationManager
return true;
}
/// <summary>
/// Clears all pending and active notifications by resetting the notification queue, display timer, and notification state.
/// </summary>
internal static void ClearNotifications()
{
NotifyQueue.Clear();
showTime = 0f;
Notifying = false;
}
/// <summary>
/// Updates the notification manager each frame.
/// </summary>
internal static void Update()
{
if (BAUNotificationManagerObj != null)
if (BAUNotificationManagerObj == null)
return;
if (TextArea == null)
return;
if (!localCamera)
{
if (!localCamera)
if (HudManager.InstanceExists)
{
if (HudManager.InstanceExists)
{
localCamera = HudManager.Instance.GetComponentInChildren<Camera>();
}
else
{
localCamera = Camera.main;
}
localCamera = HudManager.Instance.GetComponentInChildren<Camera>();
}
BAUNotificationManagerObj.transform.position = AspectPosition.ComputeWorldPosition(localCamera, AspectPosition.EdgeAlignments.Bottom, new Vector3(-1.3f, 0.7f, localCamera.nearClipPlane + 0.1f));
showTime -= Time.deltaTime;
if (showTime <= 0f && GameState.IsInGame)
else
{
BAUNotificationManagerObj.transform.Find("Sizer/ChatText (TMP)").GetComponent<TextMeshPro>().text = "";
BAUNotificationManagerObj.SetActive(false);
Notifying = false;
CheckNotifyQueue();
localCamera = Camera.main;
}
}
if (!GameState.IsInGame)
{
BAUNotificationManagerObj.SetActive(false);
showTime = 0f;
}
BAUNotificationManagerObj.transform.position = AspectPosition.ComputeWorldPosition(localCamera, AspectPosition.EdgeAlignments.Bottom, new Vector3(-1.3f, 0.7f, localCamera.nearClipPlane + 0.1f));
showTime -= Time.deltaTime;
if (showTime <= 0f && GameState.IsInGame)
{
TextArea.text = "";
BAUNotificationManagerObj.SetActive(false);
Notifying = false;
CheckNotifyQueue();
}
if (!GameState.IsInGame)
{
BAUNotificationManagerObj.SetActive(false);
showTime = 0f;
}
}
+5 -2
View File
@@ -42,7 +42,8 @@ internal sealed class UpdateManager : MonoBehaviour
/// </summary>
internal void OnMainMenu()
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_ModUpdate)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_ModUpdate))
return;
var doNotPress = FindObjectOfType<DoNotPressButton>(true);
if (doNotPress != null)
@@ -59,7 +60,9 @@ internal sealed class UpdateManager : MonoBehaviour
button.OnClick = new();
button.OnClick.AddListener(() =>
{
if (AmUpdateing || WaitForRestart) return;
if (AmUpdateing || WaitForRestart)
return;
this.StartCoroutine(CoPressDownload(doNotPress));
});
}
+16 -5
View File
@@ -67,7 +67,8 @@ internal static class BetterAntiCheat
/// <param name="oldReader">The MessageReader containing RPC data.</param>
internal static void HandleCheatRPCBeforeCheck(PlayerControl player, byte callId, MessageReader oldReader)
{
if (!IsEnabled) return;
if (!IsEnabled)
return;
MessageReader reader = MessageReader.Get(oldReader);
RPCHandler.HandleRPC(callId, player, reader, HandlerFlag.CheatRpcCheck);
@@ -82,9 +83,18 @@ internal static class BetterAntiCheat
/// <param name="oldReader">The MessageReader containing RPC data.</param>
internal static void CheckRPC(PlayerControl player, byte callId, MessageReader oldReader)
{
if (player == null || player?.Data == null) return;
if (!IsEnabled || !BAUConfigs.AntiCheat.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || !BetterGameSettings.DetectInvalidRPCs.GetBool()) return;
if (player.IsLocalPlayer() && player.IsHost()) return;
if (!IsEnabled || !BAUConfigs.AntiCheat.Value)
return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) ||
!BetterGameSettings.DetectInvalidRPCs.GetBool())
return;
if (player?.Data == null)
return;
if (player.IsLocalPlayer() && player.IsHost())
return;
MessageReader reader = MessageReader.Get(oldReader);
RPCHandler.HandleRPC(callId, player, reader, HandlerFlag.AntiCheat);
@@ -224,7 +234,8 @@ internal static class BetterAntiCheat
/// <param name="oldReader">The MessageReader containing RPC data.</param>
internal static void HandleRPC(PlayerControl player, byte callId, MessageReader oldReader)
{
if (player == null || player?.Data == null || player.IsLocalPlayer()) return;
if (player?.Data == null || player.IsLocalPlayer())
return;
MessageReader reader = MessageReader.Get(oldReader);
RPCHandler.HandleRPC(callId, player, reader, HandlerFlag.Handle);
@@ -32,7 +32,11 @@ internal sealed class AUMChatHandler : RPCHandler
Logger_.Log($"{sender.Data.PlayerName} -> {msgString}", "AUMChatLog");
if (!BAUConfigs.AntiCheat.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || !BetterGameSettings.DetectCheatClients.GetBool()) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat))
return;
if (!BAUConfigs.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool())
return;
var flag = string.IsNullOrEmpty(nameString) && string.IsNullOrEmpty(msgString);
@@ -19,7 +19,11 @@ internal sealed class KillNetworkChatHandler : RPCHandler
internal override void HandleCheatRpcCheck(PlayerControl? sender, MessageReader reader)
{
if (!BAUConfigs.AntiCheat.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || !BetterGameSettings.DetectCheatClients.GetBool()) return;
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)))
{
@@ -17,7 +17,9 @@ internal sealed class DeserializeNetObjectHandler : RPCHandler
if (innerNetObject?.TryCast<CustomNetworkTransform>() && (GameState.IsMeeting && MeetingHudPatch.timeOpen > 5))
{
var player = innerNetObject.Cast<CustomNetworkTransform>()?.myPlayer;
if (player == null) return;
if (player == null)
return;
if (BetterNotificationManager.NotifyCheat(player, "Attempting to move in meeting", forceBan: true))
{
LogRpcInfo($"Player attempted to move during meeting", player);
+7 -3
View File
@@ -140,7 +140,8 @@ internal sealed class ClientOptionItem
passiveButton.OnClick.AddListener(() =>
{
if (toggleCheck?.Invoke() == false) return;
if (toggleCheck?.Invoke() == false)
return;
if (Config != null)
{
@@ -168,7 +169,9 @@ internal sealed class ClientOptionItem
passiveButton.OnClick.AddListener(() =>
{
if (clickCheck?.Invoke() == false) return;
if (clickCheck?.Invoke() == false)
return;
onClick?.Invoke();
});
}
@@ -178,7 +181,8 @@ internal sealed class ClientOptionItem
/// </summary>
internal void UpdateToggle()
{
if (ToggleButton == null || Config == null) return;
if (ToggleButton == null || Config == null)
return;
UpdateToggleVisuals(Config.Value);
}
+17 -7
View File
@@ -55,8 +55,11 @@ internal sealed class HandshakeHandler
/// </summary>
internal void ResendSecretToPlayer()
{
if (!BAUConfigs.SendBetterRpc.Value) return;
if (HasSendSharedSecret && _extendedData.IsVerifiedBetterUser) return;
if (!BAUConfigs.SendBetterRpc.Value)
return;
if (HasSendSharedSecret && _extendedData.IsVerifiedBetterUser)
return;
HasSendSharedSecret = false;
SendSecretToPlayer();
@@ -68,8 +71,11 @@ internal sealed class HandshakeHandler
// Local client sends to client
private void SendSecretToPlayer()
{
if (_extendedData._Data.Object.IsLocalPlayer()) return;
if (HasSendSharedSecret) return;
if (_extendedData._Data.Object.IsLocalPlayer())
return;
if (HasSendSharedSecret)
return;
HasSendSharedSecret = true;
@@ -88,7 +94,8 @@ internal sealed class HandshakeHandler
// Client receives from local client
internal void HandleSecretFromSender(MessageReader reader)
{
if (_extendedData._Data?.Object?.IsLocalPlayer() == true) return;
if (_extendedData._Data?.Object?.IsLocalPlayer() == true)
return;
bool senderSupportsCrypto = reader.ReadBoolean();
byte[] sendersPublicKey = reader.ReadBytes();
@@ -151,8 +158,11 @@ internal sealed class HandshakeHandler
/// </summary>
internal void TryHandlePendingVerificationData()
{
if (!_pendingVerificationData.HasValue) return;
if (SharedSecret.GetSharedSecret().Length == 0) return;
if (!_pendingVerificationData.HasValue)
return;
if (SharedSecret.GetSharedSecret().Length == 0)
return;
var (tempKey, receivedHash) = _pendingVerificationData.Value;
+2 -1
View File
@@ -184,7 +184,8 @@ internal static class MonoExtensionManager
/// <param name="extension">The extension to unregister.</param>
internal static void UnregisterExtension(this IMonoExtension extension)
{
if (extension.BaseMono == null) return;
if (extension.BaseMono == null)
return;
if (_extensionsByBaseType.TryGetValue(extension.BaseMono.GetType(), out var extensions))
{
@@ -47,7 +47,9 @@ internal sealed class OptionDividerItem : OptionItem
/// </summary>
private void CreateBehavior()
{
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
CategoryHeaderMasked categoryHeaderMasked = UnityEngine.Object.Instantiate(Tab.AUTab.categoryHeaderOrigin, Tab.AUTab.settingsContainer);
Obj = categoryHeaderMasked.gameObject;
@@ -50,7 +50,9 @@ internal sealed class OptionHeaderItem : OptionItem
/// </summary>
private void CreateBehavior()
{
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
categoryHeaderMasked = UnityEngine.Object.Instantiate(Tab.AUTab.categoryHeaderOrigin, Tab.AUTab.settingsContainer);
Obj = categoryHeaderMasked.gameObject;
@@ -51,7 +51,9 @@ internal sealed class OptionTitleItem : OptionItem
/// </remarks>
private void CreateBehavior()
{
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
optionBehaviour = UnityEngine.Object.Instantiate(Tab.AUTab.checkboxOrigin, Tab.AUTab.settingsContainer);
Obj = optionBehaviour.gameObject;
@@ -53,7 +53,9 @@ public sealed class OptionCheckboxItem : OptionItem<bool>
protected sealed override void CreateBehavior()
{
TryLoad();
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
var ToggleOption = UnityEngine.Object.Instantiate(Tab.AUTab.checkboxOrigin, Tab.AUTab.settingsContainer);
Option = ToggleOption;
+3 -1
View File
@@ -80,7 +80,9 @@ public class OptionFloatItem : OptionItem<float>
protected override void CreateBehavior()
{
TryLoad();
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
var numberOption = UnityEngine.Object.Instantiate(Tab.AUTab.numberOptionOrigin, Tab.AUTab.settingsContainer);
Option = numberOption;
+3 -1
View File
@@ -80,7 +80,9 @@ public sealed class OptionIntItem : OptionItem<int>
protected sealed override void CreateBehavior()
{
TryLoad();
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
var numberOption = UnityEngine.Object.Instantiate(Tab.AUTab.numberOptionOrigin, Tab.AUTab.settingsContainer);
Option = numberOption;
+21 -9
View File
@@ -64,7 +64,9 @@ public abstract class OptionItem
/// <param name="custom">Custom text to display instead of the value.</param>
internal void PopNotification(string custom = "")
{
if (_id == null) return;
if (_id == null)
return;
string value = custom == string.Empty ? ValueAsString() : custom;
string msg = $"<font=\"Barlow-Black SDF\" material=\"Barlow-Black Outline\">{GetParentPath()} " +
$"<color=#868686><size=85%>{Translator.GetString("BetterSetting.SetTo")}</size></color> {value}";
@@ -286,7 +288,8 @@ public abstract class OptionItem
/// <param name="text">The description text to display.</param>
internal void CreateDescriptionButton(string text)
{
if (Option == null) return;
if (Option == null)
return;
NumberOption optionBehaviourNum = UnityEngine.Object.Instantiate(Tab.AUTab.numberOptionOrigin, Vector3.zero, Quaternion.identity, Tab.AUTab.settingsContainer);
SetupAUOption(optionBehaviourNum);
@@ -440,8 +443,10 @@ public abstract class OptionItem<T> : OptionItem
return Value;
}
internal virtual T? GetDefaultValue() => DefaultValue;
public override string ValueAsString() => Value?.ToString() ?? string.Empty;
internal virtual T? GetDefaultValue() =>
DefaultValue;
public override string ValueAsString() =>
Value?.ToString() ?? string.Empty;
internal override void SetToDefault()
{
Value = DefaultValue;
@@ -525,7 +530,8 @@ public abstract class OptionItem<T> : OptionItem
/// <param name="forceLoad">Whether to force reload even if already loaded.</param>
internal override void TryLoad(bool forceLoad = false)
{
if (!CanLoad) return;
if (!CanLoad)
return;
if (!HasLoadValue || forceLoad)
{
@@ -539,9 +545,12 @@ public abstract class OptionItem<T> : OptionItem
/// </summary>
protected virtual void Load()
{
if (!CanLoad) return;
if (!CanLoad)
return;
if (_id == null)
return;
if (_id == null) return;
Value = BetterDataManager.LoadSetting(Id, DefaultValue);
}
@@ -550,9 +559,12 @@ public abstract class OptionItem<T> : OptionItem
/// </summary>
internal virtual void Save()
{
if (!CanLoad) return;
if (!CanLoad)
return;
if (_id == null)
return;
if (_id == null) return;
BetterDataManager.SaveSetting(Id, Value);
}
}
+9 -4
View File
@@ -82,7 +82,9 @@ public sealed class OptionPlayerItem : OptionItem<int>
/// </summary>
protected sealed override void CreateBehavior()
{
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
var numberOption = UnityEngine.Object.Instantiate(Tab.AUTab.numberOptionOrigin, Tab.AUTab.settingsContainer);
Option = numberOption;
@@ -202,7 +204,8 @@ public sealed class OptionPlayerItem : OptionItem<int>
/// <param name="updateTabVisuals">Whether to update the parent tab visuals as well.</param>
internal sealed override void UpdateVisuals(bool updateTabVisuals = true)
{
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
if (Option is NumberOption numberOption)
{
@@ -251,13 +254,15 @@ public sealed class OptionPlayerItem : OptionItem<int>
/// Gets the integer value (player index) of this option.
/// </summary>
/// <returns>The current player index.</returns>
public sealed override int GetInt() => GetValue();
public sealed override int GetInt() =>
GetValue();
/// <summary>
/// Gets the float representation of the player index.
/// </summary>
/// <returns>The current player index as a float.</returns>
public sealed override float GetFloat() => GetValue();
public sealed override float GetFloat() =>
GetValue();
/// <summary>
/// Checks if the option value matches a specific integer.
+5 -2
View File
@@ -85,7 +85,9 @@ public class OptionStringItem : OptionItem<int>
protected sealed override void CreateBehavior()
{
TryLoad();
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
AllOptionsTemp.Add(this);
var numberOption = UnityEngine.Object.Instantiate(Tab.AUTab.numberOptionOrigin, Tab.AUTab.settingsContainer);
Option = numberOption;
@@ -175,7 +177,8 @@ public class OptionStringItem : OptionItem<int>
/// Gets the translated string representation of the current selection.
/// </summary>
/// <returns>The translated string for the current index.</returns>
public override string ValueAsString() => Translator.GetString(TranslatorStrings[Value], showInvalid: false);
public override string ValueAsString() =>
Translator.GetString(TranslatorStrings[Value], showInvalid: false);
/// <summary>
/// Gets the effective string value index, accounting for random selection.
+4 -2
View File
@@ -98,7 +98,8 @@ internal sealed class OptionTab
/// <param name="doNotDestroyMapPicker">Whether to preserve the map picker UI.</param>
private void CreateBehavior(bool doNotDestroyMapPicker)
{
if (!GameSettingMenu.Instance) return;
if (!GameSettingMenu.Instance)
return;
var SettingsButton = UnityEngine.Object.Instantiate(GameSettingMenu.Instance.GameSettingsButton, GameSettingMenu.Instance.GameSettingsButton.transform.parent);
TabButton = SettingsButton;
@@ -147,7 +148,8 @@ internal sealed class OptionTab
/// </summary>
private void ShowOptions()
{
if (AUTab == null) return;
if (AUTab == null)
return;
AUTab.gameObject.SetActive(true);
float spacingNum = 0f;
+7 -3
View File
@@ -183,7 +183,9 @@ public static class BAUModdedSupportFlags
/// </summary>
internal static void Initialize()
{
if (_initialized) return;
if (_initialized)
return;
_initialized = true;
foreach (var pluginInfo in IL2CPPChainloader.Instance.Plugins.Values)
{
@@ -200,11 +202,13 @@ public static class BAUModdedSupportFlags
var field = plugin.GetType().GetField("BAUFlags",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
if (field == null) return;
if (field == null)
return;
var value = field.IsStatic ? field.GetValue(null) : field.GetValue(plugin);
if (value is not IEnumerable<string> strings) return;
if (value is not IEnumerable<string> strings)
return;
var pluginName = plugin.GetType().GetCustomAttribute<BepInPlugin>()?.Name ?? plugin.GetType().Name;
+2 -1
View File
@@ -79,7 +79,8 @@ internal static class Translator
try
{
using var resourceStream = assembly.GetManifestResourceStream(resourceName);
if (resourceStream == null) return;
if (resourceStream == null)
return;
using var reader = new StreamReader(resourceStream);
var jsonContent = reader.ReadToEnd();
+5 -2
View File
@@ -30,7 +30,9 @@ internal sealed class BetterPingTracker : MonoBehaviour
/// <param name="pingAspectPosition">The AspectPosition component for positioning the display.</param>
internal void SetUp(TextMeshPro pingText, AspectPosition pingAspectPosition)
{
if (Instance != null) return;
if (Instance != null)
return;
if (pingText == null || pingAspectPosition == null)
{
Logger_.Error("BetterPingTracker.SetUp() called with null parameters!");
@@ -47,7 +49,8 @@ internal sealed class BetterPingTracker : MonoBehaviour
/// </summary>
private void Update()
{
if (aspectPosition == null || text == null) return;
if (aspectPosition == null || text == null)
return;
// Update position and appearance
aspectPosition.DistanceFromEdge = new Vector3(4f, 0.1f, -5);
+3 -1
View File
@@ -24,7 +24,9 @@ internal sealed class ExtendedPlayerControl : MonoBehaviour, IMonoExtension<Play
private void Awake()
{
if (!this.RegisterExtension()) return;
if (!this.RegisterExtension())
return;
this.StartCoroutine(CoAddBetterData());
_Player.gameObject.AddComponent<PlayerInfoDisplay>().Init(_Player);
}
+7 -4
View File
@@ -39,16 +39,19 @@ internal sealed class ExtendedPlayerInfo : MonoBehaviour, IMonoExtension<Network
[HideFromIl2Cpp]
internal void SetInfo(NetworkedPlayerInfo data)
{
if (hasSet) return;
_PlayerId = data.PlayerId;
if (hasSet)
return;
hasSet = true;
_PlayerId = data.PlayerId;
}
private float timeAccumulator = 0f;
private void Awake()
{
if (!this.RegisterExtension()) return;
if (!this.RegisterExtension())
return;
if (HandshakeHandler != null)
{
@@ -254,7 +257,7 @@ internal static class PlayerControlDataExtension
/// <param name="callback">The callback to execute with the extended data.</param>
internal static void BetterDataWait(this PlayerControl player, Action<ExtendedPlayerInfo> callback)
{
MonoExtensionManager.RunWhenNotNull<ExtendedPlayerInfo>(player, () => player?.BetterData(), callback);
MonoExtensionManager.RunWhenNotNull(player, () => player?.BetterData(), callback);
}
/// <summary>
+10 -5
View File
@@ -88,7 +88,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
if (Time.frameCount - _lastUpdateFrame < UPDATE_COOLDOWN)
return;
if (_pva == null) return;
if (_pva == null)
return;
_sbTag.Clear();
_sbInfo.Clear();
@@ -141,7 +142,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
/// </summary>
private void UpdateInfo()
{
if (_player?.Data == null || _player.BetterData() == null) return;
if (_player?.Data == null || _player.BetterData() == null)
return;
SetPlayerTags(_sbTag);
FormatPlayerInfo(_sbTag, _sbInfo);
@@ -160,7 +162,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
[HideFromIl2Cpp]
private void SetPlayerTags(StringBuilder sbTag)
{
if (_player?.Data == null) return;
if (_player?.Data == null)
return;
if (ContainsPlayerData(BetterDataManager.BetterDataFile.SickoData, _player.Data))
sbTag.Append($"<color=#00f583>{_cachedTranslations.SickoUser}</color>+++");
@@ -180,7 +183,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
[HideFromIl2Cpp]
private static void FormatPlayerInfo(StringBuilder sbTag, StringBuilder sbInfo)
{
if (sbTag.Length == 0) return;
if (sbTag.Length == 0)
return;
string tagString = sbTag.ToString();
string[] tags = tagString.Split(["+++"], System.StringSplitOptions.RemoveEmptyEntries);
@@ -257,7 +261,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
/// <param name="lastValue">Reference to last value for comparison.</param>
private static void UpdateTextIfChanged(TextMeshPro textMesh, string newText, ref string lastValue)
{
if (textMesh == null) return;
if (textMesh == null)
return;
if (newText != lastValue)
{
+28 -11
View File
@@ -147,14 +147,23 @@ internal class PlayerInfoDisplay : MonoBehaviour
/// </summary>
private void UpdatePlayerInfo()
{
if (_player == null) return;
if (_player.Data == null) return;
if (_player == null)
return;
if (_nameText == null) return;
if (_cachedTranslations == null) return;
if (_player.Data == null)
return;
if (_sbTag == null || _sbTagTop == null || _sbTagBottom == null) return;
if (_topText == null || _bottomText == null || _infoText == null) return;
if (_nameText == null)
return;
if (_cachedTranslations == null)
return;
if (_sbTag == null || _sbTagTop == null || _sbTagBottom == null)
return;
if (_topText == null || _bottomText == null || _infoText == null)
return;
var betterData = _player.BetterData();
@@ -210,7 +219,8 @@ internal class PlayerInfoDisplay : MonoBehaviour
else
{
var targetData = Utils.PlayerDataFromPlayerId(_player.shapeshiftTargetPlayerId);
if (targetData == null) return;
if (targetData == null)
return;
var betterTargetData = targetData.BetterData();
string name = betterTargetData != null ? betterTargetData.RealName : targetData.PlayerName;
@@ -234,7 +244,8 @@ internal class PlayerInfoDisplay : MonoBehaviour
/// <param name="lastValue">Reference to last value for comparison.</param>
private static void UpdateTextIfChanged(TextMeshPro textMesh, StringBuilder sb, ref string lastValue)
{
if (textMesh == null) return;
if (textMesh == null)
return;
string newText = Utils.FormatInfo(sb);
if (newText != lastValue)
@@ -324,7 +335,8 @@ internal class PlayerInfoDisplay : MonoBehaviour
[HideFromIl2Cpp]
private void SetPlayerOutline(StringBuilder sbTag)
{
if (_player?.Data == null) return;
if (_player?.Data == null)
return;
string hashPuid = Utils.GetHashPuid(_player);
string friendCode = _player.Data.FriendCode;
@@ -375,11 +387,14 @@ internal class PlayerInfoDisplay : MonoBehaviour
}
/// <summary>
/// Sets in-game specific information.
/// Sets lobby specific information.
/// </summary>
[HideFromIl2Cpp]
private void SetLobbyInfo(ref string newName, ExtendedPlayerInfo betterData, StringBuilder sbTag)
{
if (betterData == null)
return;
if (_player.IsHost() && BAUConfigs.LobbyPlayerInfo.Value)
newName = _player.GetPlayerNameAndColor();
@@ -433,7 +448,9 @@ internal class PlayerInfoDisplay : MonoBehaviour
private void UpdateColorBlindTextPosition()
{
var text = _player.cosmetics.colorBlindText;
if (!text.enabled) return;
if (!text.enabled)
return;
if (!_player.onLadder && !_player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
{
text.transform.localPosition = new Vector3(0f, -1.3f, 0.4999f);
+3 -1
View File
@@ -38,7 +38,9 @@ internal sealed class GithubAPI : MonoBehaviour
/// </remarks>
internal static void Connect()
{
if (hasTryConnect) return;
if (hasTryConnect)
return;
hasTryConnect = true;
var obj = new GameObject("GithubAPI(BAU)") { hideFlags = HideFlags.HideAndDontSave };
+4 -2
View File
@@ -48,7 +48,8 @@ internal static class RPC
/// <param name="oldReader">The message reader containing the RPC data.</param>
internal static void HandleCustomRPCPacked(PlayerControl player, MessageReader oldReader)
{
if (player == null || player.IsLocalPlayer() || player.Data == null) return;
if (player == null || player.IsLocalPlayer() || player.Data == null)
return;
MessageReader reader = MessageReader.Get(oldReader);
@@ -87,7 +88,8 @@ internal static class RPC
/// </remarks>
internal static void HandleCustomRPCLegacy(PlayerControl player, byte callId, MessageReader oldReader)
{
if (player == null || player.IsLocalPlayer() || player.Data == null || Enum.IsDefined(typeof(RpcCalls), callId)) return;
if (player == null || player.IsLocalPlayer() || player.Data == null || Enum.IsDefined(typeof(RpcCalls), callId))
return;
if (Enum.IsDefined(typeof(CustomRPC), (int)unchecked(callId)))
{
+7 -3
View File
@@ -17,14 +17,18 @@ internal static class DiscordPatch
private static void ActivityManager_UpdateActivity_Prefix(Activity activity)
{
// Skip Discord Rich Presence if other mods have disabled it via BAUModdedSupportFlags
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_DiscordRP)) return;
if (activity == null) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_DiscordRP))
return;
if (activity == null)
return;
string details = $"BAU {BAUPlugin.GetVersionText()}";
activity.Details = details;
// Skip lobby info processing if Discord already shows "In Menus"
if (activity.State == "In Menus") return;
if (activity.State == "In Menus")
return;
try
{
+10 -14
View File
@@ -34,7 +34,8 @@ internal static class OptionsMenuBehaviourPatch
private static void SetupAllClientOptions(OptionsMenuBehaviour __instance)
{
if (__instance.DisableMouseMovement == null) return;
if (__instance.DisableMouseMovement == null)
return;
// Clear previous client options to prevent duplicates
ClientOptionItem.ClientOptions.Clear();
@@ -42,7 +43,7 @@ internal static class OptionsMenuBehaviourPatch
// Toggle options with config binding
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.AntiCheat"), BAUConfigs.AntiCheat, 1, __instance);
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.SendBetterRpc"), BAUConfigs.SendBetterRpc, 1, __instance, SendBetterRpcAction);
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.BetterNotifications"), BAUConfigs.BetterNotifications, 1, __instance, ClearNotifications);
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.BetterNotifications"), BAUConfigs.BetterNotifications, 1, __instance, BetterNotificationManager.ClearNotifications);
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ForceOwnLanguage"), BAUConfigs.ForceOwnLanguage, 1, __instance);
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ChatDarkMode"), BAUConfigs.ChatDarkMode, 1, __instance, ChatPatch.SetChatTheme);
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ChatInGame"), BAUConfigs.ChatInGameplay, 1, __instance);
@@ -101,7 +102,7 @@ internal static class OptionsMenuBehaviourPatch
{
// Clean up BAU mod components and return to vanilla Among Us
ConsoleManager.DetachConsole();
BetterNotificationManager.BAUNotificationManagerObj?.DestroyObj();
BetterNotificationManager.Detach();
Harmony.UnpatchAll();
ModManager.Instance.ModStamp.gameObject.SetActive(false);
SceneChanger.ChangeScene("MainMenu");
@@ -110,7 +111,8 @@ internal static class OptionsMenuBehaviourPatch
private static void SendBetterRpcAction()
{
// Resend handshake secret to all other players when option is toggled
if (!GameState.IsInGame) return;
if (!GameState.IsInGame)
return;
foreach (var player in BAUPlugin.AllPlayerControls)
{
@@ -119,14 +121,6 @@ internal static class OptionsMenuBehaviourPatch
}
}
private static void ClearNotifications()
{
// Clear all active notifications when option is toggled
BetterNotificationManager.NotifyQueue.Clear();
BetterNotificationManager.showTime = 0f;
BetterNotificationManager.Notifying = false;
}
private static void ToggleLobbyTheme()
{
// Play lobby theme music if re-enabled while in lobby
@@ -145,7 +139,8 @@ internal static class OptionsMenuBehaviourPatch
private static void OpenSaveData()
{
// Open BAU save data folder in file explorer
if (!File.Exists(BetterDataManager.dataPath)) return;
if (!File.Exists(BetterDataManager.dataPath))
return;
Process.Start(new ProcessStartInfo
{
@@ -204,7 +199,8 @@ internal static class OptionsMenuBehaviourPatch
if (tabButton.gameObject.activeInHierarchy) activeCount++;
}
if (activeCount == 0) return;
if (activeCount == 0)
return;
// Calculate total width needed for all active tabs
float totalWidth = (activeCount - 1) * buttonSpacing + activeCount * buttonWidth;
+7 -3
View File
@@ -27,7 +27,9 @@ internal static class PrivateLobbyPatch
}
// Only create toggle UI once
if (toggle != null) return;
if (toggle != null)
return;
buttons.Clear();
// Clone April Fools toggle as template for private lobby toggle
@@ -39,7 +41,8 @@ internal static class PrivateLobbyPatch
// Get the ON and OFF buttons from the toggle
buttons.Add(toggle.transform.Find("AprilOn").GetComponent<PassiveButton>());
buttons.Add(toggle.transform.Find("AprilOff").GetComponent<PassiveButton>());
if (buttons.Count < 2) return;
if (buttons.Count < 2)
return;
toggle.gameObject.SetActive(true);
@@ -83,7 +86,8 @@ internal static class PrivateLobbyPatch
private static void TogglePrivateOnlyLobby(bool modeOn)
{
if (buttons.Count < 2) return;
if (buttons.Count < 2)
return;
// Show both buttons first
buttons[0].gameObject.SetActive(true);
+4 -2
View File
@@ -61,7 +61,8 @@ internal static class SplashIntroPatch
private static void HandleAudioDestruction(SplashManager __instance)
{
if (!BetterIntro) return;
if (!BetterIntro)
return;
if (Time.time - __instance.startTime > AudioDestroyTime)
{
@@ -86,7 +87,8 @@ internal static class SplashIntroPatch
private static void StartBetterIntro(SplashManager __instance)
{
if (BetterIntro) return;
if (BetterIntro)
return;
// Start BAU custom intro sequence
__instance.startTime = Time.time;
@@ -16,7 +16,11 @@ internal class PlatformSpoofPatch
[HarmonyPostfix]
internal static void PlatformSpecificData_Deserialize_Postfix(PlatformSpecificData __instance)
{
if (!BAUConfigs.AntiCheat.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat) || !GameState.IsVanillaServer) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat))
return;
if (!BAUConfigs.AntiCheat.Value || !GameState.IsVanillaServer)
return;
if (GameState.IsLobby)
{
@@ -98,7 +98,8 @@ internal static class VoteBanSystemPatch
private static void VoteBanSystem_AddVote_Postfix(VoteBanSystem __instance, int srcClient, int clientId)
{
// Skip logging if anti-cheat disabled
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_Anticheat))
return;
// Log the vote if it was allowed
if (DoLog)
+2 -1
View File
@@ -85,7 +85,8 @@ internal static class LobbyPatch
[HarmonyPostfix]
private static void GameStartManager_Update_Postfix(GameStartManager __instance)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_CancelStartingGame)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_CancelStartingGame))
return;
// Hide start button for non-hosts
if (!GameState.IsHost)
@@ -48,7 +48,8 @@ internal static class FindGameMoreInfoPopupPatch
private static void ShowAll()
{
if (_findGameMoreInfoPopup == null) return;
if (_findGameMoreInfoPopup == null)
return;
_sb.Clear();
var options = _findGameMoreInfoPopup.gameListing.Options;
@@ -3,7 +3,6 @@ using BetterAmongUs.Helpers;
using BetterAmongUs.Managers;
using BetterAmongUs.Modules;
using HarmonyLib;
using TMPro;
using UnityEngine;
namespace BetterAmongUs.Patches.Gameplay.Managers;
@@ -22,43 +21,7 @@ internal static class HudManagerPatch
private static void HudManager_Start_Postfix(HudManager __instance)
{
// Create custom BAU notification system if it doesn't exist
if (BetterNotificationManager.BAUNotificationManagerObj == null)
{
var ChatNotifications = __instance.Chat.chatNotification;
if (ChatNotifications != null)
{
ChatNotifications.timeOnScreen = 1f;
ChatNotifications.gameObject.SetActive(true);
// Clone chat notification system for BAU notifications
GameObject BAUNotification = UnityEngine.Object.Instantiate(ChatNotifications.gameObject);
BAUNotification.name = "BAUNotification";
BAUNotification.GetComponent<ChatNotification>().DestroyMono();
// Remove unnecessary elements from the clone
GameObject.Find($"{BAUNotification.name}/Sizer/PoolablePlayer").DestroyObj();
GameObject.Find($"{BAUNotification.name}/Sizer/ColorText").DestroyObj();
// Position notification at bottom-left corner
BAUNotification.GetComponent<AspectPosition>().DistanceFromEdge = new Vector3(-1.57f, 5.3f, -15f);
GameObject.Find($"{BAUNotification.name}/Sizer/NameText").transform.localPosition = new Vector3(-3.3192f, -0.0105f);
// Cache TextMeshPro component for text updates
BetterNotificationManager.NameText = GameObject.Find($"{BAUNotification.name}/Sizer/NameText").GetComponent<TextMeshPro>();
UnityEngine.Object.DontDestroyOnLoad(BAUNotification);
BetterNotificationManager.BAUNotificationManagerObj = BAUNotification;
BAUNotification.SetActive(false);
// Reset original chat notification settings
ChatNotifications.timeOnScreen = 0f;
ChatNotifications.gameObject.SetActive(false);
// Configure text wrapping for multi-line notifications
BetterNotificationManager.TextArea.enableWordWrapping = true;
BetterNotificationManager.TextArea.m_firstOverflowCharacterIndex = 0;
BetterNotificationManager.TextArea.overflowMode = TextOverflowModes.Overflow;
}
}
BetterNotificationManager.Init();
// Show welcome message after 1 second delay (only once per session)
LateTask.Schedule(() =>
@@ -72,47 +35,45 @@ internal static class HudManagerPatch
Utils.AddChatPrivate(WelcomeMessage, overrideName: " ");
HasBeenWelcomed = true;
}
}, 1f, "HudManagerPatch Start");
}, 1f, shouldLog: false);
}
private static GameObject? gameStart;
[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))]
[HarmonyPostfix]
private static void HudManager_Update_Postfix(HudManager __instance)
{
try
{
// Adjust GameStartManager position for better UI layout
GameObject gameStart = GameObject.Find("GameStartManager");
if (gameStart != null)
gameStart.transform.SetLocalY(-2.8f);
// Adjust GameStartManager position for better UI layout
gameStart ??= GameObject.Find("GameStartManager");
gameStart?.transform.SetLocalY(-2.8f);
// Manage in-game chat visibility based on settings and game state
if (GameState.InGame)
// Manage in-game chat visibility based on settings and game state
if (GameState.InGame)
{
if (__instance.Chat == null)
return;
if (!BAUConfigs.ChatInGameplay.Value)
{
if (!BAUConfigs.ChatInGameplay.Value)
// Vanilla chat behavior: only show chat when dead or during meetings
if (!PlayerControl.LocalPlayer.IsAlive())
{
// Vanilla chat behavior: only show chat when dead or during meetings
if (!PlayerControl.LocalPlayer.IsAlive())
{
__instance.Chat.gameObject.SetActive(true);
}
else if (GameState.IsInGamePlay && !(GameState.IsMeeting || GameState.IsExilling))
{
__instance.Chat.gameObject.SetActive(false);
}
__instance.Chat.gameObject.SetActive(true);
}
else
else if (GameState.IsInGamePlay && !(GameState.IsMeeting || GameState.IsExilling))
{
// BAU chat behavior: always show chat when enabled
if (__instance?.Chat?.gameObject.active == false)
{
__instance.Chat.gameObject.SetActive(true);
}
__instance.Chat.gameObject.SetActive(false);
}
}
else
{
// BAU chat behavior: always show chat when enabled
if (__instance.Chat.gameObject.active == false)
{
__instance.Chat.gameObject.SetActive(true);
}
}
}
catch
{
}
}
}
@@ -59,7 +59,7 @@ internal static class PlayerControlPatch
private static void PlayerControl_MurderPlayer_Postfix(PlayerControl __instance, PlayerControl target)
{
// Check for null references
if (__instance == null || target == null || target.Data == null || __instance.Data == null)
if (__instance == null || target == null || target.Data == null || __instance.Data == null)
return;
// Log kill event with player names and roles
@@ -73,7 +73,8 @@ internal static class PlayerControlPatch
[HarmonyPostfix]
private static void PlayerControl_Shapeshift_Postfix(PlayerControl __instance, PlayerControl targetPlayer, bool animate)
{
if (targetPlayer == null) return;
if (targetPlayer == null)
return;
// Log shapeshift events (both shifting and unshifting)
if (__instance != targetPlayer)
@@ -120,7 +120,9 @@ internal static class PlayerJoinAndLeftPatch
internal static void BetterShowNotification(NetworkedPlayerInfo playerData, DisconnectReasons reason = DisconnectReasons.Unknown, string forceReasonText = "")
{
// Prevent showing duplicate notifications
if (playerData.BetterData().AntiCheatInfo.BannedByAntiCheat || playerData.BetterData().HasShowDcMsg) return;
if (playerData.BetterData().AntiCheatInfo.BannedByAntiCheat || playerData.BetterData().HasShowDcMsg)
return;
playerData.BetterData().HasShowDcMsg = true;
string? playerName = playerData.BetterData().RealName;
@@ -11,7 +11,8 @@ internal static class ChatNotificationPatch
[HarmonyPostfix]
private static void ChatNotification_SetUp_Postfix(ChatNotification __instance)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BetterPingTracker)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BetterPingTracker))
return;
// Reposition to top left
__instance.GetComponent<AspectPosition>().DistanceFromEdge = new Vector3(-2.8f, 0.3f, -40f);
+22 -7
View File
@@ -21,7 +21,8 @@ internal static class ChatPatch
internal static void ClearChat()
{
if (!HudManager.InstanceExists) return;
if (!HudManager.InstanceExists)
return;
// Clear all chat bubbles
HudManager.Instance.Chat.chatBubblePool.ReclaimAll();
@@ -29,7 +30,8 @@ internal static class ChatPatch
internal static void ClearPlayerChats()
{
if (!HudManager.InstanceExists) return;
if (!HudManager.InstanceExists)
return;
// Clear only player chat bubbles (keep command bubbles)
foreach (var obj in HudManager.Instance.Chat.chatBubblePool.activeChildren.ToArray())
@@ -46,7 +48,9 @@ internal static class ChatPatch
internal static void ClearCommands()
{
if (!HudManager.InstanceExists) return;
if (!HudManager.InstanceExists)
return;
// Clear only command chat bubbles (keep player chat)
foreach (var obj in HudManager.Instance.Chat.chatBubblePool.activeChildren.ToArray())
{
@@ -129,12 +133,22 @@ internal static class ChatPatch
[HarmonyPostfix]
private static void ChatController_SetChatBubbleName_Postfix(ChatController __instance, ChatBubble bubble, NetworkedPlayerInfo playerInfo, bool isDead, bool didVote)
{
if (didVote) return;
if (bubble == null || bubble.NameText == null || playerInfo == null) return;
if (playerInfo == null)
return;
if (didVote)
return;
if (bubble?.NameText == null)
return;
var sourcePlayer = playerInfo.Object;
if (sourcePlayer == null)
return;
var localPlayer = PlayerControl.LocalPlayer;
if (sourcePlayer == null || localPlayer == null) return;
if (localPlayer == null)
return;
StringBuilder sbTag = new();
StringBuilder sbInfo = new();
@@ -152,7 +166,8 @@ internal static class ChatPatch
Role = "";
var betterData = sourcePlayer.BetterData();
if (betterData == null) return;
if (betterData == null)
return;
// Show BAU user tag
if (sourcePlayer.IsLocalPlayer() || betterData.IsBetterUser)
+3 -2
View File
@@ -17,7 +17,7 @@ internal static class GameSummaryPatch
private static void EndGameManager_SetEverythingUp_Postfix(EndGameManager __instance)
{
// Check for null references
if (__instance == null)
if (__instance == null)
return;
// Log game end to console
@@ -43,7 +43,8 @@ internal static class GameSummaryPatch
var summaryObject = CreateSummaryObject(endGameManager);
var summaryText = summaryObject.GetComponent<TextMeshPro>();
if (summaryText == null) return;
if (summaryText == null)
return;
ConfigureSummaryText(summaryText);
+13 -6
View File
@@ -16,7 +16,8 @@ internal static class MeetingHudPatch
[HarmonyPostfix]
private static void MeetingHud_Start_Postfix(MeetingHud __instance)
{
if (__instance == null || __instance.playerStates == null) return;
if (__instance == null || __instance.playerStates == null)
return;
// Add meeting info display to each player state
foreach (var pva in __instance.playerStates)
@@ -29,7 +30,8 @@ internal static class MeetingHudPatch
pva.gameObject.AddComponent<MeetingInfoDisplay>().Init(target, pva);
}
if (!GameState.IsOnlineGame) return;
if (!GameState.IsOnlineGame)
return;
// Add host icon to meeting hud
if (__instance.ProceedButton != null && __instance.HostIcon != null)
@@ -50,16 +52,21 @@ internal static class MeetingHudPatch
// Updates host icon with current host info
internal static void UpdateHostIcon()
{
if (MeetingHud.Instance == null) return;
if (GameData.Instance == null) return;
if (MeetingHud.Instance == null)
return;
if (GameData.Instance == null)
return;
var host = GameData.Instance.GetHost();
if (host == null || host.BetterData() == null) return;
if (host?.BetterData() == null)
return;
var hostColor = host.Color;
var hostRealName = host.BetterData().RealName;
if (MeetingHud.Instance.HostIcon == null || MeetingHud.Instance.ProceedButton == null) return;
if (MeetingHud.Instance.HostIcon == null || MeetingHud.Instance.ProceedButton == null)
return;
PlayerMaterial.SetColors(hostColor, MeetingHud.Instance.HostIcon);
MeetingHud.Instance.ProceedButton.gameObject.GetComponentInChildren<TextMeshPro>().text = string.Format(Translator.GetString("HostInMeeting"), hostRealName);
@@ -69,7 +69,11 @@ internal static class MiniMapBehaviourPatch
[HarmonyPostfix]
private static void MapBehaviour_Show_Postfix(MapBehaviour __instance)
{
if (!BAUConfigs.MinimapIcons.Value || BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_MinimapIcons)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_MinimapIcons))
return;
if (!BAUConfigs.MinimapIcons.Value)
return;
// Make infected overlay buttons semi-transparent and smaller
foreach (var button in __instance.infectedOverlay.allButtons)
+6 -1
View File
@@ -56,8 +56,13 @@ internal static class PlayerTabPatch
var data = OutfitData.GetOutfitData(currentI);
var button = playerTab.CreateOutfitPresetButton(name, new Vector3(2.5f, 1.55f - currentI * 0.45f, 0f), out var playerPreview, () =>
{
if (BetterDataManager.BetterDataFile.SelectedOutfitPreset == currentI)
return;
// Ignore if cooldown active or same preset selected
if (cooldown > 0f || BetterDataManager.BetterDataFile.SelectedOutfitPreset == currentI) return;
if (cooldown > 0f)
return;
cooldown = 0.5f;
// Update selected preset
@@ -14,7 +14,8 @@ internal static class ServerDropdownPatch
[HarmonyPrefix]
private static void FindAGameManager_Start_Prefix(FindAGameManager __instance)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_ServerDropDown)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_ServerDropDown))
return;
var aspectPosition = __instance.serverDropdown.transform.parent.GetComponent<AspectPosition>();
if (aspectPosition != null)
@@ -140,7 +140,8 @@ internal static class GameSettingsPatch
[HarmonyPostfix]
private static void GameSettingMenu_Start_Postfix(GameSettingMenu __instance)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_AllGameOptions)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_AllGameOptions))
return;
SetupSettings();
@@ -191,8 +192,11 @@ internal static class GameSettingsPatch
[HarmonyPrefix]
private static void GameSettingMenu_ChangeTab_Prefix(GameSettingMenu __instance, [HarmonyArgument(0)] int tabNum, [HarmonyArgument(1)] bool previewOnly)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_AllGameOptions)) return;
if (BetterSettingsTab == null) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_AllGameOptions))
return;
if (BetterSettingsTab == null)
return;
// Hide custom tab when switching away
BetterSettingsTab.AUTab?.gameObject?.SetActive(false);
@@ -233,7 +237,8 @@ internal static class GameSettingsPatch
[HarmonyPrefix]
private static void OptionsConsole_CanUse_Prefix(OptionsConsole __instance)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_AllGameOptions)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_AllGameOptions))
return;
__instance.HostOnly = false; // Allow non-hosts to use settings console
}
+6 -3
View File
@@ -34,7 +34,8 @@ internal static class UnityWebRequestPatch
[HarmonyPrefix]
private static void UnityWebRequest_SendWebRequest_Prefix(UnityWebRequest __instance)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BAUHttpHeader)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BAUHttpHeader))
return;
// Check if this is a game API request
var path = new Uri(__instance.url).AbsolutePath;
@@ -50,7 +51,8 @@ internal static class UnityWebRequestPatch
[HarmonyPostfix]
private static void UnityWebRequest_SendWebRequest_Postfix(UnityWebRequest __instance, UnityWebRequestAsyncOperation __result)
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BAUHttpHeader)) return;
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BAUHttpHeader))
return;
var path = new Uri(__instance.url).AbsolutePath;
if (path.Contains("/api/games"))
@@ -58,7 +60,8 @@ internal static class UnityWebRequestPatch
// Add callback when request completes
__result.add_completed((Action<AsyncOperation>)(_ =>
{
if (!HttpUtils.IsSuccess(__instance.responseCode)) return;
if (!HttpUtils.IsSuccess(__instance.responseCode))
return;
// Check if server supports BAU mod
var responseHeader = __instance.GetResponseHeader("BAU-Mod-Processed");