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)
{
}
}
}