Compare commits

...

2 Commits
5.0.3 ... 5.0.4

Author SHA1 Message Date
Kwoth
fb594e50fd fix: .h fixed, .xp fixed, pagination in .lb fixed 2024-05-10 15:29:04 +00:00
Kwoth
75c5a003bf fix: cleverbot:response should now be a valid module name 2024-05-10 09:53:20 +00:00
14 changed files with 179 additions and 150 deletions

View File

@@ -175,7 +175,7 @@ public sealed class SomethingOnlyChannelService : IExecOnMessage
// ignore owner and admin
if (user.Id == tch.Guild.OwnerId || user.GuildPermissions.Administrator)
{
Log.Information("{Type}-Only Channel: Ignoring owner od admin ({ChannelId})", type, msg.Channel.Id);
Log.Information("{Type}-Only Channel: Ignoring owner or admin ({ChannelId})", type, msg.Channel.Id);
return false;
}

View File

@@ -776,7 +776,7 @@ public partial class Gambling : GamblingModule<GamblingService>
await using var uow = _db.GetDbContext();
var cleanRichest = await uow.Set<DiscordUser>()
.GetTopRichest(_client.CurrentUser.Id, 0, 10_000);
.GetTopRichest(_client.CurrentUser.Id, 0, 1000);
var sg = (SocketGuild)ctx.Guild!;
return cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList();
@@ -787,10 +787,14 @@ public partial class Gambling : GamblingModule<GamblingService>
return await uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, curPage);
}
}
var res = Response()
.Paginated();
await Response()
.Paginated()
.PageItems(GetTopRichest)
.TotalElements(900)
.PageSize(9)
.CurrentPage(page)
.Page((toSend, curPage) =>

View File

@@ -67,7 +67,7 @@ public class ChatterBotService : IExecOnMessage
if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey))
return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory);
Log.Information("Cleverbot will not work as the api key is missing.");
Log.Information("Cleverbot will not work as the api key is missing");
return null;
case ChatBotImplementation.Gpt3:
if (!string.IsNullOrWhiteSpace(_creds.Gpt3ApiKey))
@@ -80,7 +80,7 @@ public class ChatterBotService : IExecOnMessage
_client.CurrentUser.Username,
_httpFactory);
Log.Information("Gpt3 will not work as the api key is missing.");
Log.Information("Gpt3 will not work as the api key is missing");
return null;
default:
return null;
@@ -128,7 +128,7 @@ public class ChatterBotService : IExecOnMessage
var res = await _perms.CheckPermsAsync(sg,
usrMsg.Channel,
usrMsg.Author,
"games",
CleverBotResponseStr.CLEVERBOT_RESPONSE,
CleverBotResponseStr.CLEVERBOT_RESPONSE);
if (!res.IsAllowed)

View File

