mirror of
https://git.lewd.wtf/PGR/ascnet
synced 2025-12-12 22:54:37 +01:00
command yay!
This commit is contained in:
132
AscNet.GameServer/Commands/Command.cs
Normal file
132
AscNet.GameServer/Commands/Command.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using AscNet.Logging;
|
||||
|
||||
namespace AscNet.GameServer.Commands
|
||||
{
|
||||
public abstract class Command
|
||||
{
|
||||
protected Session session;
|
||||
protected string[] args;
|
||||
|
||||
public abstract string Help { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Make sure to handle me well...
|
||||
/// </summary>
|
||||
/// <param name="session"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public Command(Session session, string[] args, bool validate = true)
|
||||
{
|
||||
this.session = session;
|
||||
this.args = args;
|
||||
|
||||
string? ret = Validate();
|
||||
if (ret is not null && validate)
|
||||
throw new ArgumentException(ret);
|
||||
}
|
||||
|
||||
public string? Validate()
|
||||
{
|
||||
List<PropertyInfo> argsProperties = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(x => x.GetCustomAttribute(typeof(ArgumentAttribute)) is not null).ToList();
|
||||
if (argsProperties.Count != args.Length)
|
||||
return "Invalid args length!";
|
||||
|
||||
foreach (var argProp in argsProperties)
|
||||
{
|
||||
ArgumentAttribute attr = (ArgumentAttribute)argProp.GetCustomAttribute(typeof(ArgumentAttribute))!;
|
||||
if (!attr.Pattern.IsMatch(args[attr.Position]))
|
||||
return $"Argument {argProp.Name} is invalid!";
|
||||
|
||||
argProp.SetValue(this, args[attr.Position]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract void Execute();
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ArgumentAttribute : Attribute
|
||||
{
|
||||
public int Position { get; }
|
||||
public Regex Pattern { get; }
|
||||
public string? Description { get; }
|
||||
|
||||
public ArgumentAttribute(int position, string pattern, string? description = null)
|
||||
{
|
||||
Position = position;
|
||||
Pattern = new(pattern);
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class CommandNameAttribute : Attribute
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public CommandNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandName("help")]
|
||||
internal class HelpCommand : Command
|
||||
{
|
||||
public HelpCommand(Session session, string[] args, bool validate = true) : base(session, args, validate) { }
|
||||
|
||||
public override string Help => "Show this help.";
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
string helpText = string.Empty;
|
||||
|
||||
foreach (var command in CommandFactory.commands.Keys)
|
||||
{
|
||||
Command? cmd = CommandFactory.CreateCommand(command, session, args, false);
|
||||
if (cmd is not null)
|
||||
helpText += $"{command}\n\t└─{cmd.Help}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CommandFactory
|
||||
{
|
||||
public static readonly Dictionary<string, Type> commands = new();
|
||||
|
||||
internal static readonly Logger log = new(typeof(CommandFactory), LogLevel.DEBUG, LogLevel.DEBUG);
|
||||
|
||||
public static void LoadCommands()
|
||||
{
|
||||
log.LogLevelColor[LogLevel.INFO] = ConsoleColor.White;
|
||||
log.Info("Loading commands...");
|
||||
|
||||
IEnumerable<Type> classes = from t in Assembly.GetExecutingAssembly().GetTypes()
|
||||
where t.IsClass && t.GetCustomAttribute<CommandNameAttribute>() is not null
|
||||
select t;
|
||||
|
||||
foreach (var command in classes)
|
||||
{
|
||||
CommandNameAttribute nameAttr = command.GetCustomAttribute<CommandNameAttribute>()!;
|
||||
commands.Add(nameAttr.Name, command);
|
||||
#if DEBUG
|
||||
log.Info($"Loaded {nameAttr.Name} command");
|
||||
#endif
|
||||
}
|
||||
|
||||
log.Info("Finished loading commands");
|
||||
}
|
||||
|
||||
public static Command? CreateCommand(string name, Session session, string[] args, bool validate = true)
|
||||
{
|
||||
Type? command = commands.GetValueOrDefault(name);
|
||||
if (command is null)
|
||||
return null;
|
||||
|
||||
return (Command)Activator.CreateInstance(command, new object[] { session, args, validate })!;
|
||||
}
|
||||
}
|
||||
}
|
||||
73
AscNet.GameServer/Commands/StageCommand.cs
Normal file
73
AscNet.GameServer/Commands/StageCommand.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using AscNet.Common.MsgPack;
|
||||
using AscNet.Table.share.fuben;
|
||||
|
||||
namespace AscNet.GameServer.Commands
|
||||
{
|
||||
[CommandName("stage")]
|
||||
internal class StageCommand : Command
|
||||
{
|
||||
public StageCommand(Session session, string[] args, bool validate = true) : base(session, args, validate) { }
|
||||
|
||||
[Argument(0, @"^[0-9]+$|^all$", "The target stage, value is stage id or 'all'")]
|
||||
string TargetStage { get; set; } = string.Empty;
|
||||
|
||||
public override string Help => "Modify the stage completion status of the account.";
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
if (TargetStage == "all")
|
||||
{
|
||||
session.stage.Stages.Clear();
|
||||
foreach (var stageData in StageTableReader.Instance.All)
|
||||
{
|
||||
session.stage.Stages.Add(stageData.StageId, new()
|
||||
{
|
||||
StageId = stageData.StageId,
|
||||
StarsMark = 7,
|
||||
Passed = true,
|
||||
PassTimesToday = 0,
|
||||
PassTimesTotal = 1,
|
||||
BuyCount = 0,
|
||||
Score = 0,
|
||||
LastPassTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
RefreshTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
CreateTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
BestRecordTime = 0,
|
||||
LastRecordTime = 0,
|
||||
BestCardIds = new List<long> { 1021001 },
|
||||
LastCardIds = new List<long> { 1021001 }
|
||||
});
|
||||
}
|
||||
|
||||
session.SendPush(new NotifyStageData() { StageList = session.stage.Stages.Select(x => x.Value).ToList() });
|
||||
}
|
||||
else
|
||||
{
|
||||
StageTable? stageData = StageTableReader.Instance.FromStageId(int.Parse(TargetStage));
|
||||
if (stageData is not null && !session.stage.Stages.ContainsKey(stageData.StageId))
|
||||
{
|
||||
StageDatum stage = new()
|
||||
{
|
||||
StageId = stageData.StageId,
|
||||
StarsMark = 7,
|
||||
Passed = true,
|
||||
PassTimesToday = 0,
|
||||
PassTimesTotal = 1,
|
||||
BuyCount = 0,
|
||||
Score = 0,
|
||||
LastPassTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
RefreshTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
CreateTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
BestRecordTime = 0,
|
||||
LastRecordTime = 0,
|
||||
BestCardIds = new List<long> { 1021001 },
|
||||
LastCardIds = new List<long> { 1021001 }
|
||||
};
|
||||
session.stage.Stages.Add(stageData.StageId, stage);
|
||||
|
||||
session.SendPush(new NotifyStageData() { StageList = new() { stage } });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using AscNet.Common.Database;
|
||||
using AscNet.Common.MsgPack;
|
||||
using AscNet.Table.share.fuben;
|
||||
using AscNet.Table.share.guide;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
@@ -103,7 +104,7 @@ namespace AscNet.GameServer.Handlers
|
||||
BaseEquipLoginData = new(),
|
||||
FubenData = new()
|
||||
{
|
||||
StageData = session.stage.Stages,
|
||||
StageData = session.stage.Stages.ToDictionary(x => x.Key, x => x.Value),
|
||||
FubenBaseData = new()
|
||||
},
|
||||
FubenMainLineData = new(),
|
||||
@@ -116,7 +117,6 @@ namespace AscNet.GameServer.Handlers
|
||||
notifyLogin.FashionList.AddRange(session.character.Fashions);
|
||||
|
||||
#if DEBUG
|
||||
// Per account settings flag(?)
|
||||
notifyLogin.PlayerData.GuideData = GuideGroupTableReader.Instance.All.Select(x => (long)x.Id).ToList();
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -120,7 +120,7 @@ namespace AscNet.GameServer
|
||||
#endif
|
||||
}
|
||||
|
||||
log.Info("Finished Loading Packet Handlers");
|
||||
log.Info("Finished loading packet handlers");
|
||||
}
|
||||
|
||||
public static RequestPacketHandlerDelegate? GetRequestPacketHandler(string name)
|
||||
|
||||
@@ -19,12 +19,16 @@ namespace AscNet.GameServer
|
||||
}
|
||||
}
|
||||
|
||||
public Server()
|
||||
static Server()
|
||||
{
|
||||
// TODO: add loglevel based on appsettings
|
||||
LogLevel logLevel = LogLevel.DEBUG;
|
||||
LogLevel fileLogLevel = LogLevel.DEBUG;
|
||||
log = new(typeof(Server), logLevel, fileLogLevel);
|
||||
}
|
||||
|
||||
public Server()
|
||||
{
|
||||
listener = new(IPAddress.Parse("0.0.0.0"), Common.Common.config.GameServer.Port);
|
||||
}
|
||||
|
||||
@@ -54,5 +58,10 @@ namespace AscNet.GameServer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Session? SessionFromUID(long uid)
|
||||
{
|
||||
return Sessions.FirstOrDefault(x => x.Value.player.PlayerData.Id == uid).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user