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 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("General", "ToggleKey", (KeyCode)288, "打开玩家管理面板的按键"); GameObject val = new GameObject("KickModRunner"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); 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 _bans = new Dictionary(); private readonly HashSet _known = new HashSet(); private readonly Dictionary _nameCache = new Dictionary(); 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 dictionary = null; try { dictionary = _netMan.ServerManager.Clients; } catch (Exception) { return; } if (dictionary == null) { return; } HashSet alive = new HashSet(); foreach (KeyValuePair 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 list = null; foreach (int key in _nameCache.Keys) { if (!alive.Contains(key)) { if (list == null) { list = new List(); } 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(); } if ((Object)(object)val == (Object)null && deepScan) { Player[] array = Object.FindObjectsOfType(); 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 list = new List(); foreach (KeyValuePair 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()); GUILayout.Label("按 " + ((object)KickPlugin.KeyToggle.Value/*cast due to .constrained prefix*/).ToString() + " 关闭本窗口。", Array.Empty()); 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()); 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 dictionary = null; try { dictionary = _netMan.ServerManager.Clients; } catch (Exception) { } GUILayout.Label("在线玩家 (" + (dictionary?.Count ?? 0) + "):", Array.Empty()); _scroll1 = GUILayout.BeginScrollView(_scroll1, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) }); if (dictionary != null) { List list = new List(); foreach (KeyValuePair 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()); 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()); } } GUILayout.EndScrollView(); GUILayout.Space(8f); GUILayout.Label("黑名单 (" + _bans.Count + ", 重连自动踢):", Array.Empty()); _scroll2 = GUILayout.BeginScrollView(_scroll2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(100f) }); string text2 = null; foreach (KeyValuePair ban in _bans) { GUILayout.BeginHorizontal(Array.Empty()); 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()); } GUILayout.EndScrollView(); if (text2 != null) { DoUnban(text2); } GUILayout.Space(6f); if (_notice.Length > 0 && Time.time < _noticeUntil) { GUILayout.Label(_notice, Array.Empty()); } GUILayout.Label("按 " + ((object)KickPlugin.KeyToggle.Value/*cast due to .constrained prefix*/).ToString() + " 关闭", Array.Empty()); 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()); GUI.DragWindow(); } }