133 lines
5.0 KiB
C#

using System.Net.Sockets;
using System.Reflection;
using System.Text.Json;
using DX86;
namespace Server;
public class CommandManager
{
private readonly Dictionary<string, MethodInfo> _commands = new();
public CommandManager()
{
LoadCommands();
}
private void LoadCommands()
{
var methods = Assembly.GetExecutingAssembly()
.GetTypes()
.SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.Static))
.Where(m => m.GetCustomAttribute<CommandAttribute>() != null);
foreach (var method in methods)
{
var attr = method.GetCustomAttribute<CommandAttribute>()!;
_commands[attr.Name.ToLower()] = method;
Program.messageSender.Log($"[COMMANDMANAGER] Registered command: {attr.Name}");
}
}
public void ExecuteCommand(string executor,
TcpClient? client = null,
TcpServer? clientSocket = null,
string cid = "",
params string[] args)
{
// — ensure args is never null —
args ??= Array.Empty<string>();
if (_commands.TryGetValue(executor.ToLower(), out var method))
{
try
{
var parameters = method.GetParameters();
var arguments = new object?[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
var param = parameters[i];
if (param.ParameterType == typeof(string[]))
arguments[i] = args;
else if (param.ParameterType == typeof(TcpClient))
arguments[i] = client;
else if (param.ParameterType == typeof(TcpServer))
arguments[i] = clientSocket;
else
{
Program.messageSender.Warn(
$"[COMMANDMANAGER] Unknown parameter type '{param.ParameterType.Name}' in '{executor}'. Defaulting that argument to null."
);
arguments[i] = null;
}
}
Program.messageSender.Debug($"[COMMANDMANAGER] Executing command '{executor}'…");
var rawResult = method.Invoke(null, arguments); // invoke the static command method
string result = rawResult?.ToString() ?? "";
// **Log the returned string before sending**
Program.messageSender.Debug($"[COMMANDMANAGER] Command '{executor}' returned: \"{result}\"");
var returnMessage = new Library.Server.JsonResponse
{
Id = cid,
Response = result
};
var sendClientMessage = JsonSerializer.Serialize(returnMessage);
clientSocket?.SendMessageAsync(client, sendClientMessage + "\r\n");
Program.messageSender.Debug($"[COMMANDMANAGER] Response sent to client.");
}
// If your command threw a CommandException, catch it here:
catch (TargetInvocationException ex) when (ex.InnerException is CommandException cmdEx)
{
Program.messageSender.Warn($"[COMMANDMANAGER] Command '{executor}' failed: {cmdEx.Message}");
var returnMessage = new Library.Server.JsonResponse
{
Id = cid,
Response = $"Error: {cmdEx.Message}"
};
var sendClientMessage = JsonSerializer.Serialize(returnMessage);
try
{
clientSocket?.SendMessageAsync(client, sendClientMessage + "\r\n");
Program.messageSender.Debug("[COMMANDMANAGER] Response sent to client.");
}
catch (Exception e)
{
Program.messageSender.Error($"[COMMANDMANAGER] Cannot send errormessage to Client: {e.Message}");
}
}
// Any other exception inside the invoked method
catch (TargetInvocationException ex)
{
var actualError = ex.InnerException?.Message ?? ex.Message;
Program.messageSender.Error(
$"[COMMANDMANAGER] Unexpected error in command '{executor}': {actualError}"
);
Program.messageSender.Debug(
$"[COMMANDMANAGER] Stack Trace: {ex.InnerException?.StackTrace ?? ex.StackTrace}"
);
}
// Anything else thrown before or during Invoke()
catch (Exception ex)
{
Program.messageSender.Error($"[COMMANDMANAGER] Failed to invoke command '{executor}': {ex.Message}");
}
}
else
{
Program.messageSender.Warn($"[COMMANDMANAGER] Unknown command '{executor}' received.");
var returnMessage = new Library.Server.JsonResponse
{
Id = cid,
Response = $"Unknown command '{executor}' received."
};
string sendClientMessage = JsonSerializer.Serialize(returnMessage);
clientSocket.SendMessageAsync(client, sendClientMessage + "\r\n");
}
}
}