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 NiceChat v1.2.7
BepInEx/plugins/NiceChat.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("NiceChat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.7.0")] [assembly: AssemblyInformationalVersion("1.2.7+4c75d1accc36435e7d9457468e2b00c4c86d6e92")] [assembly: AssemblyProduct("NiceChat")] [assembly: AssemblyTitle("NiceChat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.7.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NiceChat { public interface IServerVar : IDisposable { static List<IServerVar> AllServerVars; void TryRegister(); static IServerVar() { AllServerVars = new List<IServerVar>(); } } public class ServerVar<T> : IServerVar, IDisposable where T : IEquatable<T> { public delegate void ReadFromReader<T1>(FastBufferReader reader, out T1 value); private T value; private Action<FastBufferWriter, T> writeValue; private ReadFromReader<T> readValue; public string Id { get; init; } public T Value { get { return value; } set { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer) { if (!EqualityComparer<T>.Default.Equals(this.value, value)) { this.value = value; if (NetworkManager.Singleton.IsConnectedClient) { Plugin.log.LogDebug((object)$"[{Id}] Broadcasting new value \"{value}\" to all clients"); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1); writeValue(val, value); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(Id, val, (NetworkDelivery)3); } } } else { Plugin.log.LogWarning((object)("Client tried to set ServerVar \"" + Id + "\"")); } } } public ServerVar(string id, Action<FastBufferWriter, T> write, ReadFromReader<T> read, T defaultValue = default(T)) { value = defaultValue; Id = (string.IsNullOrEmpty(id) ? "taffyko.NiceChat" : ("taffyko.NiceChat." + id)); writeValue = write; readValue = read; IServerVar.AllServerVars.Add(this); ((IServerVar)this).TryRegister(); Plugin.cleanupActions.Add(Dispose); } private void Handler(ulong senderClientId, FastBufferReader messagePayload) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (senderClientId != NetworkManager.Singleton.LocalClientId) { if (NetworkManager.Singleton.IsServer) { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1); writeValue(val, value); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(Id, senderClientId, val, (NetworkDelivery)3); Plugin.log.LogDebug((object)$"[{Id}] Responded to request from {senderClientId} with value: \"{value}\""); } else { readValue(messagePayload, out value); Plugin.log.LogDebug((object)$"[{Id}] Received update from {senderClientId} with value: \"{value}\""); } } } private void OnClientConnectedCallback(ulong clientId) { if (clientId == NetworkManager.Singleton.LocalClientId) { ((IServerVar)this).TryRegister(); } } public void Dispose() { Plugin.log.LogDebug((object)("[" + Id + "] Disposed ServerVar")); if ((Object)(object)NetworkManager.Singleton != (Object)null) { NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnectedCallback; if (NetworkManager.Singleton.IsConnectedClient) { NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(Id); } } IServerVar.AllServerVars.Remove(this); } void IServerVar.TryRegister() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) Plugin.log.LogDebug((object)$"[{Id}] Attempting to register. NetworkManager: {(Object)(object)NetworkManager.Singleton != (Object)null}, Connected: {(Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsConnectedClient}"); if (!((Object)(object)NetworkManager.Singleton != (Object)null)) { return; } NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnectedCallback; if (NetworkManager.Singleton.IsConnectedClient) { NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(Id, new HandleNamedMessageDelegate(Handler)); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(Id, new HandleNamedMessageDelegate(Handler)); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(Id, new HandleNamedMessageDelegate(Handler)); Plugin.log.LogDebug((object)("[" + Id + "] Registered ServerVar")); if (!NetworkManager.Singleton.IsServer) { NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(Id, 0uL, new FastBufferWriter(0, (Allocator)2, -1), (NetworkDelivery)3); Plugin.log.LogDebug((object)$"[{Id}] Sent request from {NetworkManager.Singleton.LocalClientId} to {0uL}"); } } } } [HarmonyPatch] internal class NetworkingPatches { [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void StartOfRound_Awake_Postfix() { foreach (IServerVar allServerVar in IServerVar.AllServerVars) { allServerVar.TryRegister(); } } } [BepInPlugin("taffyko.NiceChat", "NiceChat", "1.2.7")] public class Plugin : BaseUnityPlugin { private delegate bool ParseConfigValue<T>(string input, out T output); public const string modGUID = "taffyko.NiceChat"; public const string modName = "NiceChat"; public const string modVersion = "1.2.7"; private readonly Harmony harmony = new Harmony("taffyko.NiceChat"); public static ManualLogSource log = null; internal static List<Action> cleanupActions = new List<Action>(); public static int MaxMessageHistory { get; private set; } public static float DefaultFontSize { get; private set; } public static bool EnlargeChatWindow { get; private set; } public static int CharacterLimit { get; private set; } public static float MessageRange { get; private set; } public static bool HearDeadPlayers { get; private set; } public static bool EnableTimestamps { get; private set; } public static bool TagMessageStatus { get; private set; } public static bool ShowScrollbar { get; private set; } public static float FadeOpacity { get; private set; } public static float FadeTimeAfterMessage { get; private set; } public static float FadeTimeAfterOwnMessage { get; private set; } public static float FadeTimeAfterUnfocused { get; private set; } public static bool GuiFadeFix { get; private set; } public static bool SpectatorChatHideOtherHudElements { get; private set; } public static Color InputTextColor { get; private set; } private void Awake() { ConfigInit(); log = Logger.CreateLogSource("NiceChat"); log.LogInfo((object)"Loading taffyko.NiceChat"); ServerVars.characterLimit = new ServerVar<int>("characterLimit", delegate(FastBufferWriter writer, int v) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) ((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref v, default(ForPrimitives)); }, delegate(FastBufferReader r, out int v) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref v, default(ForPrimitives)); }, 49); ServerVars.hearDeadPlayers = new ServerVar<bool>("hearDeadPlayers", delegate(FastBufferWriter writer, bool v) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) ((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref v, default(ForPrimitives)); }, delegate(FastBufferReader r, out bool v) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) ((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref v, default(ForPrimitives)); }, defaultValue: false); ServerVars.messageRange = new ServerVar<float>("messageRange", delegate(FastBufferWriter writer, float v) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) ((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref v, default(ForPrimitives)); }, delegate(FastBufferReader r, out float v) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref v, default(ForPrimitives)); }, 25f); ServerVars.modVersion = new ServerVar<string>("", delegate(FastBufferWriter writer, string v) { ((FastBufferWriter)(ref writer)).WriteValueSafe(v, false); }, delegate(FastBufferReader r, out string v) { ((FastBufferReader)(ref r)).ReadValueSafe(ref v, false); }); harmony.PatchAll(Assembly.GetExecutingAssembly()); } private void OnDestroy() { } private void ConfigInit() { //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Config.Bind<string>("README", "README", "", "All config values are text-based, as a workaround to make it possible for default values to change in future updates.\r\n\r\nSee https://github.com/taffyko/LCNiceChat/issues/3 for more information.\r\n\r\nIf you enter an invalid value, it will change back to \"default\" when the game starts."); Color vanillaValue = default(Color); ColorUtility.TryParseHtmlString("#585ed1d4", ref vanillaValue); ConfEntry("Chat", "MaxMessageHistory", 15, "Set the maximum number of messages in history before the oldest messages begin to disappear (NOTE: Long message histories can negatively impact performance)", int.TryParse, 4); ConfEntry("Chat", "DefaultFontSize", 11f, "Font size.", float.TryParse, 13f); ConfEntry("Chat", "EnlargeChatWindow", defaultValue: true, "Increases the size of the chat area.", bool.TryParse); ConfEntry("Chat", "CharacterLimit", 1000, "Maximum character limit for messages in your lobby.", int.TryParse, hostControlled: true); ConfEntry("Chat", "MessageRange", 25f, "Maximum distance from which messages between living players can be heard without a walkie-talkie.", float.TryParse, 25f, hostControlled: true); ConfEntry("Chat", "HearDeadPlayers", defaultValue: false, "When enabled, allows living players to hear messages from dead players.", bool.TryParse, hostControlled: true); ConfEntry("Chat", "EnableTimestamps", defaultValue: true, "Adds timestamps to messages whenever the clock is visible.", bool.TryParse); ConfEntry("Chat", "TagMessageStatus", defaultValue: false, "Adds tags like *WALKIE* and *DEAD* to messages in addition to the color-coding.", bool.TryParse); ConfEntry("Chat", "ShowScrollbar", defaultValue: true, "If false, the scrollbar is permanently hidden even when the chat input is focused.", bool.TryParse); ConfEntry("Chat", "InputTextColor", Color.white, "Default color of text in the input field", (ParseConfigValue<Color>)ColorUtility.TryParseHtmlString, vanillaValue, hostControlled: false); ConfEntry("Fade Behaviour", "FadeOpacity", 0f, "The opacity of the chat when it fades from inactivity. 0.0 makes the chat fade away completely.", float.TryParse, 0.2f); ConfEntry("Fade Behaviour", "FadeTimeAfterMessage", 4f, "The amount of seconds before the chat fades out after a message is sent by another player.", float.TryParse, 4f); ConfEntry("Fade Behaviour", "FadeTimeAfterOwnMessage", 2f, "The amount of seconds before the chat fades out after a message is sent by you.", float.TryParse, 2f); ConfEntry("Fade Behaviour", "FadeTimeAfterUnfocused", 1f, "The amount of seconds before the chat fades out after the chat input is unfocused.", float.TryParse, 1f); ConfEntry("Compatibility", "GuiFadeFix", defaultValue: true, "Workaround to prevent other UI elements (like the indicator from LethalLoudnessMeter) from also fading out when the chat fades", bool.TryParse); ConfEntry("Compatibility", "SpectatorChatHideOtherHudElements", defaultValue: true, "For spectator chat, ensures that only the chat window is shown, and that irrelevant HUD elements (inventory/etc.) are hidden.", bool.TryParse); } private static bool NoopParse(string input, out string output) { output = input; return true; } private void ConfEntry<T>(string category, string name, T defaultValue, string description, ParseConfigValue<T> tryParse, bool hostControlled = false) { ConfEntryInternal(category, name, defaultValue, description, tryParse, hostControlled); } private void ConfEntry<T>(string category, string name, T defaultValue, string description, ParseConfigValue<T> tryParse, T vanillaValue, bool hostControlled = false) { ConfEntryInternal(category, name, defaultValue, description, tryParse, hostControlled, ConfEntryToString(vanillaValue)); } private void ConfEntryInternal<T>(string category, string name, T defaultValue, string description, ParseConfigValue<T> tryParse, bool hostControlled = false, string? vanillaValueText = null) { ParseConfigValue<T> tryParse2 = tryParse; T defaultValue2 = defaultValue; PropertyInfo property = typeof(Plugin).GetProperty(name); string text = "[default: " + ConfEntryToString(defaultValue2) + "]\n" + description; text += (hostControlled ? "\n(This setting is overridden by the lobby host)" : "\n(This setting's effect applies to you only)"); if (vanillaValueText != null) { text = text + "\n(The original value of this setting in the base-game is " + vanillaValueText + ")"; } ConfigEntry<string> config = ((BaseUnityPlugin)this).Config.Bind<string>(category, name, "default", text); if (string.IsNullOrEmpty(config.Value)) { config.Value = "default"; } T output; bool flag = tryParse2(config.Value, out output) && config.Value != "default"; property.SetValue(null, flag ? output : defaultValue2); if (!flag) { config.Value = "default"; } EventHandler loadConfig = delegate { T output2; bool flag2 = tryParse2(config.Value, out output2) && config.Value != "default"; property.SetValue(null, flag2 ? output2 : defaultValue2); }; config.SettingChanged += loadConfig; cleanupActions.Add(delegate { config.SettingChanged -= loadConfig; property.SetValue(null, defaultValue2); }); } private string ConfEntryToString(object? value) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (value == null) { return "null"; } Type type = value.GetType(); if (type == typeof(float)) { return $"{(float)value:0.0#####}"; } if (type == typeof(Color)) { return "#" + ColorUtility.ToHtmlStringRGBA((Color)value); } return value.ToString(); } } public static class ServerVars { public static ServerVar<int> characterLimit; public static ServerVar<bool> hearDeadPlayers; public static ServerVar<float> messageRange; public static ServerVar<string> modVersion; } [HarmonyPatch] internal class Patches { public class CustomFields { public DateTime? connectTime; public bool networkReady; public InputAction? shiftAction; public InputAction? scrollAction; public TMP_Text? chatText; public TMP_InputField? chatTextField; public TextMeshProUGUI? chatTextFieldGui; public float previousChatTextHeight; public float previousScrollPosition; public RectTransform? hudBottomLeftCorner; public RectTransform? chatContainer; public RectTransform? chatTextBgRect; public RectTransform? chatTextFieldRect; public RectTransform? chatTextRect; public RectTransform? scrollContainerRect; public CanvasGroup? scrollbarCanvasGroup; public ScrollRect? scroll; public Scrollbar? scrollbar; public Action? restoreHiddenHudElementsAction; public List<Action> cleanupActions = new List<Action>(); } private record MessageContext(int senderId, bool walkie, bool senderDead); public static Dictionary<PlayerControllerB, CustomFields> fields = new Dictionary<PlayerControllerB, CustomFields>(); public static (HUDElement, float originalOpacity)[] hiddenElements = new(HUDElement, float)[0]; private static MethodInfo MethodInfo_GetChatMessageNameOpeningTag = typeof(Patches).GetMethod("GetChatMessageNameOpeningTag"); private static MethodInfo MethodInfo_GetChatMessageNameClosingTag = typeof(Patches).GetMethod("GetChatMessageNameClosingTag"); private static MethodInfo stringEqual = typeof(string).GetMethod("op_Equality", new Type[2] { typeof(string), typeof(string) }); private static MessageContext? messageContext = null; private static MethodInfo MethodInfo_Vector3_Distance = typeof(Vector3).GetMethod("Distance"); private static MethodInfo MethodInfo_CanHearPreflight = typeof(Patches).GetMethod("CanHearPreflight"); private static float timeAtLastCheck = 0f; private static MethodInfo getCharacterLimit = typeof(Patches).GetMethod("GetCharacterLimit"); private static FieldInfo FieldInfo_isPlayerDead = typeof(PlayerControllerB).GetField("isPlayerDead"); private static bool IsLocalPlayer(PlayerControllerB __instance) { return (Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController; } [HarmonyPatch(typeof(PlayerControllerB), "Awake")] [HarmonyPostfix] private static void Player_Awake(PlayerControllerB __instance) { reload(__instance); } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void Player_Update(PlayerControllerB __instance) { //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0834: Unknown result type (might be due to invalid IL or missing references) //IL_0839: Unknown result type (might be due to invalid IL or missing references) //IL_084f: Unknown result type (might be due to invalid IL or missing references) //IL_0854: Unknown result type (might be due to invalid IL or missing references) //IL_0869: Unknown result type (might be due to invalid IL or missing references) //IL_0873: Unknown result type (might be due to invalid IL or missing references) //IL_088e: Unknown result type (might be due to invalid IL or missing references) //IL_0898: Unknown result type (might be due to invalid IL or missing references) //IL_089d: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Expected O, but got Unknown //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_0658: Expected O, but got Unknown //IL_0688: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_06c0: Unknown result type (might be due to invalid IL or missing references) //IL_06f8: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_072a: Unknown result type (might be due to invalid IL or missing references) //IL_0734: Unknown result type (might be due to invalid IL or missing references) //IL_0739: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_0764: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_079c: Unknown result type (might be due to invalid IL or missing references) //IL_07ac: Unknown result type (might be due to invalid IL or missing references) //IL_07ca: Unknown result type (might be due to invalid IL or missing references) //IL_08e1: Unknown result type (might be due to invalid IL or missing references) //IL_08fb: Unknown result type (might be due to invalid IL or missing references) //IL_0900: Unknown result type (might be due to invalid IL or missing references) //IL_096e: Unknown result type (might be due to invalid IL or missing references) //IL_0973: Unknown result type (might be due to invalid IL or missing references) //IL_09d2: Unknown result type (might be due to invalid IL or missing references) //IL_09a2: Unknown result type (might be due to invalid IL or missing references) //IL_0a06: Unknown result type (might be due to invalid IL or missing references) //IL_0a0b: Unknown result type (might be due to invalid IL or missing references) //IL_0a42: Unknown result type (might be due to invalid IL or missing references) //IL_0a47: Unknown result type (might be due to invalid IL or missing references) //IL_0abc: Unknown result type (might be due to invalid IL or missing references) //IL_0ac1: Unknown result type (might be due to invalid IL or missing references) //IL_0a6e: Unknown result type (might be due to invalid IL or missing references) //IL_0a73: Unknown result type (might be due to invalid IL or missing references) //IL_0a8f: Unknown result type (might be due to invalid IL or missing references) //IL_0a94: Unknown result type (might be due to invalid IL or missing references) reload(__instance); if (!IsLocalPlayer(__instance) || (Object)(object)HUDManager.Instance == (Object)null) { return; } CustomFields customFields = fields[__instance]; if (__instance.isPlayerDead) { HUDManager hud = HUDManager.Instance; if (hud.HUDContainer.GetComponent<CanvasGroup>().alpha == 0f) { hud.HUDAnimator.SetTrigger("revealHud"); hud.ClearControlTips(); } if (Plugin.SpectatorChatHideOtherHudElements && customFields.restoreHiddenHudElementsAction == null) { HUDElement[] array = (HUDElement[])Traverse.Create((object)hud).Field("HUDElements").GetValue(); Transform bottomMiddle = hud.HUDContainer.transform.Find("BottomMiddle"); (HUDElement item, float)[] hudElementsAlphas = array.Select((HUDElement item) => (item, Mathf.Max(item.targetAlpha, item.canvasGroup.alpha))).ToArray(); customFields.restoreHiddenHudElementsAction = delegate { (HUDElement, float)[] array3 = hudElementsAlphas; for (int j = 0; j < array3.Length; j++) { var (val12, num6) = array3[j]; if (val12 != hud.Chat) { hud.PingHUDElement(val12, 0f, num6, num6); } } if ((Object)(object)bottomMiddle != (Object)null) { ((Component)bottomMiddle).gameObject.SetActive(true); } }; HUDElement[] array2 = array; foreach (HUDElement val in array2) { if (val != hud.Chat) { hud.PingHUDElement(val, 0f, 0f, 0f); } } if ((Object)(object)bottomMiddle != (Object)null) { ((Component)bottomMiddle).gameObject.SetActive(false); } } } if (customFields.restoreHiddenHudElementsAction != null && (!__instance.isPlayerDead || !Plugin.SpectatorChatHideOtherHudElements)) { customFields.restoreHiddenHudElementsAction(); customFields.restoreHiddenHudElementsAction = null; } if ((Object)(object)customFields.chatTextField != (Object)null) { customFields.chatTextField.characterLimit = ServerVars.characterLimit.Value; customFields.chatTextField.lineLimit = 0; if (customFields.shiftAction != null && customFields.shiftAction.IsPressed()) { customFields.chatTextField.lineType = (LineType)2; } else { customFields.chatTextField.lineType = (LineType)1; } } if ((Object)(object)customFields.chatText != (Object)null) { customFields.chatText.fontSize = Plugin.DefaultFontSize; if (customFields.chatText.text.Length > customFields.chatText.maxVisibleCharacters) { int num = customFields.chatText.maxVisibleCharacters / 10; while (customFields.chatText.text.Length > customFields.chatText.maxVisibleCharacters - num) { customFields.chatText.text = customFields.chatText.text.Remove(0, HUDManager.Instance.ChatMessageHistory[0].Length); HUDManager.Instance.ChatMessageHistory.RemoveAt(0); } } } if ((Object)(object)customFields.chatTextFieldGui != (Object)null) { ((Graphic)customFields.chatTextFieldGui).color = Plugin.InputTextColor; } if (!((Object)(object)customFields.chatText != (Object)null) || !((Object)(object)customFields.chatTextRect != (Object)null) || !((Object)(object)customFields.chatTextBgRect != (Object)null) || !((Object)(object)customFields.chatTextFieldRect != (Object)null)) { return; } if (Plugin.EnlargeChatWindow) { customFields.chatTextBgRect.anchorMin = new Vector2(0.35f, 0.5f); customFields.chatTextBgRect.anchorMax = new Vector2(0.8f, 0.5f); customFields.chatTextFieldRect.anchorMin = new Vector2(0.3f, 0.5f); customFields.chatTextFieldRect.anchorMax = new Vector2(0.8f, 0.5f); } else { customFields.chatTextBgRect.anchorMin = new Vector2(0.5f, 0.5f); customFields.chatTextBgRect.anchorMax = new Vector2(0.5f, 0.5f); customFields.chatTextFieldRect.anchorMin = new Vector2(0.5f, 0.5f); customFields.chatTextFieldRect.anchorMax = new Vector2(0.5f, 0.5f); } Rect rect; if ((Object)(object)customFields.scrollContainerRect == (Object)null) { Transform obj = ((Transform)customFields.chatTextBgRect).parent.Find("ChatScrollContainer"); customFields.scrollContainerRect = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null); if ((Object)(object)customFields.scrollContainerRect == (Object)null) { GameObject val2 = new GameObject { name = "ChatScrollContainer" }; customFields.scrollContainerRect = val2.AddComponent<RectTransform>(); customFields.scrollContainerRect.anchorMin = Vector2.zero; customFields.scrollContainerRect.anchorMax = Vector2.one; customFields.scrollContainerRect.offsetMin = new Vector2(0f, 40f); customFields.scrollContainerRect.offsetMax = new Vector2(0f, -3f); ((Transform)customFields.scrollContainerRect).SetParent((Transform)(object)customFields.chatTextBgRect, false); GameObject val3 = new GameObject { name = "ScrollMask" }; RectTransform val4 = val3.AddComponent<RectTransform>(); val3.AddComponent<Image>().sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0f, 0f)); val3.AddComponent<Mask>().showMaskGraphic = false; ((Transform)val4).SetParent((Transform)(object)customFields.scrollContainerRect, false); val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; ((Transform)customFields.chatTextRect).SetParent((Transform)(object)val4, false); LayoutElement val5 = default(LayoutElement); ((Component)customFields.chatText).gameObject.TryGetComponent<LayoutElement>(ref val5); Object.Destroy((Object)(object)val5); val5 = ((Component)customFields.chatText).gameObject.AddComponent<LayoutElement>(); LayoutElement obj2 = val5; rect = val4.rect; obj2.minHeight = ((Rect)(ref rect)).height; customFields.chatText.alignment = (TextAlignmentOptions)1025; ContentSizeFitter val6 = default(ContentSizeFitter); ((Component)customFields.chatText).gameObject.TryGetComponent<ContentSizeFitter>(ref val6); Object.Destroy((Object)(object)val6); ContentSizeFitter obj3 = ((Component)customFields.chatText).gameObject.AddComponent<ContentSizeFitter>(); obj3.verticalFit = (FitMode)2; obj3.horizontalFit = (FitMode)0; customFields.scroll = val2.AddComponent<ScrollRect>(); customFields.scroll.content = customFields.chatTextRect; customFields.scroll.viewport = val4; customFields.scroll.vertical = true; customFields.scroll.horizontal = false; customFields.scroll.verticalNormalizedPosition = 0f; GameObject val7 = new GameObject { name = "Scrollbar" }; customFields.scrollbarCanvasGroup = val7.AddComponent<CanvasGroup>(); RectTransform val8 = val7.AddComponent<RectTransform>(); ((Transform)val8).SetParent((Transform)(object)customFields.scrollContainerRect, false); val8.anchorMin = new Vector2(1f, 0f); val8.anchorMax = Vector2.one; val8.offsetMin = new Vector2(-7f, 0f); val8.offsetMax = new Vector2(-5f, -5f); customFields.scrollbar = val7.AddComponent<Scrollbar>(); Image obj4 = val7.AddComponent<Image>(); obj4.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0f, 0f)); ((Graphic)obj4).color = new Color(0.34509805f, 0.36862746f, 0.81960785f, 10f / 51f); GameObject val9 = new GameObject { name = "ScrollbarHandle" }; RectTransform val10 = val9.AddComponent<RectTransform>(); ((Transform)val10).SetParent((Transform)(object)val8, false); val10.offsetMin = Vector2.zero; val10.offsetMax = Vector2.zero; Image obj5 = val9.AddComponent<Image>(); obj5.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0f, 0f)); ((Graphic)obj5).color = Color.white; ((Graphic)obj5).color = new Color(0.34509805f, 0.36862746f, 0.81960785f, 0.4392157f); customFields.scrollbar.handleRect = val10; customFields.scrollbar.direction = (Direction)2; customFields.scroll.verticalScrollbar = customFields.scrollbar; } } LayoutElement val11 = default(LayoutElement); ((Component)customFields.chatText).gameObject.TryGetComponent<LayoutElement>(ref val11); if ((Object)(object)val11 != (Object)null) { RectTransform component = ((Component)((Transform)customFields.chatTextRect).parent).GetComponent<RectTransform>(); LayoutElement obj6 = val11; rect = component.rect; obj6.minHeight = ((Rect)(ref rect)).height; RectTransform? chatTextRect = customFields.chatTextRect; rect = component.rect; chatTextRect.sizeDelta = new Vector2(((Rect)(ref rect)).width - 12f, customFields.chatTextRect.sizeDelta.y); ((Transform)customFields.chatTextRect).localPosition = Vector2.op_Implicit(new Vector2(0f, ((Transform)customFields.chatTextRect).localPosition.y)); } if (!((Object)(object)customFields.chatTextField != (Object)null)) { return; } if (customFields.chatTextField.isFocused && customFields.scrollAction != null && (Object)(object)customFields.scroll != (Object)null) { float num2 = customFields.scrollAction.ReadValue<Vector2>().y / 120f; float num3 = num2; rect = customFields.chatTextRect.rect; num2 = num3 / ((Rect)(ref rect)).height; num2 *= 30f; ScrollRect? scroll = customFields.scroll; scroll.verticalNormalizedPosition += num2; } if (!((Object)(object)customFields.scroll != (Object)null) || !((Object)(object)customFields.scrollbar != (Object)null) || !((Object)(object)customFields.scrollbarCanvasGroup != (Object)null)) { return; } float preferredHeight = customFields.chatText.preferredHeight; rect = customFields.scrollContainerRect.rect; if (preferredHeight < ((Rect)(ref rect)).height) { ((Graphic)((Component)customFields.scrollbar.handleRect).GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0f); } else { ((Graphic)((Component)customFields.scrollbar.handleRect).GetComponent<Image>()).color = new Color(0.34509805f, 0.36862746f, 0.81960785f, 0.4392157f); } if (customFields.chatTextField.isFocused) { HUDManager.Instance.Chat.targetAlpha = 1f; rect = customFields.chatTextRect.rect; if (((Rect)(ref rect)).height != customFields.previousChatTextHeight) { if (customFields.chatTextField.isFocused) { float verticalNormalizedPosition = customFields.scroll.verticalNormalizedPosition; rect = customFields.chatTextRect.rect; if (verticalNormalizedPosition >= 100f / ((Rect)(ref rect)).height) { float num4 = (1f - customFields.previousScrollPosition) * customFields.previousChatTextHeight; rect = customFields.chatTextRect.rect; float num5 = ((Rect)(ref rect)).height - num4; ScrollRect? scroll2 = customFields.scroll; rect = customFields.chatTextRect.rect; scroll2.verticalNormalizedPosition = num5 / ((Rect)(ref rect)).height; goto IL_0ab5; } } customFields.scroll.verticalNormalizedPosition = 0f; goto IL_0ab5; } } else { customFields.scroll.verticalNormalizedPosition = 0f; } goto IL_0ae1; IL_0ae1: customFields.scrollbarCanvasGroup.alpha = ((Plugin.ShowScrollbar && customFields.chatTextField.isFocused) ? 1f : 0f); customFields.previousScrollPosition = customFields.scroll.verticalNormalizedPosition; return; IL_0ab5: rect = customFields.chatTextRect.rect; customFields.previousChatTextHeight = ((Rect)(ref rect)).height; goto IL_0ae1; } [HarmonyPatch(typeof(PlayerControllerB), "OnDestroy")] [HarmonyPostfix] private static void OnDestroy(PlayerControllerB __instance) { if (IsLocalPlayer(__instance) && fields.ContainsKey(__instance)) { foreach (Action cleanupAction in fields[__instance].cleanupActions) { cleanupAction(); } } fields.Remove(__instance); } private static void reload(PlayerControllerB __instance) { //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Expected O, but got Unknown CustomFields f; if (!fields.ContainsKey(__instance)) { fields[__instance] = new CustomFields(); f = fields[__instance]; f.cleanupActions.Add(delegate { if (f.restoreHiddenHudElementsAction != null) { f.restoreHiddenHudElementsAction(); } }); } else { f = fields[__instance]; } if (!IsLocalPlayer(__instance)) { return; } if ((Object)(object)f.hudBottomLeftCorner == (Object)null) { ref RectTransform? hudBottomLeftCorner = ref f.hudBottomLeftCorner; Transform obj = HUDManager.Instance.HUDContainer.transform.Find("BottomLeftCorner"); hudBottomLeftCorner = (RectTransform?)(object)((obj is RectTransform) ? obj : null); } if (((NetworkBehaviour)__instance).NetworkManager.IsConnectedClient && ((NetworkBehaviour)__instance).NetworkManager.IsServer) { ServerVars.characterLimit.Value = Plugin.CharacterLimit; ServerVars.modVersion.Value = "1.2.7"; ServerVars.hearDeadPlayers.Value = Plugin.HearDeadPlayers; ServerVars.messageRange.Value = Plugin.MessageRange; } if ((Object)(object)f.chatTextField == (Object)null) { f.chatTextField = HUDManager.Instance?.chatTextField; } if ((Object)(object)f.chatText == (Object)null) { f.chatText = (TMP_Text?)(object)HUDManager.Instance?.chatText; } if ((Object)(object)f.chatTextFieldRect == (Object)null && (Object)(object)f.chatTextField != (Object)null) { ((Component)f.chatTextField).TryGetComponent<RectTransform>(ref f.chatTextFieldRect); } if ((Object)(object)f.chatTextFieldGui == (Object)null && (Object)(object)f.chatTextField != (Object)null) { CustomFields customFields = f; Transform obj2 = ((Component)f.chatTextField).transform.Find("Text Area/Text"); customFields.chatTextFieldGui = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null); } if ((Object)(object)f.chatTextRect == (Object)null && (Object)(object)f.chatText != (Object)null) { ((Component)f.chatText).TryGetComponent<RectTransform>(ref f.chatTextRect); } if ((Object)(object)f.chatTextBgRect == (Object)null && (Object)(object)f.chatTextField != (Object)null) { Transform obj3 = ((Component)f.chatTextField).transform.parent.Find("Image"); if (obj3 != null) { ((Component)obj3).TryGetComponent<RectTransform>(ref f.chatTextBgRect); } } if (f.shiftAction == null) { f.shiftAction = __instance.playerActions.FindAction("taffyko.NiceChat.Shift", false); if (f.shiftAction == null) { __instance.playerActions.Disable(); MovementActions movement = __instance.playerActions.Movement; f.shiftAction = InputActionSetupExtensions.AddAction(MovementActions.op_Implicit(movement), "taffyko.NiceChat.Shift", (InputActionType)1, ((InputControl)Keyboard.current.shiftKey).path, (string)null, (string)null, (string)null, (string)null); __instance.playerActions.Enable(); } InputAction? shiftAction = f.shiftAction; if (shiftAction != null) { shiftAction.Enable(); } } if (f.scrollAction == null) { f.scrollAction = __instance.playerActions.FindAction("taffyko.NiceChat.Scroll", false); if (f.scrollAction == null) { __instance.playerActions.Disable(); MovementActions movement2 = __instance.playerActions.Movement; f.scrollAction = InputActionSetupExtensions.AddAction(MovementActions.op_Implicit(movement2), "taffyko.NiceChat.Scroll", (InputActionType)0, ((InputControl)Mouse.current.scroll).path, (string)null, (string)null, (string)null, (string)null); __instance.playerActions.Enable(); } } if (Plugin.GuiFadeFix) { if ((Object)(object)f.chatContainer == (Object)null) { GameObject val = new GameObject("taffyko.NiceChat.ChatContainer"); f.chatContainer = val.AddComponent<RectTransform>(); val.AddComponent<CanvasGroup>(); ((Transform)f.chatContainer).SetParent((Transform)(object)f.hudBottomLeftCorner, false); } RectTransform? chatTextFieldRect = f.chatTextFieldRect; if ((Object)(object)((chatTextFieldRect != null) ? ((Transform)chatTextFieldRect).parent : null) != (Object)(object)f.chatContainer) { RectTransform? chatTextFieldRect2 = f.chatTextFieldRect; if (chatTextFieldRect2 != null) { ((Transform)chatTextFieldRect2).SetParent((Transform)(object)f.chatContainer); } RectTransform? chatTextBgRect = f.chatTextBgRect; if (chatTextBgRect != null) { ((Transform)chatTextBgRect).SetParent((Transform)(object)f.chatContainer); } HUDManager.Instance.Chat.canvasGroup = ((Component)f.chatContainer).GetComponent<CanvasGroup>(); ((Component)f.hudBottomLeftCorner).GetComponent<CanvasGroup>().alpha = 1f; } return; } RectTransform? chatTextFieldRect3 = f.chatTextFieldRect; if ((Object)(object)((chatTextFieldRect3 != null) ? ((Transform)chatTextFieldRect3).parent : null) != (Object)(object)f.hudBottomLeftCorner) { RectTransform? chatTextFieldRect4 = f.chatTextFieldRect; if (chatTextFieldRect4 != null) { ((Transform)chatTextFieldRect4).SetParent((Transform)(object)f.hudBottomLeftCorner); } RectTransform? chatTextBgRect2 = f.chatTextBgRect; if (chatTextBgRect2 != null) { ((Transform)chatTextBgRect2).SetParent((Transform)(object)f.hudBottomLeftCorner); } HUDManager.Instance.Chat.canvasGroup = ((Component)f.hudBottomLeftCorner).GetComponent<CanvasGroup>(); } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] [HarmonyPrefix] private static bool SubmitChat_performed_Prefix() { InputAction? shiftAction = fields[StartOfRound.Instance.localPlayerController].shiftAction; if (shiftAction == null) { return true; } return !shiftAction.IsPressed(); } [HarmonyPatch(typeof(HUDManager), "PingHUDElement")] [HarmonyPrefix] private static void PingHUDElementPrefix(HUDElement element, ref float delay, float startAlpha, ref float endAlpha) { if (element != null && element == HUDManager.Instance?.Chat) { endAlpha = Plugin.FadeOpacity; if (delay == 4f) { delay = Plugin.FadeTimeAfterMessage; } else if (delay == 2f) { delay = Plugin.FadeTimeAfterOwnMessage; } else if (delay == 1f) { delay = Plugin.FadeTimeAfterUnfocused; } } } public static string GetChatMessageNameOpeningTag() { string text = "#FF0000"; string text2 = ""; if (Plugin.EnableTimestamps && TimeOfDay.Instance.currentDayTimeStarted && (Object)(object)HUDManager.Instance?.clockNumber != (Object)null && ((((UIBehaviour)HUDManager.Instance.clockNumber).IsActive() && HUDManager.Instance.Clock.targetAlpha > 0f) || StartOfRound.Instance.localPlayerController.isPlayerDead)) { text2 = text2 + "<color=#7069ff>[" + ((TMP_Text)HUDManager.Instance.clockNumber).text.Replace("\n", "") + "] </color>"; } if (!(messageContext != null)) { goto IL_010c; } if (messageContext.senderDead) { text2 += "<color=#878787>"; if (Plugin.TagMessageStatus) { text2 += "*DEAD* "; } } else { if (!messageContext.walkie) { goto IL_010c; } text2 += "<color=#00AA00>"; if (Plugin.TagMessageStatus) { text2 += "*WALKIE* "; } } goto IL_011e; IL_011e: messageContext = null; return text2; IL_010c: text2 = text2 + "<color=" + text + ">"; goto IL_011e; } public static string GetChatMessageNameClosingTag() { return "</color>: <color=#FFFF00>"; } public static bool _HelperMessageSentByLocalPlayer(HUDManager instance, string chatMessage, int playerId) { if ((int)Traverse.Create((object)instance).Field("__rpc_exec_stage").GetValue() == 2 && playerId >= 0 && playerId < StartOfRound.Instance.allPlayerScripts.Length && IsLocalPlayer(StartOfRound.Instance.allPlayerScripts[playerId])) { return true; } return false; } [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> transpiler_AddPlayerChatMessageClientRpc(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldarg_1, (object)null); yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)typeof(Patches).GetMethod("_HelperMessageSentByLocalPlayer")); Label label = generator.DefineLabel(); CodeInstruction nopInstruction = new CodeInstruction(OpCodes.Nop, (object)null); nopInstruction.labels.Add(label); CodeInstruction retInstruction = new CodeInstruction(OpCodes.Ret, (object)null); yield return new CodeInstruction(OpCodes.Brfalse, (object)label); yield return retInstruction; yield return nopInstruction; foreach (CodeInstruction instruction in instructions) { yield return instruction; } } private static bool PlayerCanHearMessage(int senderId, int recipientId, out MessageContext? messageContext) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) messageContext = null; if (senderId < 0) { return true; } if ((Object)(object)HUDManager.Instance == (Object)null) { return true; } if (HUDManager.Instance.playersManager.allPlayerScripts.Length <= senderId || HUDManager.Instance.playersManager.allPlayerScripts.Length <= recipientId) { return true; } PlayerControllerB val = HUDManager.Instance.playersManager.allPlayerScripts[senderId]; PlayerControllerB val2 = HUDManager.Instance.playersManager.allPlayerScripts[recipientId]; if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return true; } bool flag = val.holdingWalkieTalkie && val2.holdingWalkieTalkie; messageContext = new MessageContext(senderId, flag, val.isPlayerDead); if (val2.isPlayerDead) { return true; } if (val.isPlayerDead) { if (ServerVars.hearDeadPlayers.Value || val2.isPlayerDead) { return true; } return false; } if (flag) { return true; } if (Vector3.Distance(((Component)val).transform.position, ((Component)val2).transform.position) <= ServerVars.messageRange.Value) { return true; } return false; } public static bool RecipientCanHear(int recipientId) { if (StartOfRound.Instance.localPlayerController.isPlayerDead) { return true; } MessageContext messageContext; return PlayerCanHearMessage((int)StartOfRound.Instance.localPlayerController.playerClientId, recipientId, out messageContext); } public static bool CanHearPreflight(int senderId) { MessageContext messageContext; bool num = PlayerCanHearMessage(senderId, (int)StartOfRound.Instance.localPlayerController.playerClientId, out messageContext); if (num) { Patches.messageContext = messageContext; } return num; } [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> transpiler_CanHearMessageOverride(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { bool deadCheckFound = false; bool distanceCheckFound = false; using IEnumerator<CodeInstruction> e = instructions.GetEnumerator(); while (e.MoveNext()) { if (!deadCheckFound && e.Current.opcode == OpCodes.Ldfld && (FieldInfo)e.Current.operand == FieldInfo_isPlayerDead) { deadCheckFound = true; for (int i = 0; i < 5; i++) { yield return e.Current; e.MoveNext(); } yield return new CodeInstruction(OpCodes.Nop, (object)null); e.MoveNext(); } else if (!distanceCheckFound && e.Current.opcode == OpCodes.Call && (MethodInfo)e.Current.operand == MethodInfo_Vector3_Distance) { distanceCheckFound = true; yield return new CodeInstruction(OpCodes.Pop, (object)null); yield return new CodeInstruction(OpCodes.Pop, (object)null); for (int j = 0; j < 4; j++) { e.MoveNext(); } yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)MethodInfo_CanHearPreflight); } yield return e.Current; } } public static bool _ShouldSuppressDuplicateMessage(string message, string senderName) { float num = Time.fixedUnscaledTime - timeAtLastCheck; timeAtLastCheck = Time.fixedUnscaledTime; if (string.IsNullOrEmpty(senderName)) { return true; } if (num >= 0f && num < 0.1f) { return true; } return false; } public static int _GetMaxMessageCount() { return Plugin.MaxMessageHistory; } [HarmonyPatch(typeof(HUDManager), "AddChatMessage")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> transpiler_AddChatMessage(IEnumerable<CodeInstruction> instructions) { bool foundMaxMessageCount = false; bool foundPreviousMessageComparison = false; foreach (CodeInstruction instruction in instructions) { if (!foundMaxMessageCount && instruction.opcode == OpCodes.Ldc_I4_4) { yield return new CodeInstruction(OpCodes.Call, (object)typeof(Patches).GetMethod("_GetMaxMessageCount")); foundMaxMessageCount = true; continue; } if (!foundPreviousMessageComparison && instruction.opcode == OpCodes.Call && instruction.operand == stringEqual) { foundPreviousMessageComparison = true; yield return instruction; yield return new CodeInstruction(OpCodes.Ldarg_1, (object)null); yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)typeof(Patches).GetMethod("_ShouldSuppressDuplicateMessage")); yield return new CodeInstruction(OpCodes.And, (object)null); continue; } if (instruction.opcode == OpCodes.Ldstr) { switch ((string)instruction.operand) { case "<color=#FF0000>": yield return new CodeInstruction(OpCodes.Call, (object)MethodInfo_GetChatMessageNameOpeningTag); continue; case "</color>: <color=#FFFF00>'": yield return new CodeInstruction(OpCodes.Call, (object)MethodInfo_GetChatMessageNameClosingTag); continue; case "'</color>": yield return new CodeInstruction(OpCodes.Ldstr, (object)"</color>"); continue; } } yield return instruction; } } public static int GetCharacterLimit() { return Plugin.CharacterLimit + 1; } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] [HarmonyPatch(typeof(HUDManager), "EnableChat_performed")] [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageServerRpc")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> transpiler_GeneralOverrides(IEnumerable<CodeInstruction> instructions) { bool foundCharacterLimit = false; bool foundPlayerDeadCheck = false; foreach (CodeInstruction instruction in instructions) { if (!foundCharacterLimit && instruction.opcode == OpCodes.Ldc_I4_S) { if ((sbyte)instruction.operand == 50) { foundCharacterLimit = true; yield return new CodeInstruction(OpCodes.Call, (object)getCharacterLimit); continue; } } else if (!foundPlayerDeadCheck && instruction.opcode == OpCodes.Ldfld && (FieldInfo)instruction.operand == FieldInfo_isPlayerDead) { foundPlayerDeadCheck = true; yield return new CodeInstruction(OpCodes.Pop, (object)null); yield return new CodeInstruction(OpCodes.Ldc_I4_0, (object)null); continue; } yield return instruction; } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> transpiler_SubmitChat_performed(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { bool distanceCheckFound = false; using IEnumerator<CodeInstruction> e = instructions.GetEnumerator(); while (e.MoveNext()) { if (!distanceCheckFound && e.Current.opcode == OpCodes.Call && (MethodInfo)e.Current.operand == MethodInfo_Vector3_Distance) { distanceCheckFound = true; yield return new CodeInstruction(OpCodes.Pop, (object)null); yield return new CodeInstruction(OpCodes.Pop, (object)null); for (int i = 0; i < 12; i++) { e.MoveNext(); } yield return new CodeInstruction(OpCodes.Ldloc_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)typeof(Patches).GetMethod("RecipientCanHear")); } yield return e.Current; } } [HarmonyPatch(typeof(HUDManager), "AddTextToChatOnServer")] [HarmonyPrefix] private static void AddTextToChatOnServer_Prefix(HUDManager __instance, int playerId) { if (playerId >= 0 && playerId < StartOfRound.Instance.allPlayerScripts.Length && IsLocalPlayer(StartOfRound.Instance.allPlayerScripts[playerId])) { CanHearPreflight(playerId); } } } public static class PluginInfo { public const string PLUGIN_GUID = "NiceChat"; public const string PLUGIN_NAME = "NiceChat"; public const string PLUGIN_VERSION = "1.2.7"; } } namespace System.Runtime.CompilerServices { internal static class IsExternalInit { } internal class RequiredMemberAttribute : Attribute { } internal class CompilerFeatureRequiredAttribute : Attribute { public CompilerFeatureRequiredAttribute(string name) { } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] public sealed class SetsRequiredMembersAttribute : Attribute { } }