Search code examples
c#discorddsharp+

Is there a way to change command prefix without restarting a bot for changes to take action? (DSharpPlus)


I'm using this code to set configuration and register commands for CommandsNextExtension variable:

commandsConfig = new CommandsNextConfiguration
        {
            StringPrefixes = new string[] {prefix},
            EnableDms = false,
            EnableMentionPrefix = true
        };

        Commands = Client.UseCommandsNext(commandsConfig);
        Commands.RegisterCommands<CommandsList>();
        Commands.RegisterCommands<LavalinkCommands>();

Then i have this to write a new prefix to json file and after restarting a bot, prefix changes as it should:

[Command("prefix")]
    [Description("Changes the prefix for commands.")]
    public async Task Prefix(CommandContext ctx, [RemainingText] string prefix)
    {
        gPrefix[0] = prefix;
        string jsonString = File.ReadAllText("config.json");
        JObject jObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString) as JObject;
        JToken jToken = jObject.SelectToken("prefix");
        jToken.Replace(prefix);
        string updatedJsonString = jObject.ToString();
        File.WriteAllText("config.json", updatedJsonString);
        Bot.prefix = prefix;
        await ctx.Channel.SendMessageAsync($"Prefix successfully changed to {prefix}");
    }

And at this point i've tried using method UseCommandsNext with new config but i get an error: "System.InvalidOperationException: 'CommandsNext is already enabled for that client.'"

I don't think there's a way to change a config directly because

CommandsNextConfiguration Config { get; }

doesn't have a setter.

Also i've tried unregistering commands and registering them back, but obviously it doesn't have anything to do with prefix.


Solution

  • Try using a Prefix resolver delegate.

    Edit - Example: When you register commands next do

    var CommandsNext = client.UseCommandsNext(new CommandsNextConfiguration()
    {
        Services = Services,
        PrefixResolver = HandlePrefixAsync,
    });
    

    Now For our HandlePrefixAsync Method

    private static async Task<int> HandlePrefixAsync(DiscordMessage msg)
    {
        if(msg.Channel.Guild != null) return;
        string prefix = Database.GetPrefix(msg.Channel.GuildId);
        
        return msg.GetStringPrefixLength(prefix);
    }
    

    In The method HandlePrefixAsync, Return -1 if the prefix is not present otherwise return the length of the prefix

    ex: ! would return 1 ex: ? would return 1 ex: banana would return 6