Wolfringo Wolfringo
Wolfringo Wolfringo
Wolfringo (c) 2020 TehGM
DocFX, DiscordFX theme.
Search Results for

    Wolfringo Commands System

    Using AddMessageListener works well for testing, or for events that aren't Chat Messages. However having a bot written using just the message listeners would mean that you manually need to handle errors logging, prefix checking, checking if user is admin, etc - that's A LOT of repetitive boilerplate code.

    To address this, Wolfringo has an extensible Commands System. This System is attribute-based, and supports Dependency Injection out of the box.

    Enable Commands System in your bot

    Commands System is included in both Wolfringo metapackage and Wolfringo.Hosting. If you're not using either (for example when using Wolfringo.Core directly), it can be installed with Wolfringo.Commands package. See Installation instructions for guide how to install Wolfringo components.

    Like with the Bot itself, enabling Commands System depends on whether you're using Wolfringo.Hosting or not.

    • Without Wolfringo.Hosting (Normal Bot)
    • With Wolfringo.Hosting (.NET Generic Host/ASP.NET Core)

    First add following using directive to your Program.cs:

    using Wolfringo.Commands;
    

    Since Wolfringo v2.0, commands can be really easily enabled by calling WithCommands method on the client builder. This method expects a delegate, where you can build commands service.

    _client = new WolfClientBuilder()
        // .. other client configuration ...
        .WithLogging(CreateLoggerFactory())
        .WithCommands(commands => 
        {
            // determines what all the commands should start with - for example "!", "!mybot" etc. Default value is "!".
            commands.WithPrefix("!");
            // determines when the prefix is required. By default it's always required, but you can for example make prefix optional by setting this value to PrefixRequirement.Group.
            commands.WithPrefixRequirement(PrefixRequirement.Always);
            // determines whether commands are case-sensitive. By default, all commands are case-insensitive.
            commands.WithCaseSensitivity(false);
    
            // you can also register any custom service by using
            // commands.WithService<T>();
        })
        .Build();
    
    // connect bot here with "_client.ConnectAsync();"
    

    Commands enable this way will automatically inherit all services and settings, such as logging and Wolf Client itself provided to WolfClientBuilder itself. Services set inside of WithCommands delegate will be available only to Commands System.

    If you wish, you can create CommandsService separately to get more control. Please note that in such case, you need to manually provide IWolfClient instance, call StartAsync(), and that services and logging will NOT be automatically shared.

    _client = new WolfClientBuilder()
        .WithLogging(CreateLoggerFactory())
        .Build();
    CommandsService commands = new CommandsServiceBuilder()
        .WithWolfClient(_client)            // required when creating separately
        .WithLogging(CreateLoggerFactory()) // when created separately, client and commands don't share logging
        .ConfigureOptions(options => 
        {
            // do configuration here
        })
        .Build();
    
    await services.StartAsync();
    // connect bot here with "_client.ConnectAsync();"
    

    Choose where commands are loaded from

    By default, all commands in the project that starts your bot process are loaded. You can change that using .ConfigureOptions method and the CommandsOptions it provides in the delegate.

    Load commands from other assemblies

    You can load commands from other projects, or even different libraries. To do so, simply add assembly to Assemblies property:

    .ConfigureOptions(options =>
    {
        options.Assemblies.Add(typeof(HandlerInAnotherProject).Assembly));
    })
    

    Add commands individually

    You can also add individual Handler to be loaded. Simply add its type to Classes property:

    .ConfigureOptions(options =>
    {
        options.Classes.Add(typeof(Handler));
    })
    

    If you're adding handlers individually, you might want to disable behaviour of loading all commands from bot entry assembly.

    .ConfigureOptions(options =>
    {
        options.Assemblies.Clear();
    })
    

    Logging

    When using WolfClientBuilder.WithCommands() to add commands, Commands Service will automatically inherit logging configuration from the client.

    _client = new WolfClientBuilder()
        .WithLogging(CreateLoggerFactory())
        .WithCommands(commands => 
        {
            // do other config. Logging will automatically be inherited.
        })
        .Build();
    

    If you're creating CommandsService separately using CommandsServiceBuilder, CommandsServiceBuilder also has WithLogging method which functions the same way.

    Check Logging guide for more information.

    When using Wolfringo.Hosting, enabling Commands System is done inside ConfigureServices, just like the bot itself. Simply add this code:

    services.AddWolfringoCommands()
        .SetPrefix("!")           
        .SetPrefixRequirement(PrefixRequirement.Always)
        .SetCaseSensitive(false);
    

    Basic Commands configuration is pretty straightforward:

    • SetPrefix determines what all the commands should start with - for example "!", "!mybot" etc. Default value is "!".
    • SetPrefixRequirement determines when the prefix is required. By default it's always required, but you can for example make prefix optional by setting this value to PrefixRequirement.Group.
    • SetCaseSensitive determines whether commands are case-sensitive. By default, all commands are case-insensitive (the value is set to "false").
    Tip

    Using application settings file is recommended instead of hardcoding the settings. See appsettings.json example, and add following method call to your ConfigureServices:

     services.Configure<CommandsOptions>(context.Configuration.GetSection("Commands"));
    

    Choose where commands are loaded from

    By default, all commands in the project that starts your bot process are loaded. You can change that with method calls straight after AddWolfringoCommands().

    Load commands from other assemblies

    You can load commands from other projects, or even different libraries. To do so, simply call AddHandlers():

    services.AddWolfringoCommands()
        .AddHandlers(typeof(HandlerInAnotherProject).Assembly));
    

    Add commands individually

    You can also add individual Handler to be loaded. Simply call AddHandler():

    services.AddWolfringoCommands()
        .AddHandler<Handler>();
    

    If you're adding handlers individually, you might want to disable behaviour of loading all commands from bot entry assembly.

    services.AddWolfringoCommands()
        .RemoveDefaultHandlers();
    

    Logging

    One of purposes of the Commands System is to reduce amount of boilerplate code for logging etc. @TehGM.Wolfringo.Hosting.Commands.HostedCommandsHandler will automatically use logging as configured for your Host.

    Check Logging guide for more information.

    Next steps

    Now that you enabled Commands System in your bot, you can start adding Commands Handlers and commands themselves. See Creating Commands guide!

    You can also check SimpleCommandsBot Example (Normal Bot) or HostedCommandsBot Example (.NET Generic Host/ASP.NET Core) for full example on Wolfringo usage with Commands System. Feel free to also check other example projects!