@@ -10,7 +10,7 @@ using JsonSerializer = System.Text.Json.JsonSerializer;
namespace NadekoBot.Modules.Help;
public sealed class Help : NadekoModule<HelpService>
public sealed partial class Help : NadekoModule<HelpService>
{
public const string PATREON_URL = "https://patreon.com/nadekobot";
public const string PAYPAL_URL = "https://paypal.me/Kwoth";
@@ -72,7 +72,7 @@ public sealed class Help : NadekoModule<HelpService>
return;
var topLevelModules = new List<ModuleInfo>();
foreach (var m in _cmds.Modules.GroupBy(x => x.GetTopLevelModule()).Select(x => x.Key))
foreach (var m in _cmds.Modules.GroupBy(x => x.GetTopLevelModule()).OrderBy(x => x.Key.Name).Select(x => x.Key))
{
var result = await _perms.CheckPermsAsync(ctx.Guild,
ctx.Channel,
@@ -80,6 +80,11 @@ public sealed class Help : NadekoModule<HelpService>
m.Name,
null);
#if GLOBAL_NADEKO
if (m.Preconditions.Any(x => x is NoPublicBotAttribute))
continue;
#endif
if (result.IsAllowed)
topLevelModules.Add(m);
}
@@ -87,6 +92,7 @@ public sealed class Help : NadekoModule<HelpService>
await Response()
.Paginated()
.Items(topLevelModules)
.PageSize(12)
.CurrentPage(page)
.AddFooter(false)
.Page((items, _) =>
@@ -99,13 +105,13 @@ public sealed class Help : NadekoModule<HelpService>
return embed;
}
items.OrderBy(module => module.Name)
.ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
GetModuleDescription(module.Name)
+ "\n"
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
true));
items
.ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
GetModuleDescription(module.Name)
+ "\n"
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
true));
return embed;
})
@@ -310,7 +316,7 @@ public sealed class Help : NadekoModule<HelpService>
{
string cmdName;
if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix +cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else
cmdName = Format.Code(prefix + cmd.Aliases.First());
@@ -354,17 +360,16 @@ public sealed class Help : NadekoModule<HelpService>
public async Task H([Leftover] CommandInfo com = null)
{
var channel = ctx.Channel;
if (com is null)
{
var ch = channel is ITextChannel ? await ctx.User.CreateDMChannelAsync() : channel;
try
{
var ch = channel is ITextChannel ? await ctx.User.CreateDMChannelAsync() : channel;
var data = await GetHelpString();
if (data == default)
return;
await Response().Text(data).SendAsync();
await Response().Channel(ch).Text(data).SendAsync();
try
{
await ctx.OkAsync();

View File

@@ -3,6 +3,7 @@
namespace NadekoBot.Modules;
[OwnerOnly]
[NoPublicBot]
public partial class Medusa : NadekoModule<IMedusaLoaderService>
{
private readonly IMedusaeRepositoryService _repo;

View File

@@ -1,149 +1,156 @@
namespace NadekoBot.Modules.Patronage;
using NadekoBot.Modules.Patronage;
[OnlyPublicBot]
public partial class Patronage : NadekoModule
namespace NadekoBot.Modules.Help;
public partial class Help
{
private readonly PatronageService _service;
private readonly PatronageConfig _pConf;
public Patronage(PatronageService service, PatronageConfig pConf)
[OnlyPublicBot]
public partial class Patronage : NadekoModule
{
_service = service;
_pConf = pConf;
}
private readonly PatronageService _service;
private readonly PatronageConfig _pConf;
[Cmd]
[Priority(2)]
public Task Patron()
=> InternalPatron(ctx.User);
[Cmd]
[Priority(0)]
[OwnerOnly]
public Task Patron(IUser user)
=> InternalPatron(user);
[Cmd]
[Priority(0)]
[OwnerOnly]
public async Task PatronMessage(PatronTier tierAndHigher, string message)
{
_ = ctx.Channel.TriggerTypingAsync();
var result = await _service.SendMessageToPatronsAsync(tierAndHigher, message);
await Response()
.Confirm(strs.patron_msg_sent(
Format.Code(tierAndHigher.ToString()),
Format.Bold(result.Success.ToString()),
Format.Bold(result.Failed.ToString())))
.SendAsync();
}
// [OwnerOnly]
// public async Task PatronGift(IUser user, int amount)
// {
// // i can't figure out a good way to gift more than one month at the moment.
//
// if (amount < 1)
// return;
//
// var patron = _service.GiftPatronAsync(user, amount);
//
// var eb = _sender.CreateEmbed();
//
// await Response().Embed(eb.WithDescription($"Added **{days}** days of Patron benefits to {user.Mention}!")
// .AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
// .AddField("Amount", $"**{patron.Amount / 100.0f:N1}$**", true)
// .AddField("Until", TimestampTag.FromDateTime(patron.ValidThru.AddDays(1)))).SendAsync();
//
//
// }
private async Task InternalPatron(IUser user)
{
if (!_pConf.Data.IsEnabled)
public Patronage(PatronageService service, PatronageConfig pConf)
{
await Response().Error(strs.patron_not_enabled).SendAsync();
return;
_service = service;
_pConf = pConf;
}
var patron = await _service.GetPatronAsync(user.Id);
var quotaStats = await _service.GetUserQuotaStatistic(user.Id);
[Cmd]
[Priority(2)]
public Task Patron()
=> InternalPatron(ctx.User);
var eb = _sender.CreateEmbed()
.WithAuthor(user)
.WithTitle(GetText(strs.patron_info))
.WithOkColor();
[Cmd]
[Priority(0)]
[OwnerOnly]
public Task Patron(IUser user)
=> InternalPatron(user);
if (quotaStats.Commands.Count == 0
&& quotaStats.Groups.Count == 0
&& quotaStats.Modules.Count == 0)
[Cmd]
[Priority(0)]
[OwnerOnly]
public async Task PatronMessage(PatronTier tierAndHigher, string message)
{
eb.WithDescription(GetText(strs.no_quota_found));
_ = ctx.Channel.TriggerTypingAsync();
var result = await _service.SendMessageToPatronsAsync(tierAndHigher, message);
await Response()
.Confirm(strs.patron_msg_sent(
Format.Code(tierAndHigher.ToString()),
Format.Bold(result.Success.ToString()),
Format.Bold(result.Failed.ToString())))
.SendAsync();
}
else
// [OwnerOnly]
// public async Task PatronGift(IUser user, int amount)
// {
// // i can't figure out a good way to gift more than one month at the moment.
//
// if (amount < 1)
// return;
//
// var patron = _service.GiftPatronAsync(user, amount);
//
// var eb = _sender.CreateEmbed();
//
// await Response().Embed(eb.WithDescription($"Added **{days}** days of Patron benefits to {user.Mention}!")
// .AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
// .AddField("Amount", $"**{patron.Amount / 100.0f:N1}$**", true)
// .AddField("Until", TimestampTag.FromDateTime(patron.ValidThru.AddDays(1)))).SendAsync();
//
//
// }
private async Task InternalPatron(IUser user)
{
eb.AddField(GetText(strs.tier), Format.Bold(patron.Tier.ToFullName()), true)
.AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true);
if (patron.Tier != PatronTier.None)
eb.AddField(GetText(strs.expires), patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(), true);
eb.AddField(GetText(strs.quotas), "", false);
if (quotaStats.Commands.Count > 0)
if (!_pConf.Data.IsEnabled)
{
var text = GetQuotaList(quotaStats.Commands);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.commands), text, true);
await Response().Error(strs.patron_not_enabled).SendAsync();
return;
}
if (quotaStats.Groups.Count > 0)
var patron = await _service.GetPatronAsync(user.Id);
var quotaStats = await _service.GetUserQuotaStatistic(user.Id);
var eb = _sender.CreateEmbed()
.WithAuthor(user)
.WithTitle(GetText(strs.patron_info))
.WithOkColor();
if (quotaStats.Commands.Count == 0
&& quotaStats.Groups.Count == 0
&& quotaStats.Modules.Count == 0)
{
var text = GetQuotaList(quotaStats.Groups);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.groups), text, true);
eb.WithDescription(GetText(strs.no_quota_found));
}
else
{
eb.AddField(GetText(strs.tier), Format.Bold(patron.Tier.ToFullName()), true)
.AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true);
if (patron.Tier != PatronTier.None)
eb.AddField(GetText(strs.expires),
patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(),
true);
eb.AddField(GetText(strs.quotas), "", false);
if (quotaStats.Commands.Count > 0)
{
var text = GetQuotaList(quotaStats.Commands);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.commands), text, true);
}
if (quotaStats.Groups.Count > 0)
{
var text = GetQuotaList(quotaStats.Groups);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.groups), text, true);
}
if (quotaStats.Modules.Count > 0)
{
var text = GetQuotaList(quotaStats.Modules);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.modules), text, true);
}
}
if (quotaStats.Modules.Count > 0)
try
{
var text = GetQuotaList(quotaStats.Modules);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.modules), text, true);
await Response().User(ctx.User).Embed(eb).SendAsync();
_ = ctx.OkAsync();
}
catch
{
await Response().Error(strs.cant_dm).SendAsync();
}
}
private string GetQuotaList(IReadOnlyDictionary<string, FeatureQuotaStats> featureQuotaStats)
{
var text = string.Empty;
foreach (var (key, q) in featureQuotaStats)
{
text += $"\n\t`{key}`\n";
if (q.Hourly != default)
text += $" {GetEmoji(q.Hourly)} {q.Hourly.Cur}/{q.Hourly.Max} per hour\n";
if (q.Daily != default)
text += $" {GetEmoji(q.Daily)} {q.Daily.Cur}/{q.Daily.Max} per day\n";
if (q.Monthly != default)
text += $" {GetEmoji(q.Monthly)} {q.Monthly.Cur}/{q.Monthly.Max} per month\n";
}
try
{
await Response().User(ctx.User).Embed(eb).SendAsync();
_ = ctx.OkAsync();
}
catch
{
await Response().Error(strs.cant_dm).SendAsync();
return text;
}
private string GetEmoji((uint Cur, uint Max) limit)
=> limit.Cur < limit.Max
? "✅"
: "⚠️";
}
private string GetQuotaList(IReadOnlyDictionary<string, FeatureQuotaStats> featureQuotaStats)
{
var text = string.Empty;
foreach (var (key, q) in featureQuotaStats)
{
text += $"\n\t`{key}`\n";
if (q.Hourly != default)
text += $" {GetEmoji(q.Hourly)} {q.Hourly.Cur}/{q.Hourly.Max} per hour\n";
if (q.Daily != default)
text += $" {GetEmoji(q.Daily)} {q.Daily.Cur}/{q.Daily.Max} per day\n";
if (q.Monthly != default)
text += $" {GetEmoji(q.Monthly)} {q.Monthly.Cur}/{q.Monthly.Max} per month\n";
}
return text;
}
private string GetEmoji((uint Cur, uint Max) limit)
=> limit.Cur < limit.Max
? "✅"
: "⚠️";
}

