Decompiled source of HostModeration v1.0.0

plugins/Marioalexsan.HostModeration.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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 HarmonyLib;
using Marioalexsan.HostModeration;
using Microsoft.CodeAnalysis;
using Mirror;
using Newtonsoft.Json;
using Steamworks;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Marioalexsan.HostModeration")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4868952309c4817a1a783416e08debd4c6f2c308")]
[assembly: AssemblyProduct("HostModeration")]
[assembly: AssemblyTitle("Marioalexsan.HostModeration")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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;
		}
	}
}
[HarmonyPatch(typeof(ChatBehaviour), "UserCode_Cmd_SendChatMessage__String__ChatChannel")]
internal static class ProcessOperatorCommands
{
	private static bool Prefix(ChatBehaviour __instance, string _message, ChatChannel _chatChannel)
	{
		if ((_message.Contains('<') && _message.Contains('>')) || _message.Contains('\0') || _message.Length > 125 || __instance._messageSendBuffer)
		{
			return true;
		}
		if (_message == "")
		{
			return true;
		}
		string text = _message.Trim();
		if (!text.StartsWith("/"))
		{
			return true;
		}
		string text2 = text;
		string[] array = text2.Substring(1, text2.Length - 1).Split(' ', StringSplitOptions.RemoveEmptyEntries);
		if (array.Length == 0)
		{
			return true;
		}
		return HostModeration.ProcessCommand(((NetworkConnection)((NetworkBehaviour)__instance).connectionToClient).connectionId, array, (Action<string>)__instance.Target_RecieveMessage);
	}
}
[HarmonyPatch(typeof(ConsoleCommandManager), "Init_ConsoleCommand")]
internal static class AddModerationCommandsToConsole
{
	private static bool Prefix(string _name, string _output)
	{
		string[] parts = ((!string.IsNullOrWhiteSpace(_output)) ? new string[2] { _name, _output } : new string[1] { _name });
		return HostModeration.ProcessCommand(-1337, parts, (Action<string>)HostConsole._current.New_LogMessage);
	}
}
namespace Marioalexsan.HostModeration
{
	public delegate bool CommandAction(int callerConnectionId, string[] parts, Action<string> sendMessage);
	public delegate bool WrappedSteamIdCommand(int callerConnectionId, string steamId, out string statusMessage);
	public delegate bool WrappedSteamIdParamsCommand(int callerConnectionId, string steamId, string[] parts, out string statusMessage);
	internal class CommandData
	{
		public string Name { get; set; }

		public string Description { get; set; }

		public bool RequiresOperator { get; set; }

		public bool HostOnly { get; set; }

		public CommandAction Action { get; set; }

		public CommandData(string name, string description, CommandAction action)
		{
			Name = name;
			Description = description;
			RequiresOperator = true;
			HostOnly = false;
			Action = action;
			base..ctor();
		}
	}
	internal static class Commands
	{
		public static readonly CommandData[] DataList;

		public static readonly Dictionary<string, CommandData> Data;

		static Commands()
		{
			DataList = new CommandData[21]
			{
				new CommandData("hm-help", "show commands", HmHelp),
				new CommandData("hm-clients", "show clients", HmClients),
				new CommandData("hm-operators", "show operators", HmOperators),
				new CommandData("hm-bans", "show banned clients", HmBanned),
				new CommandData("hm-find-name", "find a client by name", HmFindClient),
				MakeNicknameCommand("hm-op", "promote to operator", HostModeration.PromoteToOperatorBySteamId, hostOnly: true),
				MakeSteamIdCommand("hm-op-steam", "promote to operator", HostModeration.PromoteToOperatorBySteamId, hostOnly: true),
				MakeConnIdCommand("hm-op-conn", "promote to operator", HostModeration.PromoteToOperatorBySteamId, hostOnly: true),
				MakeNicknameCommand("hm-deop", "demote operator", HostModeration.DemoteFromOperatorBySteamId, hostOnly: true),
				MakeSteamIdCommand("hm-deop-steam", "demote operator", HostModeration.DemoteFromOperatorBySteamId, hostOnly: true),
				MakeConnIdCommand("hm-deop-conn", "demote operator", HostModeration.DemoteFromOperatorBySteamId, hostOnly: true),
				MakeNicknameCommand("hm-ban", "ban client", HostModeration.BanUserBySteamId),
				MakeSteamIdCommand("hm-ban-steam", "ban client", HostModeration.BanUserBySteamId),
				MakeConnIdCommand("hm-ban-conn", "ban client", HostModeration.BanUserBySteamId),
				MakeSteamIdCommand("hm-unban-steam", "unban client", HostModeration.UnbanUserBySteamId),
				new CommandData("hm-unban-id", "unban client by ban ID", HmUnban),
				MakeNicknameCommand("hm-kick", "kick client", HostModeration.KickUserBySteamId),
				MakeSteamIdCommand("hm-kick-steam", "kick client", HostModeration.KickUserBySteamId),
				MakeConnIdCommand("hm-kick-conn", "kick client", HostModeration.KickUserBySteamId),
				MakeSteamIdCommand("hm-warn-steam", "warn client", HmWarn),
				MakeConnIdCommand("hm-warn-conn", "warn client", HmWarn)
			};
			Data = DataList.ToDictionary((CommandData x) => x.Name);
		}

