mirror of
https://github.com/MikuLeaks/KianaBH3.git
synced 2025-12-12 13:04:33 +01:00
126 lines
4.6 KiB
C#
126 lines
4.6 KiB
C#
using KianaBH.Database.Account;
|
|
using KianaBH.Enums.Player;
|
|
using KianaBH.GameServer.Server;
|
|
using KianaBH.Internationalization;
|
|
using KianaBH.KcpSharp;
|
|
using KianaBH.Util;
|
|
using System.Reflection;
|
|
|
|
namespace KianaBH.GameServer.Command;
|
|
|
|
public class CommandManager
|
|
{
|
|
public static Logger Logger { get; } = new("CommandManager");
|
|
|
|
public static Dictionary<string, ICommands> Commands { get; } = [];
|
|
public static Dictionary<string, CommandInfoAttribute> CommandInfo { get; } = [];
|
|
public static Dictionary<string, string> CommandAlias { get; } = []; // <aliaName, fullName>
|
|
|
|
public static void RegisterCommands()
|
|
{
|
|
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
|
if (typeof(ICommands).IsAssignableFrom(type) && !type.IsAbstract)
|
|
RegisterCommand(type);
|
|
|
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.RegisterItem", Commands.Count.ToString(),
|
|
I18NManager.Translate("Word.Command")));
|
|
}
|
|
|
|
public static void RegisterCommand(Type type)
|
|
{
|
|
var attr = type.GetCustomAttribute<CommandInfoAttribute>();
|
|
if (attr == null) return;
|
|
var instance = Activator.CreateInstance(type);
|
|
if (instance is not ICommands command) return;
|
|
Commands.Add(attr.Name, command);
|
|
CommandInfo.Add(attr.Name, attr);
|
|
|
|
// register alias
|
|
foreach (var alias in attr.Alias) // add alias
|
|
CommandAlias.Add(alias, attr.Name);
|
|
}
|
|
|
|
public static async void HandleCommand(string input, ICommandSender sender)
|
|
{
|
|
try
|
|
{
|
|
var argInfo = new CommandArg(input, sender);
|
|
var target = sender.GetSender();
|
|
|
|
foreach (var arg in argInfo.Args.ToList()) // Copy
|
|
{
|
|
switch (arg[0])
|
|
{
|
|
case '-':
|
|
argInfo.Attributes.Add(arg[1..]);
|
|
break;
|
|
case '@':
|
|
_ = int.TryParse(arg[1..], out target);
|
|
argInfo.Args.Remove(arg);
|
|
break;
|
|
}
|
|
}
|
|
argInfo.TargetUid = target;
|
|
if (KcpListener.Connections.Values.ToList().Find(item =>
|
|
(item as Connection)?.Player?.Uid == target) is Connection con)
|
|
argInfo.Target = con;
|
|
|
|
// find register cmd
|
|
var cmdName = argInfo.Args[0];
|
|
if (CommandAlias.TryGetValue(cmdName, out var fullName)) cmdName = fullName;
|
|
if (!Commands.TryGetValue(cmdName, out var command))
|
|
{
|
|
await sender.SendMsg(I18NManager.Translate("Game.Command.Notice.CommandNotFound"));
|
|
return;
|
|
}
|
|
argInfo.Args.RemoveAt(0);
|
|
var cmdInfo = CommandInfo[cmdName];
|
|
|
|
// Check cmd perms
|
|
if (!AccountData.HasPerm(cmdInfo.Perm, sender.GetSender()))
|
|
{
|
|
await sender.SendMsg(I18NManager.Translate("Game.Command.Notice.NoPermission"));
|
|
return;
|
|
}
|
|
if (argInfo.Target?.Player?.Uid != sender.GetSender() && !AccountData.HasPerm([PermEnum.Other], sender.GetSender()))
|
|
{
|
|
await sender.SendMsg(I18NManager.Translate("Game.Command.Notice.NoPermission"));
|
|
return;
|
|
}
|
|
|
|
// find CommandMethodAttribute
|
|
var isFound = false;
|
|
foreach (var methodInfo in command.GetType().GetMethods())
|
|
{
|
|
var attr = methodInfo.GetCustomAttribute<CommandMethodAttribute>();
|
|
if (attr == null) continue;
|
|
if (argInfo.Args.Count > 0 && attr.MethodName == argInfo.Args[0])
|
|
{
|
|
argInfo.Args.RemoveAt(0);
|
|
isFound = true;
|
|
methodInfo.Invoke(command, [argInfo]);
|
|
break;
|
|
}
|
|
}
|
|
if (isFound) return;
|
|
|
|
// find CommandDefaultAttribute
|
|
foreach (var methodInfo in command.GetType().GetMethods())
|
|
{
|
|
var attr = methodInfo.GetCustomAttribute<CommandDefaultAttribute>();
|
|
if (attr == null) continue;
|
|
isFound = true;
|
|
methodInfo.Invoke(command, [argInfo]);
|
|
break;
|
|
}
|
|
if (isFound) return;
|
|
|
|
// failed to find method
|
|
await sender.SendMsg(I18NManager.Translate(cmdInfo.Usage));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error(I18NManager.Translate("Game.Command.Notice.InternalError", ex.ToString()));
|
|
}
|
|
}
|
|
} |