View File

@@ -1194,7 +1194,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
}
//avatar
if (stats.User.AvatarId is not null && template.User.Icon.Show)
if (template.User.Icon.Show)
{
try
{

View File

@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<Version>5.0.3</Version>
<Version>5.0.4</Version>
<!-- Output/build -->
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>

View File

@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
namespace NadekoBot.Common;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
[SuppressMessage("Style", "IDE0022:Use expression body for methods")]
public sealed class NoPublicBotAttribute : PreconditionAttribute
{
public override Task<PreconditionResult> CheckPermissionsAsync(

View File

@@ -25,7 +25,7 @@ public partial class ResponseBuilder
public async Task SendAsync(bool ephemeral = false)
{
var lastPage = (_paginationBuilder.TotalElements - 1)
var lastPage = (_paginationBuilder.Elems - 1)
/ _paginationBuilder.ItemsPerPage;
var items = (await _paginationBuilder.ItemsFunc(currentPage)).ToArray();

View File

@@ -396,7 +396,7 @@ public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilde
public Func<int, Task<SimpleInteractionBase>>? InteractionFunc { get; private set; }
public int TotalElements { get; private set; } = 1;
public int Elems { get; private set; } = 1;
public int ItemsPerPage { get; private set; } = 9;
public bool AddPaginatedFooter { get; private set; } = true;
public bool IsEphemeral { get; private set; }
@@ -411,10 +411,16 @@ public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilde
public SourcedPaginatedResponseBuilder<T> Items(IReadOnlyCollection<T> col)
{
items = col;
TotalElements = col.Count;
Elems = col.Count;
ItemsFunc = (i) => Task.FromResult(items.Skip(i * ItemsPerPage).Take(ItemsPerPage));
return this;
}
public SourcedPaginatedResponseBuilder<T> TotalElements(int i)
{
Elems = i;
return this;
}
public SourcedPaginatedResponseBuilder<T> PageItems(Func<int, Task<IEnumerable<T>>> func)
{

View File

@@ -113,7 +113,7 @@ public static class ServiceCollectionExtensions
typeof(IInputTransformer),
typeof(INService)
];
foreach (var svc in a.GetTypes()
.Where(type => type.IsClass && types.Any(t => type.IsAssignableTo(t)) && !type.HasAttribute<DIIgnoreAttribute>()
#if GLOBAL_NADEKO

View File

@@ -1,4 +1,6 @@
#nullable disable
using NadekoBot.Modules.Permissions;
namespace NadekoBot.Common.TypeReaders;
public sealed class ModuleTypeReader : NadekoTypeReader<ModuleInfo>
@@ -34,7 +36,7 @@ public sealed class ModuleOrExprTypeReader : NadekoTypeReader<ModuleOrExpr>
var module = _cmds.Modules.GroupBy(m => m.GetTopLevelModule())
.FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input)
?.Key;
if (module is null && input != "ACTUALEXPRESSIONS")
if (module is null && input != "ACTUALEXPRESSIONS" && input != CleverBotResponseStr.CLEVERBOT_RESPONSE)
return new(TypeReaderResult.FromError<ModuleOrExpr>(CommandError.ParseFailed, "No such module found."));
return new(TypeReaderResult.FromSuccess(new ModuleOrExpr

View File

@@ -10,7 +10,12 @@ public static class UserExtensions
// This method is only used for the xp card
public static Uri? RealAvatarUrl(this DiscordUser usr)
=> Uri.TryCreate(CDN.GetDefaultUserAvatarUrl(usr.UserId), UriKind.Absolute, out var uri)
{
if (!string.IsNullOrWhiteSpace(usr.AvatarId))
return new Uri(CDN.GetUserAvatarUrl(usr.UserId, usr.AvatarId, 128, ImageFormat.Png));
return Uri.TryCreate(CDN.GetDefaultUserAvatarUrl(usr.UserId), UriKind.Absolute, out var uri)
? uri
: null;
}
}