Compare commits

...

4 commits

6 changed files with 280 additions and 249 deletions
src/EllieBot
Modules
strings

View file

@ -52,11 +52,8 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
public ValueTask<bool> StopHangman(ulong channelId) public ValueTask<bool> StopHangman(ulong channelId)
{ {
lock (_locker) if (_hangmanGames.TryRemove(channelId, out _))
{ return new(true);
if (_hangmanGames.TryRemove(channelId, out _))
return new(true);
}
return new(false); return new(false);
} }
@ -66,48 +63,50 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg) public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
{ {
if (_hangmanGames.ContainsKey(msg.Channel.Id)) if (!_hangmanGames.ContainsKey(msg.Channel.Id))
{ {
if (string.IsNullOrWhiteSpace(msg.Content)) return;
}
if (string.IsNullOrWhiteSpace(msg.Content))
return;
if (_cdCache.TryGetValue(msg.Author.Id, out _))
return;
HangmanGame.State state;
long rew = 0;
lock (_locker)
{
if (!_hangmanGames.TryGetValue(msg.Channel.Id, out var game))
return; return;
if (_cdCache.TryGetValue(msg.Author.Id, out _)) state = game.Guess(msg.Content.ToLowerInvariant());
if (state.GuessResult == HangmanGame.GuessResult.NoAction)
return; return;
HangmanGame.State state; if (state.GuessResult is HangmanGame.GuessResult.Incorrect or HangmanGame.GuessResult.AlreadyTried)
long rew = 0;
lock (_locker)
{ {
if (!_hangmanGames.TryGetValue(msg.Channel.Id, out var game)) _cdCache.Set(msg.Author.Id,
return; string.Empty,
new MemoryCacheEntryOptions
state = game.Guess(msg.Content.ToLowerInvariant()); {
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3)
if (state.GuessResult == HangmanGame.GuessResult.NoAction) });
return;
if (state.GuessResult is HangmanGame.GuessResult.Incorrect or HangmanGame.GuessResult.AlreadyTried)
{
_cdCache.Set(msg.Author.Id,
string.Empty,
new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3)
});
}
if (state.Phase == HangmanGame.Phase.Ended)
{
if (_hangmanGames.TryRemove(msg.Channel.Id, out _))
rew = _gcs.Data.Hangman.CurrencyReward;
}
} }
if (rew > 0) if (state.Phase == HangmanGame.Phase.Ended)
await _cs.AddAsync(msg.Author, rew, new("hangman", "win")); {
if (_hangmanGames.TryRemove(msg.Channel.Id, out _))
await SendState((ITextChannel)msg.Channel, msg.Author, msg.Content, state); rew = _gcs.Data.Hangman.CurrencyReward;
}
} }
if (rew > 0)
await _cs.AddAsync(msg.Author, rew, new("hangman", "win"));
await SendState((ITextChannel)msg.Channel, msg.Author, msg.Content, state);
} }
private Task<IUserMessage> SendState( private Task<IUserMessage> SendState(

View file

@ -53,10 +53,10 @@ public sealed partial class Help : EllieModule<HelpService>
var clientId = await _lazyClientId.Value; var clientId = await _lazyClientId.Value;
var repCtx = new ReplacementContext(Context) var repCtx = new ReplacementContext(Context)
.WithOverride("{0}", () => clientId.ToString()) .WithOverride("{0}", () => clientId.ToString())
.WithOverride("{1}", () => prefix) .WithOverride("{1}", () => prefix)
.WithOverride("%prefix%", () => prefix) .WithOverride("%prefix%", () => prefix)
.WithOverride("%bot.prefix%", () => prefix); .WithOverride("%bot.prefix%", () => prefix);
var text = SmartText.CreateFrom(botSettings.HelpText); var text = SmartText.CreateFrom(botSettings.HelpText);
return await repSvc.ReplaceAsync(text, repCtx); return await repSvc.ReplaceAsync(text, repCtx);
@ -87,8 +87,8 @@ public sealed partial class Help : EllieModule<HelpService>
} }
var menu = new SelectMenuBuilder() var menu = new SelectMenuBuilder()
.WithPlaceholder("Select a module to see its commands") .WithPlaceholder("Select a module to see its commands")
.WithCustomId("cmds:modules_select"); .WithCustomId("cmds:modules_select");
foreach (var m in topLevelModules) foreach (var m in topLevelModules)
menu.AddOption(m.Name, m.Name, GetModuleEmoji(m.Name)); menu.AddOption(m.Name, m.Name, GetModuleEmoji(m.Name));
@ -106,33 +106,33 @@ public sealed partial class Help : EllieModule<HelpService>
}); });
await Response() await Response()
.Paginated() .Paginated()
.Items(topLevelModules) .Items(topLevelModules)
.PageSize(12) .PageSize(12)
.CurrentPage(page) .CurrentPage(page)
.Interaction(inter) .Interaction(inter)
.AddFooter(false) .AddFooter(false)
.Page((items, _) => .Page((items, _) =>
{ {
var embed = CreateEmbed().WithOkColor().WithTitle(GetText(strs.list_of_modules)); var embed = CreateEmbed().WithOkColor().WithTitle(GetText(strs.list_of_modules));
if (!items.Any()) if (!items.Any())
{ {
embed = embed.WithOkColor().WithDescription(GetText(strs.module_page_empty)); embed = embed.WithOkColor().WithDescription(GetText(strs.module_page_empty));
return embed; return embed;
} }
items items
.ToList() .ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}", .ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
GetModuleDescription(module.Name) GetModuleDescription(module.Name)
+ "\n" + "\n"
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))), + Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
true)); true));
return embed; return embed;
}) })
.SendAsync(); .SendAsync();
} }
private string GetModuleDescription(string moduleName) private string GetModuleDescription(string moduleName)
@ -142,11 +142,11 @@ public sealed partial class Help : EllieModule<HelpService>
if (key.Key == strs.module_description_missing.Key) if (key.Key == strs.module_description_missing.Key)
{ {
var desc = _marmalades var desc = _marmalades
.GetLoadedMarmalades(Culture) .GetLoadedMarmalades(Culture)
.FirstOrDefault(m => m.Canaries .FirstOrDefault(m => m.Canaries
.Any(x => x.Name.Equals(moduleName, .Any(x => x.Name.Equals(moduleName,
StringComparison.InvariantCultureIgnoreCase))) StringComparison.InvariantCultureIgnoreCase)))
?.Description; ?.Description;
if (desc is not null) if (desc is not null)
return desc; return desc;
@ -238,18 +238,18 @@ public sealed partial class Help : EllieModule<HelpService>
var allowed = new List<CommandInfo>(); var allowed = new List<CommandInfo>();
var mdls = _cmds.Commands var mdls = _cmds.Commands
.Where(c => c.Module.GetTopLevelModule() .Where(c => c.Module.GetTopLevelModule()
.Name .Name
.StartsWith(module, StringComparison.InvariantCultureIgnoreCase)) .StartsWith(module, StringComparison.InvariantCultureIgnoreCase))
.ToArray(); .ToArray();
if (mdls.Length == 0) if (mdls.Length == 0)
{ {
var group = _cmds.Modules var group = _cmds.Modules
.Where(x => x.Parent is not null) .Where(x => x.Parent is not null)
.FirstOrDefault(x => string.Equals(x.Name.Replace("Commands", ""), .FirstOrDefault(x => string.Equals(x.Name.Replace("Commands", ""),
module, module,
StringComparison.InvariantCultureIgnoreCase)); StringComparison.InvariantCultureIgnoreCase));
if (group is not null) if (group is not null)
{ {
@ -272,8 +272,8 @@ public sealed partial class Help : EllieModule<HelpService>
var cmds = allowed.OrderBy(c => c.Aliases[0]) var cmds = allowed.OrderBy(c => c.Aliases[0])
.DistinctBy(x => x.Aliases[0]) .DistinctBy(x => x.Aliases[0])
.ToList(); .ToList();
// check preconditions for all commands, but only if it's not 'all' // check preconditions for all commands, but only if it's not 'all'
@ -284,12 +284,12 @@ public sealed partial class Help : EllieModule<HelpService>
succ = succ =
[ [
..(await cmds.Select(async x => ..(await cmds.Select(async x =>
{ {
var pre = await x.CheckPreconditionsAsync(Context, _services); var pre = await x.CheckPreconditionsAsync(Context, _services);
return (Cmd: x, Succ: pre.IsSuccess); return (Cmd: x, Succ: pre.IsSuccess);
}) })
.WhenAll()).Where(x => x.Succ) .WhenAll()).Where(x => x.Succ)
.Select(x => x.Cmd) .Select(x => x.Cmd)
]; ];
if (opts.View == CommandsOptions.ViewType.Hide) if (opts.View == CommandsOptions.ViewType.Hide)
@ -298,8 +298,8 @@ public sealed partial class Help : EllieModule<HelpService>
} }
var cmdsWithGroup = cmds.GroupBy(c => c.Module.GetGroupName()) var cmdsWithGroup = cmds.GroupBy(c => c.Module.GetGroupName())
.OrderBy(x => x.Key == x.First().Module.Name ? int.MaxValue : x.Count()) .OrderBy(x => x.Key == x.First().Module.Name ? int.MaxValue : x.Count())
.ToList(); .ToList();
if (cmdsWithGroup.Count == 0) if (cmdsWithGroup.Count == 0)
{ {
@ -311,8 +311,8 @@ public sealed partial class Help : EllieModule<HelpService>
} }
var sb = new SelectMenuBuilder() var sb = new SelectMenuBuilder()
.WithCustomId("cmds:submodule_select") .WithCustomId("cmds:submodule_select")
.WithPlaceholder("Select a submodule to see detailed commands"); .WithPlaceholder("Select a submodule to see detailed commands");
var groups = cmdsWithGroup.ToArray(); var groups = cmdsWithGroup.ToArray();
var embed = CreateEmbed().WithOkColor(); var embed = CreateEmbed().WithOkColor();
@ -322,17 +322,29 @@ public sealed partial class Help : EllieModule<HelpService>
var transformed = g var transformed = g
.Select(x => .Select(x =>
{ {
var prepend = string.Empty;
var isOwnerOnly = x.Preconditions.Any(x => x is OwnerOnlyAttribute);
if (isOwnerOnly)
prepend = " \\👑";
//if cross is specified, and the command doesn't satisfy the requirements, cross it out //if cross is specified, and the command doesn't satisfy the requirements, cross it out
if (opts.View == CommandsOptions.ViewType.Cross) if (opts.View == CommandsOptions.ViewType.Cross)
{ {
return $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}"; var outp = $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}";
return prepend + outp;
} }
var output = prefix + x.Aliases[0];
if (x.Aliases.Count == 1) if (x.Aliases.Count > 1)
return prefix + x.Aliases[0]; output += " | " + prefix + x.Aliases[1];
return prefix + x.Aliases[0] + " | " + prefix + x.Aliases[1]; if (opts.View == CommandsOptions.ViewType.All)
return prepend + output;
return output;
}); });
embed.AddField(g.Key, "" + string.Join("\n", transformed) + "", true); embed.AddField(g.Key, "" + string.Join("\n", transformed) + "", true);
@ -347,7 +359,9 @@ public sealed partial class Help : EllieModule<HelpService>
{ {
var groupName = smc.Data.Values.FirstOrDefault(); var groupName = smc.Data.Values.FirstOrDefault();
var mdl = _cmds.Modules.FirstOrDefault(x var mdl = _cmds.Modules.FirstOrDefault(x
=> string.Equals(x.Name.Replace("Commands", ""), groupName, StringComparison.InvariantCultureIgnoreCase)); => string.Equals(x.Name.Replace("Commands", ""),
groupName,
StringComparison.InvariantCultureIgnoreCase));
await smc.DeferAsync(); await smc.DeferAsync();
await Group(mdl); await Group(mdl);
} }
@ -359,8 +373,8 @@ public sealed partial class Help : EllieModule<HelpService>
private async Task Group(ModuleInfo group) private async Task Group(ModuleInfo group)
{ {
var menu = new SelectMenuBuilder() var menu = new SelectMenuBuilder()
.WithCustomId("cmds:group_select") .WithCustomId("cmds:group_select")
.WithPlaceholder("Select a command to see its details"); .WithPlaceholder("Select a command to see its details");
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0])) foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
{ {
@ -377,30 +391,30 @@ public sealed partial class Help : EllieModule<HelpService>
}); });
await Response() await Response()
.Paginated() .Paginated()
.Items(group.Commands.DistinctBy(x => x.Aliases[0]).ToArray()) .Items(group.Commands.DistinctBy(x => x.Aliases[0]).ToArray())
.PageSize(25) .PageSize(25)
.Interaction(inter) .Interaction(inter)
.Page((items, _) => .Page((items, _) =>
{ {
var eb = CreateEmbed() var eb = CreateEmbed()
.WithTitle(GetText(strs.cmd_group_commands(group.Name))) .WithTitle(GetText(strs.cmd_group_commands(group.Name)))
.WithOkColor(); .WithOkColor();
foreach (var cmd in items) foreach (var cmd in items)
{ {
string cmdName; string cmdName;
if (cmd.Aliases.Count > 1) if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]); cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else else
cmdName = Format.Code(prefix + cmd.Aliases.First()); cmdName = Format.Code(prefix + cmd.Aliases.First());
eb.AddField(cmdName, cmd.RealSummary(_strings, _marmalades, Culture, prefix)); eb.AddField(cmdName, cmd.RealSummary(_strings, _marmalades, Culture, prefix));
} }
return eb; return eb;
}) })
.SendAsync(); .SendAsync();
} }
[Cmd] [Cmd]
@ -419,10 +433,10 @@ public sealed partial class Help : EllieModule<HelpService>
fail = fail.Substring(prefix.Length); fail = fail.Substring(prefix.Length);
var group = _cmds.Modules var group = _cmds.Modules
.SelectMany(x => x.Submodules) .SelectMany(x => x.Submodules)
.FirstOrDefault(x => string.Equals(x.Group, .FirstOrDefault(x => string.Equals(x.Group,
fail, fail,
StringComparison.InvariantCultureIgnoreCase)); StringComparison.InvariantCultureIgnoreCase));
if (group is not null) if (group is not null)
{ {
@ -477,29 +491,29 @@ public sealed partial class Help : EllieModule<HelpService>
// order commands by top level module name // order commands by top level module name
// and make a dictionary of <ModuleName, Array<JsonCommandData>> // and make a dictionary of <ModuleName, Array<JsonCommandData>>
var cmdData = _cmds.Commands.GroupBy(x => x.Module.GetTopLevelModule().Name) var cmdData = _cmds.Commands.GroupBy(x => x.Module.GetTopLevelModule().Name)
.OrderBy(x => x.Key) .OrderBy(x => x.Key)
.ToDictionary(x => x.Key, .ToDictionary(x => x.Key,
x => x.DistinctBy(c => c.Aliases.First()) x => x.DistinctBy(c => c.Aliases.First())
.Select(com => .Select(com =>
{ {
List<string> optHelpStr = null; List<string> optHelpStr = null;
var opt = CommandsUtilityService.GetEllieOptionType(com.Attributes); var opt = CommandsUtilityService.GetEllieOptionType(com.Attributes);
if (opt is not null) if (opt is not null)
optHelpStr = CommandsUtilityService.GetCommandOptionHelpList(opt); optHelpStr = CommandsUtilityService.GetCommandOptionHelpList(opt);
return new CommandJsonObject return new CommandJsonObject
{ {
Aliases = com.Aliases.Select(alias => prefix + alias).ToArray(), Aliases = com.Aliases.Select(alias => prefix + alias).ToArray(),
Description = com.RealSummary(_strings, _marmalades, Culture, prefix), Description = com.RealSummary(_strings, _marmalades, Culture, prefix),
Usage = com.RealRemarksArr(_strings, _marmalades, Culture, prefix), Usage = com.RealRemarksArr(_strings, _marmalades, Culture, prefix),
Submodule = com.Module.Name, Submodule = com.Module.Name,
Module = com.Module.GetTopLevelModule().Name, Module = com.Module.GetTopLevelModule().Name,
Options = optHelpStr, Options = optHelpStr,
Requirements = CommandsUtilityService.GetCommandRequirements(com) Requirements = CommandsUtilityService.GetCommandRequirements(com)
}; };
}) })
.ToList()); .ToList());
var readableData = JsonConvert.SerializeObject(cmdData, Formatting.Indented); var readableData = JsonConvert.SerializeObject(cmdData, Formatting.Indented);
@ -512,17 +526,17 @@ public sealed partial class Help : EllieModule<HelpService>
[Cmd] [Cmd]
public async Task Guide() public async Task Guide()
=> await Response() => await Response()
.Confirm(strs.guide("https://commands.elliebot.net", .Confirm(strs.guide("https://commands.elliebot.net",
"https://docs.elliebot.net")) "https://docs.elliebot.net"))
.SendAsync(); .SendAsync();
[Cmd] [Cmd]
[OnlyPublicBot] [OnlyPublicBot]
public async Task Donate() public async Task Donate()
{ {
var eb = CreateEmbed() var eb = CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle("Thank you for considering to donate to the EllieBot project!"); .WithTitle("Thank you for considering to donate to the EllieBot project!");
eb eb
.WithDescription(""" .WithDescription("""
@ -554,9 +568,9 @@ public sealed partial class Help : EllieModule<HelpService>
try try
{ {
await Response() await Response()
.Channel(await ctx.User.CreateDMChannelAsync()) .Channel(await ctx.User.CreateDMChannelAsync())
.Embed(eb) .Embed(eb)
.SendAsync(); .SendAsync();
_ = ctx.OkAsync(); _ = ctx.OkAsync();
} }

View file

@ -98,10 +98,10 @@ public partial class Utility
return; return;
var embed = CreateEmbed() var embed = CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(guildId is not null .WithTitle(GetText(guildId is not null
? strs.reminder_server_list ? strs.reminder_server_list
: strs.reminder_list)); : strs.reminder_list));
List<Reminder> rems; List<Reminder> rems;
if (guildId is { } gid) if (guildId is { } gid)
@ -201,13 +201,18 @@ public partial class Utility
message, message,
ReminderType.User); ReminderType.User);
var eb = CreateEmbed()
.WithOkColor()
.WithAuthor(ctx.User)
.WithTitle(GetText(strs.reminder_created))
.AddField(GetText(strs.who_where), !isPrivate ? $"<#{targetId}>" : ctx.User.Username, true)
.AddField(GetText(strs.when), TimestampTag.FromDateTime(time, TimestampTagStyles.Relative), true)
.AddField(GetText(strs.date2), TimestampTag.FromDateTime(time, TimestampTagStyles.ShortDateTime), true)
.WithDescription(message);
await Response() await Response()
.Confirm($"\u23f0 {GetText(strs.remind2( .Embed(eb)
Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username), .SendAsync();
Format.Bold(message),
TimestampTag.FromDateTime(DateTime.UtcNow.Add(ts), TimestampTagStyles.Relative),
TimestampTag.FormatFromDateTime(time, TimestampTagStyles.ShortDateTime)))}")
.SendAsync();
return true; return true;
} }