		private static bool HmFindClient(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			if (parts.Length < 2)
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedNickname()));
				return false;
			}
			string statusMessage;
			string text = HostModeration.FindSteamIdBasedOnMatches(parts[1..], out statusMessage);
			sendMessage(Texts.StatusText(text != null, statusMessage));
			return text != null;
		}

		private static bool HmWarn(int callerConnectionId, string steamId, string[] parts, out string statusMessage)
		{
			string text = string.Join(' ', parts[2..]);
			if (string.IsNullOrWhiteSpace(text))
			{
				text = Texts.NoReasonSpecified();
			}
			return HostModeration.WarnUserBySteamId(callerConnectionId, steamId, text, out statusMessage);
		}

		private static bool HmUnban(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			if (parts.Length < 2 || !int.TryParse(parts[1], out var result))
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedListIndex()));
				return false;
			}
			string statusMessage;
			bool flag = HostModeration.UnbanUserByBanListIndex(callerConnectionId, result, out statusMessage);
			sendMessage(Texts.StatusText(flag, statusMessage));
			return flag;
		}

		private static bool HmHelp(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			return ShowPaginatedList(parts, "Commands", GetCommands, sendMessage);
			static string[] GetCommands()
			{
				return DataList.Select((CommandData x) => x.Name + " - " + x.Description).ToArray();
			}
		}

		private static bool HmClients(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			return ShowPaginatedList(parts, "Clients", GetClients, sendMessage);
			static string[] GetClients()
			{
				List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
				string[] array = new string[peerListEntries.Count];
				for (int i = 0; i < peerListEntries.Count; i++)
				{
					array[i] = Texts.ClientDetails(peerListEntries[i]);
				}
				return array;
			}
		}

		private static bool HmOperators(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			return ShowPaginatedList(parts, "Operators", GetOperators, sendMessage);
			static string[] GetOperators()
			{
				List<OperatorDetails> steamIdOperators = HostModeration.Data.SteamIdOperators;
				string[] array = new string[steamIdOperators.Count];
				for (int i = 0; i < steamIdOperators.Count; i++)
				{
					array[i] = Texts.OperatorDetails(steamIdOperators[i]);
				}
				return array;
			}
		}

		private static bool HmBanned(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			return ShowPaginatedList(parts, "Banned clients", GetBannedClients, sendMessage);
			static string[] GetBannedClients()
			{
				List<BannedClientParameter> bannedClientList = AtlyssNetworkManager._current._bannedClientList;
				string[] array = new string[bannedClientList.Count];
				for (int i = 0; i < bannedClientList.Count; i++)
				{
					array[i] = Texts.BannedClientDetails(bannedClientList[i]);
				}
				return array;
			}
		}

		private static CommandData MakeSteamIdCommand(string name, string description, WrappedSteamIdCommand executeCommand, bool hostOnly = false, bool requiresOperator = true)
		{
			WrappedSteamIdCommand executeCommand2 = executeCommand;
			return MakeSteamIdCommand(name, description, delegate(int callerConnectionId, string steamId, string[] parts, out string statusMessage)
			{
				return executeCommand2(callerConnectionId, steamId, out statusMessage);
			}, hostOnly, requiresOperator);
		}

		private static CommandData MakeSteamIdCommand(string name, string description, WrappedSteamIdParamsCommand executeCommand, bool hostOnly = false, bool requiresOperator = true)
		{
			WrappedSteamIdParamsCommand executeCommand2 = executeCommand;
			return new CommandData(name, description + " by SteamID", (int callerConnectionId, string[] parts, Action<string> sendMessage) => SteamIdCommand(callerConnectionId, parts, sendMessage, executeCommand2))
			{
				HostOnly = hostOnly,
				RequiresOperator = requiresOperator
			};
		}

		private static CommandData MakeConnIdCommand(string name, string description, WrappedSteamIdCommand executeCommand, bool hostOnly = false, bool requiresOperator = true)
		{
			WrappedSteamIdCommand executeCommand2 = executeCommand;
			return MakeConnIdCommand(name, description, delegate(int callerConnectionId, string steamId, string[] parts, out string statusMessage)
			{
				return executeCommand2(callerConnectionId, steamId, out statusMessage);
			}, hostOnly, requiresOperator);
		}

		private static CommandData MakeConnIdCommand(string name, string description, WrappedSteamIdParamsCommand executeCommand, bool hostOnly = false, bool requiresOperator = true)
		{
			WrappedSteamIdParamsCommand executeCommand2 = executeCommand;
			return new CommandData(name, description + " by ConnID", (int callerConnectionId, string[] parts, Action<string> sendMessage) => ConnIdCommand(callerConnectionId, parts, sendMessage, executeCommand2))
			{
				HostOnly = hostOnly,
				RequiresOperator = requiresOperator
			};
		}

		private static CommandData MakeNicknameCommand(string name, string description, WrappedSteamIdCommand executeCommand, bool hostOnly = false, bool requiresOperator = true)
		{
			WrappedSteamIdCommand executeCommand2 = executeCommand;
			return MakeNicknameCommand(name, description, delegate(int callerConnectionId, string steamId, string[] parts, out string statusMessage)
			{
				return executeCommand2(callerConnectionId, steamId, out statusMessage);
			}, hostOnly, requiresOperator);
		}

		private static CommandData MakeNicknameCommand(string name, string description, WrappedSteamIdParamsCommand executeCommand, bool hostOnly = false, bool requiresOperator = true)
		{
			WrappedSteamIdParamsCommand executeCommand2 = executeCommand;
			return new CommandData(name, description + " by name", (int callerConnectionId, string[] parts, Action<string> sendMessage) => NicknameCommand(callerConnectionId, parts, sendMessage, executeCommand2))
			{
				HostOnly = hostOnly,
				RequiresOperator = requiresOperator
			};
		}

		private static bool ConnIdCommand(int callerConnectionId, string[] parts, Action<string> sendMessage, WrappedSteamIdParamsCommand executeCommand)
		{
			if (parts.Length < 2 || !int.TryParse(parts[1], out var result) || !ConnUtils.ConnectionIdToSteamId(result, out string steamId))
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedConnId()));
				return false;
			}
			string statusMessage;
			bool flag = executeCommand(callerConnectionId, steamId, parts, out statusMessage);
			sendMessage(Texts.StatusText(flag, statusMessage));
			return flag;
		}

		private static bool SteamIdCommand(int callerConnectionId, string[] parts, Action<string> sendMessage, WrappedSteamIdParamsCommand executeCommand)
		{
			if (parts.Length < 2 || !Utils.IsValidSteamId(parts[1]))
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedSteamID()));
				return false;
			}
			string statusMessage;
			bool flag = executeCommand(callerConnectionId, parts[1], parts, out statusMessage);
			sendMessage(Texts.StatusText(flag, statusMessage));
			return flag;
		}

		private static bool NicknameCommand(int callerConnectionId, string[] parts, Action<string> sendMessage, WrappedSteamIdParamsCommand executeCommand)
		{
			if (parts.Length < 2)
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedNickname()));
				return false;
			}
			string statusMessage;
			string text = HostModeration.FindSteamIdBasedOnMatches(parts[1..], out statusMessage);
			if (text == null)
			{
				sendMessage(Texts.ErrorText(statusMessage));
				return false;
			}
			bool flag = executeCommand(callerConnectionId, text, parts, out statusMessage);
			sendMessage(Texts.StatusText(flag, statusMessage));
			return flag;
		}

		private static bool ShowPaginatedList(string[] parts, string subject, Func<string[]> retrieveData, Action<string> sendMessage)
		{
			int result = 1;
			int result2 = 7;
			if (parts.Length >= 2 && !int.TryParse(parts[1], out result))
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedPageNumber()));
				return false;
			}
			if (parts.Length >= 3 && (!int.TryParse(parts[2], out result2) || 5 > result2 || result2 > 100))
			{
				sendMessage(Texts.ErrorText(Texts.ExpectedPageSize()));
				return false;
			}
			string[] array = retrieveData();
			int totalPages = (int)Math.Ceiling((float)array.Length / (float)result2);
			int num = Math.Clamp((result - 1) * result2, 0, array.Length);
			int num2 = Math.Clamp(result * result2, 0, array.Length);
			sendMessage(Texts.PageHeader(subject, result, totalPages));
			for (int i = num; i < num2; i++)
			{
				sendMessage(Texts.PageEntry(i, array[i]));
			}
			if (num == num2)
			{
				sendMessage(Texts.PageNoData());
			}
			return true;
		}
	}
	internal static class ConnUtils
	{
		public static bool HasOperatorRole(int connectionId)
		{
			if (IsHost(connectionId))
			{
				return true;
			}
			if (!ConnectionIdToSteamId(connectionId, out string steamId))
			{
				return false;
			}
			return HostModeration.Data.SteamIdOperators.FindIndex((OperatorDetails x) => x.SteamId == steamId) != -1;
		}

		public static bool IsHost(int connectionId)
		{
			if (connectionId == -1337)
			{
				return true;
			}
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				if (((ListDataEntry)peerListEntries[i])._dataID == connectionId)
				{
					return peerListEntries[i]._peerPlayer._isHostPlayer;
				}
			}
			return false;
		}

		public static bool ConnectionIdToSteamId(int connectionId, [NotNullWhen(true)] out string? steamId)
		{
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				if (((ListDataEntry)peerListEntries[i])._dataID == connectionId)
				{
					steamId = peerListEntries[i]._peerPlayer._steamID;
					return true;
				}
			}
			steamId = null;
			return false;
		}

		public static bool SteamIdToConnectionId(string steamId, out int connectionId)
		{
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				if (peerListEntries[i]._peerPlayer._steamID == steamId)
				{
					connectionId = ((ListDataEntry)peerListEntries[i])._dataID;
					return true;
				}
			}
			connectionId = -1;
			return false;
		}

		public static bool ConnectionIdToPeer(int connectionId, [NotNullWhen(true)] out HC_PeerListEntry? peer)
		{
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				if (((ListDataEntry)peerListEntries[i])._dataID == connectionId)
				{
					peer = peerListEntries[i];
					return true;
				}
			}
			peer = null;
			return false;
		}

		public static string SteamIdToName(string steamId)
		{
			if (SteamIdToPeer(steamId, out HC_PeerListEntry peer))
			{
				return Texts.ClientDetails(peer);
			}
			return "Unknown";
		}

		public static string ConnectionIdToName(int connectionId)
		{
			if (connectionId == -1337)
			{
				return "Host Console";
			}
			if (ConnectionIdToPeer(connectionId, out HC_PeerListEntry peer))
			{
				return Texts.ClientDetails(peer);
			}
			return "Unknown";
		}

		public static bool SteamIdToPeer(string steamId, [NotNullWhen(true)] out HC_PeerListEntry? peer)
		{
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				if (peerListEntries[i]._peerPlayer._steamID == steamId)
				{
					peer = peerListEntries[i];
					return true;
				}
			}
			peer = null;
			return false;
		}
	}
	[BepInPlugin("Marioalexsan.HostModeration", "HostModeration", "1.0.0")]
	public class HostModeration : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("Marioalexsan.HostModeration");

		public const int HostConsoleFakeConnectionId = -1337;

		public static HostModerationData Data { get; private set; } = new HostModerationData();


		public static string DataPath => Path.Combine(Paths.ConfigPath, "Marioalexsan.HostModeration_Data.json");

		public static bool ProcessCommand(int callerConnectionId, string[] parts, Action<string> sendMessage)
		{
			if (!Commands.Data.TryGetValue(parts[0], out CommandData value))
			{
				return true;
			}
			if (value.RequiresOperator && !ConnUtils.HasOperatorRole(callerConnectionId))
			{
				sendMessage(Texts.ErrorText(Texts.CommandForbidden()));
				return false;
			}
			if (value.HostOnly && !ConnUtils.IsHost(callerConnectionId))
			{
				sendMessage(Texts.ErrorText(Texts.CommandForbidden()));
				return false;
			}
			value.Action(callerConnectionId, parts, sendMessage);
			return false;
		}

		public void Awake()
		{
			_harmony.PatchAll();
			LoadData();
			Debug.Log((object)"HostModeration loaded.");
		}

		public static void LoadData()
		{
			if (!File.Exists(DataPath))
			{
				Data = new HostModerationData();
			}
			else
			{
				Data = JsonConvert.DeserializeObject<HostModerationData>(File.ReadAllText(DataPath)) ?? throw new InvalidOperationException("JSON deserialization failed");
			}
		}

		public static void SaveData()
		{
			File.WriteAllText(DataPath, JsonConvert.SerializeObject((object)Data));
		}

		public static bool PromoteToOperatorBySteamId(int callerConnectionId, string steamId, out string statusMessage)
		{
			if (ConnUtils.SteamIdToPeer(steamId, out HC_PeerListEntry peer) && ConnUtils.IsHost(((ListDataEntry)peer)._dataID))
			{
				statusMessage = Texts.CannotPromoteDemoteHost();
				return false;
			}
			List<BannedClientParameter> bannedClientList = AtlyssNetworkManager._current._bannedClientList;
			for (int i = 0; i < bannedClientList.Count; i++)
			{
				if (bannedClientList[i]._steamID == steamId)
				{
					statusMessage = Texts.CannotPromoteBannedUsers();
					return false;
				}
			}
			for (int j = 0; j < Data.SteamIdOperators.Count; j++)
			{
				if (Data.SteamIdOperators[j].SteamId == steamId)
				{
					statusMessage = Texts.AlreadyAnOperator();
					return false;
				}
			}
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			HC_PeerListEntry peer2;
			string characterNickname = (ConnUtils.SteamIdToPeer(steamId, out peer2) ? peer2._peerPlayer._nickname : "Unknown");
			Data.SteamIdOperators.Add(new OperatorDetails
			{
				SteamId = steamId,
				CharacterNickname = characterNickname
			});
			SaveData();
			TrySendChatMessageToSteamId(steamId, Texts.NoticeText(Texts.PromotedToOp()));
			statusMessage = Texts.PromotedTargetToOp();
			return true;
		}

		public static bool DemoteFromOperatorBySteamId(int callerConnectionId, string steamId, out string statusMessage)
		{
			if (ConnUtils.SteamIdToConnectionId(steamId, out var connectionId) && ConnUtils.IsHost(connectionId))
			{
				statusMessage = Texts.CannotPromoteDemoteHost();
				return false;
			}
			for (int i = 0; i < Data.SteamIdOperators.Count; i++)
			{
				if (Data.SteamIdOperators[i].SteamId == steamId)
				{
					Data.SteamIdOperators.RemoveAt(i);
					SaveData();
					TrySendChatMessageToSteamId(steamId, Texts.NoticeText(Texts.DemotedFromOp()));
					statusMessage = Texts.DemotedTargetFromOp();
					return true;
				}
			}
			statusMessage = Texts.NotAnOperator();
			return false;
		}

		public static bool BanUserBySteamId(int callerConnectionId, string steamId, out string statusMessage)
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			string caller = ConnUtils.ConnectionIdToName(callerConnectionId);
			string target = "Unknown [SteamID " + steamId + "]";
			string characterNickname = "Unknown";
			if (ConnUtils.SteamIdToPeer(steamId, out HC_PeerListEntry peer))
			{
				if (ConnUtils.IsHost(((ListDataEntry)peer)._dataID))
				{
					statusMessage = Texts.CannotModerateHosts();
					return false;
				}
				if (ConnUtils.HasOperatorRole(((ListDataEntry)peer)._dataID) && !ConnUtils.IsHost(callerConnectionId))
				{
					statusMessage = Texts.OperatorsCannotModerateOperators();
					return false;
				}
				target = Texts.ClientDetails(peer);
				characterNickname = peer._peerPlayer._nickname;
				HostConsole._current._cmdManager.Init_KickClient(HostConsole._current._peerListEntries.IndexOf(peer), ((ListDataEntry)peer)._dataID);
			}
			List<BannedClientParameter> bannedClientList = AtlyssNetworkManager._current._bannedClientList;
			for (int i = 0; i < bannedClientList.Count; i++)
			{
				if (bannedClientList[i]._steamID == steamId)
				{
					statusMessage = Texts.AlreadyBanned();
					return false;
				}
			}
			bannedClientList.Add(new BannedClientParameter
			{
				_address = "",
				_characterNickname = characterNickname,
				_steamID = steamId
			});
			string statusMessage2;
			bool flag = DemoteFromOperatorBySteamId(callerConnectionId, steamId, out statusMessage2);
			ProfileDataManager._current.Save_HostSettingsData();
			NotifyOperators(flag ? Texts.DemotedAndBannedUser(caller, target) : Texts.BannedUser(caller, target));
			statusMessage = "";
			return true;
		}

		public static bool UnbanUserByBanListIndex(int callerConnectionId, int banListIndex, out string statusMessage)
		{
			List<BannedClientParameter> bannedClientList = AtlyssNetworkManager._current._bannedClientList;
			if (0 > banListIndex || banListIndex >= bannedClientList.Count)
			{
				statusMessage = Texts.ExpectedListIndex();
				return false;
			}
			return UnbanUserBySteamId(callerConnectionId, bannedClientList[banListIndex]._steamID, out statusMessage);
		}

		public static bool UnbanUserBySteamId(int callerConnectionId, string steamId, out string statusMessage)
		{
			List<BannedClientParameter> bannedClientList = AtlyssNetworkManager._current._bannedClientList;
			BannedClientParameter val = null;
			for (int i = 0; i < bannedClientList.Count; i++)
			{
				if (bannedClientList[i]._steamID == steamId)
				{
					val = bannedClientList[i];
					bannedClientList.RemoveAt(i--);
				}
			}
			if (val != null)
			{
				string caller = ConnUtils.ConnectionIdToName(callerConnectionId);
				string target = Texts.BannedClientDetails(val);
				ProfileDataManager._current.Save_HostSettingsData();
				NotifyOperators(Texts.UnbannedUser(caller, target));
				statusMessage = "";
				return true;
			}
			statusMessage = Texts.NotBanned();
			return false;
		}

		public static bool WarnUserBySteamId(int callerConnectionId, string steamId, string message, out string statusMessage)
		{
			if (!ConnUtils.SteamIdToPeer(steamId, out HC_PeerListEntry peer))
			{
				statusMessage = Texts.SteamIdNotConnected();
				return false;
			}
			if (ConnUtils.IsHost(((ListDataEntry)peer)._dataID))
			{
				statusMessage = Texts.CannotModerateHosts();
				return false;
			}
			if (ConnUtils.HasOperatorRole(((ListDataEntry)peer)._dataID) && (!ConnUtils.ConnectionIdToPeer(callerConnectionId, out HC_PeerListEntry _) || !ConnUtils.IsHost(callerConnectionId)))
			{
				statusMessage = Texts.OperatorsCannotModerateOperators();
				return false;
			}
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			TrySendChatMessageToConnectionId(((ListDataEntry)peer)._dataID, Texts.NoticeText(Texts.YouHaveBeenWarned(ConnUtils.HasOperatorRole(((ListDataEntry)peer)._dataID))));
			TrySendChatMessageToConnectionId(((ListDataEntry)peer)._dataID, Texts.NoticeText(Texts.WarnReason(message)));
			string caller = ConnUtils.ConnectionIdToName(callerConnectionId);
			string target = ConnUtils.SteamIdToName(steamId);
			NotifyOperators(Texts.WarnedUser(caller, target), ((ListDataEntry)peer)._dataID);
			NotifyOperators(Texts.WarnReason(message), ((ListDataEntry)peer)._dataID);
			statusMessage = "";
			return true;
		}

		public static bool KickUserBySteamId(int callerConnectionId, string steamId, out string statusMessage)
		{
			if (!ConnUtils.SteamIdToPeer(steamId, out HC_PeerListEntry peer))
			{
				statusMessage = Texts.SteamIdNotConnected();
				return false;
			}
			if (ConnUtils.IsHost(((ListDataEntry)peer)._dataID))
			{
				statusMessage = Texts.CannotModerateHosts();
				return false;
			}
			if (ConnUtils.HasOperatorRole(((ListDataEntry)peer)._dataID) && !ConnUtils.IsHost(callerConnectionId))
			{
				statusMessage = Texts.OperatorsCannotModerateOperators();
				return false;
			}
			string caller = ConnUtils.ConnectionIdToName(callerConnectionId);
			string target = ConnUtils.SteamIdToName(steamId);
			HostConsole._current._cmdManager.Init_KickClient(HostConsole._current._peerListEntries.IndexOf(peer), ((ListDataEntry)peer)._dataID);
			NotifyOperators(Texts.KickedUser(caller, target));
			statusMessage = "";
			return true;
		}

		public static string? FindSteamIdBasedOnMatches(string[] matches, out string statusMessage)
		{
			int num = 0;
			HC_PeerListEntry val = null;
			bool flag = false;
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				string nickname = peerListEntries[i]._peerPlayer._nickname;
				int num2 = 0;
				for (int j = 0; j < matches.Length; j++)
				{
					if (nickname.Contains(matches[j], StringComparison.InvariantCultureIgnoreCase))
					{
						num2 += matches[j].Length;
					}
				}
				if (num2 > num)
				{
					num = num2;
					val = peerListEntries[i];
					flag = false;
				}
				else if (num2 == num)
				{
					flag = true;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				statusMessage = Texts.NoPlayerMatch();
				return null;
			}
			if (flag)
			{
				statusMessage = Texts.MultiplePlayerMatches();
				return null;
			}
			statusMessage = Texts.PlayerMatch(val);
			return val._peerPlayer._steamID;
		}

		public static bool TrySendChatMessageToSteamId(string steamId, string message)
		{
			if (ConnUtils.SteamIdToPeer(steamId, out HC_PeerListEntry peer))
			{
				peer._peerPlayer._chatBehaviour.Target_RecieveMessage(message);
				return true;
			}
			return false;
		}

		public static bool TrySendChatMessageToConnectionId(int connectionId, string message)
		{
			if (ConnUtils.ConnectionIdToPeer(connectionId, out HC_PeerListEntry peer))
			{
				peer._peerPlayer._chatBehaviour.Target_RecieveMessage(message);
				return true;
			}
			return false;
		}

		public static void NotifyOperators(string message, int operatorToExclude = -1)
		{
			List<HC_PeerListEntry> peerListEntries = HostConsole._current._peerListEntries;
			for (int i = 0; i < peerListEntries.Count; i++)
			{
				int dataID = ((ListDataEntry)peerListEntries[i])._dataID;
				if (ConnUtils.HasOperatorRole(dataID) && dataID != operatorToExclude)
				{
					TrySendChatMessageToConnectionId(dataID, Texts.NoticeText(message));
				}
			}
			HostConsole._current.New_LogMessage(Texts.NoticeText(message));
		}
	}
	public class OperatorDetails
	{
		[JsonProperty(PropertyName = "steamId")]
		public string SteamId { get; set; } = "";


		[JsonProperty(PropertyName = "characterNickname")]
		public string CharacterNickname { get; set; } = "";

	}
	public class HostModerationData
	{
		[JsonProperty(PropertyName = "steamIdOperators")]
		public List<OperatorDetails> SteamIdOperators { get; set; } = new List<OperatorDetails>();

	}
	internal static class Texts
	{
		private const string Mod = "[HM]";

		public static string CommandForbidden()
		{
			return "[HM] You are not allowed to use that command";
		}

		public static string ExpectedConnId()
		{
			return "[HM] Expected a connection ID.";
		}

		public static string ExpectedSteamID()
		{
			return "[HM] Expected a valid Steam ID.";
		}

		public static string ExpectedListIndex()
		{
			return "[HM] Expected a valid list index.";
		}

		public static string ExpectedNickname()
		{
			return "[HM] Expected a nickname to match.";
		}

		public static string ExpectedPageNumber()
		{
			return "[HM] Page parameter should be a valid number";
		}

		public static string ExpectedPageSize()
		{
			return "[HM] Page size should be a valid number";
		}

		public static string PageHeader(string subject, int page, int totalPages)
		{
			return string.Format("{0} {1} (page {2}/{3}):", "[HM]", subject, page, totalPages);
		}

		public static string PageEntry(int index, string entry)
		{
			return $" #{index} - {entry}";
		}

		public static string PageNoData()
		{
			return " - [No data available]";
		}

		public static string NoReasonSpecified()
		{
			return "[No reason specified]";
		}

		public static string OperatorDetails(OperatorDetails peer)
		{
			return peer.CharacterNickname + " [SteamID " + peer.SteamId + "]";
		}

		public static string BannedClientDetails(BannedClientParameter peer)
		{
			return peer._characterNickname + " [SteamID " + peer._steamID + "]";
		}

		public static string ClientDetails(HC_PeerListEntry peer)
		{
			int dataID = ((ListDataEntry)peer)._dataID;
			string network_nickname = peer._peerPlayer.Network_nickname;
			string steamID = peer._peerPlayer._steamID;
			return $"{network_nickname} [ConnID {dataID} SteamID {steamID}]";
		}

		public static string PromotedToOp()
		{
			return "[HM] You have been promoted to operator";
		}

		public static string DemotedFromOp()
		{
			return "[HM] You have been demoted from operator";
		}

		public static string PromotedTargetToOp()
		{
			return "[HM] Promoted client to operator.";
		}

		public static string DemotedTargetFromOp()
		{
			return "[HM] Demoted client from operator.";
		}

		public static string CannotPromoteDemoteHost()
		{
			return "[HM] Hosts are always operators and cannot be promoted or demoted.";
		}

		public static string CannotModerateHosts()
		{
			return "[HM] Hosts cannot be moderated.";
		}

		public static string OperatorsCannotModerateOperators()
		{
			return "[HM] Operators can only be moderated by the host";
		}

		public static string CannotPromoteBannedUsers()
		{
			return "[HM] Client is banned, unban them first before trying to promote them.";
		}

		public static string AlreadyBanned()
		{
			return "[HM] Client is already banned.";
		}

		public static string AlreadyAnOperator()
		{
			return "[HM] Client is already an operator.";
		}

		public static string NotBanned()
		{
			return "[HM] Client was not found in the ban list.";
		}

		public static string NotAnOperator()
		{
			return "[HM] Client is not an operator.";
		}

		public static string SteamIdNotConnected()
		{
			return "[HM] That steam user is not connected to the server.";
		}

		public static string InvalidCallerID()
		{
			return "[HM] Invalid caller connection ID. You should notify the mod developer about this.";
		}

		public static string YouHaveBeenWarned(bool warnedAnOperator)
		{
			return "[HM] You have been warned by " + (warnedAnOperator ? "the host" : "an operator");
		}

		public static string WarnReason(string message)
		{
			return " Warn reason: " + message;
		}

		public static string NoPlayerMatch()
		{
			return "[HM] No player match was found for the given query.";
		}

		public static string MultiplePlayerMatches()
		{
			return "[HM] Multiple similar player matches were found. Try using a more specific search query.";
		}

		public static string PlayerMatch(HC_PeerListEntry peer)
		{
			return "[HM] Best player match is " + ClientDetails(peer);
		}

		public static string DemotedAndBannedUser(string caller, string target)
		{
			return "[HM] " + target + " was demoted from operator and banned by " + caller + ".";
		}

		public static string BannedUser(string caller, string target)
		{
			return "[HM] " + target + " was banned by " + caller + ".";
		}

		public static string UnbannedUser(string caller, string target)
		{
			return "[HM] Client was unbanned.";
		}

		public static string WarnedUser(string caller, string target)
		{
			return "[HM] " + target + " was warned by " + caller;
		}

		public static string KickedUser(string caller, string target)
		{
			return "[HM] " + target + " was kicked by " + caller + ".";
		}

		public static string ErrorText(string message)
		{
			return "<color=red>" + message + "</color>";
		}

		public static string NoticeText(string message)
		{
			return "<color=yellow>" + message + "</color>";
		}

		public static string SuccessText(string message)
		{
			return "<color=green>" + message + "</color>";
		}

		public static string StatusText(bool success, string message)
		{
			return success ? SuccessText(message) : ErrorText(message);
		}
	}
	internal static class Utils
	{
		public static bool IsValidSteamId(string steamId)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			int result2;
			if (ulong.TryParse(steamId, out var result))
			{
				CSteamID val = new CSteamID(result);
				result2 = (((CSteamID)(ref val)).IsValid() ? 1 : 0);
			}
			else
			{
				result2 = 0;
			}
			return (byte)result2 != 0;
		}
	}
	internal static class ModInfo
	{
		public const string GUID = "Marioalexsan.HostModeration";

		public const string NAME = "HostModeration";

		public const string VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}