mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-12 02:08:27 -04:00
Part2 of the response system rework
This commit is contained in:
@@ -23,18 +23,18 @@ public partial class Xp
|
||||
if (!result.TryPickT0(out var club, out var error))
|
||||
{
|
||||
if (error == ClubTransferError.NotOwner)
|
||||
await ReplyErrorLocalizedAsync(strs.club_owner_only);
|
||||
await Response().Error(strs.club_owner_only).SendAsync();
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.club_target_not_member);
|
||||
await Response().Error(strs.club_target_not_member).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(
|
||||
await Response().Confirm(
|
||||
strs.club_transfered(
|
||||
Format.Bold(club.Name),
|
||||
Format.Bold(newOwner.ToString())
|
||||
)
|
||||
);
|
||||
).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,15 +44,15 @@ public partial class Xp
|
||||
var result = await _service.ToggleAdminAsync(ctx.User, toAdmin);
|
||||
|
||||
if (result == ToggleAdminResult.AddedAdmin)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_admin_add(Format.Bold(toAdmin.ToString())));
|
||||
await Response().Confirm(strs.club_admin_add(Format.Bold(toAdmin.ToString()))).SendAsync();
|
||||
else if (result == ToggleAdminResult.RemovedAdmin)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_admin_remove(Format.Bold(toAdmin.ToString())));
|
||||
await Response().Confirm(strs.club_admin_remove(Format.Bold(toAdmin.ToString()))).SendAsync();
|
||||
else if (result == ToggleAdminResult.NotOwner)
|
||||
await ReplyErrorLocalizedAsync(strs.club_owner_only);
|
||||
await Response().Error(strs.club_owner_only).SendAsync();
|
||||
else if (result == ToggleAdminResult.CantTargetThyself)
|
||||
await ReplyErrorLocalizedAsync(strs.club_admin_invalid_target);
|
||||
await Response().Error(strs.club_admin_invalid_target).SendAsync();
|
||||
else if (result == ToggleAdminResult.TargetNotMember)
|
||||
await ReplyErrorLocalizedAsync(strs.club_target_not_member);
|
||||
await Response().Error(strs.club_target_not_member).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -62,29 +62,29 @@ public partial class Xp
|
||||
|
||||
if (result == ClubCreateResult.NameTooLong)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_name_too_long);
|
||||
await Response().Error(strs.club_name_too_long).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == ClubCreateResult.NameTaken)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_name_taken);
|
||||
await Response().Error(strs.club_name_taken).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == ClubCreateResult.InsufficientLevel)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_create_insuff_lvl);
|
||||
await Response().Error(strs.club_create_insuff_lvl).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == ClubCreateResult.AlreadyInAClub)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_already_in);
|
||||
await Response().Error(strs.club_already_in).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.club_created(Format.Bold(clubName)));
|
||||
await Response().Confirm(strs.club_created(Format.Bold(clubName))).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -92,19 +92,19 @@ public partial class Xp
|
||||
{
|
||||
if ((!Uri.IsWellFormedUriString(url, UriKind.Absolute) && url is not null))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_icon_url_format);
|
||||
await Response().Error(strs.club_icon_url_format).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var result = await _service.SetClubIconAsync(ctx.User.Id, url);
|
||||
if (result == SetClubIconResult.Success)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_icon_set);
|
||||
await Response().Confirm(strs.club_icon_set).SendAsync();
|
||||
else if (result == SetClubIconResult.NotOwner)
|
||||
await ReplyErrorLocalizedAsync(strs.club_owner_only);
|
||||
await Response().Error(strs.club_owner_only).SendAsync();
|
||||
else if (result == SetClubIconResult.TooLarge)
|
||||
await ReplyErrorLocalizedAsync(strs.club_icon_too_large);
|
||||
await Response().Error(strs.club_icon_too_large).SendAsync();
|
||||
else if (result == SetClubIconResult.InvalidFileType)
|
||||
await ReplyErrorLocalizedAsync(strs.club_icon_invalid_filetype);
|
||||
await Response().Error(strs.club_icon_invalid_filetype).SendAsync();
|
||||
}
|
||||
|
||||
private async Task InternalClubInfoAsync(ClubInfo club)
|
||||
@@ -123,7 +123,7 @@ public partial class Xp
|
||||
await ctx.SendPaginatedConfirmAsync(0,
|
||||
page =>
|
||||
{
|
||||
var embed = _eb.Create()
|
||||
var embed = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle($"{club}")
|
||||
.WithDescription(GetText(strs.level_x(lvl.Level + $" ({club.Xp} xp)")))
|
||||
@@ -163,7 +163,7 @@ public partial class Xp
|
||||
var club = _service.GetClubByMember(user);
|
||||
if (club is null)
|
||||
{
|
||||
await ErrorLocalizedAsync(strs.club_user_not_in_club(Format.Bold(user.ToString())));
|
||||
await Response().Error(strs.club_user_not_in_club(Format.Bold(user.ToString()))).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ public partial class Xp
|
||||
|
||||
if (!_service.GetClubByName(clubName, out var club))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_not_exists);
|
||||
await Response().Error(strs.club_not_exists).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ public partial class Xp
|
||||
|
||||
var club = _service.GetClubWithBansAndApplications(ctx.User.Id);
|
||||
if (club is null)
|
||||
return ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
return Response().Error(strs.club_admin_perms).SendAsync();
|
||||
|
||||
var bans = club.Bans.Select(x => x.User).ToArray();
|
||||
|
||||
@@ -208,7 +208,7 @@ public partial class Xp
|
||||
.Skip(page * 10).Take(10)
|
||||
.Select(x => x.ToString()));
|
||||
|
||||
return _eb.Create()
|
||||
return new EmbedBuilder()
|
||||
.WithTitle(GetText(strs.club_bans_for(club.ToString())))
|
||||
.WithDescription(toShow)
|
||||
.WithOkColor();
|
||||
@@ -225,7 +225,7 @@ public partial class Xp
|
||||
|
||||
var club = _service.GetClubWithBansAndApplications(ctx.User.Id);
|
||||
if (club is null)
|
||||
return ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
return Response().Error(strs.club_admin_perms).SendAsync();
|
||||
|
||||
var apps = club.Applicants.Select(x => x.User).ToArray();
|
||||
|
||||
@@ -234,7 +234,7 @@ public partial class Xp
|
||||
{
|
||||
var toShow = string.Join("\n", apps.Skip(page * 10).Take(10).Select(x => x.ToString()));
|
||||
|
||||
return _eb.Create()
|
||||
return new EmbedBuilder()
|
||||
.WithTitle(GetText(strs.club_apps_for(club.ToString())))
|
||||
.WithDescription(toShow)
|
||||
.WithOkColor();
|
||||
@@ -251,19 +251,19 @@ public partial class Xp
|
||||
|
||||
if (!_service.GetClubByName(clubName, out var club))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_not_exists);
|
||||
await Response().Error(strs.club_not_exists).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var result = _service.ApplyToClub(ctx.User, club);
|
||||
if (result == ClubApplyResult.Success)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_applied(Format.Bold(club.ToString())));
|
||||
await Response().Confirm(strs.club_applied(Format.Bold(club.ToString()))).SendAsync();
|
||||
else if (result == ClubApplyResult.Banned)
|
||||
await ReplyErrorLocalizedAsync(strs.club_join_banned);
|
||||
await Response().Error(strs.club_join_banned).SendAsync();
|
||||
else if (result == ClubApplyResult.AlreadyApplied)
|
||||
await ReplyErrorLocalizedAsync(strs.club_already_applied);
|
||||
await Response().Error(strs.club_already_applied).SendAsync();
|
||||
else if (result == ClubApplyResult.AlreadyInAClub)
|
||||
await ReplyErrorLocalizedAsync(strs.club_already_in);
|
||||
await Response().Error(strs.club_already_in).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -277,11 +277,11 @@ public partial class Xp
|
||||
{
|
||||
var result = _service.AcceptApplication(ctx.User.Id, userName, out var discordUser);
|
||||
if (result == ClubAcceptResult.Accepted)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_accepted(Format.Bold(discordUser.ToString())));
|
||||
await Response().Confirm(strs.club_accepted(Format.Bold(discordUser.ToString()))).SendAsync();
|
||||
else if (result == ClubAcceptResult.NoSuchApplicant)
|
||||
await ReplyErrorLocalizedAsync(strs.club_accept_invalid_applicant);
|
||||
await Response().Error(strs.club_accept_invalid_applicant).SendAsync();
|
||||
else if (result == ClubAcceptResult.NotOwnerOrAdmin)
|
||||
await ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
await Response().Error(strs.club_admin_perms).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -295,11 +295,11 @@ public partial class Xp
|
||||
{
|
||||
var result = _service.RejectApplication(ctx.User.Id, userName, out var discordUser);
|
||||
if (result == ClubDenyResult.Rejected)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_rejected(Format.Bold(discordUser.ToString())));
|
||||
await Response().Confirm(strs.club_rejected(Format.Bold(discordUser.ToString()))).SendAsync();
|
||||
else if(result == ClubDenyResult.NoSuchApplicant)
|
||||
await ReplyErrorLocalizedAsync(strs.club_accept_invalid_applicant);
|
||||
await Response().Error(strs.club_accept_invalid_applicant).SendAsync();
|
||||
else if(result == ClubDenyResult.NotOwnerOrAdmin)
|
||||
await ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
await Response().Error(strs.club_admin_perms).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -308,11 +308,11 @@ public partial class Xp
|
||||
var res = _service.LeaveClub(ctx.User);
|
||||
|
||||
if (res == ClubLeaveResult.Success)
|
||||
await ReplyConfirmLocalizedAsync(strs.club_left);
|
||||
await Response().Confirm(strs.club_left).SendAsync();
|
||||
else if (res == ClubLeaveResult.NotInAClub)
|
||||
await ReplyErrorLocalizedAsync(strs.club_not_in_a_club);
|
||||
await Response().Error(strs.club_not_in_a_club).SendAsync();
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.club_owner_cant_leave);
|
||||
await Response().Error(strs.club_owner_cant_leave).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -327,17 +327,17 @@ public partial class Xp
|
||||
var result = _service.Kick(ctx.User.Id, userName, out var club);
|
||||
if (result == ClubKickResult.Success)
|
||||
{
|
||||
return ReplyConfirmLocalizedAsync(strs.club_user_kick(Format.Bold(userName),
|
||||
Format.Bold(club.ToString())));
|
||||
return Response().Confirm(strs.club_user_kick(Format.Bold(userName),
|
||||
Format.Bold(club.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
if (result == ClubKickResult.Hierarchy)
|
||||
return ReplyErrorLocalizedAsync(strs.club_kick_hierarchy);
|
||||
return Response().Error(strs.club_kick_hierarchy).SendAsync();
|
||||
|
||||
if (result == ClubKickResult.NotOwnerOrAdmin)
|
||||
return ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
return Response().Error(strs.club_admin_perms).SendAsync();
|
||||
|
||||
return ReplyErrorLocalizedAsync(strs.club_target_not_member);
|
||||
return Response().Error(strs.club_target_not_member).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -352,17 +352,17 @@ public partial class Xp
|
||||
var result = _service.Ban(ctx.User.Id, userName, out var club);
|
||||
if (result == ClubBanResult.Success)
|
||||
{
|
||||
return ReplyConfirmLocalizedAsync(strs.club_user_banned(Format.Bold(userName),
|
||||
Format.Bold(club.ToString())));
|
||||
return Response().Confirm(strs.club_user_banned(Format.Bold(userName),
|
||||
Format.Bold(club.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
if (result == ClubBanResult.Unbannable)
|
||||
return ReplyErrorLocalizedAsync(strs.club_ban_fail_unbannable);
|
||||
return Response().Error(strs.club_ban_fail_unbannable).SendAsync();
|
||||
|
||||
if (result == ClubBanResult.WrongUser)
|
||||
return ReplyErrorLocalizedAsync(strs.club_ban_fail_user_not_found);
|
||||
return Response().Error(strs.club_ban_fail_user_not_found).SendAsync();
|
||||
|
||||
return ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
return Response().Error(strs.club_admin_perms).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -378,16 +378,16 @@ public partial class Xp
|
||||
|
||||
if (result == ClubUnbanResult.Success)
|
||||
{
|
||||
return ReplyConfirmLocalizedAsync(strs.club_user_unbanned(Format.Bold(userName),
|
||||
Format.Bold(club.ToString())));
|
||||
return Response().Confirm(strs.club_user_unbanned(Format.Bold(userName),
|
||||
Format.Bold(club.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
if (result == ClubUnbanResult.WrongUser)
|
||||
{
|
||||
return ReplyErrorLocalizedAsync(strs.club_unban_fail_user_not_found);
|
||||
return Response().Error(strs.club_unban_fail_user_not_found).SendAsync();
|
||||
}
|
||||
|
||||
return ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
return Response().Error(strs.club_admin_perms).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -399,17 +399,17 @@ public partial class Xp
|
||||
? "-"
|
||||
: desc;
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
var eb = new EmbedBuilder()
|
||||
.WithAuthor(ctx.User)
|
||||
.WithTitle(GetText(strs.club_desc_update))
|
||||
.WithOkColor()
|
||||
.WithDescription(desc);
|
||||
|
||||
await EmbedAsync(eb);
|
||||
await Response().Embed(eb).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.club_desc_update_failed);
|
||||
await Response().Error(strs.club_desc_update_failed).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,9 +417,9 @@ public partial class Xp
|
||||
public async Task ClubDisband()
|
||||
{
|
||||
if (_service.Disband(ctx.User.Id, out var club))
|
||||
await ReplyConfirmLocalizedAsync(strs.club_disbanded(Format.Bold(club.Name)));
|
||||
await Response().Confirm(strs.club_disbanded(Format.Bold(club.Name))).SendAsync();
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.club_disband_error);
|
||||
await Response().Error(strs.club_disband_error).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -430,13 +430,13 @@ public partial class Xp
|
||||
|
||||
var clubs = _service.GetClubLeaderboardPage(page);
|
||||
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.club_leaderboard(page + 1))).WithOkColor();
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.club_leaderboard(page + 1))).WithOkColor();
|
||||
|
||||
var i = page * 9;
|
||||
foreach (var club in clubs)
|
||||
embed.AddField($"#{++i} " + club, club.Xp + " xp");
|
||||
|
||||
return EmbedAsync(embed);
|
||||
return Response().Embed(embed).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -447,19 +447,19 @@ public partial class Xp
|
||||
switch (res)
|
||||
{
|
||||
case ClubRenameResult.NameTooLong:
|
||||
await ReplyErrorLocalizedAsync(strs.club_name_too_long);
|
||||
await Response().Error(strs.club_name_too_long).SendAsync();
|
||||
return;
|
||||
case ClubRenameResult.Success:
|
||||
{
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.club_renamed(clubName))).WithOkColor();
|
||||
await EmbedAsync(embed);
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.club_renamed(clubName))).WithOkColor();
|
||||
await Response().Embed(embed).SendAsync();
|
||||
return;
|
||||
}
|
||||
case ClubRenameResult.NameTaken:
|
||||
await ReplyErrorLocalizedAsync(strs.club_name_taken);
|
||||
await Response().Error(strs.club_name_taken).SendAsync();
|
||||
return;
|
||||
case ClubRenameResult.NotOwnerOrAdmin:
|
||||
await ReplyErrorLocalizedAsync(strs.club_admin_perms);
|
||||
await Response().Error(strs.club_admin_perms).SendAsync();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
|
@@ -57,7 +57,7 @@ public class ClubService : INService, IClubService
|
||||
public OneOf<ClubInfo, ClubTransferError> TransferClub(IUser from, IUser newOwner)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var club = uow.Set<ClubInfo>().GetByOwner(@from.Id);
|
||||
var club = uow.Set<ClubInfo>().GetByOwner(from.Id);
|
||||
var newOwnerUser = uow.GetOrCreateUser(newOwner);
|
||||
|
||||
if (club is null || club.Owner.UserId != from.Id)
|
||||
|
@@ -59,12 +59,12 @@ public partial class Xp : NadekoModule<XpService>
|
||||
var globalSetting = _service.GetNotificationType(ctx.User);
|
||||
var serverSetting = _service.GetNotificationType(ctx.User.Id, ctx.Guild.Id);
|
||||
|
||||
var embed = _eb.Create()
|
||||
.WithOkColor()
|
||||
.AddField(GetText(strs.xpn_setting_global), GetNotifLocationString(globalSetting))
|
||||
.AddField(GetText(strs.xpn_setting_server), GetNotifLocationString(serverSetting));
|
||||
var embed = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.AddField(GetText(strs.xpn_setting_global), GetNotifLocationString(globalSetting))
|
||||
.AddField(GetText(strs.xpn_setting_server), GetNotifLocationString(serverSetting));
|
||||
|
||||
await EmbedAsync(embed);
|
||||
await Response().Embed(embed).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -87,9 +87,9 @@ public partial class Xp : NadekoModule<XpService>
|
||||
var ex = _service.ToggleExcludeServer(ctx.Guild.Id);
|
||||
|
||||
if (ex)
|
||||
await ReplyConfirmLocalizedAsync(strs.excluded(Format.Bold(ctx.Guild.ToString())));
|
||||
await Response().Confirm(strs.excluded(Format.Bold(ctx.Guild.ToString()))).SendAsync();
|
||||
else
|
||||
await ReplyConfirmLocalizedAsync(strs.not_excluded(Format.Bold(ctx.Guild.ToString())));
|
||||
await Response().Confirm(strs.not_excluded(Format.Bold(ctx.Guild.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -100,9 +100,9 @@ public partial class Xp : NadekoModule<XpService>
|
||||
var ex = _service.ToggleExcludeRole(ctx.Guild.Id, role.Id);
|
||||
|
||||
if (ex)
|
||||
await ReplyConfirmLocalizedAsync(strs.excluded(Format.Bold(role.ToString())));
|
||||
await Response().Confirm(strs.excluded(Format.Bold(role.ToString()))).SendAsync();
|
||||
else
|
||||
await ReplyConfirmLocalizedAsync(strs.not_excluded(Format.Bold(role.ToString())));
|
||||
await Response().Confirm(strs.not_excluded(Format.Bold(role.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -116,9 +116,9 @@ public partial class Xp : NadekoModule<XpService>
|
||||
var ex = _service.ToggleExcludeChannel(ctx.Guild.Id, channel.Id);
|
||||
|
||||
if (ex)
|
||||
await ReplyConfirmLocalizedAsync(strs.excluded(Format.Bold(channel.ToString())));
|
||||
await Response().Confirm(strs.excluded(Format.Bold(channel.ToString()))).SendAsync();
|
||||
else
|
||||
await ReplyConfirmLocalizedAsync(strs.not_excluded(Format.Bold(channel.ToString())));
|
||||
await Response().Confirm(strs.not_excluded(Format.Bold(channel.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -127,16 +127,16 @@ public partial class Xp : NadekoModule<XpService>
|
||||
{
|
||||
var serverExcluded = _service.IsServerExcluded(ctx.Guild.Id);
|
||||
var roles = _service.GetExcludedRoles(ctx.Guild.Id)
|
||||
.Select(x => ctx.Guild.GetRole(x))
|
||||
.Where(x => x is not null)
|
||||
.Select(x => $"`role` {x.Mention}")
|
||||
.ToList();
|
||||
.Select(x => ctx.Guild.GetRole(x))
|
||||
.Where(x => x is not null)
|
||||
.Select(x => $"`role` {x.Mention}")
|
||||
.ToList();
|
||||
|
||||
var chans = (await _service.GetExcludedChannels(ctx.Guild.Id)
|
||||
.Select(x => ctx.Guild.GetChannelAsync(x))
|
||||
.WhenAll()).Where(x => x is not null)
|
||||
.Select(x => $"`channel` <#{x.Id}>")
|
||||
.ToList();
|
||||
.Select(x => ctx.Guild.GetChannelAsync(x))
|
||||
.WhenAll()).Where(x => x is not null)
|
||||
.Select(x => $"`channel` <#{x.Id}>")
|
||||
.ToList();
|
||||
|
||||
var rolesStr = roles.Any() ? string.Join("\n", roles) + "\n" : string.Empty;
|
||||
var chansStr = chans.Count > 0 ? string.Join("\n", chans) + "\n" : string.Empty;
|
||||
@@ -150,10 +150,10 @@ public partial class Xp : NadekoModule<XpService>
|
||||
await ctx.SendPaginatedConfirmAsync(0,
|
||||
curpage =>
|
||||
{
|
||||
var embed = _eb.Create()
|
||||
.WithTitle(GetText(strs.exclusion_list))
|
||||
.WithDescription(string.Join('\n', lines.Skip(15 * curpage).Take(15)))
|
||||
.WithOkColor();
|
||||
var embed = new EmbedBuilder()
|
||||
.WithTitle(GetText(strs.exclusion_list))
|
||||
.WithDescription(string.Join('\n', lines.Skip(15 * curpage).Take(15)))
|
||||
.WithOkColor();
|
||||
|
||||
return embed;
|
||||
},
|
||||
@@ -189,14 +189,14 @@ public partial class Xp : NadekoModule<XpService>
|
||||
await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
|
||||
|
||||
allUsers = _service.GetTopUserXps(ctx.Guild.Id, 1000)
|
||||
.Where(user => socketGuild.GetUser(user.UserId) is not null)
|
||||
.ToList();
|
||||
.Where(user => socketGuild.GetUser(user.UserId) is not null)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
await ctx.SendPaginatedConfirmAsync(page,
|
||||
curPage =>
|
||||
{
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.server_leaderboard)).WithOkColor();
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.server_leaderboard)).WithOkColor();
|
||||
|
||||
List<UserXpStats> users;
|
||||
if (opts.Clean)
|
||||
@@ -239,7 +239,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
return;
|
||||
var users = _service.GetUserXps(page);
|
||||
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.global_leaderboard)).WithOkColor();
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.global_leaderboard)).WithOkColor();
|
||||
|
||||
if (!users.Any())
|
||||
embed.WithDescription("-");
|
||||
@@ -253,7 +253,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
}
|
||||
}
|
||||
|
||||
await EmbedAsync(embed);
|
||||
await Response().Embed(embed).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -269,8 +269,10 @@ public partial class Xp : NadekoModule<XpService>
|
||||
return;
|
||||
|
||||
var count = await _service.AddXpToUsersAsync(ctx.Guild.Id, amount, role.Members.Select(x => x.Id).ToArray());
|
||||
await ReplyConfirmLocalizedAsync(
|
||||
strs.xpadd_users(Format.Bold(amount.ToString()), Format.Bold(count.ToString())));
|
||||
await Response()
|
||||
.Confirm(
|
||||
strs.xpadd_users(Format.Bold(amount.ToString()), Format.Bold(count.ToString())))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -284,7 +286,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
|
||||
_service.AddXp(userId, ctx.Guild.Id, amount);
|
||||
var usr = ((SocketGuild)ctx.Guild).GetUser(userId)?.ToString() ?? userId.ToString();
|
||||
await ReplyConfirmLocalizedAsync(strs.modified(Format.Bold(usr), Format.Bold(amount.ToString())));
|
||||
await Response().Confirm(strs.modified(Format.Bold(usr), Format.Bold(amount.ToString()))).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -301,7 +303,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
{
|
||||
_service.ReloadXpTemplate();
|
||||
await Task.Delay(1000);
|
||||
await ReplyConfirmLocalizedAsync(strs.template_reloaded);
|
||||
await Response().Confirm(strs.template_reloaded).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -315,14 +317,14 @@ public partial class Xp : NadekoModule<XpService>
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task XpReset(ulong userId)
|
||||
{
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.reset)).WithDescription(GetText(strs.reset_user_confirm));
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.reset)).WithDescription(GetText(strs.reset_user_confirm));
|
||||
|
||||
if (!await PromptUserConfirmAsync(embed))
|
||||
return;
|
||||
|
||||
_service.XpReset(ctx.Guild.Id, userId);
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.reset_user(userId));
|
||||
await Response().Confirm(strs.reset_user(userId)).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -330,14 +332,14 @@ public partial class Xp : NadekoModule<XpService>
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task XpReset()
|
||||
{
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.reset)).WithDescription(GetText(strs.reset_server_confirm));
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.reset)).WithDescription(GetText(strs.reset_server_confirm));
|
||||
|
||||
if (!await PromptUserConfirmAsync(embed))
|
||||
return;
|
||||
|
||||
_service.XpReset(ctx.Guild.Id);
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.reset_server);
|
||||
await Response().Confirm(strs.reset_server).SendAsync();
|
||||
}
|
||||
|
||||
public enum XpShopInputType
|
||||
@@ -358,15 +360,19 @@ public partial class Xp : NadekoModule<XpService>
|
||||
{
|
||||
if (!_service.IsShopEnabled())
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.xp_shop_disabled);
|
||||
await Response().Error(strs.xp_shop_disabled).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await SendConfirmAsync(GetText(strs.available_commands),
|
||||
$@"`{prefix}xpshop bgs`
|
||||
`{prefix}xpshop frames`
|
||||
await Response()
|
||||
.Confirm(GetText(strs.available_commands),
|
||||
$"""
|
||||
`{prefix}xpshop bgs`
|
||||
`{prefix}xpshop frames`
|
||||
|
||||
*{GetText(strs.xpshop_website)}*");
|
||||
*{GetText(strs.xpshop_website)}*
|
||||
""")
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -383,13 +389,13 @@ public partial class Xp : NadekoModule<XpService>
|
||||
|
||||
if (items is null)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.xp_shop_disabled);
|
||||
await Response().Error(strs.xp_shop_disabled).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (items.Count == 0)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_found);
|
||||
await Response().Error(strs.not_found).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,13 +404,15 @@ public partial class Xp : NadekoModule<XpService>
|
||||
{
|
||||
var (key, item) = items.Skip(current).First();
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
.WithTitle(item.Name)
|
||||
.AddField(GetText(strs.price), CurrencyHelper.N(item.Price, Culture, _gss.GetCurrencySign()), true)
|
||||
.WithImageUrl(string.IsNullOrWhiteSpace(item.Preview)
|
||||
? item.Url
|
||||
: item.Preview);
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(item.Name)
|
||||
.AddField(GetText(strs.price),
|
||||
CurrencyHelper.N(item.Price, Culture, _gss.GetCurrencySign()),
|
||||
true)
|
||||
.WithImageUrl(string.IsNullOrWhiteSpace(item.Preview)
|
||||
? item.Url
|
||||
: item.Preview);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(item.Desc))
|
||||
eb.AddField(GetText(strs.desc), item.Desc);
|
||||
@@ -483,20 +491,24 @@ public partial class Xp : NadekoModule<XpService>
|
||||
{
|
||||
var _ = result switch
|
||||
{
|
||||
BuyResult.XpShopDisabled => await ReplyErrorLocalizedAsync(strs.xp_shop_disabled),
|
||||
BuyResult.InsufficientFunds => await ReplyErrorLocalizedAsync(strs.not_enough(_gss.GetCurrencySign())),
|
||||
BuyResult.XpShopDisabled => await Response().Error(strs.xp_shop_disabled).SendAsync(),
|
||||
BuyResult.InsufficientFunds => await Response()
|
||||
.Error(strs.not_enough(_gss.GetCurrencySign()))
|
||||
.SendAsync(),
|
||||
BuyResult.AlreadyOwned =>
|
||||
await ReplyErrorLocalizedAsync(strs.xpshop_already_owned, GetUseInteraction()),
|
||||
BuyResult.UnknownItem => await ReplyErrorLocalizedAsync(strs.xpshop_item_not_found),
|
||||
BuyResult.InsufficientPatronTier => await ReplyErrorLocalizedAsync(strs.patron_insuff_tier),
|
||||
await Response().Error(strs.xpshop_already_owned).Interaction(GetUseInteraction()).SendAsync(),
|
||||
BuyResult.UnknownItem => await Response().Error(strs.xpshop_item_not_found).SendAsync(),
|
||||
BuyResult.InsufficientPatronTier => await Response().Error(strs.patron_insuff_tier).SendAsync(),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.xpshop_buy_success(type.ToString().ToLowerInvariant(),
|
||||
key.ToLowerInvariant()),
|
||||
GetUseInteraction());
|
||||
await Response()
|
||||
.Confirm(strs.xpshop_buy_success(type.ToString().ToLowerInvariant(),
|
||||
key.ToLowerInvariant()))
|
||||
.Interaction(GetUseInteraction())
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -506,7 +518,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
|
||||
if (!result)
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.xp_shop_item_cant_use);
|
||||
await Response().Confirm(strs.xp_shop_item_cant_use).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -525,7 +537,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
|
||||
if (!result)
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.xp_shop_item_cant_use);
|
||||
await Response().Confirm(strs.xp_shop_item_cant_use).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,7 +552,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
|
||||
if (result == BuyResult.InsufficientFunds)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(_gss.GetCurrencySign()));
|
||||
await Response().Error(strs.not_enough(_gss.GetCurrencySign())).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@ public partial class Xp
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task XpRewsReset()
|
||||
{
|
||||
var promptEmbed = _eb.Create()
|
||||
var promptEmbed = new EmbedBuilder()
|
||||
.WithPendingColor()
|
||||
.WithDescription(GetText(strs.xprewsreset_confirm));
|
||||
|
||||
@@ -69,7 +69,7 @@ public partial class Xp
|
||||
return Context.SendPaginatedConfirmAsync(page,
|
||||
cur =>
|
||||
{
|
||||
var embed = _eb.Create().WithTitle(GetText(strs.level_up_rewards)).WithOkColor();
|
||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.level_up_rewards)).WithOkColor();
|
||||
|
||||
var localRewards = allRewards.Skip(cur * 9).Take(9).ToList();
|
||||
|
||||
@@ -94,7 +94,7 @@ public partial class Xp
|
||||
public async Task XpRoleReward(int level)
|
||||
{
|
||||
_service.ResetRoleReward(ctx.Guild.Id, level);
|
||||
await ReplyConfirmLocalizedAsync(strs.xp_role_reward_cleared(level));
|
||||
await Response().Confirm(strs.xp_role_reward_cleared(level)).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -109,11 +109,11 @@ public partial class Xp
|
||||
|
||||
_service.SetRoleReward(ctx.Guild.Id, level, role.Id, action == AddRemove.Remove);
|
||||
if (action == AddRemove.Add)
|
||||
await ReplyConfirmLocalizedAsync(strs.xp_role_reward_add_role(level, Format.Bold(role.ToString())));
|
||||
await Response().Confirm(strs.xp_role_reward_add_role(level, Format.Bold(role.ToString()))).SendAsync();
|
||||
else
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.xp_role_reward_remove_role(Format.Bold(level.ToString()),
|
||||
Format.Bold(role.ToString())));
|
||||
await Response().Confirm(strs.xp_role_reward_remove_role(Format.Bold(level.ToString()),
|
||||
Format.Bold(role.ToString()))).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,10 +127,10 @@ public partial class Xp
|
||||
|
||||
_service.SetCurrencyReward(ctx.Guild.Id, level, amount);
|
||||
if (amount == 0)
|
||||
await ReplyConfirmLocalizedAsync(strs.cur_reward_cleared(level, _cp.GetCurrencySign()));
|
||||
await Response().Confirm(strs.cur_reward_cleared(level, _cp.GetCurrencySign())).SendAsync();
|
||||
else
|
||||
await ReplyConfirmLocalizedAsync(strs.cur_reward_added(level,
|
||||
Format.Bold(amount + _cp.GetCurrencySign())));
|
||||
await Response().Confirm(strs.cur_reward_added(level,
|
||||
Format.Bold(amount + _cp.GetCurrencySign()))).SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
@@ -22,7 +22,6 @@ namespace NadekoBot.Modules.Xp.Services;
|
||||
|
||||
public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
{
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly IImageCache _images;
|
||||
private readonly IBotStrings _strings;
|
||||
@@ -44,10 +43,11 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
private readonly TypedKey<bool> _xpTemplateReloadKey;
|
||||
private readonly IPatronageService _ps;
|
||||
private readonly IBotCache _c;
|
||||
|
||||
|
||||
|
||||
|
||||
private readonly QueueRunner _levelUpQueue = new QueueRunner(0, 50);
|
||||
private readonly Channel<UserXpGainData> _xpGainQueue = Channel.CreateUnbounded<UserXpGainData>();
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public XpService(
|
||||
DiscordSocketClient client,
|
||||
@@ -63,7 +63,8 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
XpConfigService xpConfig,
|
||||
IPubSub pubSub,
|
||||
IEmbedBuilderService eb,
|
||||
IPatronageService ps)
|
||||
IPatronageService ps,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_db = db;
|
||||
_images = images;
|
||||
@@ -81,6 +82,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
_xpTemplateReloadKey = new("xp.template.reload");
|
||||
_ps = ps;
|
||||
_c = c;
|
||||
_sender = sender;
|
||||
|
||||
InternalReloadXpTemplate();
|
||||
|
||||
@@ -127,7 +129,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
_ = Task.Run(() => _levelUpQueue.RunAsync());
|
||||
|
||||
|
||||
using var timer = new PeriodicTimer(5.Seconds());
|
||||
while (await timer.WaitForNextTickAsync())
|
||||
{
|
||||
@@ -142,12 +144,13 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
}
|
||||
|
||||
private async Task UpdateXp()
|
||||
{
|
||||
try
|
||||
{
|
||||
var reader = _xpGainQueue.Reader;
|
||||
|
||||
|
||||
// sum up all gains into a single UserCacheItem
|
||||
var globalToAdd = new Dictionary<ulong, UserXpGainData>();
|
||||
var guildToAdd = new Dictionary<ulong, Dictionary<ulong, UserXpGainData>>();
|
||||
@@ -159,7 +162,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
else
|
||||
ci.XpAmount += item.XpAmount;
|
||||
|
||||
|
||||
|
||||
// ad guild xp in these guilds to these users
|
||||
if (!guildToAdd.TryGetValue(item.Guild.Id, out var users))
|
||||
users = guildToAdd[item.Guild.Id] = new();
|
||||
@@ -183,77 +186,77 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
await _cs.AddAsync(user.Key, (long)(amount), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update global user xp in batches
|
||||
// group by xp amount and update the same amounts at the same time
|
||||
foreach (var group in globalToAdd.GroupBy(x => x.Value.XpAmount, x => x.Key))
|
||||
{
|
||||
var items = await ctx.Set<DiscordUser>()
|
||||
.Where(x => group.Contains(x.UserId))
|
||||
.UpdateWithOutputAsync(old => new()
|
||||
{
|
||||
TotalXp = old.TotalXp + group.Key
|
||||
},
|
||||
(_, n) => n);
|
||||
.Where(x => group.Contains(x.UserId))
|
||||
.UpdateWithOutputAsync(old => new()
|
||||
{
|
||||
TotalXp = old.TotalXp + group.Key
|
||||
},
|
||||
(_, n) => n);
|
||||
|
||||
await ctx.Set<ClubInfo>()
|
||||
.Where(x => x.Members.Any(m => group.Contains(m.UserId)))
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + (group.Key * old.Members.Count(m => group.Contains(m.UserId)))
|
||||
});
|
||||
|
||||
.Where(x => x.Members.Any(m => group.Contains(m.UserId)))
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + (group.Key * old.Members.Count(m => group.Contains(m.UserId)))
|
||||
});
|
||||
|
||||
dus.AddRange(items);
|
||||
}
|
||||
|
||||
// update guild user xp in batches
|
||||
foreach (var (guildId, toAdd) in guildToAdd)
|
||||
{
|
||||
foreach (var group in toAdd.GroupBy(x => x.Value.XpAmount, x => x.Key))
|
||||
{
|
||||
var items = await ctx
|
||||
.Set<UserXpStats>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.Where(x => group.Contains(x.UserId))
|
||||
.UpdateWithOutputAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + group.Key
|
||||
},
|
||||
(_, n) => n);
|
||||
|
||||
.Set<UserXpStats>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.Where(x => group.Contains(x.UserId))
|
||||
.UpdateWithOutputAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + group.Key
|
||||
},
|
||||
(_, n) => n);
|
||||
|
||||
gxps.AddRange(items);
|
||||
|
||||
|
||||
var missingUserIds = group.Where(userId => !items.Any(x => x.UserId == userId)).ToArray();
|
||||
foreach (var userId in missingUserIds)
|
||||
{
|
||||
await ctx
|
||||
.Set<UserXpStats>()
|
||||
.ToLinqToDBTable()
|
||||
.InsertOrUpdateAsync(() => new UserXpStats()
|
||||
{
|
||||
UserId = userId,
|
||||
GuildId = guildId,
|
||||
Xp = group.Key,
|
||||
DateAdded = DateTime.UtcNow,
|
||||
AwardedXp = 0,
|
||||
NotifyOnLevelUp = XpNotificationLocation.None
|
||||
},
|
||||
_ => new()
|
||||
{
|
||||
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
UserId = userId
|
||||
});
|
||||
.Set<UserXpStats>()
|
||||
.ToLinqToDBTable()
|
||||
.InsertOrUpdateAsync(() => new UserXpStats()
|
||||
{
|
||||
UserId = userId,
|
||||
GuildId = guildId,
|
||||
Xp = group.Key,
|
||||
DateAdded = DateTime.UtcNow,
|
||||
AwardedXp = 0,
|
||||
NotifyOnLevelUp = XpNotificationLocation.None
|
||||
},
|
||||
_ => new()
|
||||
{
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
|
||||
if (missingUserIds.Length > 0)
|
||||
{
|
||||
var missingItems = await ctx.Set<UserXpStats>()
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => missingUserIds.Contains(x.UserId))
|
||||
.ToArrayAsyncLinqToDB();
|
||||
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => missingUserIds.Contains(x.UserId))
|
||||
.ToArrayAsyncLinqToDB();
|
||||
|
||||
gxps.AddRange(missingItems);
|
||||
}
|
||||
}
|
||||
@@ -325,7 +328,11 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
await HandleNotifyInternalAsync(guildId, channelId, userId, isServer, newLevel, notifyLoc);
|
||||
};
|
||||
|
||||
private async Task HandleRewardsInternalAsync(ulong guildId, ulong userId, long oldLevel, long newLevel)
|
||||
private async Task HandleRewardsInternalAsync(
|
||||
ulong guildId,
|
||||
ulong userId,
|
||||
long oldLevel,
|
||||
long newLevel)
|
||||
{
|
||||
List<XpRoleReward> rrews;
|
||||
List<XpCurrencyReward> crews;
|
||||
@@ -364,16 +371,17 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleNotifyInternalAsync(ulong guildId,
|
||||
ulong channelId,
|
||||
ulong userId,
|
||||
private async Task HandleNotifyInternalAsync(
|
||||
ulong guildId,
|
||||
ulong channelId,
|
||||
ulong userId,
|
||||
bool isServer,
|
||||
long newLevel,
|
||||
XpNotificationLocation notifyLoc)
|
||||
{
|
||||
if (notifyLoc == XpNotificationLocation.None)
|
||||
return;
|
||||
|
||||
|
||||
var guild = _client.GetGuild(guildId);
|
||||
var user = guild?.GetUser(userId);
|
||||
var ch = guild?.GetTextChannel(channelId);
|
||||
@@ -395,10 +403,11 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
{
|
||||
if (ch is not null)
|
||||
{
|
||||
await ch.SendConfirmAsync(_eb,
|
||||
_strings.GetText(strs.level_up_channel(user.Mention,
|
||||
Format.Bold(newLevel.ToString())),
|
||||
guild.Id));
|
||||
await _sender.Response(ch)
|
||||
.Confirm(_strings.GetText(strs.level_up_channel(user.Mention,
|
||||
Format.Bold(newLevel.ToString())),
|
||||
guild.Id))
|
||||
.SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,10 +423,12 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
if (chan is null)
|
||||
return;
|
||||
|
||||
await chan.SendConfirmAsync(_eb,
|
||||
_strings.GetText(strs.level_up_global(user.Mention,
|
||||
Format.Bold(newLevel.ToString())),
|
||||
guild.Id));
|
||||
await _sender.Response(chan)
|
||||
.Confirm(
|
||||
_strings.GetText(strs.level_up_global(user.Mention,
|
||||
Format.Bold(newLevel.ToString())),
|
||||
guild.Id))
|
||||
.SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,7 +684,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
|
||||
private TypedKey<long> GetVoiceXpKey(ulong userId)
|
||||
=> new($"xp:{_client.CurrentUser.Id}:vc_join:{userId}");
|
||||
|
||||
|
||||
private async Task UserJoinedVoiceChannel(SocketGuildUser user)
|
||||
{
|
||||
var value = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
@@ -683,7 +694,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
TimeSpan.FromMinutes(_xpConfig.Data.VoiceMaxMinutes),
|
||||
overwrite: false);
|
||||
}
|
||||
|
||||
|
||||
// private void UserJoinedVoiceChannel(SocketGuildUser user)
|
||||
// {
|
||||
// var key = $"{_creds.RedisKey()}_user_xp_vc_join_{user.Id}";
|
||||
@@ -725,7 +736,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* private void UserLeftVoiceChannel(SocketGuildUser user, SocketVoiceChannel channel)
|
||||
{
|
||||
@@ -825,13 +836,13 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<UserXpStats>()
|
||||
.Where(x => x.GuildId == guildId && userIds.Contains(x.UserId))
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + amount
|
||||
});
|
||||
.Where(x => x.GuildId == guildId && userIds.Contains(x.UserId))
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + amount
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void AddXp(ulong userId, ulong guildId, int amount)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
@@ -863,7 +874,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
|
||||
private TypedKey<bool> GetUserRewKey(ulong userId)
|
||||
=> new($"xp:{_client.CurrentUser.Id}:user_gain:{userId}");
|
||||
|
||||
|
||||
private async Task<bool> SetUserRewardedAsync(ulong userId)
|
||||
=> await _c.AddAsync(GetUserRewKey(userId),
|
||||
true,
|
||||
@@ -982,7 +993,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
}
|
||||
|
||||
var outlinePen = new Pen(Color.Black, 1f);
|
||||
|
||||
|
||||
using var img = Image.Load<Rgba32>(bgBytes, out var imageFormat);
|
||||
if (template.User.Name.Show)
|
||||
{
|
||||
@@ -1253,7 +1264,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
{
|
||||
return await _images.GetXpBackgroundImageAsync();
|
||||
}
|
||||
|
||||
|
||||
var url = _xpConfig.Data.Shop.GetItemUrl(XpShopItemType.Background, item.ItemKey);
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
@@ -1428,13 +1439,13 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
|
||||
return new(_xpConfig.Data.Shop.Bgs?.Where(x => x.Value.Price >= 0).ToDictionary(x => x.Key, x => x.Value));
|
||||
}
|
||||
|
||||
|
||||
public ValueTask<Dictionary<string, XpConfig.ShopItemInfo>?> GetShopFrames()
|
||||
{
|
||||
var data = _xpConfig.Data;
|
||||
if (!data.Shop.IsEnabled)
|
||||
return new(default(Dictionary<string, XpConfig.ShopItemInfo>));
|
||||
|
||||
|
||||
return new(_xpConfig.Data.Shop.Frames?.Where(x => x.Value.Price >= 0).ToDictionary(x => x.Key, x => x.Value));
|
||||
}
|
||||
|
||||
@@ -1448,7 +1459,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
var req = type == XpShopItemType.Background
|
||||
? conf.Shop.BgsTierRequirement
|
||||
: conf.Shop.FramesTierRequirement;
|
||||
|
||||
|
||||
if (req != PatronTier.None && !_creds.IsOwner(userId))
|
||||
{
|
||||
var patron = await _ps.GetPatronAsync(userId);
|
||||
@@ -1456,12 +1467,13 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
if ((int)patron.Tier < (int)req)
|
||||
return BuyResult.InsufficientPatronTier;
|
||||
}
|
||||
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
// await using var tran = await ctx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
if (await ctx.GetTable<XpShopOwnedItem>().AnyAsyncLinqToDB(x => x.UserId == userId && x.ItemKey == key && x.ItemType == type))
|
||||
if (await ctx.GetTable<XpShopOwnedItem>()
|
||||
.AnyAsyncLinqToDB(x => x.UserId == userId && x.ItemKey == key && x.ItemType == type))
|
||||
return BuyResult.AlreadyOwned;
|
||||
|
||||
var item = GetShopItem(type, key);
|
||||
@@ -1471,17 +1483,17 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
|
||||
if (item.Price > 0 && !await _cs.RemoveAsync(userId, item.Price, new("xpshop", "buy", $"Background {key}")))
|
||||
return BuyResult.InsufficientFunds;
|
||||
|
||||
|
||||
|
||||
await ctx.GetTable<XpShopOwnedItem>()
|
||||
.InsertAsync(() => new XpShopOwnedItem()
|
||||
{
|
||||
UserId = userId,
|
||||
IsUsing = false,
|
||||
ItemKey = key,
|
||||
ItemType = type,
|
||||
DateAdded = DateTime.UtcNow,
|
||||
});
|
||||
.InsertAsync(() => new XpShopOwnedItem()
|
||||
{
|
||||
UserId = userId,
|
||||
IsUsing = false,
|
||||
ItemKey = key,
|
||||
ItemType = type,
|
||||
DateAdded = DateTime.UtcNow,
|
||||
});
|
||||
|
||||
return BuyResult.Success;
|
||||
}
|
||||
@@ -1497,54 +1509,57 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
var data = _xpConfig.Data;
|
||||
if (type == XpShopItemType.Background)
|
||||
{
|
||||
if (data.Shop.Bgs is {} bgs && bgs.TryGetValue(key, out var item))
|
||||
if (data.Shop.Bgs is { } bgs && bgs.TryGetValue(key, out var item))
|
||||
return item;
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type == XpShopItemType.Frame)
|
||||
{
|
||||
if (data.Shop.Frames is {} fs && fs.TryGetValue(key, out var item))
|
||||
if (data.Shop.Frames is { } fs && fs.TryGetValue(key, out var item))
|
||||
return item;
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(type));
|
||||
}
|
||||
|
||||
public async Task<bool> OwnsItemAsync(ulong userId,
|
||||
public async Task<bool> OwnsItemAsync(
|
||||
ulong userId,
|
||||
XpShopItemType itemType,
|
||||
string key)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<XpShopOwnedItem>()
|
||||
.AnyAsyncLinqToDB(x => x.UserId == userId
|
||||
&& x.ItemType == itemType
|
||||
&& x.ItemKey == key);
|
||||
.AnyAsyncLinqToDB(x => x.UserId == userId
|
||||
&& x.ItemType == itemType
|
||||
&& x.ItemKey == key);
|
||||
}
|
||||
|
||||
|
||||
public async Task<XpShopOwnedItem?> GetUserItemAsync(ulong userId,
|
||||
|
||||
|
||||
public async Task<XpShopOwnedItem?> GetUserItemAsync(
|
||||
ulong userId,
|
||||
XpShopItemType itemType,
|
||||
string key)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<XpShopOwnedItem>()
|
||||
.FirstOrDefaultAsyncLinqToDB(x => x.UserId == userId
|
||||
&& x.ItemType == itemType
|
||||
&& x.ItemKey == key);
|
||||
.FirstOrDefaultAsyncLinqToDB(x => x.UserId == userId
|
||||
&& x.ItemType == itemType
|
||||
&& x.ItemKey == key);
|
||||
}
|
||||
|
||||
public async Task<XpShopOwnedItem?> GetItemInUse(ulong userId,
|
||||
|
||||
public async Task<XpShopOwnedItem?> GetItemInUse(
|
||||
ulong userId,
|
||||
XpShopItemType itemType)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<XpShopOwnedItem>()
|
||||
.FirstOrDefaultAsyncLinqToDB(x => x.UserId == userId
|
||||
&& x.ItemType == itemType
|
||||
&& x.IsUsing);
|
||||
.FirstOrDefaultAsyncLinqToDB(x => x.UserId == userId
|
||||
&& x.ItemType == itemType
|
||||
&& x.IsUsing);
|
||||
}
|
||||
|
||||
public async Task<bool> UseShopItemAsync(ulong userId, XpShopItemType itemType, string key)
|
||||
@@ -1568,11 +1583,11 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
if (await OwnsItemAsync(userId, itemType, key))
|
||||
{
|
||||
await ctx.GetTable<XpShopOwnedItem>()
|
||||
.Where(x => x.UserId == userId && x.ItemType == itemType)
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
IsUsing = key == old.ItemKey
|
||||
});
|
||||
.Where(x => x.UserId == userId && x.ItemType == itemType)
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
IsUsing = key == old.ItemKey
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user