View file

@ -112,12 +112,13 @@ public partial class Utility : EllieModule
return; return;
} }
var userNames = new List<IUser>(socketGuild.Users.Count / 100); var userNames = new List<IUser>(socketGuild.Users.Count / 100);
foreach (var user in socketGuild.Users) foreach (var user in socketGuild.Users)
{ {
if (user.Activities.Any(x => x.Name is not null && x.Name.ToUpperInvariant() == game)) var activity = user.Activities.FirstOrDefault(x => x.Name is not null && x.Name.ToUpperInvariant() == game);
if (activity is not null)
{ {
game = activity.Name;
userNames.Add(user); userNames.Add(user);
} }
} }
@ -129,6 +130,9 @@ public partial class Utility : EllieModule
.PageSize(20) .PageSize(20)
.Page((names, _) => .Page((names, _) =>
{ {
var eb = CreateEmbed()
.WithTitle(GetText(strs.whos_playing_game(userNames.Count, game)));
if (names.Count == 0) if (names.Count == 0)
{ {
return CreateEmbed() return CreateEmbed()
@ -136,8 +140,7 @@ public partial class Utility : EllieModule
.WithDescription(GetText(strs.nobody_playing_game)); .WithDescription(GetText(strs.nobody_playing_game));
} }
var eb = CreateEmbed() eb = eb.WithOkColor();
.WithOkColor();
var users = names.Join('\n'); var users = names.Join('\n');
@ -646,7 +649,7 @@ public partial class Utility : EllieModule
[Ratelimit(3600)] [Ratelimit(3600)]
public async Task SaveChat(int cnt) public async Task SaveChat(int cnt)
{ {
if (cnt > 1000) if (!_creds.IsOwner(ctx.User) && cnt > 1000)
return; return;
var msgs = new List<IMessage>(cnt); var msgs = new List<IMessage>(cnt);

View file

@ -378,8 +378,8 @@ sargroupdelete:
desc: "The number of the group to delete." desc: "The number of the group to delete."
sarexclusive: sarexclusive:
desc: |- desc: |-
Toggles whether self-assigned roles are exclusive. Toggles the sar group as exclusive.
While enabled, users can only have one self-assignable role per group. While enabled, users can only have one self-assignable role from that group.
ex: ex:
- '1' - '1'
params: params:
@ -418,7 +418,11 @@ iamnot:
- role: - role:
desc: "The role to remove." desc: "The role to remove."
expradd: expradd:
desc: 'Add an expression with a trigger and a response. Bot will post a response whenever someone types the trigger word. Running this command in a server requires the Administrator permission. Running this command in DM is Bot Owner only and adds a new global expression. Guide [here](<https://docs.elliebot.net/ellie/features/expressions/>)' desc: |-
Add an expression with a trigger and a response.
Bot will post a response whenever someone types the trigger word.
Running this command in a server requires the Administrator permission.
Running this command in DM is Bot Owner only and adds a new global expression.
ex: ex:
- '"hello" Hi there %user.mention%' - '"hello" Hi there %user.mention%'
params: params:
@ -427,7 +431,7 @@ expradd:
response: response:
desc: "The text of the message that shows up when a user types the trigger word or phrase." desc: "The text of the message that shows up when a user types the trigger word or phrase."
expraddserver: expraddserver:
desc: 'Add an expression with a trigger and a response in this server. Bot will post a response whenever someone types the trigger word. This command is useful if you want to lower the permission requirement for managing expressions by using `{0}dpo`. Guide [here](<https://docs.elliebot.net/ellie/features/expressions/>).' desc: 'Add an expression with a trigger and a response in this server. Bot will post a response whenever someone types the trigger word. This command is useful if you want to lower the permission requirement for managing expressions by using `{0}dpo`.'
ex: ex:
- '"hello" Hi there %user.mention%' - '"hello" Hi there %user.mention%'
params: params:
@ -892,7 +896,9 @@ send:
text: text:
desc: "The recipient's preferred format for the message, such as plain text or formatted text with images and links." desc: "The recipient's preferred format for the message, such as plain text or formatted text with images and links."
savechat: savechat:
desc: Saves a number of messages to a text file and sends it to you. desc: |-
Saves a number of messages to a text file and sends it to you.
Max is 1000, unless you're the bot owner.
ex: ex:
- 150 - 150
params: params:
@ -3695,16 +3701,16 @@ clubicon:
- url: - url:
desc: "The URL of an image file to use as the club icon." desc: "The URL of an image file to use as the club icon."
clubbanner: clubbanner:
desc: |- desc: |-
Sets an image as a club banner. Sets an image as a club banner.
The banner will be displayed when club information is shown. The banner will be displayed when club information is shown.
ex: ex:
- 'https://i.imgur.com/example.png' - 'https://i.imgur.com/example.png'
- '' - ''
params: params:
- { } - { }
- url: - url:
desc: "URL to the image to set as a club banner." desc: "URL to the image to set as a club banner."
clubapps: clubapps:
desc: Shows the list of users who have applied to your club. Paginated. You must be club owner to use this command. desc: Shows the list of users who have applied to your club. Paginated. You must be club owner to use this command.
ex: ex:
@ -4990,60 +4996,60 @@ xpratereset:
- channel: - channel:
desc: "The channel to reset the rate for." desc: "The channel to reset the rate for."
lyrics: lyrics:
desc: |- desc: |-
Looks up lyrics for a song. Very hit or miss. Looks up lyrics for a song. Very hit or miss.
ex: ex:
- 'biri biri' - 'biri biri'
params: params:
- song: - song:
desc: "The song to look up lyrics for." desc: "The song to look up lyrics for."
userroleassign: userroleassign:
desc: |- desc: |-
Assigns a role to a user that can later be modified by that user. Assigns a role to a user that can later be modified by that user.
ex: ex:
- '@User @Role' - '@User @Role'
params: params:
- user: - user:
desc: 'The user to assign the role to.' desc: 'The user to assign the role to.'
role: role:
desc: 'The role to assign.' desc: 'The role to assign.'
userroleremove: userroleremove:
desc: |- desc: |-
Removes a previously assigned role from a user. Removes a previously assigned role from a user.
ex: ex:
- '@User @Role' - '@User @Role'
params: params:
- user: - user:
desc: 'The user to remove the role from.' desc: 'The user to remove the role from.'
role: role:
desc: 'The role to remove.' desc: 'The role to remove.'
userrolelist: userrolelist:
desc: |- desc: |-
Lists all user roles in the server, or for a specific user. Lists all user roles in the server, or for a specific user.
ex: ex:
- '' - ''
- '@User' - '@User'
params: params:
- { } - { }
- user: - user:
desc: 'The user whose roles to list.' desc: 'The user whose roles to list.'
userrolemy: userrolemy:
desc: |- desc: |-
Lists all of the user roles assigned to you. Lists all of the user roles assigned to you.
ex: ex:
- '' - ''
params: params:
- { } - { }
userrolecolor: userrolecolor:
desc: |- desc: |-
Changes the color of your assigned role. Changes the color of your assigned role.
ex: ex:
- '@Role #ff0000' - '@Role #ff0000'
params: params:
- role: - role:
desc: 'The assigned role to change the color of.' desc: 'The assigned role to change the color of.'
color: color:
desc: 'The new color for the role in hex format.' desc: 'The new color for the role in hex format.'
userroleicon: userroleicon:
desc: |- desc: |-
Changes the icon of your assigned role. Changes the icon of your assigned role.
@ -5059,12 +5065,12 @@ userroleicon:
serverEmoji: serverEmoji:
desc: 'The server emoji to be used as a new icon for the role.' desc: 'The server emoji to be used as a new icon for the role.'
userrolename: userrolename:
desc: |- desc: |-
Changes the name of your assigned role. Changes the name of your assigned role.
ex: ex:
- '@Role New Role Name' - '@Role New Role Name'
params: params:
- role: - role:
desc: 'The assigned role to rename.' desc: 'The assigned role to rename.'
name: name:
desc: 'The new name for the role.' desc: 'The new name for the role.'

View file

@ -621,7 +621,10 @@
"quote_deleted": "Quote #{0} deleted.", "quote_deleted": "Quote #{0} deleted.",
"quote_edited": "Quote Edited", "quote_edited": "Quote Edited",
"region": "Region", "region": "Region",
"remind2": "I will remind {0} to {1} {2} ({3})", "reminder_created": "Reminder Created",
"who_where": "Who / Where",
"when": "When",
"date2": "Date",
"remind_timely": "I will remind you about your timely reward {0}", "remind_timely": "I will remind you about your timely reward {0}",
"timely_button": "Click the button to claim your timely reward.", "timely_button": "Click the button to claim your timely reward.",
"remind_invalid": "Not a valid remind format. Remind must have a target, timer and a reason. Check the command list.", "remind_invalid": "Not a valid remind format. Remind must have a target, timer and a reason. Check the command list.",
@ -1203,5 +1206,6 @@
"userrole_icon_fail": "Failed to set the role icon.", "userrole_icon_fail": "Failed to set the role icon.",
"userrole_icon_invalid": "The role icon cannot be empty.", "userrole_icon_invalid": "The role icon cannot be empty.",
"userrole_hierarchy_error": "You can't assign or modify roles that are higher than or equal to your, or bots highest role.", "userrole_hierarchy_error": "You can't assign or modify roles that are higher than or equal to your, or bots highest role.",
"userrole_role_not_exists": "That role doesn't exist." "userrole_role_not_exists": "That role doesn't exist.",
"whos_playing_game": "{0} users are playing {1}"
} }