mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 09:48:26 -04:00
add: added addrolereward and removerolereward events for .notify
add: added .notify with no params showing events with descriptions add: .winlb docs: updated docs dev: updated discord.net, redid migrations
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using NadekoBot.Db.Models;
|
||||
using NadekoBot.Modules.Administration;
|
||||
|
||||
namespace NadekoBot.Modules.Xp.Services;
|
||||
|
||||
public record struct AddRoleRewardNotifyModel(ulong GuildId, ulong RoleId, ulong UserId, long Level) : INotifyModel
|
||||
{
|
||||
public static string KeyName
|
||||
=> "notify.reward.addrole";
|
||||
|
||||
public static NotifyType NotifyType
|
||||
=> NotifyType.AddRoleReward;
|
||||
|
||||
public IReadOnlyDictionary<string, Func<SocketGuild, string>> GetReplacements()
|
||||
{
|
||||
var model = this;
|
||||
return new Dictionary<string, Func<SocketGuild, string>>()
|
||||
{
|
||||
{ "%event.user%", g => g.GetUser(model.UserId)?.ToString() ?? model.UserId.ToString() },
|
||||
{ "%event.role%", g => g.GetRole(model.RoleId)?.ToString() ?? model.RoleId.ToString() },
|
||||
{ "%event.level%", g => model.Level.ToString() }
|
||||
};
|
||||
}
|
||||
|
||||
public bool TryGetUserId(out ulong userId)
|
||||
{
|
||||
userId = UserId;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryGetGuildId(out ulong guildId)
|
||||
{
|
||||
guildId = GuildId;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -20,6 +20,7 @@ public record struct LevelUpNotifyModel(
|
||||
return new Dictionary<string, Func<SocketGuild, string>>()
|
||||
{
|
||||
{ "%event.level%", g => data.Level.ToString() },
|
||||
{ "%event.user%", g => g.GetUser(data.UserId)?.ToString() ?? data.UserId.ToString() },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,11 +35,4 @@ public record struct LevelUpNotifyModel(
|
||||
userId = UserId;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class INotifyModelExtensions
|
||||
{
|
||||
public static TypedKey<T> GetTypedKey<T>(this T model)
|
||||
where T : struct, INotifyModel
|
||||
=> new(T.KeyName);
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
||||
public record struct ProtectionNotifyModel(ulong GuildId, ProtectionType ProtType, ulong UserId) : INotifyModel
|
||||
{
|
||||
public static string KeyName
|
||||
=> "notify.protection";
|
||||
|
||||
public static NotifyType NotifyType
|
||||
=> NotifyType.Protection;
|
||||
|
||||
public IReadOnlyDictionary<string, Func<SocketGuild, string>> GetReplacements()
|
||||
{
|
||||
var data = this;
|
||||
return new Dictionary<string, Func<SocketGuild, string>>()
|
||||
{
|
||||
{ "%event.type%", g => data.ProtType.ToString() },
|
||||
};
|
||||
}
|
||||
|
||||
public bool TryGetUserId(out ulong userId)
|
||||
{
|
||||
userId = UserId;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryGetGuildId(out ulong guildId)
|
||||
{
|
||||
guildId = GuildId;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using NadekoBot.Db.Models;
|
||||
using NadekoBot.Modules.Administration;
|
||||
|
||||
namespace NadekoBot.Modules.Xp.Services;
|
||||
|
||||
public record struct RemoveRoleRewardNotifyModel(ulong GuildId, ulong RoleId, ulong UserId, long Level) : INotifyModel
|
||||
{
|
||||
public static string KeyName
|
||||
=> "notify.reward.removerole";
|
||||
|
||||
public static NotifyType NotifyType
|
||||
=> NotifyType.RemoveRoleReward;
|
||||
|
||||
public IReadOnlyDictionary<string, Func<SocketGuild, string>> GetReplacements()
|
||||
{
|
||||
var model = this;
|
||||
return new Dictionary<string, Func<SocketGuild, string>>()
|
||||
{
|
||||
{ "%event.user%", g => g.GetUser(model.UserId)?.ToString() ?? model.UserId.ToString() },
|
||||
{ "%event.role%", g => g.GetRole(model.RoleId)?.ToString() ?? model.RoleId.ToString() },
|
||||
{ "%event.level%", g => model.Level.ToString() },
|
||||
};
|
||||
}
|
||||
|
||||
public bool TryGetUserId(out ulong userId)
|
||||
{
|
||||
userId = UserId;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryGetGuildId(out ulong guildId)
|
||||
{
|
||||
guildId = GuildId;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Db.Models;
|
||||
using System.Text;
|
||||
|
||||
namespace NadekoBot.Modules.Administration;
|
||||
|
||||
@@ -6,19 +7,108 @@ public partial class Administration
|
||||
{
|
||||
public class NotifyCommands : NadekoModule<NotifyService>
|
||||
{
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task Notify()
|
||||
{
|
||||
await Response()
|
||||
.Paginated()
|
||||
.Items(Enum.GetValues<NotifyType>())
|
||||
.PageSize(5)
|
||||
.Page((items, page) =>
|
||||
{
|
||||
var eb = CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.notify_available));
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
eb.AddField(item.ToString(), GetText(GetDescription(item)), false);
|
||||
}
|
||||
|
||||
return eb;
|
||||
})
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
private LocStr GetDescription(NotifyType item)
|
||||
=> item switch
|
||||
{
|
||||
NotifyType.LevelUp => strs.notify_desc_levelup,
|
||||
NotifyType.Protection => strs.notify_desc_protection,
|
||||
NotifyType.AddRoleReward => strs.notify_desc_addrolerew,
|
||||
NotifyType.RemoveRoleReward => strs.notify_desc_removerolerew,
|
||||
_ => strs.notify_desc_not_found
|
||||
};
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task Notify(NotifyType nType, [Leftover] string? message = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
await _service.DisableAsync(ctx.Guild.Id, nType);
|
||||
await Response().Confirm(strs.notify_off(nType)).SendAsync();
|
||||
// show msg
|
||||
var conf = await _service.GetNotifyAsync(ctx.Guild.Id, nType);
|
||||
if (conf is null)
|
||||
{
|
||||
await Response().Confirm(strs.notify_msg_not_set).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var eb = CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.notify_msg))
|
||||
.WithDescription(conf.Message.TrimTo(2048))
|
||||
.AddField(GetText(strs.notify_type), conf.Type.ToString(), true)
|
||||
.AddField(GetText(strs.channel),
|
||||
$"""
|
||||
<#{conf.ChannelId}>
|
||||
`{conf.ChannelId}`
|
||||
""",
|
||||
true);
|
||||
|
||||
await Response().Embed(eb).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await _service.EnableAsync(ctx.Guild.Id, ctx.Channel.Id, nType, message);
|
||||
await Response().Confirm(strs.notify_on(nType.ToString())).SendAsync();
|
||||
await Response().Confirm(strs.notify_on($"<#{ctx.Channel.Id}>", Format.Bold(nType.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task NotifyList(int page = 1)
|
||||
{
|
||||
if (--page < 0)
|
||||
return;
|
||||
|
||||
var notifs = await _service.GetForGuildAsync(ctx.Guild.Id);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var notif in notifs)
|
||||
{
|
||||
sb.AppendLine($"""
|
||||
- **{notif.Type}**
|
||||
<#{notif.ChannelId}> `{notif.ChannelId}`
|
||||
|
||||
""");
|
||||
}
|
||||
|
||||
if (notifs.Count == 0)
|
||||
sb.AppendLine(GetText(strs.notify_none));
|
||||
|
||||
await Response()
|
||||
.Confirm(GetText(strs.notify_list), text: sb.ToString())
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task NotifyClear(NotifyType nType)
|
||||
{
|
||||
await _service.DisableAsync(ctx.Guild.Id, nType);
|
||||
await Response().Confirm(strs.notify_off(nType)).SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace NadekoBot.Modules.Administration;
|
||||
|
||||
public static class NotifyModelExtensions
|
||||
{
|
||||
public static TypedKey<T> GetTypedKey<T>(this T model)
|
||||
where T : struct, INotifyModel
|
||||
=> new(T.KeyName);
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db.Models;
|
||||
using NadekoBot.Generators;
|
||||
|
||||
namespace NadekoBot.Modules.Administration;
|
||||
|
||||
@@ -199,4 +200,27 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, INService
|
||||
|
||||
guildsDict.TryRemove(guildId, out _);
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<Notify>> GetForGuildAsync(ulong guildId, int page = 0)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(page);
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
var list = await ctx.GetTable<Notify>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderBy(x => x.Type)
|
||||
.Skip(page * 10)
|
||||
.Take(10)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<Notify?> GetNotifyAsync(ulong guildId, NotifyType nType)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<Notify>()
|
||||
.Where(x => x.GuildId == guildId && x.Type == nType)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
}
|
||||
}
|
@@ -5,36 +5,6 @@ using System.Threading.Channels;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
||||
public record struct ProtectionNotifyModel(ulong GuildId, ProtectionType ProtType, ulong UserId) : INotifyModel
|
||||
{
|
||||
public static string KeyName
|
||||
=> "notify.protection";
|
||||
|
||||
public static NotifyType NotifyType
|
||||
=> NotifyType.Protection;
|
||||
|
||||
public IReadOnlyDictionary<string, Func<SocketGuild, string>> GetReplacements()
|
||||
{
|
||||
var data = this;
|
||||
return new Dictionary<string, Func<SocketGuild, string>>()
|
||||
{
|
||||
{ "%event.type%", g => data.ProtType.ToString() },
|
||||
};
|
||||
}
|
||||
|
||||
public bool TryGetUserId(out ulong userId)
|
||||
{
|
||||
userId = UserId;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryGetGuildId(out ulong guildId)
|
||||
{
|
||||
guildId = GuildId;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProtectionService : INService
|
||||
{
|
||||
public event Func<PunishmentAction, ProtectionType, IGuildUser[], Task> OnAntiProtectionTriggered = delegate
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Modules.Gambling.Common;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
using NadekoBot.Modules.Xp.Services;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling;
|
||||
|
||||
@@ -10,13 +11,19 @@ public partial class Gambling
|
||||
public sealed class BetStatsCommands : GamblingModule<UserBetStatsService>
|
||||
{
|
||||
private readonly GamblingTxTracker _gamblingTxTracker;
|
||||
private readonly IBotCache _cache;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
public BetStatsCommands(
|
||||
GamblingTxTracker gamblingTxTracker,
|
||||
GamblingConfigService gcs)
|
||||
GamblingConfigService gcs,
|
||||
IBotCache cache,
|
||||
IUserService userService)
|
||||
: base(gcs)
|
||||
{
|
||||
_gamblingTxTracker = gamblingTxTracker;
|
||||
_cache = cache;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -25,12 +32,12 @@ public partial class Gambling
|
||||
var price = await _service.GetResetStatsPriceAsync(ctx.User.Id, game);
|
||||
|
||||
var result = await PromptUserConfirmAsync(CreateEmbed()
|
||||
.WithDescription(
|
||||
$"""
|
||||
Are you sure you want to reset your bet stats for **{GetGameName(game)}**?
|
||||
.WithDescription(
|
||||
$"""
|
||||
Are you sure you want to reset your bet stats for **{GetGameName(game)}**?
|
||||
|
||||
It will cost you {N(price)}
|
||||
"""));
|
||||
It will cost you {N(price)}
|
||||
"""));
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
@@ -88,15 +95,15 @@ public partial class Gambling
|
||||
};
|
||||
|
||||
var eb = CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithAuthor(user)
|
||||
.AddField("Total Won", N(stats.Sum(x => x.PaidOut)), true)
|
||||
.AddField("Biggest Win", N(stats.Max(x => x.MaxWin)), true)
|
||||
.AddField("Biggest Bet", N(stats.Max(x => x.MaxBet)), true)
|
||||
.AddField("# Bets", stats.Sum(x => x.WinCount + x.LoseCount), true)
|
||||
.AddField("Payout",
|
||||
(stats.Sum(x => x.PaidOut) / stats.Sum(x => x.TotalBet)).ToString("P2", Culture),
|
||||
true);
|
||||
.WithOkColor()
|
||||
.WithAuthor(user)
|
||||
.AddField("Total Won", N(stats.Sum(x => x.PaidOut)), true)
|
||||
.AddField("Biggest Win", N(stats.Max(x => x.MaxWin)), true)
|
||||
.AddField("Biggest Bet", N(stats.Max(x => x.MaxBet)), true)
|
||||
.AddField("# Bets", stats.Sum(x => x.WinCount + x.LoseCount), true)
|
||||
.AddField("Payout",
|
||||
(stats.Sum(x => x.PaidOut) / stats.Sum(x => x.TotalBet)).ToString("P2", Culture),
|
||||
true);
|
||||
if (game == null)
|
||||
{
|
||||
var favGame = stats.MaxBy(x => x.WinCount + x.LoseCount);
|
||||
@@ -115,13 +122,75 @@ public partial class Gambling
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
private readonly record struct WinLbStat(
|
||||
int Rank,
|
||||
string User,
|
||||
GamblingGame Game,
|
||||
long MaxWin);
|
||||
|
||||
private TypedKey<List<WinLbStat>> GetWinLbKey(int page)
|
||||
=> new($"winlb:{page}");
|
||||
|
||||
private async Task<IReadOnlyCollection<WinLbStat>> GetCachedWinLbAsync(int page)
|
||||
{
|
||||
return await _cache.GetOrAddAsync(GetWinLbKey(page),
|
||||
async () =>
|
||||
{
|
||||
var items = await _service.GetWinLbAsync(page);
|
||||
|
||||
if (items.Count == 0)
|
||||
return [];
|
||||
|
||||
var outputItems = new List<WinLbStat>(items.Count);
|
||||
for (var i = 0; i < items.Count; i++)
|
||||
{
|
||||
var x = items[i];
|
||||
var user = (await ctx.Client.GetUserAsync(x.UserId, CacheMode.CacheOnly))?.ToString()
|
||||
?? (await _userService.GetUserAsync(x.UserId))?.Username
|
||||
?? x.UserId.ToString();
|
||||
|
||||
outputItems.Add(new WinLbStat(i + 1 + (page * 10), user, x.Game, x.MaxWin));
|
||||
}
|
||||
|
||||
return outputItems;
|
||||
},
|
||||
expiry: TimeSpan.FromMinutes(5));
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
public async Task WinLb(int page = 1)
|
||||
{
|
||||
if (--page < 0)
|
||||
return;
|
||||
|
||||
await Response()
|
||||
.Paginated()
|
||||
.PageItems(p => GetCachedWinLbAsync(p))
|
||||
.PageSize(10)
|
||||
.Page((items, curPage) =>
|
||||
{
|
||||
var eb = CreateEmbed()
|
||||
.WithOkColor();
|
||||
|
||||
for (var i = 0; i < items.Count; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
eb.AddField($"#{item.Rank} {item.User}",
|
||||
$"[{item.Game}]{N(item.MaxWin)}");
|
||||
}
|
||||
|
||||
return eb;
|
||||
})
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
public async Task GambleStats()
|
||||
{
|
||||
var stats = await _gamblingTxTracker.GetAllAsync();
|
||||
|
||||
var eb = CreateEmbed()
|
||||
.WithOkColor();
|
||||
.WithOkColor();
|
||||
|
||||
var str = "` Feature `|` Bet `|`Paid Out`|` RoI `\n";
|
||||
str += "――――――――――――――――――――\n";
|
||||
@@ -157,13 +226,13 @@ public partial class Gambling
|
||||
public async Task GambleStatsReset()
|
||||
{
|
||||
if (!await PromptUserConfirmAsync(CreateEmbed()
|
||||
.WithDescription(
|
||||
"""
|
||||
Are you sure?
|
||||
This will completely reset Gambling Stats.
|
||||
.WithDescription(
|
||||
"""
|
||||
Are you sure?
|
||||
This will completely reset Gambling Stats.
|
||||
|
||||
This action is irreversible.
|
||||
""")))
|
||||
This action is irreversible.
|
||||
""")))
|
||||
return;
|
||||
|
||||
await GambleStats();
|
||||
|
@@ -42,7 +42,7 @@ public sealed class UserBetStatsService : INService
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await ctx.GetTable<UserBetStats>()
|
||||
.DeleteAsync(x => x.UserId == userId && (game == null || x.Game == game));
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,4 +52,16 @@ public sealed class UserBetStatsService : INService
|
||||
await ctx.GetTable<GamblingStats>()
|
||||
.DeleteAsync();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<UserBetStats>> GetWinLbAsync(int page)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(page);
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<UserBetStats>()
|
||||
.OrderByDescending(x => x.MaxWin)
|
||||
.Skip(page * 10)
|
||||
.Take(10)
|
||||
.ToArrayAsyncLinqToDB();
|
||||
}
|
||||
}
|
@@ -103,11 +103,11 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
}
|
||||
|
||||
var eb = CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.time_new))
|
||||
.WithDescription(Format.Code(data.Time.ToString(Culture)))
|
||||
.AddField(GetText(strs.location), string.Join('\n', data.Address.Split(", ")), true)
|
||||
.AddField(GetText(strs.timezone), data.TimeZoneName, true);
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.time_new))
|
||||
.WithDescription(Format.Code(data.Time.ToString(Culture)))
|
||||
.AddField(GetText(strs.location), string.Join('\n', data.Address.Split(", ")), true)
|
||||
.AddField(GetText(strs.timezone), data.TimeZoneName, true);
|
||||
|
||||
await Response().Embed(eb).SendAsync();
|
||||
}
|
||||
@@ -129,16 +129,16 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
|
||||
await Response()
|
||||
.Embed(CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithTitle(movie.Title)
|
||||
.WithUrl($"https://www.imdb.com/title/{movie.ImdbId}/")
|
||||
.WithDescription(movie.Plot.TrimTo(1000))
|
||||
.AddField("Rating", movie.ImdbRating, true)
|
||||
.AddField("Genre", movie.Genre, true)
|
||||
.AddField("Year", movie.Year, true)
|
||||
.WithImageUrl(Uri.IsWellFormedUriString(movie.Poster, UriKind.Absolute)
|
||||
? movie.Poster
|
||||
: null))
|
||||
.WithOkColor()
|
||||
.WithTitle(movie.Title)
|
||||
.WithUrl($"https://www.imdb.com/title/{movie.ImdbId}/")
|
||||
.WithDescription(movie.Plot.TrimTo(1000))
|
||||
.AddField("Rating", movie.ImdbRating, true)
|
||||
.AddField("Genre", movie.Genre, true)
|
||||
.AddField("Year", movie.Year, true)
|
||||
.WithImageUrl(Uri.IsWellFormedUriString(movie.Poster, UriKind.Absolute)
|
||||
? movie.Poster
|
||||
: null))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
@@ -191,9 +191,9 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
|
||||
await Response()
|
||||
.Embed(CreateEmbed()
|
||||
.WithOkColor()
|
||||
.AddField(GetText(strs.original_url), $"<{query}>")
|
||||
.AddField(GetText(strs.short_url), $"<{shortLink}>"))
|
||||
.WithOkColor()
|
||||
.AddField(GetText(strs.original_url), $"<{query}>")
|
||||
.AddField(GetText(strs.short_url), $"<{shortLink}>"))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
@@ -214,13 +214,13 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
}
|
||||
|
||||
var embed = CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithTitle(card.Name)
|
||||
.WithDescription(card.Description)
|
||||
.WithImageUrl(card.ImageUrl)
|
||||
.AddField(GetText(strs.store_url), card.StoreUrl, true)
|
||||
.AddField(GetText(strs.cost), card.ManaCost, true)
|
||||
.AddField(GetText(strs.types), card.Types, true);
|
||||
.WithOkColor()
|
||||
.WithTitle(card.Name)
|
||||
.WithDescription(card.Description)
|
||||
.WithImageUrl(card.ImageUrl)
|
||||
.AddField(GetText(strs.store_url), card.StoreUrl, true)
|
||||
.AddField(GetText(strs.cost), card.ManaCost, true)
|
||||
.AddField(GetText(strs.types), card.Types, true);
|
||||
|
||||
await Response().Embed(embed).SendAsync();
|
||||
}
|
||||
@@ -281,10 +281,10 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
{
|
||||
var item = items[0];
|
||||
return CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithUrl(item.Permalink)
|
||||
.WithTitle(item.Word)
|
||||
.WithDescription(item.Definition);
|
||||
.WithOkColor()
|
||||
.WithUrl(item.Permalink)
|
||||
.WithTitle(item.Word)
|
||||
.WithDescription(item.Definition);
|
||||
})
|
||||
.SendAsync();
|
||||
}
|
||||
@@ -312,11 +312,11 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
{
|
||||
var model = items.First();
|
||||
var embed = CreateEmbed()
|
||||
.WithDescription(ctx.User.Mention)
|
||||
.AddField(GetText(strs.word), model.Word, true)
|
||||
.AddField(GetText(strs._class), model.WordType, true)
|
||||
.AddField(GetText(strs.definition), model.Definition)
|
||||
.WithOkColor();
|
||||
.WithDescription(ctx.User.Mention)
|
||||
.AddField(GetText(strs.word), model.Word, true)
|
||||
.AddField(GetText(strs._class), model.WordType, true)
|
||||
.AddField(GetText(strs.definition), model.Definition)
|
||||
.WithOkColor();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.Example))
|
||||
embed.AddField(GetText(strs.example), model.Example);
|
||||
@@ -404,10 +404,28 @@ public partial class Searches : NadekoModule<SearchesService>
|
||||
await Response()
|
||||
.Embed(
|
||||
CreateEmbed()
|
||||
.WithOkColor()
|
||||
.AddField("Username", usr.ToString())
|
||||
.AddField("Avatar Url", avatarUrl)
|
||||
.WithThumbnailUrl(avatarUrl.ToString()))
|
||||
.WithOkColor()
|
||||
.AddField("Username", usr.ToString())
|
||||
.AddField("Avatar Url", avatarUrl)
|
||||
.WithThumbnailUrl(avatarUrl.ToString()))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Banner([Leftover] IGuildUser? usr = null)
|
||||
{
|
||||
usr ??= (IGuildUser)ctx.User;
|
||||
|
||||
var bannerUrl = usr.GetGuildBannerUrl();
|
||||
|
||||
await Response()
|
||||
.Embed(
|
||||
CreateEmbed()
|
||||
.WithOkColor()
|
||||
.AddField("Username", usr.ToString())
|
||||
.AddField("Banner Url", bannerUrl)
|
||||
.WithThumbnailUrl(bannerUrl))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
|
@@ -344,9 +344,45 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
if (role is not null && user is not null)
|
||||
{
|
||||
if (rrew.Remove)
|
||||
_ = user.RemoveRoleAsync(role);
|
||||
{
|
||||
try
|
||||
{
|
||||
await user.RemoveRoleAsync(role);
|
||||
await _notifySub.NotifyAsync(new RemoveRoleRewardNotifyModel(guild.Id,
|
||||
role.Id,
|
||||
user.Id,
|
||||
newLevel),
|
||||
isShardLocal: true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex,
|
||||
"Unable to remove role {RoleId} from user {UserId}: {Message}",
|
||||
role.Id,
|
||||
user.Id,
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
_ = user.AddRoleAsync(role);
|
||||
{
|
||||
try
|
||||
{
|
||||
await user.AddRoleAsync(role);
|
||||
await _notifySub.NotifyAsync(new AddRoleRewardNotifyModel(guild.Id,
|
||||
role.Id,
|
||||
user.Id,
|
||||
newLevel),
|
||||
isShardLocal: true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex,
|
||||
"Unable to add role {RoleId} to user {UserId}: {Message}",
|
||||
role.Id,
|
||||
user.Id,
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user