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 ChatBoxPlus v1.0.2
plugins\ChatBoxPlus.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Logging; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace ChatBoxPlus; [BepInPlugin("repo.chatboxplus", "ChatBoxPlus", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class ChatBoxPlusPlugin : BaseUnityPlugin { public const string PluginGuid = "repo.chatboxplus"; public const string PluginName = "ChatBoxPlus"; public const string PluginVersion = "1.0.2"; public const string ChatBoxGuid = "ChatBox-UnloadedHangar"; private const string TargetPatchMethodName = "ChatManagerTTSPatch"; private static ManualLogSource _log; private bool _restored; private bool _chatBoxExtensionsPatched; private void Awake() { _log = ((BaseUnityPlugin)this).Logger; RestoreTts("Awake"); PatchChatBoxExtensions("Awake"); } private void Start() { RestoreTts("Start"); PatchChatBoxExtensions("Start"); } private void RestoreTts(string phase) { if (_restored) { return; } try { Type type = FindType("HarmonyLib.Harmony"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"HarmonyLib.Harmony was not found; TTS patch removal will be retried later."); return; } MethodInfo method = type.GetMethod("GetAllPatchedMethods", BindingFlags.Static | BindingFlags.Public); MethodInfo method2 = type.GetMethod("GetPatchInfo", BindingFlags.Static | BindingFlags.Public); MethodInfo methodInfo = FindSpecificUnpatchMethod(type); if (method == null || method2 == null || methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Harmony API shape was not recognized; cannot remove ChatBox TTS patch."); return; } object harmonyInstance = Activator.CreateInstance(type, "repo.chatboxplus"); if (!(method.Invoke(null, null) is IEnumerable enumerable)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Harmony returned no patched methods list."); return; } int num = 0; foreach (object item in enumerable) { MethodBase methodBase = item as MethodBase; if (!(methodBase == null)) { object obj = method2.Invoke(null, new object[1] { methodBase }); if (obj != null) { num += RemoveMatchingPatches(harmonyInstance, methodInfo, methodBase, obj, "Prefixes"); num += RemoveMatchingPatches(harmonyInstance, methodInfo, methodBase, obj, "Postfixes"); num += RemoveMatchingPatches(harmonyInstance, methodInfo, methodBase, obj, "Transpilers"); num += RemoveMatchingPatches(harmonyInstance, methodInfo, methodBase, obj, "Finalizers"); num += RemoveMatchingPatches(harmonyInstance, methodInfo, methodBase, obj, "ILManipulators"); } } } if (num > 0) { _restored = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Removed " + num + " ChatBox TTS-disabling Harmony patch(es) during " + phase + ".")); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("No ChatBox TTS-disabling Harmony patches were found during " + phase + ".")); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to restore ChatBox TTS during " + phase + ": " + ex)); } } private void PatchChatBoxExtensions(string phase) { if (_chatBoxExtensionsPatched) { return; } try { Type type = FindType("HarmonyLib.Harmony"); Type type2 = FindType("HarmonyLib.HarmonyMethod"); Type type3 = FindType("ChatBox.NonPatch.NonPatches"); if (type == null || type2 == null || type3 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"ChatBox/Harmony types were not found; ChatBoxPlus patches will be retried later."); return; } MethodInfo methodInfo = FindHarmonyPatchMethod(type); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Harmony.Patch API shape was not recognized; cannot apply ChatBoxPlus patches."); return; } object harmonyInstance = Activator.CreateInstance(type, "repo.chatboxplus"); MethodInfo method = type3.GetMethod("BridgedMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method2 = type3.GetMethod("AddChatMessageSystem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null || method2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"ChatBox methods were not found; cannot apply ChatBoxPlus patches."); return; } PatchWithPrefix(harmonyInstance, methodInfo, type2, method, typeof(ChatBoxPlusPlugin).GetMethod("GhostOnlyBridgedMessagePrefix", BindingFlags.Static | BindingFlags.NonPublic)); PatchWithPrefix(harmonyInstance, methodInfo, type2, method2, typeof(ChatBoxPlusPlugin).GetMethod("SuppressOutOfRangeSystemMessagePrefix", BindingFlags.Static | BindingFlags.NonPublic)); _chatBoxExtensionsPatched = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Applied ChatBoxPlus chat visibility patches during " + phase + ".")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to apply ChatBoxPlus patches during " + phase + ": " + ex)); } } private static bool GhostOnlyBridgedMessagePrefix(string message, string playerHexColor, string playerName, bool dead) { if (!dead) { return true; } if (!IsLocalPlayerDead()) { return false; } try { AddChatBoxDeadMessage(message, playerHexColor, playerName); } catch (Exception ex) { LogWarning("Failed to show ghost-only ChatBox message: " + ex); } return false; } private static bool SuppressOutOfRangeSystemMessagePrefix(string chatMessage, string nameOfUserWhoTyped) { if (string.Equals(nameOfUserWhoTyped, "Unknown", StringComparison.OrdinalIgnoreCase) && chatMessage != null && chatMessage.IndexOf("<decoding failed>", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } return true; } private static void PatchWithPrefix(object harmonyInstance, MethodInfo harmonyPatchMethod, Type harmonyMethodType, MethodBase original, MethodInfo prefix) { object obj = Activator.CreateInstance(harmonyMethodType, prefix); ParameterInfo[] parameters = harmonyPatchMethod.GetParameters(); object[] array = new object[parameters.Length]; array[0] = original; array[1] = obj; harmonyPatchMethod.Invoke(harmonyInstance, array); } private static bool IsLocalPlayerDead() { try { Type type = FindType("SemiFunc"); if (type == null) { return false; } MethodInfo method = type.GetMethod("PlayerAvatarLocal", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { return false; } object obj = method.Invoke(null, null); if (obj == null) { return false; } FieldInfo field = obj.GetType().GetField("deadSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return false; } object value = field.GetValue(obj); return value is bool && (bool)value; } catch (Exception ex) { LogWarning("Failed to read local player death state: " + ex); return false; } } private static void AddChatBoxDeadMessage(string message, string playerHexColor, string playerName) { Type type = FindType("ChatBox.NonPatch.NonPatches"); if (type == null) { return; } object chatBoxNonPatchesInstance = GetChatBoxNonPatchesInstance(type); if (chatBoxNonPatchesInstance != null) { MethodInfo method = type.GetMethod("AddChatMessageDead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { method.Invoke(chatBoxNonPatchesInstance, new object[3] { message, playerHexColor, playerName }); } } } private static object GetChatBoxNonPatchesInstance(Type nonPatchesType) { PropertyInfo property = nonPatchesType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(null, null); } MethodInfo method = nonPatchesType.GetMethod("get_Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(method != null)) { return null; } return method.Invoke(null, null); } private static MethodInfo FindHarmonyPatchMethod(Type harmonyType) { MethodInfo[] methods = harmonyType.GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "Patch")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length >= 5 && parameters[0].ParameterType == typeof(MethodBase) && parameters[1].ParameterType.FullName == "HarmonyLib.HarmonyMethod") { return methodInfo; } } } return null; } private static int RemoveMatchingPatches(object harmonyInstance, MethodInfo unpatchSpecificMethod, MethodBase original, object patchInfo, string collectionName) { object memberValue = GetMemberValue(patchInfo, collectionName); if (!(memberValue is IEnumerable enumerable)) { return 0; } List<MethodInfo> list = new List<MethodInfo>(); foreach (object item in enumerable) { MethodInfo methodInfo = GetMemberValue(item, "PatchMethod") as MethodInfo; if (IsChatBoxTtsPatch(methodInfo)) { list.Add(methodInfo); } } for (int i = 0; i < list.Count; i++) { MethodInfo methodInfo2 = list[i]; unpatchSpecificMethod.Invoke(harmonyInstance, new object[2] { original, methodInfo2 }); } return list.Count; } private static bool IsChatBoxTtsPatch(MethodInfo patchMethod) { if (patchMethod == null || patchMethod.DeclaringType == null) { return false; } if (patchMethod.Name == "ChatManagerTTSPatch") { return true; } Type declaringType = patchMethod.DeclaringType; string text = declaringType.FullName ?? string.Empty; string text2 = declaringType.Name ?? string.Empty; if (!(text2 == "ChatManagerTTSPatch")) { return text.EndsWith(".ChatManagerTTSPatch", StringComparison.Ordinal); } return true; } private static MethodInfo FindSpecificUnpatchMethod(Type harmonyType) { MethodInfo[] methods = harmonyType.GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "Unpatch")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(MethodBase) && parameters[1].ParameterType == typeof(MethodInfo)) { return methodInfo; } } } return null; } private static object GetMemberValue(object instance, string memberName) { Type type = instance.GetType(); PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(instance, null); } FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(instance); } return null; } private static Type FindType(string fullTypeName) { Type type = Type.GetType(fullTypeName + ", 0Harmony", throwOnError: false); if (type != null) { return type; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType(fullTypeName, throwOnError: false); if (type != null) { return type; } } return null; } private static void LogWarning(string message) { if (_log != null) { _log.LogWarning((object)message); } } }