mirror of
https://github.com/MikuLeaks/KianaBH3.git
synced 2025-12-13 05:14:46 +01:00
Init enter game
This commit is contained in:
79
GameServer/Command/CommandArg.cs
Normal file
79
GameServer/Command/CommandArg.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using KianaBH.Database.Account;
|
||||
using KianaBH.GameServer.Server;
|
||||
using KianaBH.Internationalization;
|
||||
|
||||
namespace KianaBH.GameServer.Command;
|
||||
|
||||
public class CommandArg
|
||||
{
|
||||
public string RawArg { get; } = "";
|
||||
public List<string> Args { get; } = [];
|
||||
public List<string> Attributes { get; } = [];
|
||||
public ICommandSender Sender { get; }
|
||||
public int TargetUid { get; set; } = 0;
|
||||
public Connection? Target { get; set; }
|
||||
|
||||
public CommandArg(string rawArg, ICommandSender sender)
|
||||
{
|
||||
Sender = sender;
|
||||
RawArg = rawArg;
|
||||
foreach (var arg in rawArg.Split(' '))
|
||||
{
|
||||
if (string.IsNullOrEmpty(arg)) continue;
|
||||
Args.Add(arg);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask SendMsg(string msg)
|
||||
{
|
||||
await Sender.SendMsg(msg);
|
||||
}
|
||||
|
||||
public int GetInt(int index)
|
||||
{
|
||||
if (Args.Count <= index) return 0;
|
||||
if (int.TryParse(Args[index], out var res))
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async ValueTask<int?> GetOption(char pre, string def = "1")
|
||||
{
|
||||
var opStr = Args.FirstOrDefault(x => x[0] == pre)?[1..] ?? def;
|
||||
if (!int.TryParse(opStr, out var op))
|
||||
{
|
||||
await SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments"));
|
||||
return null;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
public async ValueTask<bool> CheckArgCnt(int start, int? end = null)
|
||||
{
|
||||
end ??= start;
|
||||
if (Args.Count >= start && Args.Count <= end) return true;
|
||||
await SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments"));
|
||||
return false;
|
||||
}
|
||||
|
||||
public async ValueTask<bool> CheckTarget()
|
||||
{
|
||||
if (AccountData.GetAccountByUid(TargetUid) == null)
|
||||
{
|
||||
await SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async ValueTask<bool> CheckOnlineTarget(bool sendMsg = true)
|
||||
{
|
||||
if (Target == null)
|
||||
{
|
||||
if (sendMsg)
|
||||
await SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
25
GameServer/Command/CommandAttribute.cs
Normal file
25
GameServer/Command/CommandAttribute.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using KianaBH.Enums.Player;
|
||||
|
||||
namespace KianaBH.GameServer.Command;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class CommandInfoAttribute(
|
||||
string name, string desc, string usage, string[] alias, PermEnum[] perm) : Attribute
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
public string Description { get; } = desc;
|
||||
public string Usage { get; } = usage;
|
||||
public PermEnum[] Perm { get; } = perm;
|
||||
public string[] Alias { get; } = alias;
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class CommandDefaultAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class CommandMethodAttribute(string method) : Attribute
|
||||
{
|
||||
public string MethodName { get; } = method;
|
||||
}
|
||||
19
GameServer/Command/CommandExecutor.cs
Normal file
19
GameServer/Command/CommandExecutor.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
namespace KianaBH.GameServer.Command;
|
||||
|
||||
public static class CommandExecutor
|
||||
{
|
||||
public delegate void RunCommand(ICommandSender sender, string cmd);
|
||||
|
||||
public static event RunCommand? OnRunCommand;
|
||||
|
||||
public static void ExecuteCommand(ICommandSender sender, string cmd)
|
||||
{
|
||||
OnRunCommand?.Invoke(sender, cmd);
|
||||
}
|
||||
|
||||
public static void ConsoleExcuteCommand(string input)
|
||||
{
|
||||
CommandManager.HandleCommand(input, new ConsoleCommandSender(CommandManager.Logger));
|
||||
}
|
||||
}
|
||||
3
GameServer/Command/CommandInterface.cs
Normal file
3
GameServer/Command/CommandInterface.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace KianaBH.GameServer.Command;
|
||||
|
||||
public interface ICommands;
|
||||
126
GameServer/Command/CommandManager.cs
Normal file
126
GameServer/Command/CommandManager.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
41
GameServer/Command/CommandSender.cs
Normal file
41
GameServer/Command/CommandSender.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using KianaBH.Enums.Player;
|
||||
using KianaBH.GameServer.Game.Player;
|
||||
using KianaBH.Util;
|
||||
|
||||
namespace KianaBH.GameServer.Command;
|
||||
|
||||
public interface ICommandSender
|
||||
{
|
||||
public ValueTask SendMsg(string msg);
|
||||
|
||||
public int GetSender();
|
||||
}
|
||||
|
||||
public class ConsoleCommandSender(Logger logger) : ICommandSender
|
||||
{
|
||||
public async ValueTask SendMsg(string msg)
|
||||
{
|
||||
logger.Info(msg);
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public int GetSender()
|
||||
{
|
||||
return (int)ServerEnum.Console;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerCommandSender(PlayerInstance player) : ICommandSender
|
||||
{
|
||||
public PlayerInstance Player = player;
|
||||
|
||||
public async ValueTask SendMsg(string msg)
|
||||
{
|
||||
// TODO SEND MSG
|
||||
}
|
||||
|
||||
public int GetSender()
|
||||
{
|
||||
return Player.Uid;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user