From 7e54af49d2f9e5fae784297c8571ad314524f140 Mon Sep 17 00:00:00 2001 From: D1GQ Date: Fri, 28 Mar 2025 19:28:13 -0500 Subject: [PATCH] Fixes --- Helpers/ExtendedPlayerControl.cs | 35 ++++++++-- Helpers/ExtendedPlayerInfo.cs | 30 ++++++++- Modules/MonoExtensions.cs | 111 +++++++++++++++++++++++++++++++ main.cs | 2 +- 4 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 Modules/MonoExtensions.cs diff --git a/Helpers/ExtendedPlayerControl.cs b/Helpers/ExtendedPlayerControl.cs index 1777a4a..f322ea9 100644 --- a/Helpers/ExtendedPlayerControl.cs +++ b/Helpers/ExtendedPlayerControl.cs @@ -4,12 +4,35 @@ using UnityEngine; namespace BetterAmongUs.Helpers; -internal class BetterPlayerControl(IntPtr intPtr) : MonoBehaviour(intPtr) +internal class ExtendedPlayerControl : MonoBehaviour { + internal static readonly HashSet<(PlayerControl player, ExtendedPlayerControl extendedPlayer)> AllExtendedPlayerControl = []; + internal PlayerControl? _Player { get; set; } internal TextMeshPro? InfoTextInfo { get; set; } internal TextMeshPro? InfoTextTop { get; set; } internal TextMeshPro? InfoTextBottom { get; set; } + + internal void Start() + { + var player = gameObject.GetComponent(); + if (player != null) + { + if (!AllExtendedPlayerControl.Any(items => items.extendedPlayer == this)) + { + AllExtendedPlayerControl.Add((player, this)); + } + } + else + { + Destroy(this); + } + } + + internal void OnDestroy() + { + AllExtendedPlayerControl.RemoveWhere(items => items.extendedPlayer == this); + } } internal static class PlayerControlExtension @@ -50,7 +73,7 @@ internal static class PlayerControlExtension { if (pc.BetterPlayerControl() == null) { - BetterPlayerControl newExtendedPc = pc.gameObject.AddComponent(); + ExtendedPlayerControl newExtendedPc = pc.gameObject.AddComponent(); newExtendedPc._Player = pc; newExtendedPc.InfoTextInfo = InfoText_Info_TMP; newExtendedPc.InfoTextTop = InfoText_T_TMP; @@ -59,13 +82,13 @@ internal static class PlayerControlExtension } } - internal static BetterPlayerControl? BetterPlayerControl(this PlayerControl player) + internal static ExtendedPlayerControl? BetterPlayerControl(this PlayerControl player) { - return player?.GetComponent(); + return ExtendedPlayerControl.AllExtendedPlayerControl.FirstOrDefault(items => items.player == player).extendedPlayer ?? null; } - internal static BetterPlayerControl? BetterPlayerControl(this PlayerPhysics playerPhysics) + internal static ExtendedPlayerControl? BetterPlayerControl(this PlayerPhysics playerPhysics) { - return playerPhysics?.GetComponent(); + return ExtendedPlayerControl.AllExtendedPlayerControl.FirstOrDefault(items => items.player == playerPhysics.myPlayer).extendedPlayer ?? null; } } \ No newline at end of file diff --git a/Helpers/ExtendedPlayerInfo.cs b/Helpers/ExtendedPlayerInfo.cs index 98218b7..c56263c 100644 --- a/Helpers/ExtendedPlayerInfo.cs +++ b/Helpers/ExtendedPlayerInfo.cs @@ -10,6 +10,8 @@ namespace BetterAmongUs.Helpers; internal class ExtendedPlayerInfo : MonoBehaviour { + internal static readonly HashSet<(NetworkedPlayerInfo data, ExtendedPlayerInfo extendedData)> AllExtendedPlayerInfo = []; + private bool hasSet = false; internal void SetInfo(NetworkedPlayerInfo data) { @@ -21,6 +23,28 @@ internal class ExtendedPlayerInfo : MonoBehaviour } private float timeAccumulator = 0f; + + internal void Start() + { + var data = gameObject.GetComponent(); + if (data != null) + { + if (!AllExtendedPlayerInfo.Any(items => items.extendedData == this)) + { + AllExtendedPlayerInfo.Add((data, this)); + } + } + else + { + Destroy(this); + } + } + + internal void OnDestroy() + { + AllExtendedPlayerInfo.RemoveWhere(items => items.extendedData == this); + } + internal void Update() { var time = Time.deltaTime; @@ -137,19 +161,19 @@ internal static class PlayerControlDataExtension // Get BetterData from PlayerControl internal static ExtendedPlayerInfo? BetterData(this PlayerControl player) { - return player?.Data?.GetComponent(); + return ExtendedPlayerInfo.AllExtendedPlayerInfo.FirstOrDefault(items => items.data == player.Data).extendedData ?? null; } // Get BetterData from NetworkedPlayerInfo internal static ExtendedPlayerInfo? BetterData(this NetworkedPlayerInfo data) { - return data?.GetComponent(); + return ExtendedPlayerInfo.AllExtendedPlayerInfo.FirstOrDefault(items => items.data == data).extendedData ?? null; } // Get BetterData from ClientData internal static ExtendedPlayerInfo? BetterData(this ClientData data) { var player = Utils.PlayerFromClientId(data.Id); - return player?.Data?.GetComponent(); + return ExtendedPlayerInfo.AllExtendedPlayerInfo.FirstOrDefault(items => items.data == player.Data).extendedData ?? null; } } diff --git a/Modules/MonoExtensions.cs b/Modules/MonoExtensions.cs new file mode 100644 index 0000000..44c999c --- /dev/null +++ b/Modules/MonoExtensions.cs @@ -0,0 +1,111 @@ +using Il2CppInterop.Runtime; +using UnityEngine; + +namespace BetterAmongUs.Modules; + +internal abstract class MonoExtension : MonoBehaviour +{ + private static readonly Dictionary> _extensionsByBaseType = new(); + private MonoBehaviour? _baseMono; + + protected MonoBehaviour? BaseMono + { + get => _baseMono; + private set => _baseMono = value; + } + + private struct ExtensionPair + { + public MonoBehaviour? Base; + public MonoExtension? Extension; + } + + public static T? Get(MonoBehaviour mono) where T : MonoExtension + { + if (_extensionsByBaseType.TryGetValue(mono.GetType(), out var extensions)) + { + foreach (var pair in extensions) + { + if (pair.Base == mono && pair.Extension is T result) + { + return result; + } + } + } + + return null; + } + + protected bool RegisterExtension() where T : MonoBehaviour + { + var baseComponent = GetComponent(Il2CppType.From(typeof(T))) as T; + if (baseComponent == null) + { + Destroy(this); + return false; + } + + var existingExtensions = GetComponents(Il2CppType.From(GetType())); + if (existingExtensions.Length > 1) + { + Destroy(this); + return false; + } + + var baseType = typeof(T); + if (!_extensionsByBaseType.TryGetValue(baseType, out var extensions)) + { + extensions = new List(); + _extensionsByBaseType[baseType] = extensions; + } + + extensions.Add(new ExtensionPair { Base = baseComponent, Extension = this }); + BaseMono = baseComponent; + + return true; + } + + protected void UnregisterExtension() where T : MonoBehaviour + { + if (BaseMono == null) return; + + if (_extensionsByBaseType.TryGetValue(typeof(T), out var extensions)) + { + for (int i = extensions.Count - 1; i >= 0; i--) + { + if (extensions[i].Extension == this) + { + extensions.RemoveAt(i); + break; + } + } + + if (extensions.Count == 0) + { + _extensionsByBaseType.Remove(typeof(T)); + } + } + + BaseMono = null; + } + + public static void CleanAll() + { + foreach (var kvp in _extensionsByBaseType.ToArray()) + { + var extensions = kvp.Value; + for (int i = extensions.Count - 1; i >= 0; i--) + { + if (extensions[i].Base == null || extensions[i].Extension == null) + { + extensions.RemoveAt(i); + } + } + + if (extensions.Count == 0) + { + _extensionsByBaseType.Remove(kvp.Key); + } + } + } +} \ No newline at end of file diff --git a/main.cs b/main.cs index 41f1377..f2b421b 100644 --- a/main.cs +++ b/main.cs @@ -28,7 +28,7 @@ internal enum ReleaseTypes : int internal class Main : BasePlugin { internal static readonly ReleaseTypes ReleaseBuildType = ReleaseTypes.Beta; - internal const string BetaNum = "1"; + internal const string BetaNum = "2"; internal const string HotfixNum = "0"; internal const bool IsHotFix = false; internal const string PluginGuid = "com.ten.betteramongus";