refactor
This commit is contained in:
@@ -2,40 +2,35 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Main;
|
||||
using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
public interface IConsoleCommand {
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
void Execute(string[] args);
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class RCCMD : Attribute {
|
||||
public string name;
|
||||
public string description;
|
||||
|
||||
public class HelpCommand : IConsoleCommand {
|
||||
public string Name { get; } = "help";
|
||||
public string Description { get; } = "Prints available commands/cvars and their descriptions.";
|
||||
|
||||
public void Execute(string[] args) {
|
||||
RR.Console.PrintHelp();
|
||||
}
|
||||
}
|
||||
|
||||
public class PrintCVarsCommand : IConsoleCommand {
|
||||
public string Name { get; } = "print_cvars";
|
||||
public string Description { get; } = "Prints all cvars and their values.";
|
||||
|
||||
public void Execute(string[] args) {
|
||||
RR.Console.PrintCVars();
|
||||
public RCCMD(string name, string description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleService : IService {
|
||||
static readonly Logger s_logger = new(nameof(ConsoleService));
|
||||
|
||||
readonly List<IConsoleCommand> m_ConsoleCommands = new();
|
||||
public struct ConsoleCommand {
|
||||
public string name;
|
||||
public string description;
|
||||
public Action<string[]> action;
|
||||
}
|
||||
|
||||
readonly List<ConsoleCommand> m_ConsoleCommands = new();
|
||||
|
||||
FileStream m_LogFileStream;
|
||||
TextWriter m_LogFileWriter;
|
||||
@@ -60,8 +55,7 @@ namespace RebootKit.Engine.Services.Console {
|
||||
|
||||
Load();
|
||||
|
||||
RegisterCommand(new PrintCVarsCommand());
|
||||
RegisterCommand(new HelpCommand());
|
||||
RegisterCommands();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
@@ -97,37 +91,34 @@ namespace RebootKit.Engine.Services.Console {
|
||||
OnOutputMessage?.Invoke(message);
|
||||
}
|
||||
|
||||
string[] ParseCommandInputArguments(string text) {
|
||||
if (text.Length == 0) {
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
return new[] {text};
|
||||
string[] ParseCommandInput(string text) {
|
||||
return text.Split(' ');
|
||||
}
|
||||
|
||||
// @NOTE: Input must be in format: "command arg1 arg2 arg3", one command = one call
|
||||
public void Execute(string input) {
|
||||
if (input.Length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
string commandName = input;
|
||||
if (input.IndexOf(' ') != -1) {
|
||||
commandName = input.Substring(0, input.IndexOf(' '));
|
||||
string[] arguments = ParseCommandInput(input);
|
||||
if (arguments.Length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
string[] arguments = ParseCommandInputArguments(input.Substring(commandName.Length));
|
||||
string commandName = arguments[0];
|
||||
|
||||
foreach (IConsoleCommand command in m_ConsoleCommands) {
|
||||
if (command.Name.Equals(commandName)) {
|
||||
command.Execute(arguments);
|
||||
foreach (ConsoleCommand command in m_ConsoleCommands) {
|
||||
if (command.name.Equals(commandName)) {
|
||||
command.action(arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
if (cvar.name.Equals(commandName)) {
|
||||
if (arguments.Length == 1) {
|
||||
cvar.ParseFromString(arguments[0]);
|
||||
if (arguments.Length == 2) {
|
||||
cvar.ParseFromString(arguments[1]);
|
||||
}
|
||||
|
||||
WriteToOutput($"<b>{cvar.name}</b> - {cvar}\n");
|
||||
@@ -138,25 +129,84 @@ namespace RebootKit.Engine.Services.Console {
|
||||
WriteToOutput($"ERROR: Command/CVar `{commandName}` not found.");
|
||||
}
|
||||
|
||||
public void RegisterCommand(IConsoleCommand command) {
|
||||
if (m_ConsoleCommands.Any(t => t.Name.Equals(command.Name))) {
|
||||
s_logger.Error($"`{command.Name}` command is already registered");
|
||||
public void RegisterCommand(string name, string description, Action<string[]> action) {
|
||||
if (IsCommandRegistered(name)) {
|
||||
s_logger.Error($"`{name}` command is already registered");
|
||||
return;
|
||||
}
|
||||
|
||||
m_ConsoleCommands.Add(command);
|
||||
s_logger.Info($"Registered command: {command.Name}");
|
||||
m_ConsoleCommands.Add(new ConsoleCommand {
|
||||
name = name,
|
||||
description = description,
|
||||
action = action
|
||||
});
|
||||
s_logger.Info($"Registered command: {name}");
|
||||
}
|
||||
|
||||
public void PrintHelp() {
|
||||
public static ConsoleCommand[] GenerateCommandsToRegister() {
|
||||
IEnumerable<MethodInfo> methods = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(assembly => assembly.GetTypes())
|
||||
.SelectMany(type => type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static))
|
||||
.Where(method => method.GetCustomAttributes(typeof(RCCMD), false).Length > 0);
|
||||
|
||||
List<ConsoleCommand> commands = new();
|
||||
foreach (MethodInfo method in methods) {
|
||||
RCCMD attribute = (RCCMD)method.GetCustomAttributes(typeof(RCCMD), false)[0];
|
||||
|
||||
if (!method.IsStatic) {
|
||||
s_logger.Error($"Command `{attribute.name}` is not static, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.GetParameters().Length != 1) {
|
||||
s_logger.Error($"Command `{attribute.name}` has invalid number of parameters, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.GetParameters()[0].ParameterType != typeof(string[])) {
|
||||
s_logger.Error($"Command `{attribute.name}` has invalid parameter type, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
Action<string[]> action = (Action<string[]>)Delegate.CreateDelegate(typeof(Action<string[]>), method);
|
||||
|
||||
commands.Add(new ConsoleCommand {
|
||||
name = attribute.name,
|
||||
description = attribute.description,
|
||||
action = action
|
||||
});
|
||||
}
|
||||
|
||||
return commands.ToArray();
|
||||
}
|
||||
|
||||
public void RegisterCommands() {
|
||||
ConsoleCommand[] commands = GenerateCommandsToRegister();
|
||||
foreach (ConsoleCommand command in commands) {
|
||||
RegisterCommand(command.name, command.description, command.action);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsCommandRegistered(string name) {
|
||||
foreach (ConsoleCommand command in m_ConsoleCommands) {
|
||||
if (command.name.Equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[RCCMD("help", "Prints help message with all commands and cvars")]
|
||||
public static void PrintHelpCommand(string[] args) {
|
||||
StringBuilder message = new();
|
||||
|
||||
message.AppendLine("Available commands:");
|
||||
foreach (IConsoleCommand command in m_ConsoleCommands) {
|
||||
foreach (ConsoleCommand command in RR.Console.m_ConsoleCommands) {
|
||||
message.Append(" ");
|
||||
message.Append(command.Name);
|
||||
message.Append(command.name);
|
||||
message.Append(" - ");
|
||||
message.Append(command.Description);
|
||||
message.Append(command.description);
|
||||
message.AppendLine();
|
||||
}
|
||||
|
||||
@@ -169,17 +219,18 @@ namespace RebootKit.Engine.Services.Console {
|
||||
message.AppendLine();
|
||||
}
|
||||
|
||||
WriteToOutput(message.ToString());
|
||||
RR.Console.WriteToOutput(message.ToString());
|
||||
}
|
||||
|
||||
public void PrintCVars() {
|
||||
[RCCMD("cvars", "Prints all cvars")]
|
||||
public static void PrintCVars(string[] args) {
|
||||
StringBuilder message = new();
|
||||
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
message.AppendLine($"{cvar.name} - {cvar}");
|
||||
}
|
||||
|
||||
WriteToOutput(message.ToString());
|
||||
RR.Console.WriteToOutput(message.ToString());
|
||||
}
|
||||
|
||||
void Save() {
|
||||
|
||||
Reference in New Issue
Block a user