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 KickMenu v1.0.4
plugins/KickMenu/KickMenu.dll
Decompiled a month agousing System; using System.Diagnostics; using System.IO; 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.EventSystems; 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+b02e883cdd2942fb4c352f00cb39621b0dac5820")] [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.4")] [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 / banning a player.\n\nDefault: true"); BroadcastKick = config.Bind<bool>("General", "Kick / Ban Broadcast", false, "If enabled, a message will be sent to chat when a player is kicked / banned.\n\nDefault: false"); OpenMenuKey = config.Bind<KeyboardShortcut>("General", "Open Kick Menu Key", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Keybind used to open the player management menu. \n\nDefault: F1"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ConfirmKick)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(BroadcastKick)); ModSettingsManager.AddOption((BaseOption)new KeyBindOption(OpenMenuKey)); } } 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.4"; public void Awake() { //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 for lobby management. Open the menu using 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); Menu.Init(); } catch (Exception ex) { Log.LogError((object)("Failed to initialize KickMenu: " + ex.Message)); } } public void Update() { Menu.Update(); } public void OnDestroy() { Menu.Destroy(); } } internal class Menu { [CompilerGenerated] private static class <>O { public static NetworkUserGenericDelegate <0>__OnNetworkUserDiscovered; public static hook_OnDestroy <1>__OnNetworkUserDestroyed; public static Action <2>__RefreshPlayerList; } private static GameObject buttonPrefab; private static GameObject menuPanel; private static Transform contentRoot; private static bool menuOpen = false; private static float time = 0f; private static readonly KeyboardShortcut closeKey = new KeyboardShortcut((KeyCode)27, Array.Empty<KeyCode>()); public static void Init() { //IL_0006: 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) //IL_0028: 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_0033: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown buttonPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/GenericMenuButton.prefab").WaitForCompletion(); object obj = <>O.<0>__OnNetworkUserDiscovered; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserDiscovered; <>O.<0>__OnNetworkUserDiscovered = val; obj = (object)val; } NetworkUser.onNetworkUserDiscovered += (NetworkUserGenericDelegate)obj; object obj2 = <>O.<1>__OnNetworkUserDestroyed; if (obj2 == null) { hook_OnDestroy val2 = OnNetworkUserDestroyed; <>O.<1>__OnNetworkUserDestroyed = val2; obj2 = (object)val2; } NetworkUser.OnDestroy += (hook_OnDestroy)obj2; } public static void Update() { //IL_0006: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = KickMenuPlugin.ModConfig.OpenMenuKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ToggleMenu(); } if (menuOpen) { value = closeKey; if (((KeyboardShortcut)(ref value)).IsDown()) { menuOpen = false; menuPanel.SetActive(menuOpen); } } time += Time.deltaTime; if (time >= 1f) { if (menuOpen) { RefreshPlayerList(); } time -= 1f; } } public static void Destroy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown object obj = <>O.<0>__OnNetworkUserDiscovered; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserDiscovered; <>O.<0>__OnNetworkUserDiscovered = val; obj = (object)val; } NetworkUser.onNetworkUserDiscovered -= (NetworkUserGenericDelegate)obj; object obj2 = <>O.<1>__OnNetworkUserDestroyed; if (obj2 == null) { hook_OnDestroy val2 = OnNetworkUserDestroyed; <>O.<1>__OnNetworkUserDestroyed = val2; obj2 = (object)val2; } NetworkUser.OnDestroy -= (hook_OnDestroy)obj2; } private static void OnNetworkUserDiscovered(NetworkUser networkUser) { if (!((Object)(object)networkUser == (Object)null) && menuOpen) { RefreshPlayerList(); } } private static void OnNetworkUserDestroyed(orig_OnDestroy orig, NetworkUser self) { orig.Invoke(self); if (menuOpen) { RoR2Application.onNextUpdate += RefreshPlayerList; } } private static void ToggleMenu() { if ((Object)(object)menuPanel == (Object)null) { CreateMenu(); } menuOpen = !menuOpen; menuPanel.SetActive(menuOpen); if (menuOpen) { RefreshPlayerList(); } } private static void RefreshPlayerList() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if ((Object)(object)contentRoot == (Object)null) { return; } EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject((GameObject)null); } foreach (Transform item in contentRoot) { Transform val = item; Object.Destroy((Object)(object)((Component)val).gameObject); } foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { CreatePlayerEntry(readOnlyInstances); } } private static void CreateMenu() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown GameObject val = new GameObject("KickMenuCanvas"); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 1000; CanvasScaler val3 = val.AddComponent<CanvasScaler>(); val3.uiScaleMode = (ScaleMode)1; val3.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); Object.DontDestroyOnLoad((Object)(object)val); menuPanel = new GameObject("KickMenuPanel"); menuPanel.transform.SetParent(val.transform, false); RectTransform val4 = menuPanel.AddComponent<RectTransform>(); val4.sizeDelta = new Vector2(750f, 0f); val4.anchoredPosition = Vector2.zero; Image val5 = menuPanel.AddComponent<Image>(); ((Graphic)val5).color = new Color(0f, 0f, 0f, 0.75f); VerticalLayoutGroup val6 = menuPanel.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val6).padding = new RectOffset(20, 20, 20, 20); ((HorizontalOrVerticalLayoutGroup)val6).spacing = 8f; ((LayoutGroup)val6).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)val6).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val6).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false; ContentSizeFitter val7 = menuPanel.AddComponent<ContentSizeFitter>(); val7.verticalFit = (FitMode)2; val7.horizontalFit = (FitMode)0; contentRoot = menuPanel.transform; menuPanel.SetActive(false); } private static void CreatePlayerEntry(NetworkUser user) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown GameObject val = new GameObject("PlayerRow"); val.transform.SetParent(contentRoot, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(700f, 50f); HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 10f; ((LayoutGroup)val3).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; LayoutElement val4 = val.AddComponent<LayoutElement>(); val4.preferredHeight = 50f; GameObject val5 = new GameObject("PlayerName"); val5.transform.SetParent(val.transform, false); TextMeshProUGUI val6 = val5.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val6).text = user.userName; ((TMP_Text)val6).fontSize = 20f; ((TMP_Text)val6).alignment = (TextAlignmentOptions)4097; ((Graphic)val6).color = Color.white; LayoutElement val7 = val5.AddComponent<LayoutElement>(); val7.flexibleWidth = 1f; val7.preferredHeight = 40f; if (Player.IsHost() && !Player.IsHost(user)) { CreateButton(val.transform, "Kick", (UnityAction)delegate { ToggleMenu(); Popup.OpenKickPopup(user); }); CreateButton(val.transform, "Ban", (UnityAction)delegate { ToggleMenu(); Popup.OpenBanPopup(user); }); } ulong userId = Steam.GetSteamId(user); GameObject val8 = CreateButton(val.transform, "Profile", (UnityAction)delegate { ToggleMenu(); Steam.OpenSteamProfile(userId); }); if (userId == 0L && (Object)(object)val8 != (Object)null) { val8.SetActive(false); } } private static GameObject CreateButton(Transform parent, string text, UnityAction action) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)buttonPrefab)) { return null; } GameObject val = Object.Instantiate<GameObject>(buttonPrefab, parent); ((Object)val).name = text + "Button"; LayoutElement val2 = val.AddComponent<LayoutElement>(); val2.preferredWidth = 100f; val2.preferredHeight = 40f; TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)componentInChildren).text = text; ((TMP_Text)componentInChildren).fontSize = 16f; ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)514; } HGButton component = val.GetComponent<HGButton>(); if (Object.op_Implicit((Object)(object)component)) { Navigation navigation = ((Selectable)component).navigation; ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component).navigation = navigation; ((UnityEventBase)((Button)component).onClick).RemoveAllListeners(); ((UnityEvent)((Button)component).onClick).AddListener(action); } return val; } } internal static class Player { public static bool IsHost() { return NetworkServer.active; } public static bool IsHost(NetworkUser networkUser) { if ((Object)(object)networkUser == (Object)null) { return false; } return ((NetworkBehaviour)networkUser).isLocalPlayer; } private static NetworkConnection GetNetworkConnection(NetworkUser networkUser) { if ((Object)(object)networkUser == (Object)null) { return null; } if (!IsHost()) { return null; } if (IsHost(networkUser)) { KickMenuPlugin.Log.LogWarning((object)("Attempted to remove host (" + networkUser.userName + "). Action aborted.")); return null; } return ((NetworkBehaviour)networkUser).connectionToClient; } private static void SendRemoveMessage(string username, string message) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (KickMenuPlugin.ModConfig.BroadcastKick.Value) { SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "<color=#e57373>" + message + " player:</color> <color=#ffffff><noparse>" + username + "</noparse></color>"; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } } public static void RemovePlayer(NetworkUser networkUser, string message, Action<NetworkConnection> action) { if ((Object)(object)networkUser == (Object)null) { KickMenuPlugin.Log.LogWarning((object)"No connection found for player: <null NetworkUser>"); return; } string userName = networkUser.userName; NetworkConnection networkConnection = GetNetworkConnection(networkUser); if (networkConnection == null) { KickMenuPlugin.Log.LogWarning((object)("No connection found for player: " + userName)); return; } int connectionId = networkConnection.connectionId; if (!networkConnection.isReady) { KickMenuPlugin.Log.LogWarning((object)$"Client connection for {userName} is not ready (Connection ID: {connectionId}). Still attempting removal."); } try { KickMenuPlugin.Log.LogInfo((object)$"Removing player {userName} (Connection ID: {connectionId})..."); action?.Invoke(networkConnection); try { networkConnection.Disconnect(); } catch (Exception ex) { KickMenuPlugin.Log.LogDebug((object)("client.Disconnect() fallback for " + userName + " threw (connection was likely already closed): " + ex.Message)); } KickMenuPlugin.Log.LogInfo((object)$"{message} player {userName} (Connection ID: {connectionId})"); SendRemoveMessage(userName, message); } catch (Exception arg) { KickMenuPlugin.Log.LogError((object)$"Failed to remove player {userName} (Connection ID: {connectionId}): {arg}"); } } public static void Kick(NetworkUser networkUser) { RemovePlayer(networkUser, "Kicked", delegate(NetworkConnection client) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SimpleLocalizedKickReason val = new SimpleLocalizedKickReason("KICK_REASON_KICK", Array.Empty<string>()); NetworkManagerSystem.singleton.ServerKickClient(client, (BaseKickReason)(object)val); }); } public static void Ban(NetworkUser networkUser) { RemovePlayer(networkUser, "Banned", delegate(NetworkConnection client) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown NetworkManagerSystem.singleton.ServerBanClient(client); SimpleLocalizedKickReason val = new SimpleLocalizedKickReason("KICK_REASON_KICK", Array.Empty<string>()); NetworkManagerSystem.singleton.ServerKickClient(client, (BaseKickReason)(object)val); }); } } internal static class Popup { private static void OnButtonClicked(NetworkUser networkUser, string message, Action<NetworkUser> action) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown if ((Object)(object)networkUser == (Object)null || !Player.IsHost()) { return; } if (!KickMenuPlugin.ModConfig.ConfirmKick.Value) { action(networkUser); return; } 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 " + message; ((TMP_Text)dialog.descriptionLabel).text = "Are you sure you want to " + message + " " + networkUser.userName + "?"; dialog.AddActionButton((UnityAction)delegate { action(networkUser); }, "Yes", true, Array.Empty<object>()); dialog.AddCancelButton("Cancel", Array.Empty<object>()); } public static void OpenKickPopup(NetworkUser networkUser) { OnButtonClicked(networkUser, "kick", Player.Kick); } public static void OpenBanPopup(NetworkUser networkUser) { OnButtonClicked(networkUser, "ban", Player.Ban); } } internal static class Steam { public static ulong GetSteamId(NetworkUser networkUser) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)networkUser == (Object)null) { return 0uL; } NetworkUserId network_id = networkUser.Network_id; PlatformID steamId = ((NetworkUserId)(ref network_id)).steamId; return Convert.ToUInt64(((PlatformID)(ref steamId)).value); } private static string OpenSteamProfileCommand(ulong id) { if (id == 0) { return null; } return $"steam://openurl/https://steamcommunity.com/profiles/{id}"; } public static void OpenSteamProfile(ulong id) { if (id == 0) { return; } string text = OpenSteamProfileCommand(id); if (text == null) { return; } try { Process.Start(new ProcessStartInfo { FileName = text, UseShellExecute = true }); } catch (Exception ex) { KickMenuPlugin.Log.LogError((object)("Failed to open Steam profile: " + ex.Message)); } } } }