forked from EllieBotDevs/elliebot
gambling commands now show amount bet. Slightly changed the layout. Updated some gambling strings
added .btr excl
This commit is contained in:
parent
97871f3e47
commit
ae338db294
18 changed files with 178 additions and 74 deletions
|
@ -12,6 +12,7 @@ Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except da
|
||||||
- `.btr list` to list all button roles on the server
|
- `.btr list` to list all button roles on the server
|
||||||
- `.btr rm` to remove a button role from the specified message
|
- `.btr rm` to remove a button role from the specified message
|
||||||
- `.btr rma` to remove all button roles on the specified message
|
- `.btr rma` to remove all button roles on the specified message
|
||||||
|
- `.btr excl` to toggle exclusive button roles (only 1 role per message or any number)
|
||||||
- Use `.h` on any of the above for more info
|
- Use `.h` on any of the above for more info
|
||||||
- Added `.wrongsong` which will delete the last queued song.
|
- Added `.wrongsong` which will delete the last queued song.
|
||||||
- Useful in case you made a mistake, or the bot queued a wrong song
|
- Useful in case you made a mistake, or the bot queued a wrong song
|
||||||
|
|
|
@ -22,4 +22,6 @@ public sealed class ButtonRole
|
||||||
|
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string Label { get; set; } = string.Empty;
|
public string Label { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool Exclusive { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
namespace EllieBot.Migrations.PostgreSql
|
namespace EllieBot.Migrations.PostgreSql
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PostgreSqlContext))]
|
[DbContext(typeof(PostgreSqlContext))]
|
||||||
[Migration("20241127120348_guildcolors")]
|
[Migration("20241126033634_btnroles_guildcolors")]
|
||||||
partial class guildcolors
|
partial class btnroles_guildcolors
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
@ -479,6 +479,10 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("character varying(100)")
|
.HasColumnType("character varying(100)")
|
||||||
.HasColumnName("emote");
|
.HasColumnName("emote");
|
||||||
|
|
||||||
|
b.Property<bool>("Exclusive")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("exclusive");
|
||||||
|
|
||||||
b.Property<decimal>("GuildId")
|
b.Property<decimal>("GuildId")
|
||||||
.HasColumnType("numeric(20,0)")
|
.HasColumnType("numeric(20,0)")
|
||||||
.HasColumnName("guildid");
|
.HasColumnName("guildid");
|
|
@ -6,7 +6,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
namespace EllieBot.Migrations.PostgreSql
|
namespace EllieBot.Migrations.PostgreSql
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public partial class guildcolors : Migration
|
public partial class btnroles_guildcolors : Migration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
@ -24,7 +24,8 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
position = table.Column<int>(type: "integer", nullable: false),
|
position = table.Column<int>(type: "integer", nullable: false),
|
||||||
roleid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
|
roleid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
|
||||||
emote = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
emote = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||||
label = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false)
|
label = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||||
|
exclusive = table.Column<bool>(type: "boolean", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
|
@ -476,6 +476,10 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("character varying(100)")
|
.HasColumnType("character varying(100)")
|
||||||
.HasColumnName("emote");
|
.HasColumnName("emote");
|
||||||
|
|
||||||
|
b.Property<bool>("Exclusive")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("exclusive");
|
||||||
|
|
||||||
b.Property<decimal>("GuildId")
|
b.Property<decimal>("GuildId")
|
||||||
.HasColumnType("numeric(20,0)")
|
.HasColumnType("numeric(20,0)")
|
||||||
.HasColumnName("guildid");
|
.HasColumnName("guildid");
|
||||||
|
|
|
@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
namespace EllieBot.Migrations
|
namespace EllieBot.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(SqliteContext))]
|
[DbContext(typeof(SqliteContext))]
|
||||||
[Migration("20241127120303_guildcolors")]
|
[Migration("20241126033626_btnroles_guildcolors")]
|
||||||
partial class guildcolors
|
partial class btnroles_guildcolors
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
@ -357,6 +357,9 @@ namespace EllieBot.Migrations
|
||||||
.HasMaxLength(100)
|
.HasMaxLength(100)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Exclusive")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<ulong>("GuildId")
|
b.Property<ulong>("GuildId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
namespace EllieBot.Migrations
|
namespace EllieBot.Migrations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public partial class guildcolors : Migration
|
public partial class btnroles_guildcolors : Migration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
@ -23,7 +23,8 @@ namespace EllieBot.Migrations
|
||||||
Position = table.Column<int>(type: "INTEGER", nullable: false),
|
Position = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
RoleId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
RoleId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||||
Emote = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
Emote = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
Label = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false)
|
Label = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
|
||||||
|
Exclusive = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
|
@ -354,6 +354,9 @@ namespace EllieBot.Migrations
|
||||||
.HasMaxLength(100)
|
.HasMaxLength(100)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Exclusive")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<ulong>("GuildId")
|
b.Property<ulong>("GuildId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using EllieBot.Db.Models;
|
using EllieBot.Common.TypeReaders.Models;
|
||||||
|
using EllieBot.Db.Models;
|
||||||
using EllieBot.Modules.Administration.Services;
|
using EllieBot.Modules.Administration.Services;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using ContextType = Discord.Commands.ContextType;
|
using ContextType = Discord.Commands.ContextType;
|
||||||
|
@ -7,6 +8,7 @@ namespace EllieBot.Modules.Administration;
|
||||||
|
|
||||||
public partial class Administration
|
public partial class Administration
|
||||||
{
|
{
|
||||||
|
[Group("btr")]
|
||||||
public partial class ButtonRoleCommands : EllieModule<ButtonRolesService>
|
public partial class ButtonRoleCommands : EllieModule<ButtonRolesService>
|
||||||
{
|
{
|
||||||
private List<ActionRowBuilder> GetActionRows(IReadOnlyList<ButtonRole> roles)
|
private List<ActionRowBuilder> GetActionRows(IReadOnlyList<ButtonRole> roles)
|
||||||
|
@ -265,5 +267,30 @@ public partial class Administration
|
||||||
})
|
})
|
||||||
.SendAsync();
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[BotPerm(GuildPerm.ManageRoles)]
|
||||||
|
[RequireUserPermission(GuildPerm.ManageRoles)]
|
||||||
|
public Task BtnRoleExclusive(MessageLink link, PermissionAction exclusive)
|
||||||
|
=> BtnRoleExclusive(link.Message.Id, exclusive);
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[BotPerm(GuildPerm.ManageRoles)]
|
||||||
|
[RequireUserPermission(GuildPerm.ManageRoles)]
|
||||||
|
public async Task BtnRoleExclusive(ulong messageId, PermissionAction exclusive)
|
||||||
|
{
|
||||||
|
var res = await _service.SetExclusiveButtonRoles(ctx.Guild.Id, messageId, exclusive.Value);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
await Response().Confirm(strs.btnrole_exclusive).SendAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Response().Confirm(strs.btnrole_multiple).SendAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -42,32 +42,49 @@ public sealed class ButtonRolesService : IEService, IReadyExecutor
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
try
|
||||||
var buttonRole = await uow.GetTable<ButtonRole>()
|
|
||||||
.Where(x => x.ButtonId == smc.Data.CustomId && x.MessageId == smc.Message.Id)
|
|
||||||
.FirstOrDefaultAsyncLinqToDB();
|
|
||||||
|
|
||||||
if (buttonRole is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var guild = _client.GetGuild(buttonRole.GuildId);
|
|
||||||
if (guild is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var role = guild.GetRole(buttonRole.RoleId);
|
|
||||||
if (role is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (smc.User is not IGuildUser user)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (user.GetRoles().Any(x => x.Id == role.Id))
|
|
||||||
{
|
{
|
||||||
await user.RemoveRoleAsync(role.Id);
|
await using var uow = _db.GetDbContext();
|
||||||
return;
|
var buttonRole = await uow.GetTable<ButtonRole>()
|
||||||
}
|
.Where(x => x.ButtonId == smc.Data.CustomId && x.MessageId == smc.Message.Id)
|
||||||
|
.FirstOrDefaultAsyncLinqToDB();
|
||||||
|
|
||||||
await user.AddRoleAsync(role.Id);
|
if (buttonRole is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var guild = _client.GetGuild(buttonRole.GuildId);
|
||||||
|
if (guild is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var role = guild.GetRole(buttonRole.RoleId);
|
||||||
|
if (role is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (smc.User is not IGuildUser user)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (user.GetRoles().Any(x => x.Id == role.Id))
|
||||||
|
{
|
||||||
|
await user.RemoveRoleAsync(role.Id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttonRole.Exclusive)
|
||||||
|
{
|
||||||
|
var otherRoles = await uow.GetTable<ButtonRole>()
|
||||||
|
.Where(x => x.GuildId == smc.GuildId && x.MessageId == smc.Message.Id)
|
||||||
|
.Select(x => x.RoleId)
|
||||||
|
.ToListAsyncLinqToDB();
|
||||||
|
|
||||||
|
await user.RemoveRolesAsync(otherRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
await user.AddRoleAsync(role.Id);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warning(ex, "Unable to handle button role interaction for user {UserId}", inter.User.Id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +125,8 @@ public sealed class ButtonRolesService : IEService, IReadyExecutor
|
||||||
: 1,
|
: 1,
|
||||||
Emote = emoteStr,
|
Emote = emoteStr,
|
||||||
Label = string.Empty,
|
Label = string.Empty,
|
||||||
ButtonId = $"{BTN_PREFIX}:{guildId}:{guid}"
|
ButtonId = $"{BTN_PREFIX}:{guildId}:{guid}",
|
||||||
|
Exclusive = (uow.GetTable<ButtonRole>().Where(x => x.GuildId == guildId && x.MessageId == messageId).All(x => x.Exclusive))
|
||||||
},
|
},
|
||||||
_ => new()
|
_ => new()
|
||||||
{
|
{
|
||||||
|
@ -151,4 +169,16 @@ public sealed class ButtonRolesService : IEService, IReadyExecutor
|
||||||
.OrderBy(x => x.Id)
|
.OrderBy(x => x.Id)
|
||||||
.ToListAsyncLinqToDB();
|
.ToListAsyncLinqToDB();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public async Task<bool> SetExclusiveButtonRoles(ulong guildId, ulong messageId, bool exclusive)
|
||||||
|
{
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
return await uow.GetTable<ButtonRole>()
|
||||||
|
.Where(x => x.GuildId == guildId && x.MessageId == messageId)
|
||||||
|
.UpdateAsync((_) => new()
|
||||||
|
{
|
||||||
|
Exclusive = exclusive
|
||||||
|
})
|
||||||
|
> 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,7 @@ public partial class Gambling
|
||||||
i.Dispose();
|
i.Dispose();
|
||||||
|
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
var toSend = string.Empty;
|
var toSend = string.Empty;
|
||||||
if (cardObjects.Count == 5)
|
if (cardObjects.Count == 5)
|
||||||
|
@ -172,13 +172,14 @@ public partial class Gambling
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(result.Card.GetEmoji())
|
.WithDescription(result.Card.GetEmoji())
|
||||||
.AddField(GetText(strs.guess), GetGuessInfo(val, col), true)
|
.AddField(GetText(strs.guess), GetGuessInfo(val, col), true)
|
||||||
.AddField(GetText(strs.card), GetCardInfo(result.Card), true)
|
.AddField(GetText(strs.card), GetCardInfo(result.Card), false)
|
||||||
.AddField(GetText(strs.won), N((long)result.Won), false)
|
.AddField(GetText(strs.bet), N(amount), true)
|
||||||
.WithImageUrl("attachment://card.png");
|
.AddField(GetText(strs.won), N((long)result.Won), true)
|
||||||
|
.WithImageUrl("attachment://card.png");
|
||||||
|
|
||||||
using var img = await GetCardImageAsync(result.Card);
|
using var img = await GetCardImageAsync(result.Card);
|
||||||
await using var imgStream = await img.ToStreamAsync();
|
await using var imgStream = await img.ToStreamAsync();
|
||||||
|
|
|
@ -85,10 +85,10 @@ public partial class Gambling
|
||||||
: Format.Bold(GetText(strs.tails))));
|
: Format.Bold(GetText(strs.tails))));
|
||||||
|
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(msg)
|
.WithDescription(msg)
|
||||||
.WithImageUrl($"attachment://{imgName}");
|
.WithImageUrl($"attachment://{imgName}");
|
||||||
|
|
||||||
await ctx.Channel.SendFileAsync(stream,
|
await ctx.Channel.SendFileAsync(stream,
|
||||||
imgName,
|
imgName,
|
||||||
|
@ -123,18 +123,22 @@ public partial class Gambling
|
||||||
var won = (long)result.Won;
|
var won = (long)result.Won;
|
||||||
if (won > 0)
|
if (won > 0)
|
||||||
{
|
{
|
||||||
str = Format.Bold(GetText(strs.flip_guess(N(won))));
|
str = Format.Bold(GetText(strs.betflip_guess));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str = Format.Bold(GetText(strs.better_luck));
|
str = Format.Bold(GetText(strs.better_luck));
|
||||||
}
|
}
|
||||||
|
|
||||||
await Response().Embed(CreateEmbed()
|
await Response()
|
||||||
.WithAuthor(ctx.User)
|
.Embed(CreateEmbed()
|
||||||
.WithDescription(str)
|
.WithAuthor(ctx.User)
|
||||||
.WithOkColor()
|
.WithDescription(str)
|
||||||
.WithImageUrl(imageToSend.ToString())).SendAsync();
|
.AddField(GetText(strs.bet), N(amount), true)
|
||||||
|
.AddField(GetText(strs.won), N((long)result.Won), true)
|
||||||
|
.WithOkColor()
|
||||||
|
.WithImageUrl(imageToSend.ToString()))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -718,7 +718,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||||
string str;
|
string str;
|
||||||
if (win > 0)
|
if (win > 0)
|
||||||
{
|
{
|
||||||
str = GetText(strs.br_win(N(win), result.Threshold + (result.Roll == 100 ? " 👑" : "")));
|
str = GetText(strs.betroll_win(result.Threshold + (result.Roll == 100 ? " 👑" : "")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -728,7 +728,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(Format.Bold(str))
|
.WithDescription(Format.Bold(str))
|
||||||
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture))
|
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture), true)
|
||||||
|
.AddField(GetText(strs.bet), N(amount), true)
|
||||||
|
.AddField(GetText(strs.won), N((long)result.Won), true)
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
await Response().Embed(eb).SendAsync();
|
await Response().Embed(eb).SendAsync();
|
||||||
|
@ -922,8 +924,8 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(sb.ToString())
|
.WithDescription(sb.ToString())
|
||||||
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
|
.AddField(GetText(strs.bet), N(amount), true)
|
||||||
.AddField(GetText(strs.won), $"{(long)result.Won}", true)
|
.AddField(GetText(strs.won), $"{N((long)result.Won)}", true)
|
||||||
.WithAuthor(ctx.User);
|
.WithAuthor(ctx.User);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,10 @@ public partial class Gambling
|
||||||
|
|
||||||
|
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(Format.Bold(text))
|
.WithDescription(Format.Bold(text))
|
||||||
.WithImageUrl($"attachment://result.png")
|
.WithImageUrl($"attachment://result.png")
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
var bb = new ButtonBuilder(emote: Emoji.Parse("🔁"), customId: "slot:again", label: "Pull Again");
|
var bb = new ButtonBuilder(emote: Emoji.Parse("🔁"), customId: "slot:again", label: "Pull Again");
|
||||||
var inter = _inter.Create(ctx.User.Id,
|
var inter = _inter.Create(ctx.User.Id,
|
||||||
|
@ -168,7 +168,8 @@ public partial class Gambling
|
||||||
await using (var uow = _db.GetDbContext())
|
await using (var uow = _db.GetDbContext())
|
||||||
{
|
{
|
||||||
ownedAmount = uow.Set<DiscordUser>()
|
ownedAmount = uow.Set<DiscordUser>()
|
||||||
.FirstOrDefault(x => x.UserId == ctx.User.Id)?.CurrencyAmount
|
.FirstOrDefault(x => x.UserId == ctx.User.Id)
|
||||||
|
?.CurrencyAmount
|
||||||
?? 0;
|
?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1499,18 +1499,22 @@ snipe:
|
||||||
- snipe
|
- snipe
|
||||||
- sn
|
- sn
|
||||||
btnroleadd:
|
btnroleadd:
|
||||||
- btnradd
|
- add
|
||||||
- btnra
|
- a
|
||||||
btnroleremove:
|
btnroleremove:
|
||||||
- btnrrem
|
- rem
|
||||||
- btnrr
|
- r
|
||||||
- btnrrm
|
- rm
|
||||||
btnroleremoveall:
|
btnroleremoveall:
|
||||||
- btnrremall
|
- remall
|
||||||
- btnrra
|
- rma
|
||||||
btnrolelist:
|
btnrolelist:
|
||||||
- btnrlist
|
- list
|
||||||
- btnrl
|
- l
|
||||||
|
- ls
|
||||||
|
btnroleexclusive:
|
||||||
|
- excl
|
||||||
|
- e
|
||||||
wrongsong:
|
wrongsong:
|
||||||
- wrongsong
|
- wrongsong
|
||||||
- wrongtrack
|
- wrongtrack
|
||||||
|
|
|
@ -4769,6 +4769,19 @@ btnrolelist:
|
||||||
- ''
|
- ''
|
||||||
params:
|
params:
|
||||||
- { }
|
- { }
|
||||||
|
btnroleexclusive:
|
||||||
|
desc: |-
|
||||||
|
Toggles whether button roles are exclusive or not.
|
||||||
|
If enabled, users can only pick one role from the buttons per message.
|
||||||
|
If disabled, users can pick any number of roles.
|
||||||
|
ex:
|
||||||
|
- '123123123 enable'
|
||||||
|
- '123123123 disable'
|
||||||
|
params:
|
||||||
|
- message:
|
||||||
|
desc: "A message link or id of the message"
|
||||||
|
enable:
|
||||||
|
desc: "Whether to enable or disable exclusive button roles"
|
||||||
wrongsong:
|
wrongsong:
|
||||||
desc: |-
|
desc: |-
|
||||||
Removes the last queued song.
|
Removes the last queued song.
|
||||||
|
|
|
@ -238,10 +238,10 @@
|
||||||
"sb_user": "User soft-banned",
|
"sb_user": "User soft-banned",
|
||||||
"awarded": "{2} has awarded {0} to {1}",
|
"awarded": "{2} has awarded {0} to {1}",
|
||||||
"better_luck": "Better luck next time ^_^",
|
"better_luck": "Better luck next time ^_^",
|
||||||
"br_win": "Congratulations! You won {0} for rolling above {1}",
|
"betroll_win": "Congratulations! You rolled above {0}",
|
||||||
"deck_reshuffled": "Deck reshuffled.",
|
"deck_reshuffled": "Deck reshuffled.",
|
||||||
"flipped": "Flipped {0}",
|
"flipped": "Flipped {0}",
|
||||||
"flip_guess": "You guessed it! You won {0}",
|
"betflip_guess": "You guessed it!",
|
||||||
"flip_invalid": "Invalid number specified. You can flip 1 to {0} coins.",
|
"flip_invalid": "Invalid number specified. You can flip 1 to {0} coins.",
|
||||||
"flip_results": "Flipped {0} coins. {1} heads, {2} tails.",
|
"flip_results": "Flipped {0} coins. {1} heads, {2} tails.",
|
||||||
"cards_left": "{0} cards left in the deck.",
|
"cards_left": "{0} cards left in the deck.",
|
||||||
|
@ -266,7 +266,8 @@
|
||||||
"available_tests": "Available Tests",
|
"available_tests": "Available Tests",
|
||||||
"test_results_for": "Test results for {0}",
|
"test_results_for": "Test results for {0}",
|
||||||
"won": "Won",
|
"won": "Won",
|
||||||
"multiplier": "Multiplier",
|
"bet": "Bet",
|
||||||
|
"multi": "Multi",
|
||||||
"tails": "Tail",
|
"tails": "Tail",
|
||||||
"take": "successfully took {0} from {1}",
|
"take": "successfully took {0} from {1}",
|
||||||
"take_fail": "was unable to take {0} from {1} because the user doesn't have that much {2}!",
|
"take_fail": "was unable to take {0} from {1} because the user doesn't have that much {2}!",
|
||||||
|
@ -1129,6 +1130,8 @@
|
||||||
"btnrole_none": "There are no button roles on this page.",
|
"btnrole_none": "There are no button roles on this page.",
|
||||||
"btnrole_removeall_not_found": "Button role successfully removed but message wasn't found.",
|
"btnrole_removeall_not_found": "Button role successfully removed but message wasn't found.",
|
||||||
"btnrole_removed": "Button role removed.",
|
"btnrole_removed": "Button role removed.",
|
||||||
|
"btnrole_exclusive": "Users can now pick only one of the roles from that message.",
|
||||||
|
"btnrole_multiple": "Users can now pick any number of button roles from that message.",
|
||||||
"no_last_queued_found": "No last queued track found.",
|
"no_last_queued_found": "No last queued track found.",
|
||||||
"wrongsong_success": "Oops! Wrong song removed: {0}",
|
"wrongsong_success": "Oops! Wrong song removed: {0}",
|
||||||
"server_not_found": "Server not found.",
|
"server_not_found": "Server not found.",
|
||||||
|
|
Reference in a new issue