Decompiled source of bwbyKickMod v1.1.0

BepInEx/plugins/KickMod.dll

Decompiled 29 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Logging;
using FishNet.Managing.Server;
using FishNet.Object;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace KickMod;

[BepInPlugin("com.trae.kick", "Host Kick Menu", "1.0.0")]
public class KickPlugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigEntry<KeyCode> KeyToggle;

	private void Awake()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		KeyToggle = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)288, "打开玩家管理面板的按键");
		GameObject val = new GameObject("KickModRunner");
		Object.DontDestroyOnLoad((Object)(object)val);
		val.AddComponent<KickRunner>();
		Log.LogInfo((object)("[KickMod] 已加载。按 " + ((object)KeyToggle.Value/*cast due to .constrained prefix*/).ToString() + " 打开玩家管理面板(仅房主可用)"));
	}
}
internal class KickRunner : MonoBehaviour
{
	private bool _show;

	private Rect _win = new Rect((float)Screen.width * 0.35f, (float)Screen.height * 0.25f, 420f, 400f);

	private Vector2 _scroll1 = Vector2.zero;

	private Vector2 _scroll2 = Vector2.zero;

	private readonly Dictionary<string, string> _bans = new Dictionary<string, string>();

	private readonly HashSet<int> _known = new HashSet<int>();

	private readonly Dictionary<int, string> _nameCache = new Dictionary<int, string>();

	private float _nextScan;

	private string _notice = "";

	private float _noticeUntil;

	private NetworkManager _netMan;

	private PropertyInfo _piInstances;

	private string BanFile => Path.Combine(Paths.ConfigPath, "kickmod_bans.txt");

	private void Start()
	{
		_piInstances = typeof(NetworkManager).GetProperty("Instances", BindingFlags.Static | BindingFlags.Public);
		LoadBans();
	}

