mirror of
https://github.com/rafi1212122/BLHX.Server.git
synced 2025-12-12 14:34:39 +01:00
Command system and input system
This commit is contained in:
105
BLHX.Server.Game/Commands/Command.cs
Normal file
105
BLHX.Server.Game/Commands/Command.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using BLHX.Server.Common.Utils;
|
||||
using System.Reflection;
|
||||
|
||||
namespace BLHX.Server.Game.Commands;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class commandHandler : Attribute
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public string Example { get; }
|
||||
|
||||
public commandHandler(string commandName, string description, string example)
|
||||
{
|
||||
Name = commandName;
|
||||
Description = description;
|
||||
Example = example;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ArgumentAttribute : Attribute
|
||||
{
|
||||
public string Key { get; }
|
||||
|
||||
public ArgumentAttribute(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Command
|
||||
{
|
||||
readonly Dictionary<string, PropertyInfo> argsProperties;
|
||||
|
||||
public Command()
|
||||
{
|
||||
argsProperties = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.Where(x => Attribute.IsDefined(x, typeof(ArgumentAttribute)))
|
||||
.ToDictionary(x => ((ArgumentAttribute)Attribute.GetCustomAttribute(x, typeof(ArgumentAttribute))!).Key, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public virtual void Execute(Dictionary<string, string> args)
|
||||
{
|
||||
foreach (var arg in args)
|
||||
{
|
||||
if (argsProperties.TryGetValue(arg.Key, out var prop))
|
||||
prop.SetValue(this, arg.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CommandHandler
|
||||
{
|
||||
public static readonly List<Command> Commands = new List<Command>();
|
||||
|
||||
static readonly Dictionary<string, Action<Dictionary<string, string>>> commandFunctions;
|
||||
|
||||
static CommandHandler()
|
||||
{
|
||||
commandFunctions = new Dictionary<string, Action<Dictionary<string, string>>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
RegisterCommands(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
|
||||
public static void RegisterCommands(Assembly assembly)
|
||||
{
|
||||
var commandTypes = assembly.GetTypes()
|
||||
.Where(t => Attribute.IsDefined(t, typeof(commandHandler)) && typeof(Command).IsAssignableFrom(t));
|
||||
|
||||
foreach (var commandType in commandTypes)
|
||||
{
|
||||
var commandAttribute = (commandHandler)Attribute.GetCustomAttribute(commandType, typeof(commandHandler));
|
||||
if (commandAttribute != null)
|
||||
{
|
||||
var commandInstance = (Command)Activator.CreateInstance(commandType);
|
||||
commandFunctions[commandAttribute.Name] = commandInstance.Execute;
|
||||
Commands.Add(commandInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleCommand(string commandLine)
|
||||
{
|
||||
var parts = commandLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 0)
|
||||
return;
|
||||
|
||||
if (!commandFunctions.TryGetValue(parts[0], out var command))
|
||||
{
|
||||
Logger.c.Warn($"Unknown command: {parts[0]}");
|
||||
return;
|
||||
}
|
||||
|
||||
var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
for (var i = 1; i < parts.Length; i++)
|
||||
{
|
||||
var argParts = parts[i].Split('=', 2);
|
||||
if (argParts.Length == 2)
|
||||
arguments[argParts[0]] = argParts[1];
|
||||
}
|
||||
|
||||
command(arguments);
|
||||
}
|
||||
}
|
||||
32
BLHX.Server.Game/Commands/HelpCommand.cs
Normal file
32
BLHX.Server.Game/Commands/HelpCommand.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace BLHX.Server.Game.Commands;
|
||||
|
||||
[commandHandler("help", "Print out all commands with their description and example", "help")]
|
||||
public class HelpCommand : Command
|
||||
{
|
||||
static readonly Dictionary<Type, commandHandler?> commandAttributes = new Dictionary<Type, commandHandler?>();
|
||||
|
||||
public override void Execute(Dictionary<string, string> args)
|
||||
{
|
||||
base.Execute(args);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine("Available Commands: ");
|
||||
foreach (var command in CommandHandler.Commands)
|
||||
{
|
||||
if (!commandAttributes.TryGetValue(command.GetType(), out var attr))
|
||||
{
|
||||
attr = command.GetType().GetCustomAttribute(typeof(commandHandler)) as commandHandler;
|
||||
commandAttributes[command.GetType()] = attr;
|
||||
}
|
||||
|
||||
if (attr != null)
|
||||
sb.AppendLine($" {attr.Name} - {attr.Description} (Example: {attr.Example})");
|
||||
}
|
||||
|
||||
Console.Write(sb.ToString());
|
||||
}
|
||||
}
|
||||
15
BLHX.Server.Game/Commands/SaveCommand.cs
Normal file
15
BLHX.Server.Game/Commands/SaveCommand.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using BLHX.Server.Common.Utils;
|
||||
|
||||
namespace BLHX.Server.Game.Commands;
|
||||
|
||||
[commandHandler("save", "Save the current state", "save")]
|
||||
public class SaveCommand : Command
|
||||
{
|
||||
public override void Execute(Dictionary<string, string> args)
|
||||
{
|
||||
base.Execute(args);
|
||||
|
||||
Logger.c.Log("Saving...");
|
||||
Logger.c.Log("Saved!");
|
||||
}
|
||||
}
|
||||
18
BLHX.Server.Game/InputSystem.cs
Normal file
18
BLHX.Server.Game/InputSystem.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using BLHX.Server.Game.Commands;
|
||||
|
||||
namespace BLHX.Server.Game;
|
||||
|
||||
public static class InputSystem
|
||||
{
|
||||
public static void Start()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var command = Console.ReadLine();
|
||||
|
||||
if (string.IsNullOrEmpty(command)) continue;
|
||||
|
||||
CommandHandler.HandleCommand(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user