Decompiled source of KickMenu v1.0.2

plugins/KickMenu/KickMenu.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2;
using RiskOfOptions;
using RiskOfOptions.Components.Options;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Networking;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[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("KickMenu")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6e9ba716f472e7a9538dc8c6bb98e1f90131f8ef")]
[assembly: AssemblyProduct("KickMenu")]
[assembly: AssemblyTitle("KickMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 KickMenu
{
	[BepInPlugin("Bamboooz.KickMenu", "KickMenu", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class KickMenuPlugin : BaseUnityPlugin
	{
		public static class ModConfig
		{
			public static ConfigEntry<bool> ConfirmKick;

			public static ConfigEntry<bool> BroadcastKick;

			public static ConfigEntry<KeyboardShortcut> OpenMenuKey;

			public static void Init(ConfigFile config)
			{
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Expected O, but got Unknown
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Expected O, but got Unknown
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Expected O, but got Unknown
				ConfirmKick = config.Bind<bool>("General", "Confirmation Dialog", true, "If enabled, a confirmation dialog will appear before kicking a player.\n\nDefault: true");
				BroadcastKick = config.Bind<bool>("General", "Kick Broadcast", false, "If enabled, a message will be sent to chat when a player is kicked.\n\nDefault: false");
				OpenMenuKey = config.Bind<KeyboardShortcut>("Controls", "Open Kick Menu Key", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Keybind used to open the player kick menu. \n\nDefault: F1");
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ConfirmKick));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(BroadcastKick));
				ModSettingsManager.AddOption((BaseOption)new KeyBindOption(OpenMenuKey));
			}
		}

		private static GameObject buttonPrefab;

		internal static ManualLogSource Log;

		public const string PluginGUID = "Bamboooz.KickMenu";

		public const string PluginAuthor = "Bamboooz";

		public const string PluginName = "KickMenu";

		public const string PluginVersion = "1.0.0";

		private GameObject menuPanel;

		private Transform contentRoot;

		private bool menuOpen = false;

		public void Awake()
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				ModSettingsManager.SetModDescription("A Risk of Rain 2 mod that allows you to kick players from your lobby as well as during the game. Default keybind to open the menu is F1.");
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
				string path = Path.Combine(directoryName, "icon.png");
				if (!File.Exists(path))
				{
					path = Path.Combine(Path.GetDirectoryName(directoryName), "icon.png");
				}
				if (File.Exists(path))
				{
					Texture2D val = new Texture2D(2, 2);
					if (ImageConversion.LoadImage(val, File.ReadAllBytes(path)))
					{
						ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)));
					}
				}
				ModConfig.Init(((BaseUnityPlugin)this).Config);
				NetworkUser.onNetworkUserDiscovered += new NetworkUserGenericDelegate(OnNetworkUserDiscovered);
				NetworkUser.OnDestroy += new hook_OnDestroy(OnNetworkUserDestroyed);
				buttonPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/GenericMenuButton.prefab").WaitForCompletion();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to initialize KickMenu: " + ex.Message));
			}
		}

		public void OnDestroy()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			NetworkUser.onNetworkUserDiscovered -= new NetworkUserGenericDelegate(OnNetworkUserDiscovered);
			NetworkUser.OnDestroy -= new hook_OnDestroy(OnNetworkUserDestroyed);
		}

		public void Update()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost())
			{
				KeyboardShortcut value = ModConfig.OpenMenuKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleMenu();
				}
			}
		}

		private bool IsHost()
		{
			return NetworkServer.active;
		}

		private bool IsHost(NetworkUser networkUser)
		{
			return NetworkUser.readOnlyLocalPlayersList.Contains(networkUser);
		}

		private void OnNetworkUserDiscovered(NetworkUser networkUser)
		{
			if (!((Object)(object)networkUser == (Object)null) && menuOpen)
			{
				RefreshPlayerList();
			}
		}

		private void OnNetworkUserDestroyed(orig_OnDestroy orig, NetworkUser self)
		{
			if ((Object)(object)self != (Object)null && menuOpen)
			{
				RefreshPlayerList();
			}
			orig.Invoke(self);
		}

		private bool IsSolo()
		{
			return !NetworkUser.readOnlyInstancesList.Any((NetworkUser user) => !((NetworkBehaviour)user).isLocalPlayer);
		}

		private void ToggleMenu()
		{
			if ((Object)(object)menuPanel == (Object)null)
			{
				CreateMenu();
			}
			if (menuOpen || !IsSolo())
			{
				menuOpen = !menuOpen;
				menuPanel.SetActive(menuOpen);
				if (menuOpen)
				{
					RefreshPlayerList();
				}
			}
		}

		private void CreateMenu()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			GameObject val = new GameObject("KickMenuCanvas");
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 1000;
			val.AddComponent<CanvasScaler>();
			val.AddComponent<GraphicRaycaster>();
			Object.DontDestroyOnLoad((Object)(object)val);
			menuPanel = new GameObject("KickMenuPanel");
			menuPanel.transform.SetParent(val.transform);
			RectTransform val3 = menuPanel.AddComponent<RectTransform>();
			val3.sizeDelta = new Vector2(500f, 450f);
			val3.anchoredPosition = Vector2.zero;
			Image val4 = menuPanel.AddComponent<Image>();
			((Graphic)val4).color = new Color(0f, 0f, 0f, 0.75f);
			VerticalLayoutGroup val5 = menuPanel.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val5).padding = new RectOffset(20, 20, 20, 20);
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 8f;
			((LayoutGroup)val5).childAlignment = (TextAnchor)1;
			ContentSizeFitter val6 = menuPanel.AddComponent<ContentSizeFitter>();
			val6.verticalFit = (FitMode)2;
			contentRoot = menuPanel.transform;
			menuPanel.SetActive(false);
		}

		private void RefreshPlayerList()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			foreach (Transform item in contentRoot)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				if (!IsHost(readOnlyInstances))
				{
					CreatePlayerEntry(readOnlyInstances);
				}
			}
		}

		private void CreatePlayerEntry(NetworkUser user)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			GameObject val = new GameObject("PlayerRow");
			val.transform.SetParent(contentRoot);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(450f, 50f);
			HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val3).spacing = 15f;
			((LayoutGroup)val3).childAlignment = (TextAnchor)4;
			LayoutElement val4 = val.AddComponent<LayoutElement>();
			val4.preferredHeight = 50f;
			GameObject val5 = new GameObject("PlayerName");
			val5.transform.SetParent(val.transform);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.sizeDelta = new Vector2(280f, 40f);
			LayoutElement val7 = val5.AddComponent<LayoutElement>();
			val7.preferredWidth = 280f;
			TextMeshProUGUI val8 = val5.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val8).text = user.userName;
			((TMP_Text)val8).fontSize = 20f;
			((TMP_Text)val8).alignment = (TextAlignmentOptions)4097;
			((Graphic)val8).color = Color.white;
			if (!Object.op_Implicit((Object)(object)buttonPrefab))
			{
				return;
			}
			GameObject val9 = Object.Instantiate<GameObject>(buttonPrefab, val.transform);
			((Object)val9).name = "KickButton";
			RectTransform component = val9.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(120f, 40f);
			LayoutElement val10 = val9.AddComponent<LayoutElement>();
			val10.preferredWidth = 120f;
			val10.preferredHeight = 40f;
			TextMeshProUGUI componentInChildren = val9.GetComponentInChildren<TextMeshProUGUI>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				((TMP_Text)componentInChildren).text = "Kick";
				((TMP_Text)componentInChildren).fontSize = 16f;
				((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)514;
			}
			HGButton component2 = val9.GetComponent<HGButton>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				((UnityEventBase)((Button)component2).onClick).RemoveAllListeners();
				((UnityEvent)((Button)component2).onClick).AddListener((UnityAction)delegate
				{
					OnKickButtonClicked(user);
				});
			}
		}

		private void OnKickButtonClicked(NetworkUser networkUser)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			if ((Object)(object)networkUser == (Object)null || !IsHost())
			{
				return;
			}
			if (!ModConfig.ConfirmKick.Value)
			{
				KickPlayer(networkUser);
				return;
			}
			ToggleMenu();
			SimpleDialogBox dialog = SimpleDialogBox.Create((MPEventSystem)null);
			((Component)dialog).gameObject.AddComponent<RooEscapeRouter>().escapePressed.AddListener((UnityAction)delegate
			{
				if (Object.op_Implicit((Object)(object)dialog) && Object.op_Implicit((Object)(object)dialog.rootObject))
				{
					Object.Destroy((Object)(object)dialog.rootObject);
				}
			});
			((TMP_Text)dialog.headerLabel).text = "Confirm Kick";
			((TMP_Text)dialog.descriptionLabel).text = "Are you sure you want to kick " + networkUser.userName + "?";
			dialog.AddActionButton((UnityAction)delegate
			{
				KickPlayer(networkUser);
			}, "Yes", true, Array.Empty<object>());
			dialog.AddCancelButton("Cancel", Array.Empty<object>());
		}

		private void KickPlayer(NetworkUser networkUser)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			try
			{
				if ((Object)(object)networkUser == (Object)null || !IsHost())
				{
					return;
				}
				if (IsHost(networkUser))
				{
					Log.LogWarning((object)("Attempted to kick host (" + networkUser.userName + "). Action aborted."));
					return;
				}
				NetworkConnection connectionToClient = ((NetworkBehaviour)networkUser).connectionToClient;
				if (connectionToClient == null)
				{
					Log.LogWarning((object)("No connection found for player: " + networkUser.userName));
					return;
				}
				if (!connectionToClient.isReady)
				{
					Log.LogWarning((object)$"Client connection for {networkUser.userName} is not ready. Connection ID: {connectionToClient.connectionId}");
				}
				Log.LogInfo((object)$"Kicking player {networkUser.userName} (Connection ID: {connectionToClient.connectionId})");
				SimpleLocalizedKickReason val = new SimpleLocalizedKickReason("KICK_REASON_KICK", Array.Empty<string>());
				NetworkManagerSystem.singleton.ServerKickClient(connectionToClient, (BaseKickReason)(object)val);
				if (ModConfig.BroadcastKick.Value)
				{
					Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
					{
						baseToken = "<color=#e57373>Kicked player:</color> <color=#ffffff><noparse>" + networkUser.userName + "</noparse></color>"
					});
				}
				RefreshPlayerList();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Exception in KickPlayer: " + ex.Message + "\n" + ex.StackTrace));
			}
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
}