예제 #1
0
        public void InitializeHandlers(Action <string, CommandHandlerAttribute> globalCommandRegister)
        {
            foreach (var(method, cmdAttr, parserType) in ResolveHandlers())
            {
                // Get a safe command name to take command duplicate situation
                var safeCommandName = cmdAttr.Command;
                var cmdIndex        = 0;
                while (commandHandlers.ContainsKey(safeCommandName))
                {
                    safeCommandName = $"{safeCommandName}{++cmdIndex}";
                }
                if (cmdIndex > 0)
                {
                    Logger.LogWarning($"Command {safeCommandName} was duplicated! Rename to '{safeCommandName}'");
                }
                // Add command handlers to dictionary
                var commandHandlerInfo = new CommandHandlerInfo
                {
                    CommandHandler = method,
                    IsAwaitable    = method.ReturnType.GetMethods().Any((method) => method.Name == "GetAwaiter"),
                };

                // Add parser instance to dictionary
                // Check parser assignable
                if (!typeof(IParser).IsAssignableFrom(parserType))
                {
                    Logger.LogWarning($"Command handler parser type not implement IParse interface!");
                }
                // Add 'commandHandler' as Parser
                if (parserType == CommandContainerType)
                {
                    parsers.Add(parserType, CommandContainer as IParser);
                }
                // Create new parser instance in Arrtibute
                else if (parserType != typeof(DefaultParser) && !parsers.ContainsKey(parserType))
                {
                    parsers.Add(parserType, Activator.CreateInstance(parserType) as IParser);
                }

                // Associate command and parser
                commandHandlerInfo.HandlerParserType = parserType;
                commandHandlers.Add(safeCommandName, commandHandlerInfo);

                // if command has CommandAlias attribute, register as global command
                if (method.GetCustomAttribute <CommandAliasAttribute>() is CommandAliasAttribute attr)
                {
                    globalCommandRegister(attr.Alias, cmdAttr);
                }
            }
        }
        /// <inheritdoc />
        public Task ExecuteAsync(IServerCommand serverCommand, CancellationToken cancellationToken)
        {
            var serverCommandType = serverCommand.GetType();

            if (!_serverCommandHandlerInfo.TryGetValue(serverCommandType, out var commandHandlerInfo))
            {
                var handlerType        = typeof(IServerCommandHandler <>).MakeGenericType(serverCommandType);
                var executeAsyncMethod = handlerType.GetRuntimeMethod("ExecuteAsync", new[] { serverCommandType, typeof(CancellationToken) });
                var handler            = _ftpConnectionAccessor.FtpConnection.ConnectionServices.GetRequiredService(handlerType);

                commandHandlerInfo = new CommandHandlerInfo(handler, executeAsyncMethod);
                _serverCommandHandlerInfo.Add(serverCommandType, commandHandlerInfo);
            }

            return((Task)commandHandlerInfo.ExecuteMethodInfo.Invoke(
                       commandHandlerInfo.CommandHandler,
                       new object[] { serverCommand, cancellationToken }));
        }
예제 #3
0
        public static void Handle(ClientMessage clientMessage, Session session)
        {
            var message = clientMessage.Payload.ReadString16L();

            if (message.StartsWith("@"))
            {
                string commandRaw = message.Remove(0, 1);
                CommandHandlerResponse response       = CommandHandlerResponse.InvalidCommand;
                CommandHandlerInfo     commandHandler = null;
                string   command    = null;
                string[] parameters = null;

                try
                {
                    CommandManager.ParseCommand(message.Remove(0, 1), out command, out parameters);
                }
                catch (Exception ex)
                {
                    log.Error($"Exception while parsing command: {commandRaw}", ex);
                    return;
                }

                try
                {
                    response = CommandManager.GetCommandHandler(session, command, parameters, out commandHandler);
                }
                catch (Exception ex)
                {
                    log.Error($"Exception while getting command handler for: {commandRaw}", ex);
                }

                if (response == CommandHandlerResponse.Ok)
                {
                    try
                    {
                        if (commandHandler.Attribute.IncludeRaw)
                        {
                            parameters = CommandManager.StuffRawIntoParameters(message.Remove(0, 1), command, parameters);
                        }
                        ((CommandHandler)commandHandler.Handler).Invoke(session, parameters);
                    }
                    catch (Exception ex)
                    {
                        log.Error($"Exception while invoking command handler for: {commandRaw}", ex);
                    }
                }
                else if (response == CommandHandlerResponse.SudoOk)
                {
                    string[] sudoParameters = new string[parameters.Length - 1];
                    for (int i = 1; i < parameters.Length; i++)
                    {
                        sudoParameters[i - 1] = parameters[i];
                    }
                    try
                    {
                        if (commandHandler.Attribute.IncludeRaw)
                        {
                            parameters = CommandManager.StuffRawIntoParameters(message.Remove(0, 1), command, parameters);
                        }
                        ((CommandHandler)commandHandler.Handler).Invoke(session, sudoParameters);
                    }
                    catch (Exception ex)
                    {
                        log.Error($"Exception while invoking command handler for: {commandRaw}", ex);
                    }
                }
                else
                {
                    switch (response)
                    {
                    case CommandHandlerResponse.InvalidCommand:
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Unknown command: {command}", ChatMessageType.Help));
                        break;

                    case CommandHandlerResponse.InvalidParameterCount:
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Invalid parameter count, got {parameters.Length}, expected {commandHandler.Attribute.ParameterCount}!", ChatMessageType.Help));
                        session.Network.EnqueueSend(new GameMessageSystemChat($"@{commandHandler.Attribute.Command} - {commandHandler.Attribute.Description}", ChatMessageType.Broadcast));
                        session.Network.EnqueueSend(new GameMessageSystemChat($"Usage: @{commandHandler.Attribute.Command} {commandHandler.Attribute.Usage}", ChatMessageType.Broadcast));
                        break;

                    default:
                        break;
                    }
                }
            }
            else
            {
                // We only want to handle @commands, thank you very much!
                // session.Player.HandleActionTalk(message);
            }
        }