using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using OutwardChatCommandsManager.Commands;
using OutwardChatCommandsManager.Events;
using OutwardChatCommandsManager.Managers;
using OutwardChatCommandsManager.Utility;
using OutwardChatCommandsManager.Utility.Data;
using OutwardChatCommandsManager.Utility.Data.Executors;
using OutwardChatCommandsManager.Utility.Data.Interfaces;
using OutwardChatCommandsManager.Utility.Data.Serialization;
using OutwardChatCommandsManager.Utility.Enums;
using OutwardChatCommandsManager.Utility.Helpers;
using OutwardModsCommunicator.EventBus;
using OutwardModsCommunicator.Managers;
using SideLoader;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OutwardChatCommandsManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OutwardChatCommandsManager")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace OutwardChatCommandsManager
{
[BepInPlugin("gymmed.chat_commands_manager", "Chat Commands Manager", "0.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class OCCM : BaseUnityPlugin
{
[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
public class ResourcesPrefabManager_Load
{
private static void Postfix(ResourcesPrefabManager __instance)
{
foreach (KeyValuePair<ManagerChatCommands, ChatCommand> command in ManagerChatCommandsHelper.Commands)
{
ChatCommandsManager.Instance.AddChatCommand(command.Value);
}
}
}
public const string GUID = "gymmed.chat_commands_manager";
public const string NAME = "Chat Commands Manager";
public const string VERSION = "0.0.1";
public static string prefix = "[Chat-Commands-Manager]";
public const string EVENTS_LISTENER_GUID = "gymmed.chat_commands_manager_*";
public const string COMMAND_KEY = "Execute last/locked command";
internal static ManualLogSource Log;
public static ConfigEntry<int> HistorySize;
internal void Awake()
{
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
LogMessage("Hello world from Chat Commands Manager 0.0.1!");
HistorySize = ((BaseUnityPlugin)this).Config.Bind<int>("Commands History", "HistorySize", 10, "How many previously typed commands should be kept in history?");
HistorySize.SettingChanged += delegate
{
ChatCommandsManager.History.MaxSize = HistorySize.Value;
};
int length = Enum.GetValues(typeof(HotkeySlots)).Length;
for (int i = 0; i < length; i++)
{
CustomKeybindings.AddAction("Execute last/locked command " + (i + 1), (KeybindingsCategory)0, (ControlType)2, (InputType)1);
}
new Harmony("gymmed.chat_commands_manager").PatchAll();
EventBusRegister.RegisterEvents();
EventBusSubscriber.AddSubscribers();
SL.OnSceneLoaded += delegate
{
Character firstLocalCharacter = CharacterManager.Instance.GetFirstLocalCharacter();
if ((Object)(object)firstLocalCharacter != (Object)null)
{
ChatCommandsSerializer.Instance.LoadManagerState(firstLocalCharacter);
}
Character secondLocalCharacter = CharacterManager.Instance.GetSecondLocalCharacter();
if ((Object)(object)secondLocalCharacter != (Object)null)
{
ChatCommandsSerializer.Instance.LoadManagerState(secondLocalCharacter);
}
};
}
internal void Update()
{
int length = Enum.GetValues(typeof(HotkeySlots)).Length;
int num = 0;
for (int i = 0; i < length; i++)
{
if (!HotkeySlotsHelper.TryGet((HotkeySlots)i, out var invocation))
{
num++;
}
if (!CustomKeybindings.GetKeyDown("Execute last/locked command " + (i + 1)))
{
continue;
}
if (invocation != null)
{
invocation.TriggerFunction();
continue;
}
IReadOnlyList<ChatCommandInvocation> items = ChatCommandsManager.History.Items;
int num2 = items.Count();
if (num2 > num)
{
ChatCommandInvocation chatCommandInvocation = items[num2 - num];
if (chatCommandInvocation != null)
{
chatCommandInvocation.TriggerFunction();
continue;
}
}
CharacterHelpers.BroadCastChatMessageToLocalCharacters($"Could not retrieve command for {i + 1} hotkey.", ChatLogStatus.Warning);
}
}
public static void LogMessage(string message)
{
Log.LogMessage((object)(prefix + " " + message));
}
public static void LogSL(string message)
{
SL.Log(prefix + " " + message);
}
public static string GetProjectLocation()
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
}
}
namespace OutwardChatCommandsManager.Utility
{
internal class ChatPanelHistoryState
{
public int HistoryIndex = -1;
public string CachedLiveInput;
}
}
namespace OutwardChatCommandsManager.Utility.Helpers
{
public static class CharacterHelpers
{
public static void BroadCastChatMessageToLocalCharacters(string message, ChatLogStatus status = ChatLogStatus.Info)
{
Character firstLocalCharacter = CharacterManager.Instance.GetFirstLocalCharacter();
object obj;
if (firstLocalCharacter == null)
{
obj = null;
}
else
{
CharacterUI characterUI = firstLocalCharacter.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
if ((Object)obj != (Object)null)
{
ChatHelpers.SendChatLog(firstLocalCharacter.CharacterUI.ChatPanel, message, status);
}
Character secondLocalCharacter = CharacterManager.Instance.GetSecondLocalCharacter();
object obj2;
if (secondLocalCharacter == null)
{
obj2 = null;
}
else
{
CharacterUI characterUI2 = secondLocalCharacter.CharacterUI;
obj2 = ((characterUI2 != null) ? characterUI2.ChatPanel : null);
}
if ((Object)obj2 != (Object)null)
{
ChatHelpers.SendChatLog(secondLocalCharacter.CharacterUI.ChatPanel, message, status);
}
}
}
public static class ChatHelpers
{
public static void SendChatLog(ChatPanel panel, string message, ChatLogStatus status = ChatLogStatus.Info)
{
panel.ChatMessageReceived("System", ChatLogStatusHelper.GetChatLogText(message, status));
}
public static void LogAllCommandsToChat(Character character)
{
object panel;
if (character == null)
{
panel = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
panel = ((characterUI != null) ? characterUI.ChatPanel : null);
}
SendChatLog((ChatPanel)panel, "Providing a list of all registered commands by Chat Commands Manager Mod:", ChatLogStatus.Warning);
ChatLogAllChatCommands(character);
}
public static void ChatLogAllChatCommands(Character character)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
ChatPanel panel = (ChatPanel)obj;
foreach (KeyValuePair<OriginalChatCommands, OriginalChatCommand> command in OriginalChatCommandsHelper.Commands)
{
SendChatLog(panel, command.Value.Name, ChatLogStatus.Success);
}
foreach (KeyValuePair<string, ChatCommand> chatCommand in ChatCommandsManager.ChatCommands)
{
SendChatLog(panel, chatCommand.Value.Name, ChatLogStatus.Success);
}
SendChatLog(panel, $"Total {OriginalChatCommandsHelper.Commands.Count() + ChatCommandsManager.ChatCommands.Count()} commands. {OriginalChatCommandsHelper.Commands.Count()} original commands. {ChatCommandsManager.ChatCommands.Count()} added commands.");
SendChatLog(panel, "For more info use:\"/help\"");
}
public static void ShowCommandsHistory(Character character, Dictionary<string, string> arguments)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
ChatPanel val = (ChatPanel)obj;
if ((Object)(object)val == (Object)null)
{
OCCM.LogMessage("ChatHelpers@ShowCommandsHistory Tried to log chat command to missing chatPanel.");
return;
}
SendChatLog(val, "History of chat commands invocations:");
arguments.TryGetValue("detailed", out var value);
if (!string.IsNullOrWhiteSpace(value))
{
foreach (ChatCommandInvocation item in ChatCommandsManager.History.Items)
{
SendChatLog(val, "");
ChatLogChatCommand(val, item.Command);
ChatLogChatCommandArguments(val, item.Arguments);
}
return;
}
string text = null;
foreach (ChatCommandInvocation item2 in ChatCommandsManager.History.Items)
{
text = item2.Command?.Name;
if (string.IsNullOrEmpty(text))
{
text = "null";
}
SendChatLog(val, text, ChatLogStatus.Success);
}
}
public static void LockKey(Character character, Dictionary<string, string> arguments)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
ChatPanel val = (ChatPanel)obj;
if ((Object)(object)val == (Object)null)
{
OCCM.LogMessage("ChatHelpers@ChatLogChatCommand Tried to log chat command to missing chatPanel.");
return;
}
arguments.TryGetValue("index", out var value);
if (string.IsNullOrWhiteSpace(value))
{
value = "1";
}
string value2;
ChatCommandInvocation invocation;
if (!int.TryParse(value, out var result))
{
int num = 1;
int length = Enum.GetValues(typeof(HotkeySlots)).Length;
SendChatLog(val, $"Error: \"Provided incorrect {value} lock key index. Can use from {num} to {length}. " + "Ex.: \"/lockKey 1\"\"", ChatLogStatus.Error);
}
else if (!arguments.TryGetValue("show", out value2) || string.IsNullOrWhiteSpace(value2))
{
IReadOnlyList<ChatCommandInvocation> items = ChatCommandsManager.History.Items;
int num2 = items.Count();
if (num2 < 2)
{
SendChatLog(val, "No previous command to lock to key.", ChatLogStatus.Warning);
return;
}
ChatCommandInvocation chatCommandInvocation = items[num2 - 2];
HotkeySlotsHelper.Lock((HotkeySlots)(result - 1), chatCommandInvocation);
SendChatLog(val, $"Successfully assigned lock key {result} to {chatCommandInvocation.Command?.Name}.", ChatLogStatus.Success);
}
else if (!string.Equals(value2, "show", StringComparison.OrdinalIgnoreCase))
{
SendChatLog(val, "Provided argument \"" + value2 + "\" is incorrect! It can only be \"show\" or left empty.", ChatLogStatus.Error);
}
else if (!HotkeySlotsHelper.TryGet((HotkeySlots)(result - 1), out invocation))
{
SendChatLog(val, "Your slot key " + value + " doesn't have assigned chat command.", ChatLogStatus.Warning);
}
else
{
SendChatLog(val, $"Lock key {result} was assigned to {invocation.Command.Name} chat command with arguments:");
ChatLogChatCommandArguments(val, invocation.Arguments);
}
}
public static void ReleaseKey(Character character, Dictionary<string, string> arguments)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
ChatPanel val = (ChatPanel)obj;
if ((Object)(object)val == (Object)null)
{
OCCM.LogMessage("ChatHelpers@ChatLogChatCommand Tried to log chat command to missing chatPanel.");
return;
}
arguments.TryGetValue("index", out var value);
if (string.IsNullOrWhiteSpace(value))
{
value = "1";
}
if (!int.TryParse(value, out var result))
{
int num = 1;
int length = Enum.GetValues(typeof(HotkeySlots)).Length;
SendChatLog(val, $"Error: \"Provided incorrect {result} lock key index. Can use from {num} to {length}. " + "Ex.: \"/lockKey 1\"\"", ChatLogStatus.Error);
return;
}
HotkeySlots slot = (HotkeySlots)(result - 1);
if (!HotkeySlotsHelper.TryGet(slot, out var invocation))
{
SendChatLog(val, "Your slot key " + value + " doesn't have assigned chat command.", ChatLogStatus.Warning);
return;
}
HotkeySlotsHelper.Release(slot);
SendChatLog(val, $"Lock key {result} was released from {invocation.Command.Name} chat command with arguments:", ChatLogStatus.Success);
ChatLogChatCommandArguments(val, invocation.Arguments);
}
public static void ChatLogChatCommand(Character character, Dictionary<string, string> arguments)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
ChatPanel val = (ChatPanel)obj;
if ((Object)(object)val == (Object)null)
{
OCCM.LogMessage("ChatHelpers@ChatLogChatCommand Tried to log chat command to missing chatPanel.");
return;
}
arguments.TryGetValue("command", out var value);
if (string.IsNullOrWhiteSpace(value))
{
if (!ChatCommandsManager.ChatCommands.TryGetValue("help", out var value2))
{
SendChatLog(val, "help command not found!", ChatLogStatus.Error);
return;
}
SendChatLog(val, "Help command triggered!");
ChatLogChatCommand(val, value2);
return;
}
SendChatLog(val, "Help command triggered!");
if (!ChatCommandsManager.ChatCommands.TryGetValue(value, out var value3))
{
if (!OriginalChatCommandsHelper.CommandsByName.TryGetValue(value, out var value4))
{
SendChatLog(val, value + " command not found! Are you sure it exist? Type:\"/commands\"", ChatLogStatus.Error);
}
else
{
ChatLogChatCommand(val, value4);
}
}
else
{
ChatLogChatCommand(val, value3);
}
}
public static void ChatLogChatCommand(ChatPanel panel, IChatCommand chatCommand)
{
if ((Object)(object)panel == (Object)null)
{
OCCM.LogMessage("ChatHelpers@ChatLogChatCommand Tried to log chat command to missing chatPanel.");
return;
}
SendChatLog(panel, "Command Name: " + chatCommand.Name, ChatLogStatus.Success);
SendChatLog(panel, "Command Description: " + chatCommand.Description, ChatLogStatus.Success);
SendChatLog(panel, "Command Parameters: ", ChatLogStatus.Success);
ChatLogChatCommandParameters(panel, chatCommand);
SendChatLog(panel, $"Command Is Cheat: {chatCommand.IsCheat}", ChatLogStatus.Success);
SendChatLog(panel, $"Command Require Debug Mode: {chatCommand.RequireDebugMode}", ChatLogStatus.Success);
}
public static void ChatLogChatCommandParameters(ChatPanel panel, IChatCommand chatCommand)
{
foreach (KeyValuePair<string, (string, string)> parameter in chatCommand.Parameters)
{
string text = (string.IsNullOrEmpty(parameter.Value.Item2) ? "null" : parameter.Value.Item2);
SendChatLog(panel, "-parameter name: " + parameter.Key + " => default value: " + text + "\n-description: " + parameter.Value.Item1, ChatLogStatus.Success);
}
}
public static void ChatLogChatCommandArguments(ChatPanel panel, Dictionary<string, string> arguments)
{
string text = "";
foreach (KeyValuePair<string, string> argument in arguments)
{
text = ((!string.IsNullOrWhiteSpace(argument.Value)) ? ("-parameter name: " + argument.Key + " => argument value: " + argument.Value) : ("-parameter name: " + argument.Key));
SendChatLog(panel, text, ChatLogStatus.Success);
}
}
public static ChatPanel GetChatPanel(Character character)
{
if (character == null)
{
return null;
}
CharacterUI characterUI = character.CharacterUI;
if (characterUI == null)
{
return null;
}
return characterUI.ChatPanel;
}
public static bool TryGetValidCommand(string message, out IChatCommand command)
{
command = null;
if (message.StartsWith("/"))
{
MessageCommand messageCommand = new MessageCommand(message);
string key = messageCommand.Command.Substring(1);
IChatCommand chatCommand = null;
if (!ChatCommandsManager.ChatCommands.TryGetValue(key, out var value))
{
if (!OriginalChatCommandsHelper.CommandsByName.TryGetValue(key, out var value2))
{
return false;
}
chatCommand = value2;
}
else
{
chatCommand = value;
}
if (chatCommand.RequireDebugMode && !Global.CheatsEnabled)
{
return false;
}
if (messageCommand.Arguments.Count > chatCommand.Parameters.Count)
{
OCCM.LogMessage("Command " + chatCommand.Name + " retrieved too many arguments from user.");
return false;
}
command = chatCommand;
return true;
}
return false;
}
public static bool HasValidCommand(string message)
{
if (message.StartsWith("/"))
{
MessageCommand messageCommand = new MessageCommand(message);
if (!ChatCommandsManager.ChatCommands.TryGetValue(messageCommand.Command.Substring(1), out var value))
{
return false;
}
if (messageCommand.Arguments.Count > value.Parameters.Count)
{
OCCM.LogMessage("Command " + value.Name + " retrieved too many arguments from user.");
return false;
}
return true;
}
return false;
}
public static List<string> Tokenize(string input)
{
List<string> list = new List<string>();
StringBuilder stringBuilder = new StringBuilder();
bool flag = false;
char c = '\0';
bool flag2 = false;
foreach (char c2 in input)
{
if (flag2)
{
stringBuilder.Append(c2);
flag2 = false;
}
else if (c2 == '\\')
{
flag2 = true;
}
else if (flag)
{
if (c2 == c)
{
flag = false;
}
else
{
stringBuilder.Append(c2);
}
}
else if (c2 == '"' || c2 == '\'')
{
flag = true;
c = c2;
}
else if (char.IsWhiteSpace(c2))
{
if (stringBuilder.Length > 0)
{
list.Add(stringBuilder.ToString());
stringBuilder.Clear();
}
}
else
{
stringBuilder.Append(c2);
}
}
if (stringBuilder.Length > 0)
{
list.Add(stringBuilder.ToString());
}
return list;
}
public static Dictionary<string, string> GetArgumentsForCommand(string message, IChatCommand command)
{
return GetArguments(GetArgumentsFromMessage(message), command.Parameters);
}
public static List<string> GetArgumentsFromMessage(string message)
{
return Tokenize(message).Skip(1).ToList();
}
public static Dictionary<string, string> GetArguments(List<string> arguments, Dictionary<string, (string description, string defaultValue)> parameters)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
List<string> list = new List<string>(arguments);
Dictionary<string, (string, string)> dictionary2 = new Dictionary<string, (string, string)>(parameters);
for (int num = list.Count - 1; num >= 0; num--)
{
string text = list[num];
if (text.StartsWith("--") && text.Contains("="))
{
int num2 = text.IndexOf('=');
string key = text.Substring(2, num2 - 2);
string value = text.Substring(num2 + 1);
dictionary[key] = value;
list.RemoveAt(num);
dictionary2.Remove(key);
}
}
int num3 = 0;
foreach (KeyValuePair<string, (string, string)> item in dictionary2)
{
string key2 = item.Key;
if (num3 < list.Count)
{
dictionary[key2] = list[num3];
}
else
{
dictionary[key2] = item.Value.Item2;
}
num3++;
}
return dictionary;
}
}
}
namespace OutwardChatCommandsManager.Utility.Enums
{
public enum ChatLogStatus
{
Info,
Success,
Warning,
Error
}
public static class ChatLogStatusHelper
{
public static string GetChatLogText(string message, ChatLogStatus status = ChatLogStatus.Info)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
return status switch
{
ChatLogStatus.Success => Global.SetTextColor(message, Global.LIGHT_GREEN),
ChatLogStatus.Warning => Global.SetTextColor(message, Global.LIGHT_ORANGE),
ChatLogStatus.Error => "<color=#" + UnityEngineExtensions.ToHex(Global.LIGHT_RED) + ">" + message + "</color>",
_ => message,
};
}
}
public enum CommandExecutors
{
OriginalCommand,
ChatCommand
}
public static class CommandExecutorsHelper
{
public static Dictionary<CommandExecutors, ICommandExecutor> Executors(Character character)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
CharacterUI characterUI = character.CharacterUI;
obj = ((characterUI != null) ? characterUI.ChatPanel : null);
}
if ((Object)obj == (Object)null)
{
OCCM.LogMessage("CommandExecutorsHelper@Executors Chracter panel is missing!");
return null;
}
return new Dictionary<CommandExecutors, ICommandExecutor>
{
{
CommandExecutors.OriginalCommand,
new GameChatForwardExecutor(character.CharacterUI.ChatPanel)
},
{
CommandExecutors.ChatCommand,
new ManagedCommandExecutor()
}
};
}
public static ICommandExecutor GetCommandExecutor(CommandExecutors executor, Character character)
{
Dictionary<CommandExecutors, ICommandExecutor> dictionary = Executors(character);
if (dictionary == null)
{
return new ManagedCommandExecutor();
}
return dictionary[executor];
}
}
public enum EventRegistryParams
{
CommandName,
CommandParameters,
CommandAction,
IsCheatCommand,
CommandDescription,
CommandRequiresDebugMode
}
public static class EventRegistryParamsHelper
{
private static readonly Dictionary<EventRegistryParams, (string key, Type type, string description)> _registry = new Dictionary<EventRegistryParams, (string, Type, string)>
{
[EventRegistryParams.CommandName] = ("command", typeof(string), "Required. The text players type in chat (e.g. \"/command\") to trigger your handler."),
[EventRegistryParams.CommandParameters] = ("parameters", typeof(Dictionary<string, (string, string)>), "Optional. Parameters with name and (description, default value) provided as dictionary."),
[EventRegistryParams.CommandAction] = ("function", typeof(Action<Character, Dictionary<string, string>>), "Required. The method to execute when the command is triggered. Character is the command caller and Dictionary stores parameter and argument(value)."),
[EventRegistryParams.IsCheatCommand] = ("isCheatCommand", typeof(bool), "Optional. Default false. Determines if player game will be saved after triggering your command."),
[EventRegistryParams.CommandDescription] = ("description", typeof(string), "Optional. Default null. Provides description of command for users."),
[EventRegistryParams.CommandRequiresDebugMode] = ("debugMode", typeof(bool), "Optional. Default false. Determines if command requires debug mode to work.")
};
public static (string key, Type type, string description) Get(EventRegistryParams param)
{
return _registry[param];
}
public static (string key, Type type, string description)[] Combine(params object[] items)
{
List<(string, Type, string)> list = new List<(string, Type, string)>();
foreach (object obj in items)
{
if (obj is (string, Type, string) item)
{
list.Add(item);
continue;
}
if (obj is (string, Type, string)[] collection)
{
list.AddRange(collection);
continue;
}
throw new ArgumentException("Unsupported item type: " + obj?.GetType().FullName);
}
return list.ToArray();
}
}
public enum HotkeySlots
{
Slot1,
Slot2,
Slot3
}
public static class HotkeySlotsHelper
{
private static readonly Dictionary<HotkeySlots, ChatCommandInvocation> _locked = new Dictionary<HotkeySlots, ChatCommandInvocation>();
public static Dictionary<HotkeySlots, ChatCommandInvocation> Locked => _locked;
public static void Lock(HotkeySlots slot, ChatCommandInvocation invocation)
{
_locked[slot] = invocation;
}
public static void Release(HotkeySlots slot)
{
_locked.Remove(slot);
}
public static bool TryGet(HotkeySlots slot, out ChatCommandInvocation invocation)
{
return _locked.TryGetValue(slot, out invocation);
}
}
public enum ManagerChatCommands
{
Help,
Commands,
LockKey,
ReleaseKey,
ShowCommandsHistory
}
public static class ManagerChatCommandsHelper
{
public static readonly Dictionary<ManagerChatCommands, ChatCommand> Commands = new Dictionary<ManagerChatCommands, ChatCommand>
{
{
ManagerChatCommands.Help,
new ChatCommand("help", new Dictionary<string, (string, string)> {
{
"command",
("name of command like \"toggleDebug\".", "")
} }, "Provides details about command. Ex.:\"/help toggleDebug\".", isCheat: false, delegate(Character character, Dictionary<string, string> parameters)
{
ChatHelpers.ChatLogChatCommand(character, parameters);
})
},
{
ManagerChatCommands.Commands,
new ChatCommand("commands", new Dictionary<string, (string, string)>(), "Provides details about command. Ex.:\"/help toggleDebug\".", isCheat: false, delegate(Character character, Dictionary<string, string> parameters)
{
ChatHelpers.LogAllCommandsToChat(character);
})
},
{
ManagerChatCommands.LockKey,
new ChatCommand("lockKey", new Dictionary<string, (string, string)>
{
{
"index",
("Required. Key number example \"1\".", "1")
},
{
"show",
("Optional. Shows which command is already locked instead of locking it. Ex.:\".lockKey 1 show\".", "")
}
}, "Locks last command with arguments to provided Chat Commands Manager key. Ex.:\"/lockKey 1\".", isCheat: false, delegate(Character character, Dictionary<string, string> parameters)
{
ChatHelpers.LockKey(character, parameters);
})
},
{
ManagerChatCommands.ReleaseKey,
new ChatCommand("releaseKey", new Dictionary<string, (string, string)> {
{
"index",
("Required. Key number example \"1\".", "1")
} }, "Releases command from provided Chat Commands Manager key. Ex.:\"/releaseKey 1\".", isCheat: false, delegate(Character character, Dictionary<string, string> parameters)
{
ChatHelpers.ReleaseKey(character, parameters);
})
},
{
ManagerChatCommands.ShowCommandsHistory,
new ChatCommand("history", new Dictionary<string, (string, string)> {
{
"detailed",
("Optional. Provides commands with arguments used example \"/history detailed\".", "")
} }, "Show used commands history. Ex.:\"/history\".", isCheat: false, delegate(Character character, Dictionary<string, string> parameters)
{
ChatHelpers.ShowCommandsHistory(character, parameters);
})
}
};
}
public enum OriginalChatCommands
{
ToggleDebug,
Teleport,
Defeat,
Weather
}
public static class OriginalChatCommandsHelper
{
public static readonly Dictionary<OriginalChatCommands, OriginalChatCommand> Commands = new Dictionary<OriginalChatCommands, OriginalChatCommand>
{
{
OriginalChatCommands.ToggleDebug,
new OriginalChatCommand("toggleDebug", new Dictionary<string, (string, string)> {
{
"status",
("Enable or disable debug mode. Can be provided as on or off, everything else is ignored.", null)
} }, "Turns on Debug mode. Ex.:\"/toggleDebug on\"", isCheat: true, requireDebugMode: false)
},
{
OriginalChatCommands.Teleport,
new OriginalChatCommand("tp", new Dictionary<string, (string, string)> {
{
"position",
("Teleport position.", null)
} }, "Tries to teleport player to provided position. Ex.:\"/tp 12.5,0,-4\"", isCheat: true, requireDebugMode: true)
},
{
OriginalChatCommands.Defeat,
new OriginalChatCommand("defeat", new Dictionary<string, (string, string)>
{
{
"subcommand",
("One of: \nlist - provides list of deafeats | \nforce - forces defeat scenario | \nclear - restores normal defeat behaviour.", null)
},
{
"id",
("Defeat ID (required for 'force')", "")
}
}, "Defeat scenario managing command. Ex.:\"/defeat list\"", isCheat: true, requireDebugMode: true)
},
{
OriginalChatCommands.Weather,
new OriginalChatCommand("weather", new Dictionary<string, (string, string)>
{
{
"id",
("Weather ID index(0..n)", "0")
},
{
"instant",
("If true, apply change immediately (true/false)", "true")
}
}, "Checks/sets the weather. Ex.:\"/weather 1 true\"", isCheat: true, requireDebugMode: true)
}
};
public static readonly Dictionary<string, OriginalChatCommand> CommandsByName = Commands.Values.ToDictionary<OriginalChatCommand, string, OriginalChatCommand>((OriginalChatCommand c) => c.Name, (OriginalChatCommand c) => c, StringComparer.InvariantCultureIgnoreCase);
}
}
namespace OutwardChatCommandsManager.Utility.Data
{
public class ChatCommandHistory
{
private int _maxSize;
private readonly List<ChatCommandInvocation> _items = new List<ChatCommandInvocation>();
public IReadOnlyList<ChatCommandInvocation> Items => _items;
public int MaxSize
{
get
{
return _maxSize;
}
set
{
_maxSize = value;
}
}
public ChatCommandHistory(int maxSize = 10)
{
MaxSize = maxSize;
}
public ChatCommandHistory()
{
MaxSize = OCCM.HistorySize.Value;
}
public ChatCommandHistory(List<ChatCommandInvocation> oldHistory)
{
MaxSize = OCCM.HistorySize.Value;
_items = new List<ChatCommandInvocation>(oldHistory);
}
public void Add(ChatCommandInvocation invocation)
{
if (_items.Count >= MaxSize)
{
_items.RemoveAt(0);
}
_items.Add(invocation);
}
public ChatCommandInvocation GetFirst()
{
if (_items.Count <= 0)
{
return null;
}
return _items.First();
}
public ChatCommandInvocation GetLast()
{
if (_items.Count <= 0)
{
return null;
}
return _items.Last();
}
public ChatCommandInvocation ElementAt(int index)
{
if (_items.Count <= index || index <= -1)
{
return null;
}
return _items.ElementAt(index);
}
public int FindPreviousUnique(int start)
{
if (start < 1 || start > Items.Count - 1)
{
return -1;
}
if (start <= 0 || start >= Items.Count)
{
return start;
}
string message = Items[start].Message;
for (int num = start - 1; num >= 0; num--)
{
if (Items[num].Message != message)
{
return num;
}
}
return start;
}
}
public class ChatCommandInvocation
{
private Character _character;
private IChatCommand _command;
private Dictionary<string, string> _arguments;
private string _message;
private ICommandExecutor executor;
public Character Character
{
get
{
return _character;
}
set
{
_character = value;
}
}
public IChatCommand Command
{
get
{
return _command;
}
set
{
_command = value;
}
}
public Dictionary<string, string> Arguments
{
get
{
return _arguments;
}
set
{
_arguments = value;
}
}
public string Message
{
get
{
return _message;
}
set
{
_message = value;
}
}
public ICommandExecutor Executor
{
get
{
return executor;
}
set
{
executor = value;
}
}
public ChatCommandInvocation(Character character, IChatCommand command, Dictionary<string, string> arguments, ICommandExecutor executor, string message = null)
{
Character = character;
Command = command;
Arguments = arguments;
Message = message;
Executor = executor;
}
public ChatCommandInvocation(Character character, IChatCommand command, ICommandExecutor executor, string message = null)
{
Character = character;
Command = command;
Message = message;
Arguments = ChatHelpers.GetArgumentsForCommand(message, command);
Executor = executor;
}
public void TriggerFunction()
{
if (Command == null)
{
OCCM.LogMessage("ChatCommandInvocation@TriggerFunction doesn't have a command to trigger!");
return;
}
if ((Object)(object)Character == (Object)null)
{
OCCM.LogMessage("ChatCommandInvocation@TriggerFunction doesn't have a character triggering command!");
return;
}
if (Arguments == null)
{
OCCM.LogMessage("ChatCommandInvocation@TriggerFunction doesn't have provided arguments to trigger command!");
return;
}
ChatCommandsManager.History.Add(this);
Executor.Execute(this);
}
}
internal class ChatForwardExecutor
{
}
}
namespace OutwardChatCommandsManager.Utility.Data.Serialization
{
public class ArgumentData
{
[XmlElement("Parameter")]
[DefaultValue("")]
public string Parameter { get; set; } = "";
[XmlElement("Argument")]
[DefaultValue("")]
public string Argument { get; set; } = "";
}
public class ChatCommandData
{
[XmlElement("Name")]
[DefaultValue("")]
public string Name { get; set; } = "";
}
public class ChatCommandInvocationData
{
[XmlElement("CharacterUID")]
[DefaultValue(null)]
public UID CharacterUID { get; set; } = UID.op_Implicit((string)null);
[XmlElement("Command")]
[DefaultValue(null)]
public ChatCommandData Command { get; set; }
[XmlArray("Arguments")]
[XmlArrayItem("Argument")]
[DefaultValue(null)]
public List<ArgumentData> Arguments { get; set; }
[XmlElement("Message")]
[DefaultValue(null)]
public string Message { get; set; }
[XmlElement("Executor")]
[DefaultValue(null)]
public string ExecutorName { get; set; }
[XmlIgnore]
public CommandExecutors? Executor
{
get
{
if (!string.IsNullOrWhiteSpace(ExecutorName))
{
if (!Enum.TryParse<CommandExecutors>(ExecutorName, out var result))
{
return null;
}
return result;
}
return null;
}
}
}
public class ChatCommandsManagerState
{
public List<ChatCommandInvocation> History;
public Dictionary<HotkeySlots, ChatCommandInvocation> LockedHotKeys;
public ChatCommandsManagerState(List<ChatCommandInvocation> history = null, Dictionary<HotkeySlots, ChatCommandInvocation> lockedHotKeys = null)
{
History = history;
LockedHotKeys = lockedHotKeys;
}
public ChatCommandsManagerState(IReadOnlyList<ChatCommandInvocation> history = null, Dictionary<HotkeySlots, ChatCommandInvocation> lockedHotKeys = null)
{
History = history.ToList();
LockedHotKeys = lockedHotKeys;
}
public ChatCommandsManagerState()
{
History = null;
LockedHotKeys = null;
}
}
[XmlRoot("ChatCommandsManager")]
public class ChatCommandsManagerStateFile
{
[XmlArray("History")]
[XmlArrayItem("ChatCommandInvocation")]
[DefaultValue(null)]
public List<ChatCommandInvocationData> History { get; set; }
[XmlArray("HotkeyBindings")]
[XmlArrayItem("Hotkey")]
[DefaultValue(null)]
public List<HotkeyBindingData> HotkeyBindings { get; set; }
}
public class HotkeyBindingData
{
[XmlElement("Slot")]
[DefaultValue(null)]
public string SlotName { get; set; } = "";
[XmlElement("Invocation")]
[DefaultValue(null)]
public ChatCommandInvocationData Invocation { get; set; }
[XmlIgnore]
public HotkeySlots? Slot
{
get
{
if (!string.IsNullOrWhiteSpace(SlotName))
{
if (!Enum.TryParse<HotkeySlots>(SlotName, out var result))
{
return null;
}
return result;
}
return null;
}
}
}
public class ParameterDefinitionData
{
[XmlElement("Name")]
[DefaultValue("")]
public string Name { get; set; } = "";
[XmlElement("Description")]
[DefaultValue("")]
public string Description { get; set; } = "";
[XmlElement("Default")]
[DefaultValue("")]
public string DefaultValue { get; set; } = "";
}
}
namespace OutwardChatCommandsManager.Utility.Data.Interfaces
{
public interface IChatCommand
{
string Name { get; set; }
Dictionary<string, (string, string)> Parameters { get; set; }
string Description { get; set; }
bool IsCheat { get; set; }
bool RequireDebugMode { get; set; }
void TriggerFunction(Character character, Dictionary<string, string> Arguments);
}
public interface ICommandExecutor
{
CommandExecutors ExecutorType { get; }
void Execute(ChatCommandInvocation invocation);
}
}
namespace OutwardChatCommandsManager.Utility.Data.Executors
{
public static class ChatExecutionGuard
{
[ThreadStatic]
public static bool IsForwarding;
}
public sealed class GameChatForwardExecutor : ICommandExecutor
{
private readonly ChatPanel _panel;
public CommandExecutors ExecutorType => CommandExecutors.OriginalCommand;
public GameChatForwardExecutor(ChatPanel panel)
{
_panel = panel;
}
public void Execute(ChatCommandInvocation invocation)
{
ChatExecutionGuard.IsForwarding = true;
try
{
_panel.m_chatEntry.text = invocation.Message;
_panel.SendChatMessage();
}
finally
{
ChatExecutionGuard.IsForwarding = false;
}
}
}
public sealed class ManagedCommandExecutor : ICommandExecutor
{
public CommandExecutors ExecutorType => CommandExecutors.ChatCommand;
public void Execute(ChatCommandInvocation invocation)
{
invocation.Command.TriggerFunction(invocation.Character, invocation.Arguments);
}
}
}
namespace OutwardChatCommandsManager.Patches
{
[HarmonyPatch(typeof(ChatPanel), "SendChatMessage")]
public static class Patch_ChatPanel_SendChatMessage
{
private static bool Prefix(ChatPanel __instance)
{
if (ChatExecutionGuard.IsForwarding)
{
return true;
}
if (!ChatHelpers.TryGetValidCommand(__instance.m_chatEntry.text, out var command))
{
return true;
}
if (command is OriginalChatCommand)
{
new ChatCommandInvocation(((UIElement)__instance).LocalCharacter, command, new GameChatForwardExecutor(__instance), __instance.m_chatEntry.text).TriggerFunction();
return true;
}
new ChatCommandInvocation(((UIElement)__instance).LocalCharacter, command, new ManagedCommandExecutor(), __instance.m_chatEntry.text).TriggerFunction();
return false;
}
private static void Postfix(ChatPanel __instance)
{
if (!((Object)(object)__instance?.m_chatEntry == (Object)null))
{
__instance.m_chatEntry.text = "";
if (!__instance.m_chatEntry.isFocused)
{
__instance.m_chatEntry.ActivateInputField();
}
}
}
}
[HarmonyPatch(typeof(ChatPanel), "Update")]
public static class Patch_ChatPanel_Update
{
private static readonly ConditionalWeakTable<ChatPanel, ChatPanelHistoryState> _state = new ConditionalWeakTable<ChatPanel, ChatPanelHistoryState>();
private static void Postfix(ChatPanel __instance)
{
if (!((Object)(object)__instance.m_chatEntry == (Object)null) && __instance.m_chatEntry.isFocused)
{
ChatPanelHistoryState orCreateValue = _state.GetOrCreateValue(__instance);
InputField chatEntry = __instance.m_chatEntry;
if (Input.GetKeyDown((KeyCode)273))
{
HandleArrowUp(chatEntry, orCreateValue);
}
else if (Input.GetKeyDown((KeyCode)274))
{
HandleArrowDown(chatEntry, orCreateValue);
}
else if (Input.anyKeyDown && !Input.GetKeyDown((KeyCode)13))
{
ExitHistoryMode(orCreateValue);
}
}
}
private static void PlayErrorSound()
{
Global.AudioManager.PlaySound((Sounds)10055, 0f, 1f, 1f, 1f, 1f);
}
private static void HandleArrowUp(InputField input, ChatPanelHistoryState state)
{
IReadOnlyList<ChatCommandInvocation> items = ChatCommandsManager.History.Items;
if (items.Count == 0)
{
PlayErrorSound();
return;
}
if (state.HistoryIndex == -1)
{
state.CachedLiveInput = input.text;
state.HistoryIndex = items.Count - 1;
}
else
{
int num = ChatCommandsManager.History.FindPreviousUnique(state.HistoryIndex);
if (num == state.HistoryIndex)
{
PlayErrorSound();
return;
}
state.HistoryIndex = num;
}
input.text = items[state.HistoryIndex].Message;
input.caretPosition = input.text.Length;
}
private static void HandleArrowDown(InputField input, ChatPanelHistoryState state)
{
if (state.HistoryIndex == -1)
{
PlayErrorSound();
return;
}
IReadOnlyList<ChatCommandInvocation> items = ChatCommandsManager.History.Items;
int historyIndex = state.HistoryIndex;
string message = items[historyIndex].Message;
for (int i = historyIndex + 1; i < items.Count; i++)
{
if (items[i].Message != message)
{
state.HistoryIndex = i;
input.text = items[i].Message;
input.caretPosition = input.text.Length;
return;
}
}
input.text = state.CachedLiveInput ?? "";
ExitHistoryMode(state);
input.caretPosition = input.text.Length;
PlayErrorSound();
}
private static void ExitHistoryMode(ChatPanelHistoryState state)
{
state.HistoryIndex = -1;
state.CachedLiveInput = null;
}
}
[HarmonyPatch(typeof(WorldSave), "PrepareSave")]
public class Patch_WorldSave_PrepareSave
{
private static bool Prefix()
{
foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
{
ChatCommandsSerializer.Instance.AutomaticSaveManagerToXml(item.ControlledCharacter);
}
if (ChatCommandsManager.HasUsedCheat)
{
return false;
}
return true;
}
}
}
namespace OutwardChatCommandsManager.Managers
{
public class ChatCommandsManager
{
private static ChatCommandsManager _instance;
private static Dictionary<string, ChatCommand> _chatCommands = new Dictionary<string, ChatCommand>();
private static bool _hasUsedCheat = false;
private static ChatCommandHistory _history = new ChatCommandHistory();
public static ChatCommandsManager Instance
{
get
{
if (_instance == null)
{
_instance = new ChatCommandsManager();
}
return _instance;
}
}
public static Dictionary<string, ChatCommand> ChatCommands
{
get
{
return _chatCommands;
}
set
{
_chatCommands = value;
}
}
public static bool HasUsedCheat
{
get
{
return _hasUsedCheat;
}
set
{
_hasUsedCheat = value;
}
}
public static ChatCommandHistory History
{
get
{
return _history;
}
set
{
_history = value;
}
}
private ChatCommandsManager()
{
}
public void RestoreHistory(List<ChatCommandInvocation> oldHistory)
{
History = new ChatCommandHistory(oldHistory);
}
public void AddChatCommand(ChatCommand chatCommand)
{
if (string.IsNullOrEmpty(chatCommand.Name))
{
OCCM.LogMessage("ChatCommandManager@AddChatCommand Tried to create empty chat command!");
return;
}
if (ChatCommands.ContainsKey(chatCommand.Name))
{
OCCM.LogMessage("ChatCommandManager@AddChatCommand Command already exist with name " + chatCommand.Name + "!");
return;
}
ChatCommands.Add(chatCommand.Name, chatCommand);
EventBusPublisher.SendAddedCommand(chatCommand);
}
public void RemoveChatCommand(string name)
{
ChatCommand value;
if (string.IsNullOrEmpty(name))
{
OCCM.LogMessage("ChatCommandManager@RemoveChatCommand Tried to remove empty chat command!");
}
else if (ChatCommands.TryGetValue(name, out value))
{
ChatCommands.Remove(name);
EventBusPublisher.SendRemovedCommand(value);
}
}
}
public class ChatCommandsSerializer
{
private static ChatCommandsSerializer _instance;
private string _configPath = "";
public static ChatCommandsSerializer Instance
{
get
{
if (_instance == null)
{
_instance = new ChatCommandsSerializer();
}
return _instance;
}
}
public string ConfigPath
{
get
{
return _configPath;
}
set
{
_configPath = value;
}
}
private ChatCommandsSerializer()
{
ConfigPath = Path.Combine(PathsManager.ConfigPath, "Chat_Commands_Manager");
}
public string GetCharacterXmlFilePath(Character character)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: 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)
if (character != null)
{
_ = character.UID;
if (0 == 0)
{
string configPath = ConfigPath;
UID uID = character.UID;
return Path.Combine(configPath, ((UID)(ref uID)).Value, "ChatCommandsManagerState.xml");
}
}
OCCM.LogMessage("ChatCommandsSerializer@GetCharacterXmlFilePath Provided null character!");
return Path.Combine(ConfigPath, "ChatCommandsManagerState.xml");
}
public ChatCommandsManagerStateFile Load(string path)
{
try
{
if (!File.Exists(path))
{
OCCM.LogMessage("Chat Commands Manager file not found at: " + path);
return null;
}
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ChatCommandsManagerStateFile));
using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
return xmlSerializer.Deserialize(stream) as ChatCommandsManagerStateFile;
}
catch (Exception ex)
{
OCCM.LogSL("Failed to load Chat Commands Manager file at '" + path + "': " + ex.Message);
return null;
}
}
public void LoadManagerState(Character character)
{
string characterXmlFilePath = GetCharacterXmlFilePath(character);
if (File.Exists(characterXmlFilePath))
{
LoadManagerState(characterXmlFilePath);
}
}
public void LoadManagerState(string path)
{
try
{
if (!File.Exists(path))
{
OCCM.LogSL("ChatCommandsSerializer@LoadManagerState file not found at: " + path);
return;
}
ChatCommandsManagerStateFile chatCommandsManagerStateFile = Load(path);
if (chatCommandsManagerStateFile == null)
{
return;
}
ChatCommandsManagerState managerState = GetManagerState(chatCommandsManagerStateFile);
ChatCommandsManager.Instance.RestoreHistory(managerState.History);
int length = Enum.GetValues(typeof(HotkeySlots)).Length;
int num = 0;
while (num < managerState.LockedHotKeys.Count && length > num)
{
HotkeySlots hotkeySlots = (HotkeySlots)num;
if (managerState.LockedHotKeys.TryGetValue(hotkeySlots, out var _))
{
HotkeySlotsHelper.Lock(hotkeySlots, managerState.LockedHotKeys[hotkeySlots]);
}
num++;
num++;
}
}
catch (Exception ex)
{
OCCM.LogMessage("ChatCommandsSerializer@LoadManagerState failed loading '" + path + "': " + ex.Message);
}
}
public ChatCommandsManagerState GetChatManagerState()
{
return new ChatCommandsManagerState(ChatCommandsManager.History.Items, HotkeySlotsHelper.Locked);
}
public void AutomaticSaveManagerToXml(Character character)
{
SaveManagerStateToXml(GetCharacterXmlFilePath(character), GetChatManagerState());
}
public void SaveManagerStateToXml(string filePath, ChatCommandsManagerState state)
{
try
{
string directoryName = Path.GetDirectoryName(filePath);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
ChatCommandsManagerStateFile o = BuildManagerStateFile(state);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ChatCommandsManagerStateFile));
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
NewLineOnAttributes = false
};
using XmlWriter xmlWriter = XmlWriter.Create(filePath, settings);
xmlSerializer.Serialize(xmlWriter, o);
}
catch (Exception ex)
{
OCCM.LogMessage("ChatCommandsSerializer@SaveManagerStateToXml failed saving '" + filePath + "': " + ex.Message);
}
}
public ChatCommandsManagerState GetManagerState(ChatCommandsManagerStateFile file)
{
ChatCommandsManagerState chatCommandsManagerState = new ChatCommandsManagerState();
List<ChatCommandInvocation> list = new List<ChatCommandInvocation>();
Dictionary<HotkeySlots, ChatCommandInvocation> dictionary = new Dictionary<HotkeySlots, ChatCommandInvocation>();
foreach (ChatCommandInvocationData item in file.History)
{
if (GetInvocationFromData(item, out var invocation))
{
list.Add(invocation);
}
}
foreach (HotkeyBindingData hotkeyBinding in file.HotkeyBindings)
{
if (GetInvocationFromData(hotkeyBinding.Invocation, out var invocation2) && hotkeyBinding.Slot.HasValue)
{
dictionary.Add(hotkeyBinding.Slot.Value, invocation2);
}
}
chatCommandsManagerState.History = list;
chatCommandsManagerState.LockedHotKeys = dictionary;
return chatCommandsManagerState;
}
public bool GetInvocationFromData(ChatCommandInvocationData invocationData, out ChatCommandInvocation invocation)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
invocation = null;
ChatCommandData command = invocationData.Command;
if (!ChatCommandsManager.ChatCommands.TryGetValue(command.Name, out var value))
{
OCCM.LogMessage("ChatCommandsSerializer@GetManagerState command " + command.Name + " not found!");
return false;
}
Character character = CharacterManager.Instance.GetCharacter(UID.op_Implicit(invocationData.CharacterUID));
if ((Object)(object)character == (Object)null)
{
OCCM.LogMessage("ChatCommandsSerializer@GetManagerState character not found!");
return false;
}
ICommandExecutor commandExecutor = null;
invocation = new ChatCommandInvocation(executor: (!invocationData.Executor.HasValue) ? new ManagedCommandExecutor() : CommandExecutorsHelper.GetCommandExecutor(invocationData.Executor.Value, character), character: character, command: value, arguments: GetArgumentsFromInvocationData(invocationData.Arguments), message: invocationData.Message);
return true;
}
public Dictionary<string, string> GetArgumentsFromInvocationData(List<ArgumentData> argumentsData)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (ArgumentData argumentsDatum in argumentsData)
{
dictionary.Add(argumentsDatum.Parameter, argumentsDatum.Argument);
}
return dictionary;
}
public ChatCommandsManagerStateFile BuildManagerStateFile(ChatCommandsManagerState state)
{
ChatCommandsManagerStateFile chatCommandsManagerStateFile = new ChatCommandsManagerStateFile
{
History = new List<ChatCommandInvocationData>(),
HotkeyBindings = new List<HotkeyBindingData>()
};
foreach (ChatCommandInvocation item2 in state.History)
{
chatCommandsManagerStateFile.History.Add(GetInvocationData(item2));
}
foreach (KeyValuePair<HotkeySlots, ChatCommandInvocation> lockedHotKey in state.LockedHotKeys)
{
HotkeyBindingData item = new HotkeyBindingData
{
SlotName = (lockedHotKey.Key.ToString() ?? ""),
Invocation = GetInvocationData(lockedHotKey.Value)
};
chatCommandsManagerStateFile.HotkeyBindings.Add(item);
}
return chatCommandsManagerStateFile;
}
public ChatCommandInvocationData GetInvocationData(ChatCommandInvocation invocation)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
IChatCommand command = invocation.Command;
ChatCommandData command2 = new ChatCommandData
{
Name = command.Name
};
ChatCommandInvocationData chatCommandInvocationData = new ChatCommandInvocationData
{
CharacterUID = invocation.Character.UID,
Command = command2,
Arguments = new List<ArgumentData>(),
ExecutorName = invocation.Executor.ExecutorType.ToString(),
Message = invocation.Message
};
foreach (KeyValuePair<string, string> argument in invocation.Arguments)
{
ArgumentData item = new ArgumentData
{
Parameter = argument.Key,
Argument = argument.Value
};
chatCommandInvocationData.Arguments.Add(item);
}
return chatCommandInvocationData;
}
}
}
namespace OutwardChatCommandsManager.Events
{
public static class EventBusPublisher
{
public const string Event_AddedCommand = "ChatCommandsManager@AddChatCommand_After";
public const string Event_RemovedCommand = "ChatCommandsManager@RemoveChatCommand_After";
public static void SendAddedCommand(ChatCommand chatCommand)
{
//IL_001a: 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)
//IL_0038: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00c6: Expected O, but got Unknown
OCCM.LogMessage("Added " + chatCommand.Name + " command!");
EventPayload val = new EventPayload { };
string item;
((Dictionary<string, object>)val)[item] = chatCommand.Name;
string item2 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandDescription).key;
((Dictionary<string, object>)val)[item2] = chatCommand.Description;
string item3 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandParameters).key;
((Dictionary<string, object>)val)[item3] = chatCommand.Parameters;
string item4 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandAction).key;
((Dictionary<string, object>)val)[item4] = chatCommand.Function;
string item5 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandRequiresDebugMode).key;
((Dictionary<string, object>)val)[item5] = chatCommand.RequireDebugMode;
string item6 = EventRegistryParamsHelper.Get(EventRegistryParams.IsCheatCommand).key;
((Dictionary<string, object>)val)[item6] = chatCommand.IsCheat;
EventPayload val2 = val;
EventBus.Publish("gymmed.chat_commands_manager", "ChatCommandsManager@AddChatCommand_After", val2);
}
public static void SendRemovedCommand(ChatCommand chatCommand)
{
//IL_001a: 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)
//IL_0038: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00c6: Expected O, but got Unknown
OCCM.LogMessage("Removed " + chatCommand.Name + " command!");
EventPayload val = new EventPayload { };
string item;
((Dictionary<string, object>)val)[item] = chatCommand.Name;
string item2 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandDescription).key;
((Dictionary<string, object>)val)[item2] = chatCommand.Description;
string item3 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandParameters).key;
((Dictionary<string, object>)val)[item3] = chatCommand.Parameters;
string item4 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandAction).key;
((Dictionary<string, object>)val)[item4] = chatCommand.Function;
string item5 = EventRegistryParamsHelper.Get(EventRegistryParams.CommandRequiresDebugMode).key;
((Dictionary<string, object>)val)[item5] = chatCommand.RequireDebugMode;
string item6 = EventRegistryParamsHelper.Get(EventRegistryParams.IsCheatCommand).key;
((Dictionary<string, object>)val)[item6] = chatCommand.IsCheat;
EventPayload val2 = val;
EventBus.Publish("gymmed.chat_commands_manager", "ChatCommandsManager@RemoveChatCommand_After", val2);
}
}
public static class EventBusRegister
{
private static readonly (string key, Type type, string description)[] CommandData = new(string, Type, string)[6]
{
EventRegistryParamsHelper.Get(EventRegistryParams.CommandName),
EventRegistryParamsHelper.Get(EventRegistryParams.CommandDescription),
EventRegistryParamsHelper.Get(EventRegistryParams.CommandParameters),
EventRegistryParamsHelper.Get(EventRegistryParams.CommandAction),
EventRegistryParamsHelper.Get(EventRegistryParams.IsCheatCommand),
EventRegistryParamsHelper.Get(EventRegistryParams.CommandRequiresDebugMode)
};
public static void RegisterEvents()
{
EventBus.RegisterEvent("gymmed.chat_commands_manager_*", "ChatCommandsManager@AddChatCommand", "Adds command to chat commands manager.", CommandData);
EventBus.RegisterEvent("gymmed.chat_commands_manager_*", "ChatCommandsManager@RemoveChatCommand", "Removes command from chat commands manager.", new(string, Type, string)[1] { EventRegistryParamsHelper.Get(EventRegistryParams.CommandName) });
EventBus.RegisterEvent("gymmed.chat_commands_manager", "ChatCommandsManager@AddChatCommand_After", "Fires event when comment was added to chat commands manager.", CommandData);
EventBus.RegisterEvent("gymmed.chat_commands_manager", "ChatCommandsManager@RemoveChatCommand_After", "Fires event when comment was removed from chat commands manager.", CommandData);
}
}
public static class EventBusSubscriber
{
public const string Event_AddCommand = "ChatCommandsManager@AddChatCommand";
public const string Event_RemoveCommand = "ChatCommandsManager@RemoveChatCommand";
public static void AddSubscribers()
{
EventBus.Subscribe("gymmed.chat_commands_manager_*", "ChatCommandsManager@AddChatCommand", (Action<EventPayload>)AddCommand);
EventBus.Subscribe("gymmed.chat_commands_manager_*", "ChatCommandsManager@RemoveChatCommand", (Action<EventPayload>)RemoveCommand);
}
public static void AddCommand(EventPayload payload)
{
if (payload == null)
{
return;
}
string text = payload.Get<string>(EventRegistryParamsHelper.Get(EventRegistryParams.CommandName).key, (string)null);
if (string.IsNullOrEmpty(text))
{
OCCM.LogMessage("command is required field! Name your command.");
return;
}
Action<Character, Dictionary<string, string>> val = payload.Get<Action<Character, Dictionary<string, string>>>(EventRegistryParamsHelper.Get(EventRegistryParams.CommandAction).key, (Action<Character, Dictionary<string, string>>)null);
if (val == null)
{
OCCM.LogMessage("function is required field! Please define what your command will do.");
return;
}
Dictionary<string, (string, string)> parameters = payload.Get<Dictionary<string, (string, string)>>(EventRegistryParamsHelper.Get(EventRegistryParams.CommandParameters).key, (Dictionary<string, (string, string)>)null);
string description = payload.Get<string>(EventRegistryParamsHelper.Get(EventRegistryParams.CommandDescription).key, (string)null);
bool isCheat = payload.Get<bool>(EventRegistryParamsHelper.Get(EventRegistryParams.IsCheatCommand).key, false);
bool requireDebugMode = payload.Get<bool>(EventRegistryParamsHelper.Get(EventRegistryParams.CommandRequiresDebugMode).key, false);
ChatCommandsManager.Instance.AddChatCommand(new ChatCommand(text, parameters, description, isCheat, val, requireDebugMode));
}
public static void RemoveCommand(EventPayload payload)
{
if (payload != null)
{
string text = payload.Get<string>(EventRegistryParamsHelper.Get(EventRegistryParams.CommandName).key, (string)null);
if (string.IsNullOrEmpty(text))
{
OCCM.LogMessage("command is required field! Name your command.");
}
else
{
ChatCommandsManager.Instance.RemoveChatCommand(text);
}
}
}
}
}
namespace OutwardChatCommandsManager.Commands
{
public class ChatCommand : IChatCommand
{
private string _name;
private Dictionary<string, (string, string)> _parameters;
private string _description;
private bool _isCheat;
private bool _requireDebugMode;
private Action<Character, Dictionary<string, string>> _function;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public Dictionary<string, (string, string)> Parameters
{
get
{
return _parameters;
}
set
{
_parameters = value;
}
}
public string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
public bool IsCheat
{
get
{
return _isCheat;
}
set
{
_isCheat = value;
}
}
public bool RequireDebugMode
{
get
{
return _requireDebugMode;
}
set
{
_requireDebugMode = value;
}
}
public Action<Character, Dictionary<string, string>> Function
{
get
{
return _function;
}
set
{
_function = value;
}
}
public ChatCommand(string name, Dictionary<string, (string, string)> parameters, string description, bool isCheat, Action<Character, Dictionary<string, string>> function, bool requireDebugMode = false)
{
Name = name;
Parameters = parameters;
Description = description;
IsCheat = isCheat;
Function = function;
RequireDebugMode = requireDebugMode;
}
public virtual void TriggerFunction(Character character, Dictionary<string, string> arguments)
{
if (RequireDebugMode && !Global.CheatsEnabled)
{
return;
}
if (IsCheat)
{
ChatCommandsManager.HasUsedCheat = true;
}
try
{
Function?.Invoke(character, arguments);
}
catch (Exception ex)
{
if (string.IsNullOrEmpty(Name))
{
OCCM.LogMessage("ChatCommand@TriggerFunction encountered an error: \"" + ex.Message + "\"");
return;
}
OCCM.LogMessage("Command " + Name + " encountered an error: \"" + ex.Message + "\"");
}
}
}
public class MessageCommand
{
private string _command = "";
private List<string> _arguments;
public string Command
{
get
{
return _command;
}
set
{
_command = value;
}
}
public List<string> Arguments
{
get
{
return _arguments;
}
set
{
_arguments = value;
}
}
public MessageCommand(string message)
{
List<string> list = ChatHelpers.Tokenize(message);
string command = "";
if (list.Count > 0)
{
command = list[0];
}
List<string> arguments = list.Skip(1).ToList();
Command = command;
Arguments = arguments;
}
}
public class OriginalChatCommand : IChatCommand
{
private string _name;
private Dictionary<string, (string, string)> _parameters;
private string _description;
private bool _isCheat;
private bool _requireDebugMode;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public Dictionary<string, (string, string)> Parameters
{
get
{
return _parameters;
}
set
{
_parameters = value;
}
}
public string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
public bool IsCheat
{
get
{
return _isCheat;
}
set
{
_isCheat = value;
}
}
public bool RequireDebugMode
{
get
{
return _requireDebugMode;
}
set
{
_requireDebugMode = value;
}
}
public OriginalChatCommand(string name, Dictionary<string, (string, string)> parameters, string description, bool isCheat, bool requireDebugMode)
{
Name = name;
Parameters = parameters;
Description = description;
IsCheat = isCheat;
RequireDebugMode = requireDebugMode;
}
public void TriggerFunction(Character character, Dictionary<string, string> Arguments)
{
}
}
}