mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-19 15:51:52 +00:00
A lot of code cleanup, with null checks and guards
This commit is contained in:
1 parent
22dcff9b59
commit
01c951f990
79 files changed
+631
-359
No files matched your search
+4
-2
@@ -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.
|
||||
|
||||
@@ -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>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -32,7 +32,9 @@ internal abstract class AbstractJsonFile
|
||||
/// </summary>
|
||||
internal virtual void Init()
|
||||
{
|
||||
if (_hasInit) return;
|
||||
if (_hasInit)
|
||||
return;
|
||||
|
||||
_hasInit = true;
|
||||
|
||||
if (!IsFileValid())
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -184,7 +184,9 @@ internal sealed class SharedSecretExchange
|
||||
/// </summary>
|
||||
internal void ClearData()
|
||||
{
|
||||
if (HasBeenCleared) return;
|
||||
if (HasBeenCleared)
|
||||
return;
|
||||
|
||||
HasBeenCleared = true;
|
||||
publicKey = [];
|
||||
tempKey = 0;
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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)))
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in new issue
Block a user