Add command prefix configuration
This commit is contained in:
parent
87619a728e
commit
2206185d55
@ -2,7 +2,14 @@ namespace PluralKit.Bot
|
|||||||
{
|
{
|
||||||
public class BotConfig
|
public class BotConfig
|
||||||
{
|
{
|
||||||
|
public static readonly string[] DefaultPrefixes = {"pk;", "pk!"};
|
||||||
|
|
||||||
public string Token { get; set; }
|
public string Token { get; set; }
|
||||||
public ulong? ClientId { get; set; }
|
public ulong? ClientId { get; set; }
|
||||||
|
|
||||||
|
// ASP.NET configuration merges arrays with defaults, so we leave this field nullable
|
||||||
|
// and fall back to the separate default array at the use site :)
|
||||||
|
// This does bind [] as null (therefore default) instead of an empty array, but I can live w/ that.
|
||||||
|
public string[] Prefixes { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,11 +23,11 @@ namespace PluralKit.Bot
|
|||||||
private readonly ProxyService _proxy;
|
private readonly ProxyService _proxy;
|
||||||
private readonly ILifetimeScope _services;
|
private readonly ILifetimeScope _services;
|
||||||
private readonly IDatabase _db;
|
private readonly IDatabase _db;
|
||||||
private readonly IDataStore _data;
|
private readonly BotConfig _config;
|
||||||
|
|
||||||
public MessageCreated(LastMessageCacheService lastMessageCache, LoggerCleanService loggerClean,
|
public MessageCreated(LastMessageCacheService lastMessageCache, LoggerCleanService loggerClean,
|
||||||
IMetrics metrics, ProxyService proxy, DiscordShardedClient client,
|
IMetrics metrics, ProxyService proxy, DiscordShardedClient client,
|
||||||
CommandTree tree, ILifetimeScope services, IDatabase db, IDataStore data)
|
CommandTree tree, ILifetimeScope services, IDatabase db, BotConfig config)
|
||||||
{
|
{
|
||||||
_lastMessageCache = lastMessageCache;
|
_lastMessageCache = lastMessageCache;
|
||||||
_loggerClean = loggerClean;
|
_loggerClean = loggerClean;
|
||||||
@ -37,7 +37,7 @@ namespace PluralKit.Bot
|
|||||||
_tree = tree;
|
_tree = tree;
|
||||||
_services = services;
|
_services = services;
|
||||||
_db = db;
|
_db = db;
|
||||||
_data = data;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscordChannel ErrorChannelFor(MessageCreateEventArgs evt) => evt.Channel;
|
public DiscordChannel ErrorChannelFor(MessageCreateEventArgs evt) => evt.Channel;
|
||||||
@ -87,26 +87,19 @@ namespace PluralKit.Bot
|
|||||||
var content = evt.Message.Content;
|
var content = evt.Message.Content;
|
||||||
if (content == null) return false;
|
if (content == null) return false;
|
||||||
|
|
||||||
var argPos = -1;
|
// Check for command prefix
|
||||||
// Check if message starts with the command prefix
|
if (!HasCommandPrefix(content, out var cmdStart))
|
||||||
if (content.StartsWith("pk;", StringComparison.InvariantCultureIgnoreCase)) argPos = 3;
|
return false;
|
||||||
else if (content.StartsWith("pk!", StringComparison.InvariantCultureIgnoreCase)) argPos = 3;
|
|
||||||
else if (DiscordUtils.HasMentionPrefix(content, ref argPos, out var id)) // Set argPos to the proper value
|
|
||||||
if (id != _client.CurrentUser.Id) // But undo it if it's someone else's ping
|
|
||||||
argPos = -1;
|
|
||||||
|
|
||||||
// If we didn't find a prefix, give up handling commands
|
// Trim leading whitespace from command without actually modifying the string
|
||||||
if (argPos == -1) return false;
|
|
||||||
|
|
||||||
// Trim leading whitespace from command without actually modifying the wring
|
|
||||||
// This just moves the argPos pointer by however much whitespace is at the start of the post-argPos string
|
// This just moves the argPos pointer by however much whitespace is at the start of the post-argPos string
|
||||||
var trimStartLengthDiff = content.Substring(argPos).Length - content.Substring(argPos).TrimStart().Length;
|
var trimStartLengthDiff = content.Substring(cmdStart).Length - content.Substring(cmdStart).TrimStart().Length;
|
||||||
argPos += trimStartLengthDiff;
|
cmdStart += trimStartLengthDiff;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var system = ctx.SystemId != null ? await _db.Execute(c => c.QuerySystem(ctx.SystemId.Value)) : null;
|
var system = ctx.SystemId != null ? await _db.Execute(c => c.QuerySystem(ctx.SystemId.Value)) : null;
|
||||||
await _tree.ExecuteCommand(new Context(_services, evt.Client, evt.Message, argPos, system, ctx));
|
await _tree.ExecuteCommand(new Context(_services, evt.Client, evt.Message, cmdStart, system, ctx));
|
||||||
}
|
}
|
||||||
catch (PKError)
|
catch (PKError)
|
||||||
{
|
{
|
||||||
@ -117,6 +110,26 @@ namespace PluralKit.Bot
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasCommandPrefix(string message, out int argPos)
|
||||||
|
{
|
||||||
|
// First, try prefixes defined in the config
|
||||||
|
var prefixes = _config.Prefixes ?? BotConfig.DefaultPrefixes;
|
||||||
|
foreach (var prefix in prefixes)
|
||||||
|
{
|
||||||
|
if (!message.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase)) continue;
|
||||||
|
|
||||||
|
argPos = prefix.Length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, check mention prefix (must be the bot user, ofc)
|
||||||
|
argPos = -1;
|
||||||
|
if (DiscordUtils.HasMentionPrefix(message, ref argPos, out var id))
|
||||||
|
return id == _client.CurrentUser.Id;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private async ValueTask<bool> TryHandleProxy(MessageCreateEventArgs evt, MessageContext ctx)
|
private async ValueTask<bool> TryHandleProxy(MessageCreateEventArgs evt, MessageContext ctx)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -17,6 +17,7 @@ The configuration file needs to be placed in the bot's working directory (usuall
|
|||||||
The configuration file is in JSON format (albeit with a `.conf` extension). The following keys are available (using `.` to indicate a nested object level), bolded key names are required:
|
The configuration file is in JSON format (albeit with a `.conf` extension). The following keys are available (using `.` to indicate a nested object level), bolded key names are required:
|
||||||
* **`PluralKit.Bot.Token`**: the Discord bot token to connect with
|
* **`PluralKit.Bot.Token`**: the Discord bot token to connect with
|
||||||
* **`PluralKit.Database`**: the URI of the database to connect to (in [ADO.NET Npgsql format](https://www.connectionstrings.com/npgsql/))
|
* **`PluralKit.Database`**: the URI of the database to connect to (in [ADO.NET Npgsql format](https://www.connectionstrings.com/npgsql/))
|
||||||
|
* `PluralKit.Bot.Prefixes`: an array of command prefixes to use (default `["pk;", "pk!"]`).
|
||||||
* `PluralKit.Bot.ClientId` *(optional)*: the ID of the bot's user account, used when generating invite links through `pk;invite`. It's automatically determined if not present, but overriding it may be useful for private instances that still want a public invite link.
|
* `PluralKit.Bot.ClientId` *(optional)*: the ID of the bot's user account, used when generating invite links through `pk;invite`. It's automatically determined if not present, but overriding it may be useful for private instances that still want a public invite link.
|
||||||
* `PluralKit.SentryUrl` *(optional)*: the [Sentry](https://sentry.io/welcome/) client key/DSN to report runtime errors to. If absent, disables Sentry integration.
|
* `PluralKit.SentryUrl` *(optional)*: the [Sentry](https://sentry.io/welcome/) client key/DSN to report runtime errors to. If absent, disables Sentry integration.
|
||||||
* `PluralKit.InfluxUrl` *(optional)*: the URL to an [InfluxDB](https://www.influxdata.com/products/influxdb-overview/) server to report aggregate statistics to. An example of these stats can be seen on [the public stats page](https://stats.pluralkit.me).
|
* `PluralKit.InfluxUrl` *(optional)*: the URL to an [InfluxDB](https://www.influxdata.com/products/influxdb-overview/) server to report aggregate statistics to. An example of these stats can be seen on [the public stats page](https://stats.pluralkit.me).
|
||||||
|
Loading…
Reference in New Issue
Block a user