using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using AutoMapRoom.HarmonyPatches;
using AutoMapRoom.Packets;
using AutoMapRoom.Wrappers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Nessie.ATLYSS.EasySettings;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Events;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("s0apy.amr")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.7.0")]
[assembly: AssemblyInformationalVersion("1.2.7+581b313e19d151a73c669bcd234868c6fed604ff")]
[assembly: AssemblyProduct("AutoMapRoom")]
[assembly: AssemblyTitle("AutoMapRoom")]
[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 AutoMapRoom
{
public enum FormattingType
{
Truncate,
Acronym
}
[BepInPlugin("s0apy.amr", "AutoMapRoom", "1.2.7")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Main : BaseUnityPlugin
{
public static string currentActiveTrigger = "";
public static string currentMapRoomName = "";
public static string currentChatRoom = "";
public static Dictionary<string, string> roomNameCache = new Dictionary<string, string>();
public static bool _modDisabledGlobalChat = false;
public static bool IsReady = false;
public static FormattingType ServerFormattingRule = FormattingType.Truncate;
internal static ManualLogSource Log;
internal static ConfigEntry<bool> ModEnabled;
internal static ConfigEntry<bool> DebugLoggingEnabled;
internal static ConfigEntry<bool> DisableGlobalOnRoomJoin;
internal static ConfigEntry<bool> SwitchActiveChannel;
private ConfigEntry<KeyCode> _menuKey;
internal static ConfigEntry<bool> EnableOnGUIDebugMenu;
internal static ConfigEntry<FormattingType> HostFormattingChoice;
private bool _showMenu = false;
private Rect _windowRect = new Rect(20f, 20f, 300f, 220f);
private bool _isBindingKey = false;
private bool _ignoreToggleInputForFrame = false;
internal static bool _isCodeTalkerLoaded = false;
private void Awake()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
InitConfig();
Settings.OnInitialized.AddListener(new UnityAction(AddSettings));
Settings.OnApplySettings.AddListener((UnityAction)delegate
{
((BaseUnityPlugin)this).Config.Save();
});
if (Type.GetType("CodeTalker.Networking.CodeTalkerNetwork, CodeTalker") != null)
{
_isCodeTalkerLoaded = true;
Log.LogInfo((object)"CodeTalker found. Server enforcement will be active.");
}
else
{
Log.LogInfo((object)"CodeTalker not found. Using local setting. This may cause room splits in multiplayer.");
}
Harmony.CreateAndPatchAll(typeof(Hook), (string)null);
Log.LogInfo((object)"Auto Map Room plugin loaded and patched!");
}
private void InitConfig()
{
ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, "Globally enables or disables the auto room switching feature.");
DebugLoggingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Debug Logging", false, "Enables verbose logging for troubleshooting.");
SwitchActiveChannel = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Switch Active Channel", false, "If enabled, automatically switches your active chat channel to the room channel when you enter a new area.");
DisableGlobalOnRoomJoin = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Mute Global in Rooms", false, "Automatically mutes the global chat channel when you join a map/region room.");
EnableOnGUIDebugMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("2. OnGUI Menu", "Enable OnGUI Debug Menu", false, "Enables a legacy OnGUI menu for changing settings. The keybind below will only work if this is enabled.");
_menuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. OnGUI Menu", "Menu Key", (KeyCode)293, "The key to press to show/hide the OnGUI settings menu (if enabled).");
HostFormattingChoice = ((BaseUnityPlugin)this).Config.Bind<FormattingType>("9. Host Settings", "Room Name Format", FormattingType.Truncate, "[HOST ONLY] The naming rule your server will enforce on all players. Truncate = first 12 chars. Acronym = first letter of each word.");
}
private void AddSettings()
{
SettingsTab modTab = Settings.ModTab;
modTab.AddHeader("AutoMapRoom Settings");
modTab.AddToggle("Enable Auto Room Switching", ModEnabled);
modTab.AddToggle("Switch Active Channel", SwitchActiveChannel);
modTab.AddToggle("Mute Global in Rooms", DisableGlobalOnRoomJoin);
modTab.AddSpace();
modTab.AddToggle("Enable OnGUI Debug Menu", EnableOnGUIDebugMenu);
modTab.AddToggle("Enable Debug Logging", DebugLoggingEnabled);
modTab.AddKeyButton("OnGUI Menu Key", _menuKey);
modTab.AddSpace();
modTab.AddDropdown<FormattingType>("[HOST ONLY] Room Name Format", HostFormattingChoice);
}
private void Update()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if (!EnableOnGUIDebugMenu.Value)
{
_showMenu = false;
}
else if (_ignoreToggleInputForFrame)
{
_ignoreToggleInputForFrame = false;
}
else if (Input.GetKeyDown(_menuKey.Value))
{
_showMenu = !_showMenu;
if (!_showMenu)
{
_isBindingKey = false;
}
}
}
private void OnGUI()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
if (_showMenu)
{
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
_windowRect = GUILayout.Window(1862, _windowRect, new WindowFunction(DrawSettingsWindow), "AutoMapRoom [1.2.7]", Array.Empty<GUILayoutOption>());
}
}
private void DrawSettingsWindow(int windowID)
{
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: 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_0036: Invalid comparison between Unknown and I4
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Invalid comparison between Unknown and I4
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Invalid comparison between Unknown and I4
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
if (_isBindingKey)
{
GUILayout.Label("Press any key to bind. Press Esc to cancel.", Array.Empty<GUILayoutOption>());
if (Event.current.isKey && (int)Event.current.keyCode > 0)
{
if ((int)Event.current.type == 4)
{
KeyCode keyCode = Event.current.keyCode;
if ((int)keyCode == 27)
{
_isBindingKey = false;
}
else
{
_menuKey.Value = keyCode;
_isBindingKey = false;
((BaseUnityPlugin)this).Config.Save();
_ignoreToggleInputForFrame = true;
}
}
Event.current.Use();
}
}
ModEnabled.Value = GUILayout.Toggle(ModEnabled.Value, " Enable Auto Room Switching", Array.Empty<GUILayoutOption>());
SwitchActiveChannel.Value = GUILayout.Toggle(SwitchActiveChannel.Value, " Switch Active Channel", Array.Empty<GUILayoutOption>());
DebugLoggingEnabled.Value = GUILayout.Toggle(DebugLoggingEnabled.Value, " Enable Debug Logging", Array.Empty<GUILayoutOption>());
DisableGlobalOnRoomJoin.Value = GUILayout.Toggle(DisableGlobalOnRoomJoin.Value, " Mute Global in Rooms", Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("Open Menu Key:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
object obj;
if (!_isBindingKey)
{
KeyCode value = _menuKey.Value;
obj = ((object)(KeyCode)(ref value)).ToString();
}
else
{
obj = "...";
}
string text = (string)obj;
if (GUILayout.Button(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
{
_isBindingKey = !_isBindingKey;
}
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
GUI.DragWindow();
}
public static void OnRuleRequestReceived(PacketHeader header, PacketBase packet)
{
if (packet is RuleRequestPacket)
{
BroadcastRule();
}
}
public static void OnRuleReceived(PacketHeader header, PacketBase packet)
{
if (packet is FormattingRulePacket formattingRulePacket)
{
Log.LogWarning((object)$"Received server rule: Room names will be formatted using the '{formattingRulePacket.Rule}' rule.");
ServerFormattingRule = formattingRulePacket.Rule;
roomNameCache.Clear();
}
}
public static void BroadcastRule()
{
if (_isCodeTalkerLoaded && !((Object)(object)Player._mainPlayer == (Object)null) && Player._mainPlayer._isHostPlayer)
{
Log.LogInfo((object)$"Broadcasting server formatting rule to all clients: '{HostFormattingChoice.Value}'");
CodeTalkerNetwork.SendNetworkPacket((PacketBase)(object)new FormattingRulePacket(HostFormattingChoice.Value));
}
}
public static void RequestRule()
{
if (_isCodeTalkerLoaded)
{
Log.LogInfo((object)"Requesting formatting rule from the server...");
CodeTalkerNetwork.SendNetworkPacket((PacketBase)(object)new RuleRequestPacket());
}
}
}
internal static class ModInfo
{
public const string GUID = "s0apy.amr";
public const string NAME = "AutoMapRoom";
public const string VERSION = "1.2.7";
}
}
namespace AutoMapRoom.Wrappers
{
public class Player
{
internal static Player GetPlayer()
{
return Player._mainPlayer;
}
}
}
namespace AutoMapRoom.HarmonyPatches
{
[HarmonyPatch]
internal static class Hook
{
[CompilerGenerated]
private static class <>O
{
public static PacketListener <0>__OnRuleReceived;
public static PacketListener <1>__OnRuleRequestReceived;
}
private static readonly FieldInfo _inGlobalChatField;
private static float _roomChangeBuffer;
private const float ROOM_CHANGE_DELAY = 0.5f;
private static string _pendingRoomChange;
private static bool _listenersInitialized;
static Hook()
{
_roomChangeBuffer = 0f;
_pendingRoomChange = null;
_listenersInitialized = false;
_inGlobalChatField = AccessTools.Field(typeof(ChatBehaviour), "_inGlobalChat");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "OnGameConditionChange")]
private static void OnGameConditionChange_Postfix(Player __instance, GameCondition _newCondition)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)__instance != (Object)(object)Player._mainPlayer))
{
Main.IsReady = (int)_newCondition == 1;
LogDebug($"Game condition changed to {_newCondition}. AutoMapRoom ready status: {Main.IsReady}");
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "OnStartAuthority")]
private static void OnPlayerReady_Postfix(Player __instance)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
if (!((NetworkBehaviour)__instance).isLocalPlayer)
{
return;
}
if (Main._isCodeTalkerLoaded && !_listenersInitialized)
{
LogDebug("Player has authority. Initializing CodeTalker listeners...");
object obj = <>O.<0>__OnRuleReceived;
if (obj == null)
{
PacketListener val = Main.OnRuleReceived;
<>O.<0>__OnRuleReceived = val;
obj = (object)val;
}
CodeTalkerNetwork.RegisterListener<FormattingRulePacket>((PacketListener)obj);
if (__instance._isHostPlayer)
{
LogDebug("This client is the host. Listening for rule requests.");
object obj2 = <>O.<1>__OnRuleRequestReceived;
if (obj2 == null)
{
PacketListener val2 = Main.OnRuleRequestReceived;
<>O.<1>__OnRuleRequestReceived = val2;
obj2 = (object)val2;
}
CodeTalkerNetwork.RegisterListener<RuleRequestPacket>((PacketListener)obj2);
}
_listenersInitialized = true;
}
if (__instance._isHostPlayer)
{
Main.BroadcastRule();
}
else
{
Main.RequestRule();
}
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(ChatBehaviour), "Cmd_JoinChatRoom")]
public static void Call_Cmd_JoinChatRoom(ChatBehaviour instance, string chatroom)
{
throw new NotImplementedException("Stub!");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MapVisualOverrideTrigger), "OnTriggerStay")]
private static void OnTriggerStay_Postfix(MapVisualOverrideTrigger __instance, Collider other)
{
if (Main.IsReady && Main.ModEnabled.Value && !string.IsNullOrWhiteSpace(__instance._reigonName) && IsMainPlayer(other))
{
Main.currentActiveTrigger = FormatRoomName(__instance._reigonName);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MapVisualOverrideTrigger), "OnTriggerExit")]
private static void OnTriggerExit_Postfix(MapVisualOverrideTrigger __instance, Collider other)
{
if (Main.IsReady && Main.ModEnabled.Value && !string.IsNullOrWhiteSpace(__instance._reigonName) && IsMainPlayer(other))
{
string text = FormatRoomName(__instance._reigonName);
if (Main.currentActiveTrigger == text)
{
Main.currentActiveTrigger = "";
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "OnPlayerMapInstanceChange")]
private static void OnMapInstanceChange_Postfix(Player __instance, MapInstance _new)
{
if (!((Object)(object)Player._mainPlayer == (Object)null) && !((Object)(object)__instance != (Object)(object)Player._mainPlayer))
{
if (AtlyssNetworkManager._current._soloMode)
{
LogDebug("Singleplayer enabled, clearing room.");
Main.currentChatRoom = "";
}
else if (!((Object)(object)_new == (Object)null))
{
Main.currentMapRoomName = FormatRoomName(_new._mapName);
Main.currentActiveTrigger = "";
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "Update")]
private static void PlayerUpdate_Postfix(Player __instance)
{
if (!Main.IsReady || !Main.ModEnabled.Value || (Object)(object)__instance != (Object)(object)Player._mainPlayer || AtlyssNetworkManager._current._soloMode)
{
return;
}
string text = Main.currentActiveTrigger;
if (string.IsNullOrEmpty(text))
{
text = Main.currentMapRoomName ?? "";
}
if (_pendingRoomChange != text)
{
_pendingRoomChange = text;
_roomChangeBuffer = 0f;
}
if (_pendingRoomChange != null && _pendingRoomChange != Main.currentChatRoom)
{
_roomChangeBuffer += Time.deltaTime;
if (_roomChangeBuffer >= 0.5f)
{
LogDebug("Cooldown complete. Committing to room change: " + _pendingRoomChange);
UpdateChatRoom(_pendingRoomChange);
_pendingRoomChange = null;
_roomChangeBuffer = 0f;
}
}
}
internal static void UpdateChatRoom(string desiredRoom)
{
LogDebug("Updating chat room to '" + desiredRoom + "'");
if (string.IsNullOrEmpty(desiredRoom))
{
LeaveRoom();
}
else
{
JoinRoom(desiredRoom);
}
Main.currentChatRoom = desiredRoom;
}
private static string FormatRoomName(string regionName)
{
if (string.IsNullOrWhiteSpace(regionName))
{
return "";
}
if (Main.roomNameCache.TryGetValue(regionName, out string value))
{
return value;
}
FormattingType formattingType = (Main._isCodeTalkerLoaded ? Main.ServerFormattingRule : Main.HostFormattingChoice.Value);
FormattingType formattingType2 = formattingType;
FormattingType formattingType3 = formattingType2;
string text3;
if (formattingType3 != 0 && formattingType3 == FormattingType.Acronym)
{
string text = regionName.Replace(" ", "");
if (text.Length > 12)
{
StringBuilder stringBuilder = new StringBuilder();
string[] array = regionName.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string[] array2 = array;
foreach (string text2 in array2)
{
if (char.IsLetterOrDigit(text2[0]))
{
stringBuilder.Append(char.ToUpper(text2[0]));
}
}
text3 = stringBuilder.ToString();
}
else
{
text3 = text;
}
}
else
{
text3 = ((regionName.Length > 12) ? regionName.Substring(0, 12) : regionName);
}
Main.roomNameCache[regionName] = text3;
return text3;
}
private static bool IsMainPlayer(Collider other)
{
return (Object)(object)Player.GetPlayer() != (Object)null && (Object)(object)((Component)((Component)other).gameObject.transform.root).gameObject == (Object)(object)((Component)Player.GetPlayer()).gameObject;
}
private static void JoinRoom(string roomName)
{
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
Player player = Player.GetPlayer();
if (!((Object)(object)player?._chatBehaviour == (Object)null) && ((Component)player._chatBehaviour).gameObject.activeInHierarchy)
{
bool flag = (bool)_inGlobalChatField.GetValue(player._chatBehaviour);
if (Main.DisableGlobalOnRoomJoin.Value && flag)
{
_inGlobalChatField.SetValue(player._chatBehaviour, false);
Main._modDisabledGlobalChat = true;
LogDebug("Silently disabled Global Chat.");
}
if (Main.SwitchActiveChannel.Value)
{
player._chatBehaviour._setChatChannel = (ChatChannel)2;
LogDebug("Switched to room: #" + roomName);
}
else
{
LogDebug("Joined room in background: #" + roomName);
}
Call_Cmd_JoinChatRoom(player._chatBehaviour, roomName);
}
}
private static void LeaveRoom()
{
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
Player player = Player.GetPlayer();
if (!((Object)(object)player?._chatBehaviour == (Object)null) && ((Component)player._chatBehaviour).gameObject.activeInHierarchy)
{
bool flag = (bool)_inGlobalChatField.GetValue(player._chatBehaviour);
if (Main.DisableGlobalOnRoomJoin.Value && !flag && Main._modDisabledGlobalChat)
{
_inGlobalChatField.SetValue(player._chatBehaviour, true);
Main._modDisabledGlobalChat = false;
LogDebug("Silently re-enabled Global Chat.");
}
if (Main.SwitchActiveChannel.Value)
{
player._chatBehaviour._setChatChannel = (ChatChannel)0;
LogDebug("Returned to Global chat.");
}
else
{
LogDebug("Left room in background.");
}
Call_Cmd_JoinChatRoom(player._chatBehaviour, "");
}
}
private static void LogDebug(string message)
{
if (Main.DebugLoggingEnabled.Value)
{
Main.Log.LogInfo((object)message);
}
}
}
}
namespace AutoMapRoom.Packets
{
public class FormattingRulePacket : PacketBase
{
public override string PacketSourceGUID => "s0apy.amr";
[JsonProperty]
public FormattingType Rule { get; set; }
public FormattingRulePacket()
{
}
public FormattingRulePacket(FormattingType rule)
{
Rule = rule;
}
}
public class RuleRequestPacket : PacketBase
{
public override string PacketSourceGUID => "s0apy.amr";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}