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 Garrys Mod Hear Display v1.0.1
GMHearDisplay.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GMHearDisplay.Patches; using GameNetcodeStuff; using HarmonyLib; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("GMHearDisplay")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("GMHearDisplay")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("be13cb0f-c894-4d78-b9c2-2c9bb103c566")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace GMHearDisplay { [BepInPlugin("dev.closeraven783.gmheardisplay", "GM Hear Display", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class GMHearDisplayMain : BaseUnityPlugin { internal static class PluginInfo { public const string GUID = "dev.closeraven783.gmheardisplay"; public const string NAME = "GM Hear Display"; public const string VERSION = "1.0.1"; } internal static ManualLogSource Log; private readonly Harmony _harmony = new Harmony("dev.closeraven783.gmheardisplay"); private static GMHearDisplayMain Instance; public static ConfigEntry<bool> ShowVoiceUI { get; private set; } public static ConfigEntry<float> MaxDistance { get; private set; } public static ConfigEntry<float> BarelyHearThreshold { get; private set; } public static ConfigEntry<string> TextColor { get; private set; } private void Awake() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } Log = ((BaseUnityPlugin)this).Logger; SetupBaseConfig(); SetupLethalConfig(); Log.LogInfo((object)"Plugin [dev.closeraven783.gmheardisplay (GM Hear Display) v1.0.1] is loaded!"); GameObject val = new GameObject("GMHearDisplay"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<VoiceDisplayRunner>(); } private void SetupBaseConfig() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown ShowVoiceUI = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Voice UI", true, "Enable or disable the voice UI display"); MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Distances", "Max Distance", 45f, new ConfigDescription("Maximum distance players can (probably) hear you normally", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>())); BarelyHearThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Distances", "Barely Hear Threshold", 47f, new ConfigDescription("Distance threshold for barely hearing", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 120f), Array.Empty<object>())); TextColor = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "Text Color", "#FFFFFF", "Hex color of the UI text (e.g., #FF0000 for red)"); } private void SetupLethalConfig() { try { Type type = Type.GetType("LethalConfig.LethalConfigManager, LethalConfig"); if (type != null) { Log.LogInfo((object)"LethalConfig found, adding config entries..."); AddLethalConfigEntries(type); } } catch (Exception ex) { Log.LogWarning((object)("Could not initialize LethalConfig: " + ex.Message)); } } private void AddLethalConfigEntries(Type lethalConfigManager) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_00f6: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_0127: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown try { Assembly assembly = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { if (assembly2.GetName().Name == "LethalConfig") { assembly = assembly2; break; } } if (assembly == null) { Log.LogError((object)"Could not find LethalConfig assembly!"); return; } Type type = assembly.GetType("LethalConfig.ConfigItems.BaseConfigItem"); if (type == null) { Log.LogError((object)"Could not find BaseConfigItem type!"); return; } MethodInfo method = lethalConfigManager.GetMethod("AddConfigItem", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { type }, null); BoolCheckBoxConfigItem val = new BoolCheckBoxConfigItem(ShowVoiceUI, false); ConfigEntry<float> maxDistance = MaxDistance; FloatSliderOptions val2 = new FloatSliderOptions { RequiresRestart = false }; ((BaseRangeOptions<float>)val2).Min = 0f; ((BaseRangeOptions<float>)val2).Max = 100f; FloatSliderConfigItem val3 = new FloatSliderConfigItem(maxDistance, val2); ConfigEntry<float> barelyHearThreshold = BarelyHearThreshold; FloatSliderOptions val4 = new FloatSliderOptions { RequiresRestart = false }; ((BaseRangeOptions<float>)val4).Min = 100f; ((BaseRangeOptions<float>)val4).Max = 120f; FloatSliderConfigItem val5 = new FloatSliderConfigItem(barelyHearThreshold, val4); HexColorInputFieldConfigItem val6 = new HexColorInputFieldConfigItem(TextColor, false); Log.LogInfo((object)"LethalConfig entires added"); } catch (Exception arg) { Log.LogError((object)$"Failed to add LethalConfig entries: {arg}"); } } } } namespace GMHearDisplay.Patches { public class VoiceDisplayUI { private static readonly Dictionary<PlayerControllerB, AudioSource> playerVoiceAudios = new Dictionary<PlayerControllerB, AudioSource>(); private static PlayerControllerB localPlayer; private static AudioSource localVoiceAudio; private static float nextSearchTime = 0f; private static Texture2D voiceIconTexture; private static Color ParseHexColor(string hex) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (ColorUtility.TryParseHtmlString(hex, ref result)) { return result; } return Color.white; } public static void LoadVoiceIcon() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, "Assets", "voice_icon.png"); if (!File.Exists(text)) { text = Path.Combine(directoryName, "voice_icon.png"); if (!File.Exists(text)) { GMHearDisplayMain.Log.LogError((object)("Voice icon not found at either:\n" + Path.Combine(directoryName, "Assets", "voice_icon.png") + "\nor\n" + text)); return; } GMHearDisplayMain.Log.LogInfo((object)("Voice icon found at root: " + text)); } byte[] array = File.ReadAllBytes(text); voiceIconTexture = new Texture2D(3, 2); if (ImageConversion.LoadImage(voiceIconTexture, array)) { ((Texture)voiceIconTexture).filterMode = (FilterMode)0; } else { GMHearDisplayMain.Log.LogError((object)"Failed to load image data into texture"); } } catch (Exception arg) { GMHearDisplayMain.Log.LogError((object)$"Failed to load voice icon: {arg}"); } } private static void UpdateVoiceInfo() { if (Time.time < nextSearchTime) { return; } nextSearchTime = Time.time + 1.5f; playerVoiceAudios.Clear(); PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>(); localPlayer = StartOfRound.Instance?.localPlayerController; PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if ((Object)(object)val == (Object)null) { continue; } AudioSource[] componentsInChildren = ((Component)val).GetComponentsInChildren<AudioSource>(); AudioSource[] array3 = componentsInChildren; foreach (AudioSource val2 in array3) { if ((Object)(object)val2 != (Object)null && val2.spatialBlend > 0.5f) { playerVoiceAudios[val] = val2; if ((Object)(object)val == (Object)(object)localPlayer) { localVoiceAudio = val2; } break; } } } } public static void OnGUI() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Expected O, but got Unknown //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) if (!GMHearDisplayMain.ShowVoiceUI.Value) { return; } UpdateVoiceInfo(); if ((Object)(object)localPlayer != (Object)null && localPlayer.isPlayerDead) { return; } if ((Object)(object)localPlayer == (Object)null || (Object)(object)localVoiceAudio == (Object)null) { GUIStyle style = new GUIStyle(GUI.skin.label) { fontSize = 16 }; DrawTextWithStroke(new Rect(20f, 20f, 250f, 30f), "waiting for voice :3", style, Color.white, Color.black, 1f); return; } GUIStyle style2 = new GUIStyle(GUI.skin.label) { fontSize = 20 }; Rect rect = default(Rect); ((Rect)(ref rect))..ctor(20f, 500f, 300f, 50f); DrawTextWithStroke(rect, "Who can hear you:", style2, ParseHexColor(GMHearDisplayMain.TextColor.Value), Color.black, 1.5f); float value = GMHearDisplayMain.MaxDistance.Value; float value2 = GMHearDisplayMain.BarelyHearThreshold.Value; Vector3 position = ((Component)localPlayer).transform.position; float num = 550f; bool flag = false; bool flag2 = false; Rect val = default(Rect); Rect rect2 = default(Rect); Rect val2 = default(Rect); Rect rect3 = default(Rect); foreach (KeyValuePair<PlayerControllerB, AudioSource> playerVoiceAudio in playerVoiceAudios) { PlayerControllerB key = playerVoiceAudio.Key; if ((Object)(object)key == (Object)null || (Object)(object)key == (Object)(object)localPlayer) { continue; } float num2 = Vector3.Distance(((Component)key).transform.position, position); bool flag3 = key.voicePlayerState != null && key.voicePlayerState.IsSpeaking; if (num2 <= value) { flag = true; float num3 = Mathf.Clamp01(num2 / value); Color textColor = Color.Lerp(Color.green, Color.red, num3 * num3); float num4 = 0f; if (flag3 && (Object)(object)voiceIconTexture != (Object)null) { float num5 = 24f; float num6 = 20f; float num7 = num + 5f; ((Rect)(ref val))..ctor(num6, num7, num5, num5); GUI.DrawTexture(val, (Texture)(object)voiceIconTexture); num4 = num5 + 5f; } string text = $"{key.playerUsername} ({num2:F1}m)"; GUIStyle style3 = new GUIStyle(GUI.skin.label) { fontSize = 18 }; ((Rect)(ref rect2))..ctor(20f + num4, num, 300f - num4, 35f); DrawTextWithStroke(rect2, text, style3, textColor, Color.black, 1f, eightWayStroke: true); num += 35f; } else if (num2 <= value2) { flag2 = true; float num8 = 0f; if (flag3 && (Object)(object)voiceIconTexture != (Object)null) { float num9 = 24f; float num10 = 20f; float num11 = num + 7f; ((Rect)(ref val2))..ctor(num10, num11, num9, num9); GUI.DrawTexture(val2, (Texture)(object)voiceIconTexture); num8 = num9 + 5f; } string text2 = $"{key.playerUsername} might be barely hearing you ({num2:F1}m)"; GUIStyle val3 = new GUIStyle(GUI.skin.label); val3.fontSize = 18; ((Rect)(ref rect3))..ctor(20f + num8, num + 2f, 300f - num8, 30f); DrawTextWithStroke(rect3, text2, val3, Color.yellow, new Color(0.2f, 0.2f, 0f)); num += 35f; } } if (!flag && !flag2) { DrawTextWithStroke(new Rect(20f, num + 3f, 300f, 25f), "No one", style2, Color.gray, Color.black, 1f); } GUI.color = Color.white; } private static void DrawTextWithStroke(Rect rect, string text, GUIStyle style, Color textColor, Color strokeColor, float strokeThickness = 2f, bool eightWayStroke = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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) Color color = GUI.color; GUI.color = strokeColor; if (eightWayStroke) { Rect val = default(Rect); for (float num = 0f - strokeThickness; num <= strokeThickness; num += strokeThickness) { for (float num2 = 0f - strokeThickness; num2 <= strokeThickness; num2 += strokeThickness) { if (num != 0f || num2 != 0f) { ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + num, ((Rect)(ref rect)).y + num2, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height); GUI.Label(val, text, style); } } } } else { Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x - strokeThickness, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height); GUI.Label(val2, text, style); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x + strokeThickness, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height); GUI.Label(val2, text, style); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x, ((Rect)(ref rect)).y - strokeThickness, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height); GUI.Label(val2, text, style); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + strokeThickness, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height); GUI.Label(val2, text, style); } GUI.color = textColor; GUI.Label(rect, text, style); GUI.color = color; } } public class VoiceDisplayRunner : MonoBehaviour { private void Start() { VoiceDisplayUI.LoadVoiceIcon(); } private void OnGUI() { VoiceDisplayUI.OnGUI(); } } }