static async Task Main(string[] args) { // register to unhandled exceptions handling // this allows logging exceptions that were not handled with a try-catch block AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; // optional: create a logger factory ILoggerFactory logFactory = CreateLoggerFactory(); // optional: enable DI - add logger factory to it as well IServiceCollection services = new ServiceCollection() .AddSingleton <ILoggerFactory>(logFactory); // create client and listen to events we're interested in _client = new WolfClient(logFactory.CreateLogger <WolfClient>()); _client.AddMessageListener <WelcomeEvent>(OnWelcome); // these 2 callbacks are invoked if received message is a WolfEvent (first callback) // initialize commands system CommandsOptions options = new CommandsOptions() { Prefix = "!", // set prefix RequirePrefix = PrefixRequirement.Always, // make prefix always required - can also for example require it in group only CaseSensitivity = false // make commands case insensitive }; CommandsService commands = new CommandsService(_client, options, logFactory.CreateLogger <CommandsService>(), services.BuildServiceProvider()); await commands.StartAsync(); // calling StartAsync causes reload of all commands // start connection and prevent the application from closing await _client.ConnectAsync(); await Task.Delay(-1); }
protected override async Task InitializeCommandsAsync() { await this._lock.WaitAsync(_hostCancellationToken).ConfigureAwait(false); try { this._log.LogDebug("Initializing commands"); this.Commands.Clear(); CommandsOptions options = this._commandOptions.CurrentValue; foreach (Assembly asm in options.Assemblies) { this.AddAssembly(asm); } foreach (Type t in options.Classes) { this.AddType(t.GetTypeInfo()); } this.Commands = Commands.OrderByDescending(cmd => cmd.Priority).ToArray(); } finally { this._lock.Release(); } }
protected override async Task InitializeCommandsAsync() { _log.LogDebug("Initializing CommandService"); try { (Commands as IDisposable)?.Dispose(); } catch { } CommandsOptions options = this._commandOptions.CurrentValue; CommandServiceConfig config = new CommandServiceConfig(); config.CaseSensitiveCommands = options.CaseSensitive; if (options.DefaultRunMode != RunMode.Default) { config.DefaultRunMode = options.DefaultRunMode; } config.IgnoreExtraArgs = options.IgnoreExtraArgs; this.Commands = new CommandService(config); foreach (Assembly asm in options.Assemblies) { await this.Commands.AddModulesAsync(asm, _serviceProvider).ConfigureAwait(false); } foreach (Type t in options.Classes) { await this.Commands.AddModuleAsync(t, _serviceProvider).ConfigureAwait(false); } }
public StellarisModsHandler(IStellarisModsStore stellarisModsStore, ILogger <StellarisModsHandler> log, IOptionsSnapshot <EinherjiOptions> einherjiOptions, IOptionsSnapshot <CommandsOptions> commandsOptions) { this._stellarisModsStore = stellarisModsStore; this._log = log; this._einherjiOptions = einherjiOptions.Value; this._commandsOptions = commandsOptions.Value; }
public IEnumerable <string> GetArgValidationErrors() { var errors = new List <string>(); if (List) { return(errors); } if (!ShowDefaults && Account == ServiceAccount.User) { if (string.IsNullOrWhiteSpace(Username)) { errors.Add("user is required when account=User"); } if (string.IsNullOrWhiteSpace(Password)) { errors.Add("pwd is required when account=User"); } } if (string.IsNullOrWhiteSpace(CommandLine)) { errors.Add("command is required"); } else { if (ExtraArgs.Count > 0) { CommandLine = CommandLine.TrimEnd() + " " + string.Join(" ", ExtraArgs); ExtraArgs.Clear(); } _commandRunData = CommandsOptions.Load(CommandLine); if (_commandRunData.Errors.Count > 0) { errors.Add("errors with arguments for /command"); errors.AddRange(_commandRunData.Errors); } else { _serviceCommand = _commandRunData.Command as ICanRunAsService; if (_serviceCommand == null) { errors.Add(_commandRunData.Command.GetType().Name + " does not implement ICanRunAsService"); } else { ServiceName = ServiceName ?? _serviceCommand.ServiceName; DisplayName = DisplayName ?? _serviceCommand.DisplayName; Description = Description ?? _serviceCommand.Description; } } } return(errors); }
public HelpHandler(ILogger <HelpHandler> log, IOptionsSnapshot <EinherjiOptions> einherjiOptions, IOptionsSnapshot <CommandsOptions> commandsOptions, IOptionsSnapshot <CommunityGoalsOptions> eliteOptions, SimpleCommandHandler simpleCommands, RegexCommandHandler regexCommands) { this._commandsOptions = commandsOptions.Value; this._einherjiOptions = einherjiOptions.Value; this._eliteOptions = eliteOptions.Value; this._log = log; this._simpleCommands = simpleCommands; this._regexCommands = regexCommands; }
private void ListCommandsThatCanBeRunAsService() { var commands = CommandsOptions.GetCommands() .Where(c => typeof(ICanRunAsService).IsAssignableFrom(c.CommandType)) .ToList(); if (commands.Count == 0) { Writer.WriteLine("no commands implement ICanRunAsService"); } else { foreach (var command in commands) { Writer.WriteLine(command.Attribute.FirstPrototype); } } }
private Task HandleCommandInternalAsync(SocketMessage msg) { // most of the implementation here taken from https://discord.foxbot.me/docs/guides/commands/intro.html // with my own pinch of customizations - TehGM // Don't process the command if it was a system message if (!(msg is SocketUserMessage message)) { return(Task.CompletedTask); } // Determine if the message is a command based on the prefix and make sure no bots trigger commands CommandsOptions options = this._commandOptions.CurrentValue; // only execute if not a bot message if (!options.AcceptBotMessages && message.Author.IsBot) { return(Task.CompletedTask); } // get prefix and argPos int argPos = 0; bool requirePrefix = msg.Channel is SocketGuildChannel ? options.RequirePublicMessagePrefix : options.RequirePrivateMessagePrefix; bool hasStringPrefix = message.HasStringPrefix(options.Prefix, ref argPos); bool hasMentionPrefix = false; if (!hasStringPrefix) { hasMentionPrefix = message.HasMentionPrefix(_client.CurrentUser, ref argPos); } // if prefix not found but is required, return if (requirePrefix && (!string.IsNullOrWhiteSpace(options.Prefix) && !hasStringPrefix) && (options.AcceptMentionPrefix && !hasMentionPrefix)) { return(Task.CompletedTask); } // Create a WebSocket-based command context based on the message SocketCommandContext context = new SocketCommandContext(_client, message); return(HandleCommandAsync(context, argPos)); }
/// <inheritdoc/> public ICommandInstance InitializeCommand(ICommandInstanceDescriptor descriptor, CommandsOptions options) { // validate this is a correct command attribute type if (!(descriptor.Attribute is CommandAttribute command)) { throw new ArgumentException($"{this.GetType().Name} can only be used with {typeof(CommandAttribute).Name} commands", nameof(descriptor.Attribute)); } // init instance return(new StandardCommandInstance( text: command.Text, method: descriptor.Method, requirements: descriptor.GetRequirements(), prefixOverride: descriptor.GetPrefixOverride(), prefixRequirementOverride: descriptor.GetPrefixRequirementOverride(), caseSensitivityOverride: descriptor.GetCaseSensitivityOverride())); }
public CommandsService(IOptions <CommandsOptions> options, IServiceProvider provider, DiscordClient client, ILogger <CommandsService> logger) { this._logger = logger; this._logger.LogTrace("Building Commands service"); this._options = options.Value; var config = new CommandsNextConfiguration { CaseSensitive = this._options.CaseSensitive, EnableMentionPrefix = this._options.EnableMentionPrefix, StringPrefixes = this._options.Prefixes, DmHelp = false, Services = provider }; this.CommandsExtension = client.UseCommandsNext(config); this.CommandsExtension.SetHelpFormatter <HelpFormatter>(); this.CommandsExtension.RegisterUserFriendlyTypeName <string>("text"); this.CommandsExtension.RegisterUserFriendlyTypeName <float>("floating point number"); this.CommandsExtension.RegisterUserFriendlyTypeName <double>("floating point number"); this.CommandsExtension.RegisterUserFriendlyTypeName <sbyte>("small integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <short>("small integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <int>("integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <long>("integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <byte>("unsigned small integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <ushort>("unsigned small integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <uint>("unsigned integer"); this.CommandsExtension.RegisterUserFriendlyTypeName <ulong>("unsigned integer"); this.CommandsExtension.CommandErrored += this.CommandsExtensionOnCommandErrored; this.CommandsExtension.CommandExecuted += this.CommandsExtensionOnCommandExecuted; var assemblies = Utils.LoadAndListPmkAssemblies(); HashSet <Type> nestedTypesNotToRegister = new(); foreach (var assembly in assemblies.Where(a => a.FullName?.Contains("PaperMalKing", StringComparison.InvariantCultureIgnoreCase) ?? true)) { nestedTypesNotToRegister.Clear(); this._logger.LogTrace("Found {Assembly} which may contain Commands modules", assembly); foreach (var type in assembly.GetExportedTypes() .Where(t => t.FullName !.EndsWith("Commands", StringComparison.InvariantCultureIgnoreCase))) { this._logger.LogTrace("Trying to register {@Type} command module", type); try { if (nestedTypesNotToRegister.Contains(type)) { continue; } var nestedTypes = type.GetNestedTypes(BindingFlags.Public) .Where(t => t.FullName !.EndsWith("Commands", StringComparison.InvariantCultureIgnoreCase)); foreach (var nestedType in nestedTypes) { nestedTypesNotToRegister.Add(nestedType); } this.CommandsExtension.RegisterCommands(type); } catch (Exception ex) { this._logger.LogError(ex, "Error occured while trying to register {FullName}", type.FullName); } this._logger.LogDebug("Successfully registered {@Type}", type); } } if (!this.CommandsExtension.RegisteredCommands.Any()) { this._logger.LogCritical("No commands were registered"); } this._logger.LogTrace("Building Commands service"); }
/// <inheritdoc/> public ICommandInstance InitializeCommand(ICommandInstanceDescriptor descriptor, CommandsOptions options) { // validate this is a correct command attribute type if (!(descriptor.Attribute is RegexCommandAttribute regexCommand)) { throw new ArgumentException($"{this.GetType().Name} can only be used with {typeof(RegexCommandAttribute).Name} commands", nameof(descriptor.Attribute)); } // if pattern starts with ^, replace it with \G // this will ensure it'll match start of the string when starting from index after prefix string pattern = regexCommand.Pattern; if (pattern.Length > 0 && pattern[0] == '^') { pattern = $@"\G{pattern.Substring(1)}"; } // init instance return(new RegexCommandInstance( pattern: pattern, regexOptions: regexCommand.Options, method: descriptor.Method, requirements: descriptor.GetRequirements(), prefixOverride: descriptor.GetPrefixOverride(), prefixRequirementOverride: descriptor.GetPrefixRequirementOverride(), caseSensitivityOverride: descriptor.GetCaseSensitivityOverride())); }
public void CmdDependencyInjection(IWolfClient client, ChatMessage message, IServiceProvider services, ILogger log, CommandsOptions options) { log.LogInformation("Current user: {UserID}", client.CurrentUserID.Value); log.LogInformation("Message contents: {Message}", message.Text); log.LogInformation("Type of IServiceProvider: {Type}", services.GetType().Name); log.LogInformation("Prefix: {Prefix}", options.Prefix); }