	private void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown(KickPlugin.KeyToggle.Value))
		{
			_show = !_show;
		}
		if (Time.time >= _nextScan)
		{
			_nextScan = Time.time + 1f;
			RefreshNetMan();
			if (IsHost())
			{
				ScanNewConnections();
			}
		}
	}

	private void RefreshNetMan()
	{
		try
		{
			if ((Object)(object)_netMan != (Object)null && _netManagerAlive())
			{
				return;
			}
			_netMan = null;
			if (_piInstances == null)
			{
				return;
			}
			object value = _piInstances.GetValue(null, null);
			if (!(value is IEnumerable enumerable))
			{
				return;
			}
			foreach (object item in enumerable)
			{
				NetworkManager val = (NetworkManager)((item is NetworkManager) ? item : null);
				if ((Object)(object)val != (Object)null)
				{
					_netMan = val;
					break;
				}
			}
		}
		catch (Exception)
		{
			_netMan = null;
		}
	}

	private bool _netManagerAlive()
	{
		try
		{
			return (Object)(object)_netMan != (Object)null && (Object)(object)((Component)_netMan).gameObject != (Object)null;
		}
		catch
		{
			return false;
		}
	}

	private bool IsHost()
	{
		return (Object)(object)_netMan != (Object)null && _netMan.IsServerStarted;
	}

	private void ScanNewConnections()
	{
		Dictionary<int, NetworkConnection> dictionary = null;
		try
		{
			dictionary = _netMan.ServerManager.Clients;
		}
		catch (Exception)
		{
			return;
		}
		if (dictionary == null)
		{
			return;
		}
		HashSet<int> alive = new HashSet<int>();
		foreach (KeyValuePair<int, NetworkConnection> item in dictionary)
		{
			NetworkConnection value = item.Value;
			if (value == (NetworkConnection)null || !value.IsActive)
			{
				continue;
			}
			alive.Add(item.Key);
			if (!_nameCache.ContainsKey(item.Key))
			{
				string value2 = ResolveName(value, deepScan: true);
				if (!string.IsNullOrEmpty(value2))
				{
					_nameCache[item.Key] = value2;
				}
			}
			if (!_known.Contains(item.Key))
			{
				_known.Add(item.Key);
				string text = SafeAddress(value);
				if (!string.IsNullOrEmpty(text) && _bans.ContainsKey(text))
				{
					value.Kick((KickReason)0, (LoggingType)3, "");
					Notice("已自动踢出黑名单玩家: " + NameOf(value));
					KickPlugin.Log.LogInfo((object)("[KickMod] 黑名单玩家被自动踢出: " + text));
				}
			}
		}
		_known.RemoveWhere((int id) => !alive.Contains(id));
		List<int> list = null;
		foreach (int key in _nameCache.Keys)
		{
			if (!alive.Contains(key))
			{
				if (list == null)
				{
					list = new List<int>();
				}
				list.Add(key);
			}
		}
		if (list != null)
		{
			for (int num = 0; num < list.Count; num++)
			{
				_nameCache.Remove(list[num]);
			}
		}
	}

	private void DoKick(NetworkConnection conn)
	{
		if (!(conn == (NetworkConnection)null))
		{
			conn.Kick((KickReason)0, (LoggingType)3, "");
			Notice("已踢出: " + NameOf(conn));
			KickPlugin.Log.LogInfo((object)("[KickMod] 踢出玩家: " + NameOf(conn) + " (" + SafeAddress(conn) + ")"));
		}
	}

	private void DoBan(NetworkConnection conn)
	{
		if (!(conn == (NetworkConnection)null))
		{
			string text = SafeAddress(conn);
			string text2 = NameOf(conn);
			if (!string.IsNullOrEmpty(text))
			{
				_bans[text] = text2;
				SaveBans();
			}
			conn.Kick((KickReason)0, (LoggingType)3, "");
			Notice("已拉黑并踢出: " + text2);
			KickPlugin.Log.LogInfo((object)("[KickMod] 拉黑玩家: " + text2 + " (" + text + ")"));
		}
	}

	private void DoUnban(string addr)
	{
		_bans.Remove(addr);
		SaveBans();
		Notice("已移出黑名单: " + addr);
	}

	private string NameOf(NetworkConnection conn)
	{
		if (conn == (NetworkConnection)null)
		{
			return "?";
		}
		if (_nameCache.TryGetValue(conn.ClientId, out var value))
		{
			return value;
		}
		value = ResolveName(conn, deepScan: false);
		if (!string.IsNullOrEmpty(value))
		{
			_nameCache[conn.ClientId] = value;
			return value;
		}
		return "Client #" + conn.ClientId;
	}

	private string ResolveName(NetworkConnection conn, bool deepScan)
	{
		try
		{
			if (IsSelf(conn))
			{
				Player localPlayer = Player.LocalPlayer;
				if ((Object)(object)localPlayer != (Object)null && !string.IsNullOrEmpty(localPlayer.SteamName))
				{
					return localPlayer.SteamName;
				}
			}
			Player val = null;
			if ((Object)(object)conn.FirstObject != (Object)null)
			{
				val = ((Component)conn.FirstObject).GetComponent<Player>();
			}
			if ((Object)(object)val == (Object)null && deepScan)
			{
				Player[] array = Object.FindObjectsOfType<Player>();
				for (int i = 0; i < array.Length; i++)
				{
					if ((Object)(object)array[i] != (Object)null && ((NetworkBehaviour)array[i]).Owner == conn)
					{
						val = array[i];
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.SteamName))
			{
				return val.SteamName;
			}
		}
		catch (Exception)
		{
		}
		return null;
	}

	private string SafeAddress(NetworkConnection conn)
	{
		try
		{
			return conn.GetAddress();
		}
		catch (Exception)
		{
			return "";
		}
	}

	private bool IsSelf(NetworkConnection conn)
	{
		try
		{
			return conn.IsLocalClient || conn.IsHost;
		}
		catch (Exception)
		{
			return false;
		}
	}

	private void Notice(string msg)
	{
		_notice = msg;
		_noticeUntil = Time.time + 3f;
	}

	private void LoadBans()
	{
		try
		{
			_bans.Clear();
			if (File.Exists(BanFile))
			{
				string[] array = File.ReadAllLines(BanFile);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.Length == 0)
					{
						continue;
					}
					int num = text.IndexOf('|');
					if (num > 0)
					{
						string text2 = text.Substring(0, num).Trim();
						if (text2.Length > 0)
						{
							_bans[text2] = text.Substring(num + 1).Trim();
						}
					}
					else
					{
						_bans[text] = "";
					}
				}
			}
			KickPlugin.Log.LogInfo((object)("[KickMod] 黑名单已加载: " + _bans.Count + " 人"));
		}
		catch (Exception ex)
		{
			KickPlugin.Log.LogWarning((object)("[KickMod] 黑名单读取失败: " + ex.Message));
		}
	}

	private void SaveBans()
	{
		try
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, string> ban in _bans)
			{
				list.Add(ban.Key + "|" + ban.Value);
			}
			File.WriteAllLines(BanFile, list.ToArray());
		}
		catch (Exception ex)
		{
			KickPlugin.Log.LogWarning((object)("[KickMod] 黑名单保存失败: " + ex.Message));
		}
	}

	private void OnGUI()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (_show)
		{
			if (!IsHost())
			{
				_win = GUILayout.Window(7301, _win, new WindowFunction(DrawNotHost), "KickMod — 仅房主可用", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(320f) });
			}
			else
			{
				_win = GUILayout.Window(7302, _win, new WindowFunction(DrawHost), "KickMod — 房主管理面板", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(430f) });
			}
		}
	}

	private void DrawNotHost(int id)
	{
		//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)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		GUILayout.Label("你不是房主, 无法管理玩家。", Array.Empty<GUILayoutOption>());
		GUILayout.Label("按 " + ((object)KickPlugin.KeyToggle.Value/*cast due to .constrained prefix*/).ToString() + " 关闭本窗口。", Array.Empty<GUILayoutOption>());
		GUIStyle val = new GUIStyle(GUI.skin.label);
		val.fontSize = 11;
		val.normal.textColor = new Color(1f, 1f, 1f, 0.55f);
		GUILayout.Space(4f);
		GUILayout.Label("作者, dy小文大王。有问题可以私信我", val, Array.Empty<GUILayoutOption>());
		GUI.DragWindow();
	}

	private void DrawHost(int id)
	{
		//IL_004d: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Expected O, but got Unknown
		//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<int, NetworkConnection> dictionary = null;
		try
		{
			dictionary = _netMan.ServerManager.Clients;
		}
		catch (Exception)
		{
		}
		GUILayout.Label("在线玩家 (" + (dictionary?.Count ?? 0) + "):", Array.Empty<GUILayoutOption>());
		_scroll1 = GUILayout.BeginScrollView(_scroll1, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) });
		if (dictionary != null)
		{
			List<NetworkConnection> list = new List<NetworkConnection>();
			foreach (KeyValuePair<int, NetworkConnection> item in dictionary)
			{
				if (item.Value != (NetworkConnection)null && item.Value.IsActive)
				{
					list.Add(item.Value);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				NetworkConnection conn = list[i];
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				string text = (IsSelf(conn) ? " (你/房主)" : "");
				GUILayout.Label(NameOf(conn) + text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
				if (!IsSelf(conn))
				{
					if (GUILayout.Button("踢出", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
					{
						DoKick(conn);
					}
					if (GUILayout.Button("拉黑", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
					{
						DoBan(conn);
					}
				}
				GUILayout.EndHorizontal();
			}
			if (list.Count == 0)
			{
				GUILayout.Label("(没有其他玩家)", Array.Empty<GUILayoutOption>());
			}
		}
		GUILayout.EndScrollView();
		GUILayout.Space(8f);
		GUILayout.Label("黑名单 (" + _bans.Count + ", 重连自动踢):", Array.Empty<GUILayoutOption>());
		_scroll2 = GUILayout.BeginScrollView(_scroll2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(100f) });
		string text2 = null;
		foreach (KeyValuePair<string, string> ban in _bans)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			string text3 = (string.IsNullOrEmpty(ban.Value) ? ban.Key : (ban.Value + " (" + ban.Key + ")"));
			GUILayout.Label(text3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(340f) });
			if (GUILayout.Button("移除", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
			{
				text2 = ban.Key;
			}
			GUILayout.EndHorizontal();
		}
		if (_bans.Count == 0)
		{
			GUILayout.Label("(空)", Array.Empty<GUILayoutOption>());
		}
		GUILayout.EndScrollView();
		if (text2 != null)
		{
			DoUnban(text2);
		}
		GUILayout.Space(6f);
		if (_notice.Length > 0 && Time.time < _noticeUntil)
		{
			GUILayout.Label(_notice, Array.Empty<GUILayoutOption>());
		}
		GUILayout.Label("按 " + ((object)KickPlugin.KeyToggle.Value/*cast due to .constrained prefix*/).ToString() + " 关闭", Array.Empty<GUILayoutOption>());
		GUIStyle val = new GUIStyle(GUI.skin.label);
		val.fontSize = 11;
		val.normal.textColor = new Color(1f, 1f, 1f, 0.55f);
		GUILayout.Space(4f);
		GUILayout.Label("作者, dy小文大王。有问题可以私信我", val, Array.Empty<GUILayoutOption>());
		GUI.DragWindow();
	}
}