Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of REPODepot v0.0.9
REPODepotHelper.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using REPODepotHelper.Patches.PlayerHealthUIPatch; using TMPro; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("REPODepotHelper")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("REPODepotHelper")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("37b0274d-29c0-4703-a18e-1b2de1d02450")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace REPODepotHelper { public static class PluginInfo { public const string PLUGIN_ID = "REPODepotHelper"; public const string PLUGIN_NAME = "REPODepotHelper"; public const string PLUGIN_VERSION = "0.0.6"; public const string PLUGIN_GUID = "blindmice.repo.repodepothelper"; } [BepInPlugin("blindmice.repo.repodepothelper", "REPODepotHelper", "0.0.6")] public class Plugin : BaseUnityPlugin { private FileSystemWatcher fileSystemWatcher; public ManualLogSource PluginLogger; public static ConfigEntry<bool> enableDebugLogs; public static ConfigEntry<bool> enableHealthUI; public static ConfigEntry<int> healthUIFontSize; public static ConfigEntry<bool> healthUIFancyColors; public static Plugin Instance { get; private set; } public static event Action OnConfigReloaded; public static void LogMessage(object message) { if (enableDebugLogs.Value) { Instance.PluginLogger.LogMessage((object)("REPODepotHelper: " + message)); } } public static void LogError(object message) { if (enableDebugLogs.Value) { Instance.PluginLogger.LogError((object)("REPODepotHelper: " + message)); } } public static void LogWarning(object message) { if (enableDebugLogs.Value) { Instance.PluginLogger.LogWarning((object)("REPODepotHelper: " + message)); } } private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) Instance = this; PluginLogger = ((BaseUnityPlugin)this).Logger; PluginLogger.LogInfo((object)"Loading plugin REPODepotHelper 0.0.6"); LoadConfig(); new Harmony("blindmice.repo.repodepothelper").PatchAll(); PluginLogger.LogInfo((object)"Loaded plugin REPODepotHelper 0.0.6"); StartFileWatcher(); } private void Start() { } private void StartFileWatcher() { PluginLogger.LogInfo((object)"Starting File Watcher for hot plugin reload..."); fileSystemWatcher = new FileSystemWatcher { Path = Paths.ConfigPath, Filter = "blindmice.repo.repodepothelper.cfg", NotifyFilter = NotifyFilters.LastWrite }; fileSystemWatcher.Changed += OnConfigFileChanged; fileSystemWatcher.EnableRaisingEvents = true; } private void OnConfigFileChanged(object sender, FileSystemEventArgs e) { Thread.Sleep(2000); LoadConfig(); PluginLogger.LogInfo((object)"Reloading config"); Plugin.OnConfigReloaded?.Invoke(); } private void LoadConfig() { enableDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Debug Logs", false, "Log debug messages (Recommended value = false)"); enableHealthUI = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Enable Players Health UI", true, "Shows player health on screen"); healthUIFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "Health text font size", 15, "Changes the font size for player health text on screen"); healthUIFancyColors = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Fancy text color", true, "Enable text color based on how much health players have"); } } } namespace REPODepotHelper.Scripts { public class PlayerMiniAvatar : MonoBehaviour { [SerializeField] private Material bodyMaterial; private Material copyBodyMaterial; private MeshRenderer leftLegRenderer; private MeshRenderer rightLegRenderer; private MeshRenderer leftArmRenderer; private MeshRenderer rightArmRenderer; private MeshRenderer bodyTopRenderer; private MeshRenderer bodyBottomRenderer; private MeshRenderer headTopRenderer; private MeshRenderer headBottomRenderer; private MeshRenderer healthFrameRenderer; [SerializeField] private GameObject leftLeg; [SerializeField] private GameObject rightLeg; [SerializeField] private GameObject leftArm; [SerializeField] private GameObject rightArm; [SerializeField] private GameObject bodyTop; [SerializeField] private GameObject bodyBottom; [SerializeField] private GameObject headTop; [SerializeField] private GameObject headBottom; [SerializeField] private GameObject healthFrame; [SerializeField] private string[] colors = new string[36] { "#FFFFFF", "#787878", "#1A1A1A", "#FF6969", "#FF3131", "#802727", "#4B2324", "#FF0047", "#FF006A", "#FF00D6", "#FF99F1", "#C599FF", "#9C50E9", "#63006C", "#2B1C46", "#2E3087", "#2500FF", "#4C6AFF", "#00A4D9", "#00FFDE", "#8FFFD3", "#8CFF88", "#3ED162", "#00FF19", "#8AFF00", "#548400", "#3D6A3E", "#17593A", "#FFFA5A", "#FFDC00", "#9F8A00", "#FF7900", "#FF6925", "#6F3C1F", "#655D28", "#B48C53" }; [SerializeField] private string currentColor; [SerializeField] private int currentColorIndex; [SerializeField] private GameObject arenaCrown; private int nameID; private void Awake() { Initialize(); SetRandomColor(); EnableCrown(); Debug.Log((object)("Generated mini avatar with color " + currentColor + " and " + (arenaCrown.activeSelf ? "with" : "without") + " crown")); } private void Initialize() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown copyBodyMaterial = new Material(bodyMaterial); leftLegRenderer = leftLeg.GetComponent<MeshRenderer>(); rightLegRenderer = rightLeg.GetComponent<MeshRenderer>(); leftArmRenderer = leftArm.GetComponent<MeshRenderer>(); rightArmRenderer = rightArm.GetComponent<MeshRenderer>(); bodyTopRenderer = bodyTop.GetComponent<MeshRenderer>(); bodyBottomRenderer = bodyBottom.GetComponent<MeshRenderer>(); headTopRenderer = headTop.GetComponent<MeshRenderer>(); headBottomRenderer = headBottom.GetComponent<MeshRenderer>(); healthFrameRenderer = healthFrame.GetComponent<MeshRenderer>(); } private void EnableCrown() { if ((double)Random.value < 0.5) { arenaCrown.SetActive(true); } else { arenaCrown.SetActive(false); } } public void SetRandomColor(bool isEditor = false) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) int randomColor = GetRandomColor(); if (currentColorIndex == randomColor) { randomColor = GetRandomColor(); } currentColorIndex = randomColor; Color val = default(Color); if (ColorUtility.TryParseHtmlString(colors[randomColor], ref val)) { currentColor = colors[randomColor]; nameID = Shader.PropertyToID("_AlbedoColor"); copyBodyMaterial.SetColor(nameID, val); ((Renderer)leftLegRenderer).material = copyBodyMaterial; ((Renderer)rightLegRenderer).material = copyBodyMaterial; ((Renderer)leftArmRenderer).material = copyBodyMaterial; ((Renderer)rightArmRenderer).material = copyBodyMaterial; ((Renderer)bodyTopRenderer).material = copyBodyMaterial; ((Renderer)bodyBottomRenderer).material = copyBodyMaterial; ((Renderer)headTopRenderer).material = copyBodyMaterial; ((Renderer)headBottomRenderer).material = copyBodyMaterial; ((Renderer)healthFrameRenderer).material = copyBodyMaterial; } if (isEditor) { EnableCrown(); } } private int GetRandomColor() { return Random.Range(0, colors.Length); } public void ResetColor() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) nameID = Shader.PropertyToID("_AlbedoColor"); bodyMaterial.SetColor(nameID, Color.white); } } } namespace REPODepotHelper.Scripts.CrystalBall { public class CrystalBallHelper { public static Dictionary<string, CrystalEvent> goodLines = new Dictionary<string, CrystalEvent>(); public static Dictionary<string, CrystalEvent> badLines = new Dictionary<string, CrystalEvent>(); public static Dictionary<string, CrystalEvent> rareLines = new Dictionary<string, CrystalEvent>(); private PlayerAvatar playerAvatar; private int[] healing = new int[6] { 5, 10, 20, 40, 100, -1 }; private int[] hurt = new int[6] { 5, 10, 20, 40, 100, -1 }; public PlayerAvatar GetPlayerAvatar() { return playerAvatar; } public void SetPlayerAvatar(PlayerAvatar playerAvatar) { this.playerAvatar = playerAvatar; } public CrystalBallHelper() { goodLines.Clear(); badLines.Clear(); rareLines.Clear(); goodLines.Add("Taxman was generous and gave you some health", new CrystalEvent(delegate { HealPlayer(Random.Range(1, 10)); })); badLines.Add("[Unity Error]: NullReferenceError: unable to update players' health", new CrystalEvent(delegate { HurtPlayer(Random.Range(1, 10)); })); rareLines.Add($"Your lucky numbers are {Random.Range(0, 1000)} {Random.Range(0, 1000)} {Random.Range(0, 1000)} {Random.Range(0, 1000)} {Random.Range(0, 1000)} {Random.Range(0, 1000)} {Random.Range(0, 1000)} {Random.Range(0, 1000)}", new CrystalEvent(delegate { SemiFunc.StatSetRunCurrency(SemiFunc.StatGetRunCurrency() + Random.Range(1000, 10000)); })); } public void HealPlayer(int heal = 0) { int num = ((heal == 0) ? healing[Random.Range(0, healing.Length)] : heal); playerAvatar.playerHealth.HealOther((num == -1) ? Random.Range(10, 100) : num, true); } public void HurtPlayer(int damage = 0) { int num = ((damage == 0) ? hurt[Random.Range(0, hurt.Length)] : damage); playerAvatar.playerHealth.Hurt((num == -1) ? Random.Range(10, 100) : num, true, -1); } public void KillPlayer() { playerAvatar.playerHealth.Death(); } public void UpdatePlayerHealth(bool isPositive) { FieldInfo? field = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = (int)field.GetValue("health"); typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num2 = (int)field.GetValue("health"); playerAvatar.playerHealth.UpdateHealthRPC(num + 5, num2 + 5, true); } } public class CrystalBall : MonoBehaviour { private enum State { Idle, Active } [SerializeField] private string currentLine; [SerializeField] [Range(0f, 1f)] private float goodLinePercent = 0.29f; [SerializeField] [Range(0f, 1f)] private float badLinePercent = 0.69f; [SerializeField] [Range(0f, 1f)] private float rareLinePercent = 0.02f; [SerializeField] private float coolDownUntilNextSentence = 6f; private PhysGrabObject physGrabObject; private float percent; private Dictionary<string, CrystalEvent> crystalEvent; private State currentState; private CrystalBallHelper crystalBallHelper; private readonly float MAX_COOLDOWN = 8f; private readonly float MIN_COOLDOWN = 20f; public void Awake() { if (goodLinePercent + badLinePercent + rareLinePercent > 1f) { Debug.LogWarning((object)"Invalid line percent. Resetting to default values."); goodLinePercent = 0.29f; badLinePercent = 0.69f; rareLinePercent = 0.02f; } physGrabObject = ((Component)this).GetComponent<PhysGrabObject>(); crystalBallHelper = new CrystalBallHelper(); } private void Update() { } private void StateActive() { if (PhysGrabber.instance.grabbed) { currentState = State.Idle; coolDownUntilNextSentence = Random.Range(MIN_COOLDOWN, MAX_COOLDOWN); } else if (!ChatManager.instance.StateIsPossessed()) { currentState = State.Idle; coolDownUntilNextSentence = Random.Range(MIN_COOLDOWN, MAX_COOLDOWN); } if (Plugin.enableDebugLogs.Value) { Debug.Log((object)$"The cooldown is {coolDownUntilNextSentence}s"); } } private void StateIdle() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) if (coolDownUntilNextSentence > 0f && physGrabObject.grabbed) { coolDownUntilNextSentence -= Time.deltaTime; } else { if (!Object.op_Implicit((Object)(object)PhysGrabber.instance) || !PhysGrabber.instance.grabbed) { return; } GetLine(); List<PlayerAvatar> list = SemiFunc.PlayerGetAllPlayerAvatarWithinRange(10f, ((Component)PhysGrabber.instance).transform.position, false, default(LayerMask)); float num = float.MaxValue; foreach (PlayerAvatar item in list) { if (!((Object)(object)item == (Object)(object)PlayerAvatar.instance)) { float num2 = Vector3.Distance(((Component)PhysGrabber.instance).transform.position, ((Component)item).transform.position); if (num2 < num) { num = num2; } } } string text = currentLine; currentState = State.Active; Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.3f, 0.6f, 1f); ChatManager.instance.PossessChatScheduleStart(10); ChatManager.instance.PossessChat((PossessChatID)0, text, 2.5f, val, 0f, false, 0, (UnityEvent)null); ChatManager.instance.PossessChatScheduleEnd(); } } private void GetLine() { percent = Random.value; Debug.Log((object)$"Generating line with {percent}"); if (percent <= rareLinePercent) { KeyValuePair<string, CrystalEvent> keyValuePair = CrystalBallHelper.rareLines.ElementAt(Random.Range(0, CrystalBallHelper.rareLines.Count)); crystalEvent = new Dictionary<string, CrystalEvent> { { keyValuePair.Key, keyValuePair.Value } }; currentLine = keyValuePair.Key; if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Randomly picked the line \"" + currentLine + "\"")); } keyValuePair.Value.Execute(); } else if (percent <= goodLinePercent) { KeyValuePair<string, CrystalEvent> keyValuePair2 = CrystalBallHelper.goodLines.ElementAt(Random.Range(0, CrystalBallHelper.goodLines.Count)); crystalEvent = new Dictionary<string, CrystalEvent> { { keyValuePair2.Key, keyValuePair2.Value } }; currentLine = keyValuePair2.Key; if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Randomly picked the line \"" + currentLine + "\"")); } keyValuePair2.Value.Execute(); } else { KeyValuePair<string, CrystalEvent> keyValuePair3 = CrystalBallHelper.badLines.ElementAt(Random.Range(0, CrystalBallHelper.badLines.Count)); crystalEvent = new Dictionary<string, CrystalEvent> { { keyValuePair3.Key, keyValuePair3.Value } }; currentLine = keyValuePair3.Key; if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Randomly picked the line \"" + currentLine + "\"")); } keyValuePair3.Value.Execute(); } } } public class CrystalEvent { private Action action; public CrystalEvent(Action action) { this.action = action; } public void Execute() { action?.Invoke(); } } } namespace REPODepotHelper.Patches { [HarmonyPatch(typeof(PlayerHealth), "Update")] public class PlayerHealthUpdatePatch { private static StringBuilder playeDataString = new StringBuilder(); private static void Postfix(PlayerHealth __instance) { if (!SemiFunc.RunIsLevel() || !Plugin.enableHealthUI.Value) { return; } playeDataString.Clear(); GameObject val = GameObject.Find("PlayerHealthUI"); if (!((Object)(object)val != (Object)null)) { return; } TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).fontSize = Plugin.healthUIFontSize.Value; List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { return; } foreach (PlayerAvatar item in list) { PlayerInfo orCreate = PlayerInfoManager.GetOrCreate(item); orCreate.Refresh(); if (!((Object)(object)orCreate.playerHealth != (Object)null)) { continue; } if (Plugin.healthUIFancyColors.Value) { playeDataString.AppendLine(orCreate.GetName(isFancy: true) + " " + orCreate.GetStatus(isFancy: true)); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName(isFancy: true) + ": " + orCreate.GetStatus(isFancy: true))); } } else { playeDataString.AppendLine(orCreate.GetName() + " " + orCreate.GetStatus()); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName() + ": " + orCreate.GetStatus())); } } } ((TMP_Text)component).text = playeDataString.ToString(); } } [HarmonyPatch(typeof(PlayerHealth), "Heal")] public class PlayerHealthHealPatch { private static StringBuilder playeDataString = new StringBuilder(); private static void Postfix(PlayerHealth __instance) { if (!SemiFunc.RunIsLevel() || !Plugin.enableHealthUI.Value) { return; } playeDataString.Clear(); TextMeshProUGUI component = GameObject.Find("PlayerHealthUI").GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).fontSize = Plugin.healthUIFontSize.Value; List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { return; } foreach (PlayerAvatar item in list) { PlayerInfo orCreate = PlayerInfoManager.GetOrCreate(item); orCreate.Refresh(); if (!((Object)(object)orCreate.playerHealth != (Object)null)) { continue; } if (Plugin.healthUIFancyColors.Value) { playeDataString.AppendLine(orCreate.GetName(isFancy: true) + " " + orCreate.GetStatus(isFancy: true)); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName(isFancy: true) + ": " + orCreate.GetStatus(isFancy: true))); } } else { playeDataString.AppendLine(orCreate.GetName() + " " + orCreate.GetStatus()); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName() + ": " + orCreate.GetStatus())); } } } ((TMP_Text)component).text = playeDataString.ToString(); } } [HarmonyPatch(typeof(PlayerHealth), "Hurt")] public class PlayerHealthHurtPatch { private static StringBuilder playeDataString = new StringBuilder(); private static void Postfix(PlayerHealth __instance) { if (!SemiFunc.RunIsLevel() || !Plugin.enableHealthUI.Value) { return; } playeDataString.Clear(); TextMeshProUGUI component = GameObject.Find("PlayerHealthUI").GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).fontSize = Plugin.healthUIFontSize.Value; List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { return; } foreach (PlayerAvatar item in list) { PlayerInfo orCreate = PlayerInfoManager.GetOrCreate(item); orCreate.Refresh(); if (!((Object)(object)orCreate.playerHealth != (Object)null)) { continue; } if (Plugin.healthUIFancyColors.Value) { playeDataString.AppendLine(orCreate.GetName(isFancy: true) + " " + orCreate.GetStatus(isFancy: true)); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName(isFancy: true) + ": " + orCreate.GetStatus(isFancy: true))); } } else { playeDataString.AppendLine(orCreate.GetName() + " " + orCreate.GetStatus()); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName() + ": " + orCreate.GetStatus())); } } } ((TMP_Text)component).text = playeDataString.ToString(); } } [HarmonyPatch(typeof(LoadingUI), "StopLoading")] public class LoadingUIPatch { private static StringBuilder playeDataString = new StringBuilder(); private static void Postfix(LoadingUI __instance) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.RunIsLevel() || !Plugin.enableHealthUI.Value) { return; } playeDataString.Clear(); GameObject val = new GameObject("PlayerHealthUI"); GameObject val2 = GameObject.Find("Game Hud"); GameObject val3 = GameObject.Find("Haul Goal"); val.transform.SetParent(val2.transform); val.layer = val2.layer; TextMeshProUGUI val4 = val.AddComponent<TextMeshProUGUI>(); TextMeshProUGUI component = val3.GetComponent<TextMeshProUGUI>(); bool enableWordWrapping = (((TMP_Text)val4).enableAutoSizing = false); ((TMP_Text)val4).enableWordWrapping = enableWordWrapping; ((TMP_Text)val4).fontSize = Plugin.healthUIFontSize.Value; ((TMP_Text)val4).font = ((TMP_Text)component).font; ((TMP_Text)val4).fontStyle = (FontStyles)1; ((TMP_Text)val4).horizontalAlignment = (HorizontalAlignmentOptions)1; ((TMP_Text)val4).verticalAlignment = (VerticalAlignmentOptions)1024; ((TMP_Text)val4).alignment = (TextAlignmentOptions)516; RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(1f, 0f); component2.anchorMax = new Vector2(1f, 0f); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = new Vector2(-100f, 25f); List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { return; } foreach (PlayerAvatar item in list) { PlayerInfo orCreate = PlayerInfoManager.GetOrCreate(item); orCreate.Refresh(); if (!((Object)(object)orCreate.playerHealth != (Object)null)) { continue; } if (Plugin.healthUIFancyColors.Value) { playeDataString.AppendLine(orCreate.GetName(isFancy: true) + " " + orCreate.GetStatus(isFancy: true)); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName(isFancy: true) + ": " + orCreate.GetStatus(isFancy: true))); } } else { playeDataString.AppendLine(orCreate.GetName() + " " + orCreate.GetStatus()); if (Plugin.enableDebugLogs.Value) { Debug.Log((object)("Creating UI for " + orCreate.GetName() + ": " + orCreate.GetStatus())); } } } ((TMP_Text)val4).text = playeDataString.ToString(); } } public class PlayerInfo { public string playerName; public int health; public int healthPrevious; public int maxHealth; public float healthPercent; public string playerColor; public string status; public string statusColor = "#FFFFFF"; private string RED_HEALTH = "#FF392A"; private float RED_PERCENT = 0.2f; private string YELLOW_HEALTH = "#D0FF00"; private float YELLOW_PERCENT = 0.6f; private string GREEN_HEALTH = "#43FF2A"; private PlayerAvatar player; public PlayerHealth playerHealth; public PlayerInfo(PlayerAvatar player) { this.player = player; BuildProfile(); } private void BuildProfile() { playerHealth = GetPlayerHealth(); health = GetHealth(); healthPrevious = GetHealthPrevious(); maxHealth = GetMaxHealth(); healthPercent = GetHealthPercent(); playerColor = GetColor(); if (health <= 0) { statusColor = RED_HEALTH; } else if (healthPercent < RED_PERCENT) { statusColor = RED_HEALTH; } else if (healthPercent < YELLOW_PERCENT) { statusColor = YELLOW_HEALTH; } else { statusColor = GREEN_HEALTH; } status = GetStatus(); } public void Refresh() { BuildProfile(); } private PlayerHealth GetPlayerHealth() { return ((Component)player).GetComponent<PlayerHealth>(); } public string GetName(bool isFancy = false) { FieldInfo field = ((object)player).GetType().GetField("playerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (isFancy) { return "<color=#" + playerColor + ">" + (string)field.GetValue(player) + ":</color>"; } return "<color=#FFFFFF>" + (string)field.GetValue(player) + ":</color>"; } private int GetHealth() { return (int)((object)playerHealth).GetType().GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(playerHealth); } private int GetHealthPrevious() { return (int)((object)playerHealth).GetType().GetField("healthPrevious", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(playerHealth); } private int GetMaxHealth() { return (int)((object)playerHealth).GetType().GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(playerHealth); } private float GetHealthPercent() { if (maxHealth <= 0) { return 0f; } return (float)health / (float)maxHealth; } public string GetStatus(bool isFancy = false) { if (isFancy) { if (health > 0) { return $"<color={statusColor}>{health}/{maxHealth}</color>"; } return "<color=" + statusColor + ">Dead</color>"; } if (health > 0) { return $"{health}/{maxHealth}"; } return "Dead"; } private string GetColor() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Material val = (Material)((object)playerHealth).GetType().GetField("bodyMaterial", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(playerHealth); int num = Shader.PropertyToID("_AlbedoColor"); return ColorUtility.ToHtmlStringRGB(val.GetColor(num)); } } } namespace REPODepotHelper.Patches.PlayerHealthUIPatch { public class PlayerInfoManager { private static Dictionary<PlayerAvatar, PlayerInfo> players = new Dictionary<PlayerAvatar, PlayerInfo>(); public static PlayerInfo GetOrCreate(PlayerAvatar player) { if (!players.TryGetValue(player, out var value)) { value = new PlayerInfo(player); players[player] = value; } return value; } public static IEnumerable<PlayerInfo> GetPlayers() { return players.Values; } public static void Clear() { players.Clear(); } public static void Remove(PlayerAvatar player) { players.Remove(player); } } }