using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ChatCommandAPI.BuiltinCommands; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks.Data; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("baer1")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) baer1 2025")] [assembly: AssemblyDescription("A Lethal Company modding API for easy creation of Minecraft-style Chat Commands")] [assembly: AssemblyFileVersion("0.4.1.0")] [assembly: AssemblyInformationalVersion("0.4.1+45a5755de4e6f3759a230e50d7ca2bcaf508ef3b")] [assembly: AssemblyProduct("ChatCommandsAPI")] [assembly: AssemblyTitle("baer1.ChatCommandAPI")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/baerchen201/LethalChatCommands.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator { object IEnumerator.Current => _item; T IEnumerator.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => 1; T IReadOnlyList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection.Count => 1; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return EqualityComparer.Default.Equals(_item, item); } void ICollection.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { if (!EqualityComparer.Default.Equals(_item, item)) { return -1; } return 0; } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } 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; } } } namespace ChatCommandAPI { [BepInPlugin("baer1.ChatCommandAPI", "ChatCommandsAPI", "0.4.1")] public class ChatCommandAPI : BaseUnityPlugin { internal struct ConfirmationRequest { public string? action; public Action callback; } internal static ConfirmationRequest? confirmationRequest; internal static Dictionary confirmationRequests = new Dictionary(); internal static ulong? targetClientId; internal ConfigEntry builtInCommands; private List builtInServerCommandList; private List commandList; private ConfigEntry commandPrefix; private ConfigEntry enableServerMode; internal List serverCommandList; private ConfigEntry serverCommandPrefix; private ConfigEntry serverWelcomeMessage; public static ChatCommandAPI Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; internal static Harmony? Harmony { get; set; } public string CommandPrefix => commandPrefix.Value; public IReadOnlyList CommandList => commandList; public bool EnableServerMode => enableServerMode.Value; public string ServerCommandPrefix => serverCommandPrefix.Value; public IReadOnlyList ServerCommandList { get { if (!builtInCommands.Value) { return serverCommandList; } return builtInServerCommandList.Concat(serverCommandList).ToList(); } } public string? ServerWelcomeMessage { get { if (!Utility.IsNullOrWhiteSpace(serverWelcomeMessage.Value)) { return string.Format(serverWelcomeMessage.Value.Trim(), ServerCommandPrefix); } return null; } } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; commandPrefix = ((BaseUnityPlugin)this).Config.Bind("General", "CommandPrefix", "/", "Client Command Prefix"); enableServerMode = ((BaseUnityPlugin)this).Config.Bind("Server", "EnableServerMode", true, "Whether to enable server functionality (if you are host, anyone can use commands, even without the mods)"); serverCommandPrefix = ((BaseUnityPlugin)this).Config.Bind("Server", "ServerCommandPrefix", "!", "Sever Command Prefix"); builtInCommands = ((BaseUnityPlugin)this).Config.Bind("Server", "BuiltInCommands", true, "Enables 'status' and 'servermods' commands"); serverWelcomeMessage = ((BaseUnityPlugin)this).Config.Bind("Server", "ServerWelcomeMessage", "This server has available commands.\nType {0}help for more information", "A welcome message that is displayed to any player that joins (clear to disable). {0} is replaced with ServerCommandPrefix"); RegisterCommands(); Patch(); Logger.LogInfo((object)"ChatCommandsAPI v0.4.1 has loaded!"); static void Patch() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("baer1.ChatCommandAPI"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } } private void RegisterCommands() { commandList = new List(); new Help(); new Position(); new PlayerList(); new Confirm(); new Deny(); new ErrorCommand(); serverCommandList = new List(); builtInServerCommandList = new List(); new ServerHelp(); new ServerStatus(); new ServerMods(); new ServerConfirm(); new ServerDeny(); } public bool RegisterCommand(Command command) { Command command2 = command; if (commandList.Any((Command i) => i.GetType() == command2.GetType())) { return false; } commandList.Add(command2); return true; } public bool RegisterServerCommand(ServerCommand command) { ServerCommand command2 = command; if (serverCommandList.Any((ServerCommand i) => i.GetType() == command2.GetType())) { return false; } serverCommandList.Add(command2); return true; } public bool RegisterBuiltInServerCommand(ServerCommand command) { ServerCommand command2 = command; if (builtInServerCommandList.Any((ServerCommand i) => i.GetType() == command2.GetType())) { return false; } builtInServerCommandList.Add(command2); return true; } public bool IsCommand(string command) { return command.StartsWith(CommandPrefix); } public bool IsServerCommand(string command) { return command.StartsWith(ServerCommandPrefix); } public bool ParseCommand(string input, out string command, out string[] args, out Dictionary kwargs) { command = null; args = null; kwargs = null; Match match = new Regex("(?:" + Regex.Escape(CommandPrefix) + "|" + Regex.Escape(ServerCommandPrefix) + ")([a-z]+)(?: ([^ =\"]+|(?:\"[^\"]*?\")))*?(?: ([^ =\"]+=[^ \"]+|[^ =\"]+=\"[^\"]*?\"))*\\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline).Match(input); if (!match.Success) { return false; } command = match.Groups[1].Value; List list = new List(); foreach (Capture capture3 in match.Groups[2].Captures) { list.Add(capture3.Value.Replace("\"", "")); } Dictionary dictionary = new Dictionary(); foreach (Capture capture4 in match.Groups[3].Captures) { dictionary.Add(capture4.Value.Split('=')[0], capture4.Value.Split('=')[1].Replace("\"", "")); } args = list.ToArray(); kwargs = dictionary; return true; } public bool RunCommand(string command, string[] args, Dictionary kwargs, out string? error) { string command2 = command; Command[] array = CommandList.Where((Command i) => i.Commands.Select((string s) => s.ToLower()).Contains(command2.ToLower())).ToArray(); int num = array.Length; if (num <= 1) { if (num == 0) { error = "Command " + command2 + " not found"; return false; } } else { Logger.LogWarning((object)("Command " + command2 + " has multiple matches: " + GeneralExtensions.Join(array.Select((Command i) => i.Name + " (" + i.GetType().Assembly.FullName + ")"), (Func)null, ", "))); } try { return array[0].Invoke(args, kwargs, out error); } catch (Exception ex) { Logger.LogError((object)ex.ToString()); error = ex.ToString(); return false; } } public bool RunCommand(PlayerControllerB caller, string command, string[] args, Dictionary kwargs, out string? error) { string command2 = command; ServerCommand[] array = ServerCommandList.Where((ServerCommand i) => i.Commands.Select((string s) => s.ToLower()).Contains(command2.ToLower())).ToArray(); int num = array.Length; if (num <= 1) { if (num == 0) { error = "Command " + command2 + " not found"; return false; } } else { Logger.LogWarning((object)("Server command " + command2 + " has multiple matches: " + GeneralExtensions.Join(array.Select((ServerCommand i) => i.Name + " (" + i.GetType().Assembly.FullName + ")"), (Func)null, ", "))); } try { return array[0].Invoke(caller, args, kwargs, out error); } catch (Exception ex) { Logger.LogError((object)ex.ToString()); error = ex.ToString(); return false; } } public static void AskConfirm(string action, Action callback) { ConfirmationRequest value = default(ConfirmationRequest); value.action = action; value.callback = callback; confirmationRequest = value; } public static void AskConfirm(Action callback) { ConfirmationRequest value = default(ConfirmationRequest); value.callback = callback; confirmationRequest = value; } public static Task AskConfirmAsync(string action) { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); ConfirmationRequest value = default(ConfirmationRequest); value.action = action; value.callback = taskCompletionSource.SetResult; confirmationRequest = value; return taskCompletionSource.Task; } public static Task AskConfirmAsync() { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); ConfirmationRequest value = default(ConfirmationRequest); value.callback = taskCompletionSource.SetResult; confirmationRequest = value; return taskCompletionSource.Task; } public static void AskConfirm(PlayerControllerB caller, string action, Action callback) { confirmationRequests[caller.actualClientId] = new ConfirmationRequest { action = action, callback = callback }; } public static void AskConfirm(PlayerControllerB caller, Action callback) { confirmationRequests[caller.actualClientId] = new ConfirmationRequest { callback = callback }; } public static Task AskConfirmAsync(PlayerControllerB caller, string action) { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); confirmationRequests[caller.actualClientId] = new ConfirmationRequest { action = action, callback = taskCompletionSource.SetResult }; return taskCompletionSource.Task; } public static Task AskConfirmAsync(PlayerControllerB caller) { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); confirmationRequests[caller.actualClientId] = new ConfirmationRequest { callback = taskCompletionSource.SetResult }; return taskCompletionSource.Task; } private static void UpdateChat() { ((TMP_Text)HUDManager.Instance.chatText).text = string.Join("\n", HUDManager.Instance.ChatMessageHistory); HUDManager.Instance.PingHUDElement(HUDManager.Instance.Chat, 4f, 1f, 0.2f); } public static void Print(string text) { HUDManager.Instance.ChatMessageHistory.Add("" + text + ""); UpdateChat(); } public static void Print(string text, Color color) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) HUDManager.Instance.ChatMessageHistory.Add($"{text}"); UpdateChat(); } [Obsolete] public static void Print(string text, Tuple color) { HUDManager.Instance.ChatMessageHistory.Add($"{text}"); UpdateChat(); } public static void Print(string text, (byte, byte, byte) color) { HUDManager.Instance.ChatMessageHistory.Add($"{text}"); UpdateChat(); } public static void Print(string text, byte r, byte g, byte b) { HUDManager.Instance.ChatMessageHistory.Add($"{text}"); UpdateChat(); } public static void PrintWarning(string text) { HUDManager.Instance.ChatMessageHistory.Add("" + text + ""); UpdateChat(); } public static void PrintError(string text) { HUDManager.Instance.ChatMessageHistory.Add("" + text + ""); UpdateChat(); } public static void PrintCommandError(string? error) { PrintError("Error running command" + (Utility.IsNullOrWhiteSpace(error) ? "" : (": " + error + ""))); } public static void Print(PlayerControllerB caller, string text) { SendToPlayer("" + text + "", caller.actualClientId); } public static void Print(PlayerControllerB caller, string text, Color color) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) SendToPlayer($"{text}", caller.actualClientId); } [Obsolete] public static void Print(PlayerControllerB caller, string text, Tuple color) { SendToPlayer($"{text}", caller.actualClientId); } public static void Print(PlayerControllerB caller, string text, (byte, byte, byte) color) { SendToPlayer($"{text}", caller.actualClientId); } public static void Print(PlayerControllerB caller, string text, byte r, byte g, byte b) { SendToPlayer($"{text}", caller.actualClientId); } public static void PrintWarning(PlayerControllerB caller, string text) { SendToPlayer("" + text + "", caller.actualClientId); } public static void PrintError(PlayerControllerB caller, string text) { SendToPlayer("" + text + "", caller.actualClientId); } public static void PrintCommandError(PlayerControllerB caller, string? error) { PrintError(caller, "Error running command" + (Utility.IsNullOrWhiteSpace(error) ? "" : (": " + error + ""))); } private static void SendToPlayer(string text, ulong clientId) { targetClientId = clientId; HUDManager.Instance.AddTextMessageClientRpc(text); targetClientId = null; } } public abstract class Command { public virtual string Name => GetType().Name; public virtual string[] Commands => new string[1] { Name.ToLower() }; public virtual string? Description => null; public virtual string[]? Syntax => null; public virtual bool Hidden => false; protected Command() { ChatCommandAPI.Instance.RegisterCommand(this); } public abstract bool Invoke(string[] args, Dictionary kwargs, out string? error); } public abstract class ServerCommand { public virtual string Name => GetType().Name; public virtual string[] Commands => new string[1] { Name.ToLower() }; public virtual string? Description => null; public virtual string[]? Syntax => null; public virtual bool Hidden => false; protected ServerCommand() { ChatCommandAPI.Instance.RegisterServerCommand(this); } internal ServerCommand(bool builtIn = true) { if (builtIn) { ChatCommandAPI.Instance.RegisterBuiltInServerCommand(this); } else { ChatCommandAPI.Instance.RegisterServerCommand(this); } } public abstract bool Invoke(PlayerControllerB caller, string[] args, Dictionary kwargs, out string? error); } public abstract class ToggleCommand : Command { public virtual string? ToggleDescription => null; public sealed override string Description { get { if (ToggleDescription != null) { return ToggleDescription + " - " + ValueString; } return ValueString; } } public sealed override string[] Syntax => new string[2] { "", "{ on | off }" }; public virtual string EnabledString => "enabled"; public virtual string DisabledString => "disabled"; public virtual bool Value { get; set; } public virtual string ValueString { get { if (!Value) { return DisabledString; } return EnabledString; } } public virtual void PrintValue() { ChatCommandAPI.Print(Name + " " + ValueString); } public override bool Invoke(string[] args, Dictionary kwargs, out string error) { error = "Invalid argument"; if (args.Length == 0) { Value = !Value; } else { switch (args[0]) { case "on": case "enable": Value = true; break; case "off": case "disable": Value = false; break; default: return false; } } PrintValue(); return true; } } public static class Utils { public static bool IsPlayerControlled(PlayerControllerB? player) { if ((Object)(object)player != (Object)null && player != null && !player.disconnectedMidGame && !player.isTestingPlayer) { if (!player.isPlayerControlled) { return player.isPlayerDead; } return true; } return false; } public static PlayerControllerB? GetPlayer(string id, out string error, bool strict = false) { string id2 = id; id2 = id2.Trim(); error = "No player specified"; if (id2.Length == 0) { return null; } error = null; string text = id2.ToLower(); if ((text == "@s" || text == "@me") ? true : false) { return GameNetworkManager.Instance.localPlayerController; } uint result; PlayerControllerB[] array; switch (id2[0]) { case '#': if (uint.TryParse(id2.TrimStart('#'), out result) && result < StartOfRound.Instance.allPlayerScripts.Length && IsPlayerControlled(StartOfRound.Instance.allPlayerScripts[result])) { return StartOfRound.Instance.allPlayerScripts[result]; } error = "Invalid player id"; return null; case '@': array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && string.Equals(i.playerUsername, id2.TrimStart('@'), StringComparison.CurrentCultureIgnoreCase)).ToArray(); if (array.Length == 0 && !strict) { array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && i.playerUsername.ToLower().StartsWith(id2.ToLower().TrimStart('@'))).ToArray(); } break; default: if (uint.TryParse(id2, out result) && result < StartOfRound.Instance.allPlayerScripts.Length && IsPlayerControlled(StartOfRound.Instance.allPlayerScripts[result])) { return StartOfRound.Instance.allPlayerScripts[result]; } array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && string.Equals(i.playerUsername, id2, StringComparison.CurrentCultureIgnoreCase)).ToArray(); if (array.Length == 0 && !strict) { array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && i.playerUsername.ToLower().StartsWith(id2.ToLower())).ToArray(); } break; } if (array.Length > 1) { if (strict) { error = "Multiple players match"; return null; } ChatCommandAPI.PrintWarning("Multiple players match, selecting first..."); } if (array.Length != 0) { return array[0]; } error = "No player matches"; return null; } public static bool GetPlayer(string id, out PlayerControllerB player, out string error, bool strict = false) { player = GameNetworkManager.Instance.localPlayerController; PlayerControllerB player2 = GetPlayer(id, out error, strict); if ((Object)(object)player2 == (Object)null) { return false; } player = player2; return true; } public static Vector3? ParsePosition(Vector3 origin, Quaternion rotation, string x, string y, string z) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) x = x.Trim(); y = y.Trim(); z = z.Trim(); ChatCommandAPI.Logger.LogDebug((object)("x:" + x + " y:" + y + ", z:" + z)); if (!x.StartsWith("^") || !y.StartsWith("^") || !z.StartsWith("^")) { return ParsePosition(origin, x, y, z); } string text = x; x = text.Substring(1, text.Length - 1); text = y; y = text.Substring(1, text.Length - 1); text = z; z = text.Substring(1, text.Length - 1); if ((!float.TryParse(x, out var result) && x.Length > 0) || (!float.TryParse(y, out var result2) && y.Length > 0) || (!float.TryParse(z, out var result3) && z.Length > 0)) { return null; } return origin + rotation * Vector3.forward * result3 + rotation * Vector3.up * result2 + rotation * Vector3.right * result; } public static Vector3? ParsePosition(Vector3 origin, string x, string y, string z) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) x = x.Trim(); y = y.Trim(); z = z.Trim(); float result; if (x.StartsWith('~')) { string text = x; x = text.Substring(1, text.Length - 1); if (!float.TryParse(x, out result) && x.Length > 0) { return null; } result += origin.x; } else if (!float.TryParse(x, out result)) { return null; } float result2; if (y.StartsWith('~')) { string text = y; y = text.Substring(1, text.Length - 1); if (!float.TryParse(y, out result2) && y.Length > 0) { return null; } result2 += origin.y; } else if (!float.TryParse(y, out result2)) { return null; } float result3; if (z.StartsWith('~')) { string text = z; z = text.Substring(1, text.Length - 1); if (!float.TryParse(z, out result3) && z.Length > 0) { return null; } result3 += origin.z; } else if (!float.TryParse(z, out result3)) { return null; } return new Vector3(result, result2, result3); } public static Vector3? ParsePosition(string x, string y, string z) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) x = x.Trim(); y = y.Trim(); z = z.Trim(); if (!float.TryParse(x, out var result) || !float.TryParse(y, out var result2) || !float.TryParse(z, out var result3)) { return null; } return new Vector3(result, result2, result3); } public static bool ParsePosition(Vector3 origin, Quaternion rotation, string x, string y, string z, out Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) position = default(Vector3); Vector3? val = ParsePosition(origin, rotation, x, y, z); if (!val.HasValue) { return false; } position = val.Value; return true; } public static bool ParsePosition(Vector3 origin, string x, string y, string z, out Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); Vector3? val = ParsePosition(origin, x, y, z); if (!val.HasValue) { return false; } position = val.Value; return true; } public static bool ParsePosition(string x, string y, string z, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); Vector3? val = ParsePosition(x, y, z); if (!val.HasValue) { return false; } position = val.Value; return true; } public static Vector3? ParsePosition(Vector3 origin, Quaternion rotation, string input) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (ParseSingleCommaSeparatedPositionString(input, out string x, out string y, out string z)) { return ParsePosition(origin, rotation, x, y, z); } return null; } public static Vector3? ParsePosition(Vector3 origin, string input) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (ParseSingleCommaSeparatedPositionString(input, out string x, out string y, out string z)) { return ParsePosition(origin, x, y, z); } return null; } public static Vector3? ParsePosition(string input) { if (ParseSingleCommaSeparatedPositionString(input, out string x, out string y, out string z)) { return ParsePosition(x, y, z); } return null; } public static bool ParsePosition(Vector3 origin, Quaternion rotation, string input, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); if (ParseSingleCommaSeparatedPositionString(input, out string x, out string y, out string z)) { return ParsePosition(origin, rotation, x, y, z, out position); } return false; } public static bool ParsePosition(Vector3 origin, string input, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); if (ParseSingleCommaSeparatedPositionString(input, out string x, out string y, out string z)) { return ParsePosition(origin, x, y, z, out position); } return false; } public static bool ParsePosition(string input, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); if (ParseSingleCommaSeparatedPositionString(input, out string x, out string y, out string z)) { return ParsePosition(x, y, z, out position); } return false; } internal static bool ParseSingleCommaSeparatedPositionString(string input, out string x, out string y, out string z) { x = "0"; y = "0"; z = "0"; Match match = new Regex("^(?:([^,]+),){2}([^,]+)$", RegexOptions.Multiline).Match(input); if (!match.Success) { return false; } x = match.Groups[1].Captures[0].Value; y = match.Groups[1].Captures[1].Value; z = match.Groups[2].Captures[0].Value; return true; } [Obsolete] public static bool IsInsideFactory(Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Object.FindObjectsOfType().Any((OutOfBoundsTrigger i) => position.y < ((Component)i).gameObject.transform.position.y); } [Obsolete] public static PlayerControllerB? GetPlayer(string id, bool strict = false) { string id2 = id; id2 = id2.Trim(); string text = id2.ToLower(); if ((text == "@s" || text == "@me") ? true : false) { return GameNetworkManager.Instance.localPlayerController; } uint result; PlayerControllerB[] array; switch (id2[0]) { case '#': if (uint.TryParse(id2.TrimStart('#'), out result) && result < StartOfRound.Instance.allPlayerScripts.Length && IsPlayerControlled(StartOfRound.Instance.allPlayerScripts[result])) { return StartOfRound.Instance.allPlayerScripts[result]; } ChatCommandAPI.PrintError("Invalid player id"); return null; case '@': array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && string.Equals(i.playerUsername, id2.TrimStart('@'), StringComparison.CurrentCultureIgnoreCase)).ToArray(); if (array.Length == 0 && !strict) { array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && i.playerUsername.ToLower().StartsWith(id2.ToLower().TrimStart('@'))).ToArray(); } break; default: if (uint.TryParse(id2, out result) && result < StartOfRound.Instance.allPlayerScripts.Length && IsPlayerControlled(StartOfRound.Instance.allPlayerScripts[result])) { return StartOfRound.Instance.allPlayerScripts[result]; } array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && string.Equals(i.playerUsername, id2, StringComparison.CurrentCultureIgnoreCase)).ToArray(); if (array.Length == 0 && !strict) { array = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB i) => IsPlayerControlled(i) && i.playerUsername.ToLower().StartsWith(id2.ToLower())).ToArray(); } break; } if (array.Length > 1) { ChatCommandAPI.PrintWarning("Multiple players with this name exist, selecting first..."); } if (array.Length != 0) { return array[0]; } ChatCommandAPI.PrintError("No player with username found"); return null; } [Obsolete] public static bool GetPlayer(string id, out PlayerControllerB player, bool strict = false) { player = GameNetworkManager.Instance.localPlayerController; PlayerControllerB player2 = GetPlayer(id, strict); if ((Object)(object)player2 == (Object)null) { return false; } player = player2; return true; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "baer1.ChatCommandAPI"; public const string PLUGIN_NAME = "ChatCommandsAPI"; public const string PLUGIN_VERSION = "0.4.1"; } } namespace ChatCommandAPI.Patches { [HarmonyPatch(typeof(GameNetworkManager), "StartHost")] internal static class GameNetworkManager_StartHost { private static void Postfix() { ServerStatus.startTime = DateTime.Now; ChatCommandAPI.confirmationRequests.Clear(); } } [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageServerRpc")] internal static class HUDManager_AddPlayerChatMessageServerRpc { private static bool Prefix(ref HUDManager __instance, ref string chatMessage, ref int playerId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)((NetworkBehaviour)__instance).__rpc_exec_stage != 1 || (!((NetworkBehaviour)__instance).NetworkManager.IsServer && !((NetworkBehaviour)__instance).NetworkManager.IsHost) || Utility.IsNullOrWhiteSpace(chatMessage) || !ChatCommandAPI.Instance.IsServerCommand(chatMessage)) { return true; } ChatCommandAPI.Logger.LogInfo((object)$">> Parsing server command by player {playerId}: {chatMessage}"); PlayerControllerB val = null; if (playerId >= 0 && playerId < StartOfRound.Instance.allPlayerScripts.Length) { val = StartOfRound.Instance.allPlayerScripts[playerId]; } ChatCommandAPI.Logger.LogDebug((object)(" caller: " + (((Object)(object)val == (Object)null) ? "null" : val.playerUsername))); if ((Object)(object)val == (Object)null || !Utils.IsPlayerControlled(val)) { ChatCommandAPI.Logger.LogWarning((object)$"Server command sent by invalid player {playerId}: {chatMessage}"); return true; } if (ChatCommandAPI.Instance.ParseCommand(chatMessage, out string command, out string[] args, out Dictionary kwargs)) { StringBuilder stringBuilder = new StringBuilder("<< Parsed command: " + command + "(" + (((Object)(object)val == (Object)null) ? "null" : $"#{val.playerClientId} {val.playerUsername}") + ((args.Length != 0 || kwargs.Count > 0) ? ", " : "")); if (args.Length != 0) { stringBuilder.Append(GeneralExtensions.Join((IEnumerable)args, (Func)null, ", ")); if (kwargs.Count > 0) { stringBuilder.Append(", "); } } stringBuilder.Append(GeneralExtensions.Join(kwargs.Select((KeyValuePair kvp) => kvp.Key + ": " + kvp.Value), (Func)null, ", ")); ChatCommandAPI.Logger.LogInfo((object)(stringBuilder?.ToString() + ")")); if (!ChatCommandAPI.Instance.RunCommand(val, command, args, kwargs, out string error)) { ChatCommandAPI.Logger.LogWarning((object)(" Error running command: " + (error ?? "null"))); if ((Object)(object)val != (Object)null && error != null) { ChatCommandAPI.PrintCommandError(val, error); } } return false; } ChatCommandAPI.Logger.LogInfo((object)"<< Invalid command"); if ((Object)(object)val != (Object)null) { ChatCommandAPI.PrintError(val, "Invalid command"); } return false; } } [HarmonyPatch(typeof(HUDManager), "AddTextMessageClientRpc")] internal static class HUDManager_AddTextMessageClientRpc { private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(NetworkBehaviour), "__endSendClientRpc", (Type[])null, (Type[])null), (string)null) }).Advance(-1).Insert((CodeInstruction[])(object)new CodeInstruction[1] { CodeInstruction.Call(typeof(HUDManager_AddTextMessageClientRpc), "RedirectMessageToClient", (Type[])null, (Type[])null) }) .InstructionEnumeration(); } public static ClientRpcParams RedirectMessageToClient(ClientRpcParams clientRpcParams) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!ChatCommandAPI.targetClientId.HasValue) { return clientRpcParams; } ClientRpcParams result = default(ClientRpcParams); result.Send.TargetClientIds = new <>z__ReadOnlySingleElementList(ChatCommandAPI.targetClientId.Value); return result; } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] internal static class HUDManager_SubmitChat_performed { private static bool Prefix(ref HUDManager __instance, ref CallbackContext context) { string text = __instance.chatTextField.text; if (!((CallbackContext)(ref context)).performed || Utility.IsNullOrWhiteSpace(text) || !ChatCommandAPI.Instance.IsCommand(text)) { return true; } __instance.localPlayer.isTypingChat = false; __instance.chatTextField.text = ""; EventSystem.current.SetSelectedGameObject((GameObject)null); __instance.PingHUDElement(__instance.Chat, 2f, 1f, 0.2f); ((Behaviour)__instance.typingIndicator).enabled = false; ChatCommandAPI.Logger.LogInfo((object)(">> Parsing command: " + text)); if (ChatCommandAPI.Instance.ParseCommand(text, out string command, out string[] args, out Dictionary kwargs)) { StringBuilder stringBuilder = new StringBuilder("<< Parsed command: " + command + "("); if (args.Length != 0) { stringBuilder.Append(GeneralExtensions.Join((IEnumerable)args, (Func)null, ", ")); if (kwargs.Count > 0) { stringBuilder.Append(", "); } } stringBuilder.Append(GeneralExtensions.Join(kwargs.Select((KeyValuePair kvp) => kvp.Key + ": " + kvp.Value), (Func)null, ", ")); ChatCommandAPI.Logger.LogInfo((object)(stringBuilder?.ToString() + ")")); if (!ChatCommandAPI.Instance.RunCommand(command, args, kwargs, out string error)) { ChatCommandAPI.Logger.LogWarning((object)(" Error running command: " + (error ?? "null"))); if (error != null) { ChatCommandAPI.PrintCommandError(error); } } return false; } ChatCommandAPI.Logger.LogInfo((object)"<< Invalid command"); ChatCommandAPI.PrintError("Invalid command"); return false; } } [HarmonyPatch(typeof(StartOfRound), "SyncAlreadyHeldObjectsServerRpc")] internal static class StartOfRound_SyncAlreadyHeldObjectsServerRpc { private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(string) }, (Type[])null), (string)null) }).Insert((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldarg_1, (object)null), CodeInstruction.Call(typeof(StartOfRound_SyncAlreadyHeldObjectsServerRpc), "SendWelcomeMessage", (Type[])null, (Type[])null) }).InstructionEnumeration(); } internal static void SendWelcomeMessage(ulong clientId) { if (ChatCommandAPI.Instance.ServerWelcomeMessage != null && !Utility.IsNullOrWhiteSpace(ChatCommandAPI.Instance.ServerWelcomeMessage) && !ChatCommandAPI.Instance.serverCommandList.All((ServerCommand i) => i.Hidden)) { ChatCommandAPI.targetClientId = clientId; HUDManager.Instance.AddTextMessageClientRpc("" + ChatCommandAPI.Instance.ServerWelcomeMessage + ""); ChatCommandAPI.targetClientId = null; } } } } namespace ChatCommandAPI.BuiltinCommands { public class Confirm : Command { public override string[] Commands => new string[3] { Name.ToLower(), "c", "con" }; public override string Description { get { if (ChatCommandAPI.confirmationRequest.HasValue && ChatCommandAPI.confirmationRequest.Value.action != null) { return "Confirms " + ChatCommandAPI.confirmationRequest.Value.action; } return "Confirms an action"; } } public override bool Hidden => !ChatCommandAPI.confirmationRequest.HasValue; public override bool Invoke(string[] args, Dictionary kwargs, out string error) { error = "No action currently needs confirmation"; if (!ChatCommandAPI.confirmationRequest.HasValue) { return false; } ChatCommandAPI.confirmationRequest.Value.callback(obj: true); ChatCommandAPI.confirmationRequest = null; return true; } } public class Deny : Command { public override string[] Commands => new string[3] { Name.ToLower(), "d", "den" }; public override string Description { get { if (ChatCommandAPI.confirmationRequest.HasValue && ChatCommandAPI.confirmationRequest.Value.action != null) { return "Cancels " + ChatCommandAPI.confirmationRequest.Value.action; } return "Cancels an action"; } } public override bool Hidden => !ChatCommandAPI.confirmationRequest.HasValue; public override bool Invoke(string[] args, Dictionary kwargs, out string error) { error = "No action currently needs confirmation"; if (!ChatCommandAPI.confirmationRequest.HasValue) { return false; } ChatCommandAPI.confirmationRequest.Value.callback(obj: false); ChatCommandAPI.confirmationRequest = null; return true; } } public class ErrorCommand : Command { public override string Name => "Error"; public override string Description => "Raises a NullReferenceException, for testing"; public override bool Hidden => true; public override bool Invoke(string[] args, Dictionary kwargs, out string error) { error = null; return Func().EndsWith("a"); static string Func() { return null; } } } public class Position : Command { public override string[] Commands => new string[4] { "pos", "getpos", "showpos", Name }; public override string Description => "Shows the current position of [player] or yourself"; public override string[] Syntax => new string[1] { "[player]" }; public override bool Hidden => true; public override bool Invoke(string[] args, Dictionary kwargs, out string? error) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) error = null; PlayerControllerB player = GameNetworkManager.Instance.localPlayerController; if (args.Length != 0 && !Utils.GetPlayer(args[0], out player, out error)) { return false; } error = "This player is dead"; if (player.isPlayerDead) { return false; } string[] obj = new string[6] { "Position of player ", player.playerUsername, ":\n", null, null, null }; Vector3 position = ((Component)player).transform.position; obj[3] = ((object)(Vector3)(ref position)).ToString(); obj[4] = (((Object)(object)((Component)player).transform.parent != (Object)null) ? $"\nrelative to {((Object)((Component)player).transform.parent).name}:\n{((Component)player).transform.parent.InverseTransformPoint(((Component)player).transform.position)}" : ""); obj[5] = ""; ChatCommandAPI.Print(string.Concat(obj)); ChatCommandAPI.Logger.LogInfo((object)string.Format("Position of player {0}: {1}{2}", player.playerUsername, ((Component)player).transform.position, ((Object)(object)((Component)player).transform.parent != (Object)null) ? $" - ({((Object)((Component)player).transform.parent).name}){((Component)player).transform.parent.InverseTransformPoint(((Component)player).transform.position)}" : "")); return true; } } public class Help : Command { internal const string SEPARATOR = "===============\n"; public override bool Hidden => true; public override string Description => "Displays all available commands"; public override bool Invoke(string[] args, Dictionary kwargs, out string error) { error = "No commands have been registered yet"; if (ChatCommandAPI.Instance.CommandList == null || ChatCommandAPI.Instance.CommandList.Count((Command i) => !i.Hidden) == 0) { return false; } ChatCommandAPI.Print("===============\n" + string.Join("===============\n", ChatCommandAPI.Instance.CommandList.Where((Command i) => !i.Hidden).Select(delegate(Command i) { StringBuilder stringBuilder = new StringBuilder(i.Name + ((i.Description == null) ? "" : (" - " + i.Description)) + "\n"); string[] array = i.Syntax ?? new string[1]; foreach (string text in array) { stringBuilder.Append("" + ChatCommandAPI.Instance.CommandPrefix + i.Commands[0] + (Utility.IsNullOrWhiteSpace(text) ? "" : " ") + "" + text + "\n"); } return stringBuilder.ToString(); })) + "===============\n".Trim()); return true; } } public class PlayerList : Command { public override string[] Commands => new string[2] { "players", Name }; public override string Description => "Lists all active players"; public override bool Hidden => true; public override bool Invoke(string[] args, Dictionary kwargs, out string error) { error = "No players connected"; if (!StartOfRound.Instance.allPlayerScripts.Any(Utils.IsPlayerControlled)) { return false; } ChatCommandAPI.Print("" + string.Join('\n', from i in StartOfRound.Instance.allPlayerScripts.Where(Utils.IsPlayerControlled) select $"#{i.playerClientId}: {i.playerUsername}") + ""); return true; } } public class ServerConfirm : ServerCommand { public override string[] Commands => new string[3] { "Confirm".ToLower(), "c", "con" }; public override string Description { get { if (ChatCommandAPI.confirmationRequest.HasValue && ChatCommandAPI.confirmationRequest.Value.action != null) { return "Confirms " + ChatCommandAPI.confirmationRequest.Value.action; } return "Confirms an action"; } } public override bool Hidden => !ChatCommandAPI.confirmationRequest.HasValue; public ServerConfirm() : base(builtIn: true) { } public override bool Invoke(PlayerControllerB caller, string[] args, Dictionary kwargs, out string? error) { error = "No action currently needs confirmation"; if (!ChatCommandAPI.confirmationRequests.TryGetValue(caller.actualClientId, out var value)) { return false; } value.callback(obj: true); ChatCommandAPI.confirmationRequests.Remove(caller.actualClientId); return true; } } public class ServerDeny : ServerCommand { public override string[] Commands => new string[3] { "Deny".ToLower(), "d", "den" }; public override string Description { get { if (ChatCommandAPI.confirmationRequest.HasValue && ChatCommandAPI.confirmationRequest.Value.action != null) { return "Cancels " + ChatCommandAPI.confirmationRequest.Value.action; } return "Cancels an action"; } } public override bool Hidden => !ChatCommandAPI.confirmationRequest.HasValue; public ServerDeny() : base(builtIn: true) { } public override bool Invoke(PlayerControllerB caller, string[] args, Dictionary kwargs, out string? error) { error = "No action currently needs confirmation"; if (!ChatCommandAPI.confirmationRequests.TryGetValue(caller.actualClientId, out var value)) { return false; } value.callback(obj: false); ChatCommandAPI.confirmationRequests.Remove(caller.actualClientId); return true; } } public class ServerHelp : ServerCommand { public override string Name => "Help"; public override bool Hidden => true; public override string Description => "Displays all available commands on the server"; public override bool Invoke(PlayerControllerB caller, string[] args, Dictionary kwargs, out string? error) { error = "This server has no available commands"; if (ChatCommandAPI.Instance.ServerCommandList == null || ChatCommandAPI.Instance.ServerCommandList.Count((ServerCommand i) => !i.Hidden) == 0) { return false; } ChatCommandAPI.Print(caller, "===============\n" + string.Join("===============\n", ChatCommandAPI.Instance.ServerCommandList.Where((ServerCommand i) => !i.Hidden).Select(delegate(ServerCommand i) { StringBuilder stringBuilder = new StringBuilder(i.Name + ((i.Description == null) ? "" : (" - " + i.Description)) + "\n"); string[] array = i.Syntax ?? new string[1]; foreach (string text in array) { stringBuilder.Append("" + ChatCommandAPI.Instance.ServerCommandPrefix + i.Commands[0] + (Utility.IsNullOrWhiteSpace(text) ? "" : " ") + "" + text + "\n"); } return stringBuilder.ToString(); })) + "===============\n".Trim()); return true; } } public class ServerMods : ServerCommand { public override string Name => "ServerMods"; public override string Description => "Shows a list of all mods installed on the server"; public ServerMods() : base(builtIn: true) { } public override bool Invoke(PlayerControllerB caller, string[] args, Dictionary kwargs, out string? error) { error = null; ChatCommandAPI.Print(caller, $"Mods ({Chainloader.PluginInfos.Count}):\n" + GeneralExtensions.Join((IEnumerable)Chainloader.PluginInfos.Select((KeyValuePair i) => $"{i.Key} ({i.Value.Metadata.Version})").OrderBy((string s) => s, StringComparer.CurrentCultureIgnoreCase), (Func)null, "\n")); return true; } } public class ServerStatus : ServerCommand { internal static DateTime startTime = new DateTime(0L); public override string Name => "Status"; public override string Description => "Displays information about this server"; public ServerStatus() : base(builtIn: true) { } public override bool Invoke(PlayerControllerB caller, string[] args, Dictionary kwargs, out string? error) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) error = null; StringBuilder stringBuilder = new StringBuilder("Current game: "); Lobby? currentLobby = GameNetworkManager.Instance.currentLobby; object obj; if (currentLobby.HasValue) { Lobby value = currentLobby.Value; obj = ((Lobby)(ref value)).GetData("name"); } else { obj = "unknown"; } stringBuilder.Append((string?)obj + "\n"); stringBuilder.Append("Players:\n"); PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (Utils.IsPlayerControlled(val)) { stringBuilder.Append(val.isPlayerDead ? "" : ""); stringBuilder.Append($" #{val.playerClientId} {val.playerUsername}"); if (val.isHostPlayerObject) { stringBuilder.Append(" (HOST)"); } stringBuilder.Append(val.isPlayerDead ? "\n" : "\n"); } } if (startTime.Ticks > 0) { TimeSpan timeSpan = DateTime.Now - startTime; stringBuilder.Append($"\nGame time: {(int)timeSpan.TotalHours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}"); } ChatCommandAPI.Print(caller, stringBuilder.ToString()); return true; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }