Attribute for checking if command is for in-game only; Added CommandException.cs and InvalidParametersException.cs Added NecroSkeletonCount to GameServerConfig.cs, thus the amount of necro skeletons can now be set. Added new quest command: !quest set [questId] [stepId] to fast-forward to a specific quest.
138 lines
4.4 KiB
C#
138 lines
4.4 KiB
C#
using DiIiS_NA.Core.Logging;
|
|
using DiIiS_NA.LoginServer.Battle;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using FluentNHibernate.Utils;
|
|
|
|
namespace DiIiS_NA.GameServer.CommandManager
|
|
{
|
|
public class CommandGroup
|
|
{
|
|
private static readonly Logger Logger = LogManager.CreateLogger("CmdGrp");
|
|
|
|
private CommandGroupAttribute Attributes { get; set; }
|
|
|
|
private readonly Dictionary<CommandAttribute, MethodInfo> _commands = new();
|
|
|
|
public void Register(CommandGroupAttribute attributes)
|
|
{
|
|
Attributes = attributes;
|
|
RegisterDefaultCommand();
|
|
RegisterCommands();
|
|
}
|
|
|
|
private void RegisterCommands()
|
|
{
|
|
foreach (var method in GetType().GetMethods())
|
|
{
|
|
object[] attributes = method.GetCustomAttributes(typeof(CommandAttribute), true);
|
|
if (attributes.Length == 0) continue;
|
|
|
|
var attribute = (CommandAttribute)attributes[0];
|
|
if (attribute is DefaultCommand) continue;
|
|
|
|
if (!_commands.ContainsKey(attribute))
|
|
_commands.Add(attribute, method);
|
|
else
|
|
Logger.Fatal($"$[red]$Command$[/]$ '$[underline white]${attribute.Name.SafeAnsi()}$[/]$' already exists.");
|
|
}
|
|
}
|
|
|
|
private void RegisterDefaultCommand()
|
|
{
|
|
foreach (var method in GetType().GetMethods())
|
|
{
|
|
object[] attributes = method.GetCustomAttributes(typeof(DefaultCommand), true);
|
|
if (attributes.Length == 0) continue;
|
|
if (method.Name.ToLower() == "fallback") continue;
|
|
|
|
_commands.Add(new DefaultCommand(Attributes.MinUserLevel), method);
|
|
return;
|
|
}
|
|
|
|
// set the fallback command if we couldn't find a defined DefaultCommand.
|
|
_commands.Add(new DefaultCommand(Attributes.MinUserLevel), GetType().GetMethod("Fallback"));
|
|
}
|
|
|
|
public virtual string Handle(string parameters, BattleClient invokerClient = null)
|
|
{
|
|
// check if the user has enough privileges to access command group.
|
|
// check if the user has enough privileges to invoke the command.
|
|
if (invokerClient != null && Attributes.MinUserLevel > invokerClient.Account.UserLevel)
|
|
#if DEBUG
|
|
return $"You don't have enough privileges to invoke that command (Min. level: {Attributes.MinUserLevel}).";
|
|
#else
|
|
return "You don't have enough privileges to invoke that command.";
|
|
#endif
|
|
if (invokerClient?.InGameClient == null && Attributes.InGameOnly)
|
|
return "You can only use this command in-game.";
|
|
string[] @params = null;
|
|
CommandAttribute target = null;
|
|
|
|
if (parameters == string.Empty)
|
|
target = GetDefaultSubcommand();
|
|
else
|
|
{
|
|
@params = parameters.Split(' ');
|
|
target = GetSubcommand(@params[0]) ?? GetDefaultSubcommand();
|
|
|
|
if (!Equals(target, GetDefaultSubcommand()))
|
|
@params = @params.Skip(1).ToArray();
|
|
}
|
|
|
|
// check if the user has enough privileges to invoke the command.
|
|
if (invokerClient != null && target.MinUserLevel > invokerClient.Account.UserLevel)
|
|
#if DEBUG
|
|
return $"You don't have enough privileges to invoke that command (Min. level: {Attributes.MinUserLevel}).";
|
|
#else
|
|
return "You don't have enough privileges to invoke that command.";
|
|
#endif
|
|
if (invokerClient?.InGameClient == null && target.InGameOnly)
|
|
return "This command can only be invoked in-game.";
|
|
|
|
try
|
|
{
|
|
return (string)_commands[target].Invoke(this, new object[] { @params, invokerClient });
|
|
}
|
|
catch (CommandException commandException)
|
|
{
|
|
return commandException.Message;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.ErrorException(ex, "Command Handling Error");
|
|
return "An error occurred while executing the command.";
|
|
}
|
|
}
|
|
|
|
public string GetHelp(string command)
|
|
{
|
|
foreach (var pair in _commands.Where(pair => command == pair.Key.Name))
|
|
{
|
|
return pair.Key.Help;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
[DefaultCommand]
|
|
public virtual string Fallback(string[] @params = null, BattleClient invokerClient = null)
|
|
{
|
|
var output = _commands
|
|
.Where(pair => pair.Key.Name.Trim() != string.Empty)
|
|
.Where(pair => invokerClient == null || pair.Key.MinUserLevel <= invokerClient.Account.UserLevel)
|
|
.Aggregate("Available subcommands: ", (current, pair) => current + (pair.Key.Name + ", "));
|
|
|
|
return output.Substring(0, output.Length - 2) + ".";
|
|
}
|
|
|
|
protected CommandAttribute GetDefaultSubcommand() => _commands.Keys.First();
|
|
|
|
protected CommandAttribute GetSubcommand(string name) => _commands.Keys.FirstOrDefault(command => command.Name == name);
|
|
}
|
|
}
|