From bdc8785fe18a42ecf766e3958c3ca55ec35218ce Mon Sep 17 00:00:00 2001 From: rfi Date: Thu, 22 Feb 2024 21:22:48 +0700 Subject: [PATCH] extending command for user and prevent err in build ship menu --- BLHX.Server.Common/Database/Player.cs | 10 +++- BLHX.Server.Game/Commands/Command.cs | 65 ++++++++++++++++++++---- BLHX.Server.Game/Commands/HelpCommand.cs | 29 +++++++++-- BLHX.Server.Game/Connection.cs | 5 +- BLHX.Server.Game/Handlers/P11.cs | 5 ++ BLHX.Server.Game/Handlers/P12.cs | 5 ++ BLHX.Server.Game/Handlers/P50.cs | 29 +++++++++++ BLHX.Server.Game/Managers/ChatManager.cs | 2 +- 8 files changed, 133 insertions(+), 17 deletions(-) diff --git a/BLHX.Server.Common/Database/Player.cs b/BLHX.Server.Common/Database/Player.cs index 1136f51..3d665e4 100644 --- a/BLHX.Server.Common/Database/Player.cs +++ b/BLHX.Server.Common/Database/Player.cs @@ -335,15 +335,21 @@ namespace BLHX.Server.Common.Database case ResourceFieldType.Gold: if (Data.Data.GoldFieldTemplate.TryGetValue((int)Level, out var goldTemplate)) { + var res = Player.Resources.FirstOrDefault(x => x.Id == 7); var num = (goldTemplate.HourTime * goldTemplate.Production) / 3600f * LastHarvestTime.GetSecondsPassed(); - Player.DoResource(7, (int)Math.Min((uint)Math.Floor(num), goldTemplate.Store)); + + if (res is not null) + res.Num = Math.Min((uint)Math.Floor(num), goldTemplate.Store); } break; case ResourceFieldType.Oil: if (Data.Data.OilFieldTemplate.TryGetValue((int)Level, out var oilTemplate)) { + var res = Player.Resources.FirstOrDefault(x => x.Id == 5); var num = (oilTemplate.HourTime * oilTemplate.Production) / 3600f * LastHarvestTime.GetSecondsPassed(); - Player.DoResource(5, (int)Math.Min((uint)Math.Floor(num), oilTemplate.Store)); + + if (res is not null) + res.Num = Math.Min((uint)Math.Floor(num), oilTemplate.Store); } break; } diff --git a/BLHX.Server.Game/Commands/Command.cs b/BLHX.Server.Game/Commands/Command.cs index b821974..65bf50a 100644 --- a/BLHX.Server.Game/Commands/Command.cs +++ b/BLHX.Server.Game/Commands/Command.cs @@ -30,8 +30,30 @@ public class ArgumentAttribute : Attribute } } +[Flags] +public enum CommandUsage +{ + None = 0, + Console = 1, + User = 2 +} + public abstract class Command { + public virtual CommandUsage Usage + { + get + { + var usage = CommandUsage.None; + if (GetType().GetMethod(nameof(Execute), [typeof(Dictionary), typeof(Connection)])?.DeclaringType == GetType()) + usage |= CommandUsage.User; + if (GetType().GetMethod(nameof(Execute), [typeof(Dictionary)])?.DeclaringType == GetType()) + usage |= CommandUsage.Console; + + return usage; + } + } + readonly Dictionary argsProperties; public Command() @@ -50,6 +72,11 @@ public abstract class Command } } + public virtual void Execute(Dictionary args, Connection connection) + { + Execute(args); + } + protected T Parse(string? value, T fallback = default!) { var tryParseMethod = typeof(T).GetMethod("TryParse", [typeof(string), typeof(T).MakeByRefType()]); @@ -72,10 +99,12 @@ public static class CommandHandlerFactory public static readonly List Commands = new List(); static readonly Dictionary>> commandFunctions; + static readonly Dictionary, Connection>> commandFunctionsConn; static CommandHandlerFactory() { commandFunctions = new Dictionary>>(StringComparer.OrdinalIgnoreCase); + commandFunctionsConn = new Dictionary, Connection>>(StringComparer.OrdinalIgnoreCase); RegisterCommands(Assembly.GetExecutingAssembly()); } @@ -91,24 +120,23 @@ public static class CommandHandlerFactory if (commandAttribute != null) { var commandInstance = (Command)Activator.CreateInstance(commandType)!; - commandFunctions[commandAttribute.Name] = commandInstance.Execute; + + if (commandInstance.Usage.HasFlag(CommandUsage.Console)) + commandFunctions[commandAttribute.Name] = commandInstance.Execute; + if (commandInstance.Usage.HasFlag(CommandUsage.User)) + commandFunctionsConn[commandAttribute.Name] = commandInstance.Execute; + Commands.Add(commandInstance); } } } - public static void HandleCommand(string commandLine) + public static void HandleCommand(string commandLine, Connection? connection = null) { 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(StringComparer.OrdinalIgnoreCase); for (var i = 1; i < parts.Length; i++) { @@ -117,6 +145,25 @@ public static class CommandHandlerFactory arguments[argParts[0]] = argParts[1]; } - command(arguments); + if (connection is not null) + { + if (!(commandFunctionsConn).TryGetValue(parts[0], out var command)) + { + Logger.c.Warn($"Unknown command: {parts[0]}"); + return; + } + + command(arguments, connection); + } + else + { + if (!(commandFunctions).TryGetValue(parts[0], out var command)) + { + Logger.c.Warn($"Unknown command: {parts[0]}"); + return; + } + + command(arguments); + } } } diff --git a/BLHX.Server.Game/Commands/HelpCommand.cs b/BLHX.Server.Game/Commands/HelpCommand.cs index 28cd30d..b1553d6 100644 --- a/BLHX.Server.Game/Commands/HelpCommand.cs +++ b/BLHX.Server.Game/Commands/HelpCommand.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using BLHX.Server.Game.Handlers; +using System.Reflection; using System.Text; namespace BLHX.Server.Game.Commands; @@ -15,7 +16,29 @@ public class HelpCommand : Command StringBuilder sb = new StringBuilder(); sb.AppendLine("Available Commands: "); - foreach (var command in CommandHandlerFactory.Commands) + foreach (var command in CommandHandlerFactory.Commands.Where(x => x.Usage.HasFlag(CommandUsage.Console))) + { + 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}), Usage: {command.Usage}"); + } + + Console.Write(sb.ToString()); + } + + public override void Execute(Dictionary args, Connection connection) + { + base.Execute(args); + + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("Available Commands: "); + foreach (var command in CommandHandlerFactory.Commands.Where(x => x.Usage.HasFlag(CommandUsage.User))) { if (!commandAttributes.TryGetValue(command.GetType(), out var attr)) { @@ -27,6 +50,6 @@ public class HelpCommand : Command sb.AppendLine($" {attr.Name} - {attr.Description} (Example: {attr.Example})"); } - Console.Write(sb.ToString()); + connection.SendSystemMsg(sb.ToString()); } } diff --git a/BLHX.Server.Game/Connection.cs b/BLHX.Server.Game/Connection.cs index 80542a0..16645a4 100644 --- a/BLHX.Server.Game/Connection.cs +++ b/BLHX.Server.Game/Connection.cs @@ -7,7 +7,6 @@ using ProtoBuf; using System.Buffers.Binary; using System.Net; using System.Net.Sockets; -using System.Reflection; using System.Text; namespace BLHX.Server.Game @@ -148,7 +147,7 @@ namespace BLHX.Server.Game DBManager.PlayerContext.Save(); this.NotifyResourceList(); #if DEBUG - c.Log($"Tick"); + c.Log("Ticked!"); #endif } @@ -167,6 +166,8 @@ namespace BLHX.Server.Game this.NotifyShopMonthData(); this.NotifyChapterData(); this.NotifyBagData(); + this.NotifyBuildShipData(); + this.NotifyActivityData(); this.NotifyDormData(); this.NotifyNavalAcademy(); } diff --git a/BLHX.Server.Game/Handlers/P11.cs b/BLHX.Server.Game/Handlers/P11.cs index fc6351d..d132837 100644 --- a/BLHX.Server.Game/Handlers/P11.cs +++ b/BLHX.Server.Game/Handlers/P11.cs @@ -113,5 +113,10 @@ namespace BLHX.Server.Game.Handlers { connection.Send(new Sc11752()); } + + public static void NotifyActivityData(this Connection connection) + { + connection.Send(new Sc11200()); + } } } diff --git a/BLHX.Server.Game/Handlers/P12.cs b/BLHX.Server.Game/Handlers/P12.cs index 3ac204c..72eb4ba 100644 --- a/BLHX.Server.Game/Handlers/P12.cs +++ b/BLHX.Server.Game/Handlers/P12.cs @@ -48,5 +48,10 @@ namespace BLHX.Server.Game.Handlers }); } } + + public static void NotifyBuildShipData(this Connection connection) + { + connection.Send(new Sc12024()); + } } } diff --git a/BLHX.Server.Game/Handlers/P50.cs b/BLHX.Server.Game/Handlers/P50.cs index 02fd4b3..f285133 100644 --- a/BLHX.Server.Game/Handlers/P50.cs +++ b/BLHX.Server.Game/Handlers/P50.cs @@ -22,6 +22,12 @@ namespace BLHX.Server.Game.Handlers { var req = packet.Decode(); + if (req.Content.StartsWith("/")) + { + Commands.CommandHandlerFactory.HandleCommand(req.Content.Substring(1), connection); + return; + } + GameServer.ChatManager.SendChat(new() { Content = req.Content, @@ -35,4 +41,27 @@ namespace BLHX.Server.Game.Handlers }); } } + + static class P50ConnectionNotifyExtensions + { + public static void SendSystemMsg(this Connection connection, string msg) + { + + var ntf = new Sc50101() + { + Content = msg, + Player = new() + { + Name = "System", + Display = new() + { + Icon = 107061 + } + }, + Type = 1 + }; + + connection.Send(ntf); + } + } } diff --git a/BLHX.Server.Game/Managers/ChatManager.cs b/BLHX.Server.Game/Managers/ChatManager.cs index 6a57073..2ed8880 100644 --- a/BLHX.Server.Game/Managers/ChatManager.cs +++ b/BLHX.Server.Game/Managers/ChatManager.cs @@ -6,7 +6,7 @@ namespace BLHX.Server.Game.Managers { List messages = []; - public void SendChat(MsgInfo msgInfo) + public void SendChat(MsgInfo msgInfo, bool broadcast = true) { msgInfo.Timestamp = (uint)DateTimeOffset.Now.ToUnixTimeSeconds();