Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
8176cdbf96 | |||
113dc3748a | |||
5c72c6562f | |||
dd939ce55a | |||
1a52085340 | |||
487c7865cb | |||
3ba1d06fd0 |
44 changed files with 263 additions and 213 deletions
28
CHANGELOG.md
28
CHANGELOG.md
|
@ -2,6 +2,34 @@
|
|||
|
||||
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o
|
||||
|
||||
## [5.1.14] - 03.10.2024
|
||||
|
||||
## Changed
|
||||
|
||||
- Improved `.xplb -c`, it will now correctly only show users who are still in the server with no count limit
|
||||
|
||||
## Fixed
|
||||
|
||||
- Fixed marmalade load error on startup
|
||||
|
||||
## [5.1.13] - 03.10.2024
|
||||
|
||||
### Fixed
|
||||
|
||||
- Grpc api server will no longer start unless enabled in creds
|
||||
- Seq comment in creds fixed
|
||||
|
||||
## [5.1.12] - 03.10.2024
|
||||
|
||||
### Added
|
||||
|
||||
- Added support for `seq` for logging. If you fill in seq url and apiKey in creds.yml, bot will sends logs to it
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed the Check for updates service not using the right URL and spitting an error in the console.
|
||||
- Fixed another bug in `.greet` / `.bye` system, which caused it to show wrong message on a wrong server occasionally
|
||||
|
||||
## [5.1.11] - 03.10.2024
|
||||
|
||||
### Added
|
||||
|
|
|
@ -25,7 +25,7 @@ public sealed class Bot : IBot
|
|||
public bool IsReady { get; private set; }
|
||||
public int ShardId { get; set; }
|
||||
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly CommandService _commandService;
|
||||
private readonly DbService _db;
|
||||
|
||||
|
@ -42,6 +42,9 @@ public sealed class Bot : IBot
|
|||
_credsProvider = new BotCredsProvider(totalShards, credPath);
|
||||
_creds = _credsProvider.GetCreds();
|
||||
|
||||
LogSetup.SetupLogger(shardId, _creds);
|
||||
Log.Information("Pid: {ProcessId}", Environment.ProcessId);
|
||||
|
||||
_db = new EllieDbService(_credsProvider);
|
||||
|
||||
var messageCacheSize =
|
||||
|
@ -115,7 +118,7 @@ public sealed class Bot : IBot
|
|||
// svcs.Components.Remove<IPlanner, Planner>();
|
||||
// svcs.Components.Add<IPlanner, RemovablePlanner>();
|
||||
|
||||
svcs.AddSingleton<IBotCredentials>(_ => _credsProvider.GetCreds());
|
||||
svcs.AddSingleton<IBotCreds>(_ => _credsProvider.GetCreds());
|
||||
svcs.AddSingleton<DbService, DbService>(_db);
|
||||
svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
|
||||
svcs.AddSingleton<DiscordSocketClient>(Client);
|
||||
|
|
|
@ -26,17 +26,6 @@ public static class UserXpExtensions
|
|||
return usr;
|
||||
}
|
||||
|
||||
public static async Task<IReadOnlyCollection<UserXpStats>> GetUsersFor(
|
||||
this DbSet<UserXpStats> xps,
|
||||
ulong guildId,
|
||||
int page)
|
||||
=> await xps.ToLinqToDBTable()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderByDescending(x => x.Xp + x.AwardedXp)
|
||||
.Skip(page * 9)
|
||||
.Take(9)
|
||||
.ToArrayAsyncLinqToDB();
|
||||
|
||||
public static async Task<List<UserXpStats>> GetTopUserXps(this DbSet<UserXpStats> xps, ulong guildId, int count)
|
||||
=> await xps.ToLinqToDBTable()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
<Version>5.1.11</Version>
|
||||
<Version>5.1.14</Version>
|
||||
|
||||
<!-- Output/build -->
|
||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||
|
|
|
@ -208,11 +208,11 @@ public class GreetService : IEService, IReadyExecutor
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private TypedKey<GreetSettings?> GreetSettingsKey(GreetType type)
|
||||
=> new($"greet_settings:{type}");
|
||||
private TypedKey<GreetSettings?> GreetSettingsKey(ulong gid, GreetType type)
|
||||
=> new($"greet_settings:{gid}:{type}");
|
||||
|
||||
public async Task<GreetSettings?> GetGreetSettingsAsync(ulong gid, GreetType type)
|
||||
=> await _cache.GetOrAddAsync<GreetSettings?>(GreetSettingsKey(type),
|
||||
=> await _cache.GetOrAddAsync<GreetSettings?>(GreetSettingsKey(gid, type),
|
||||
() => InternalGetGreetSettingsAsync(gid, type),
|
||||
TimeSpan.FromSeconds(3));
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
|
|||
{
|
||||
private readonly DbService _db;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
|
||||
private ConcurrentDictionary<ulong, List<ReactionRoleV2>> _cache;
|
||||
private readonly object _cacheLock = new();
|
||||
|
@ -24,7 +24,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
|
|||
DiscordSocketClient client,
|
||||
IPatronageService ps,
|
||||
DbService db,
|
||||
IBotCredentials creds)
|
||||
IBotCreds creds)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
|
|
|
@ -9,13 +9,13 @@ namespace EllieBot.Modules.Administration;
|
|||
public sealed class StickyRolesService : IEService, IReadyExecutor
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DbService _db;
|
||||
private HashSet<ulong> _stickyRoles = new();
|
||||
|
||||
public StickyRolesService(
|
||||
DiscordSocketClient client,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
DbService db)
|
||||
{
|
||||
_client = client;
|
||||
|
|
|
@ -19,7 +19,7 @@ public sealed class CheckForUpdatesService : IEService, IReadyExecutor
|
|||
private readonly IMessageSenderService _sender;
|
||||
|
||||
|
||||
private const string RELEASES_URL = "https://toastielab.dev/Emotions-stuff/elliebot/releases";
|
||||
private const string RELEASES_URL = "https://toastielab.dev/api/v1/repos/Emotions-stuff/elliebot/releases";
|
||||
|
||||
public CheckForUpdatesService(
|
||||
BotConfigService bcs,
|
||||
|
|
|
@ -15,7 +15,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
|||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
|
||||
private ImmutableDictionary<ulong, IDMChannel> ownerChannels =
|
||||
new Dictionary<ulong, IDMChannel>().ToImmutableDictionary();
|
||||
|
@ -36,7 +36,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
|||
CommandHandler cmdHandler,
|
||||
DbService db,
|
||||
IBotStrings strings,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
IHttpClientFactory factory,
|
||||
BotConfigService bss,
|
||||
IPubSub pubSub,
|
||||
|
|
|
@ -6,49 +6,6 @@ namespace EllieBot.Modules.EllieExpressions;
|
|||
|
||||
public static class EllieExpressionExtensions
|
||||
{
|
||||
private static string ResolveTriggerString(this string str, DiscordSocketClient client)
|
||||
=> str.Replace("%bot.mention%", client.CurrentUser.Mention, StringComparison.Ordinal);
|
||||
|
||||
public static async Task<IUserMessage> Send(
|
||||
this EllieExpression cr,
|
||||
IUserMessage ctx,
|
||||
IReplacementService repSvc,
|
||||
DiscordSocketClient client,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
var channel = cr.DmResponse ? await ctx.Author.CreateDMChannelAsync() : ctx.Channel;
|
||||
|
||||
var trigger = cr.Trigger.ResolveTriggerString(client);
|
||||
var substringIndex = trigger.Length;
|
||||
if (cr.ContainsAnywhere)
|
||||
{
|
||||
var pos = ctx.Content.AsSpan().GetWordPosition(trigger);
|
||||
if (pos == WordPosition.Start)
|
||||
substringIndex += 1;
|
||||
else if (pos == WordPosition.End)
|
||||
substringIndex = ctx.Content.Length;
|
||||
else if (pos == WordPosition.Middle)
|
||||
substringIndex += ctx.Content.IndexOf(trigger, StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
var canMentionEveryone = (ctx.Author as IGuildUser)?.GuildPermissions.MentionEveryone ?? true;
|
||||
|
||||
var repCtx = new ReplacementContext(client: client,
|
||||
guild: (ctx.Channel as ITextChannel)?.Guild as SocketGuild,
|
||||
channel: ctx.Channel,
|
||||
user: ctx.Author
|
||||
)
|
||||
.WithOverride("%target%",
|
||||
() => canMentionEveryone
|
||||
? ctx.Content[substringIndex..].Trim()
|
||||
: ctx.Content[substringIndex..].Trim().SanitizeMentions(true));
|
||||
|
||||
var text = SmartText.CreateFrom(cr.Response);
|
||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||
|
||||
return await sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static WordPosition GetWordPosition(this ReadOnlySpan<char> str, in ReadOnlySpan<char> word)
|
||||
{
|
||||
|
|
|
@ -11,10 +11,10 @@ public partial class EllieExpressions : EllieModule<EllieExpressionsService>
|
|||
All
|
||||
}
|
||||
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
|
||||
public EllieExpressions(IBotCredentials creds, IHttpClientFactory clientFactory)
|
||||
public EllieExpressions(IBotCreds creds, IHttpClientFactory clientFactory)
|
||||
{
|
||||
_creds = creds;
|
||||
_clientFactory = clientFactory;
|
||||
|
|
|
@ -249,8 +249,9 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
|
||||
try
|
||||
{
|
||||
if (guild is SocketGuild sg)
|
||||
{
|
||||
if (guild is not SocketGuild sg)
|
||||
return false;
|
||||
|
||||
var result = await _permChecker.CheckPermsAsync(
|
||||
guild,
|
||||
msg.Channel,
|
||||
|
@ -286,9 +287,16 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var sentMsg = await expr.Send(msg, _repSvc, _client, _sender);
|
||||
var cu = sg.CurrentUser;
|
||||
|
||||
var channel = expr.DmResponse ? await msg.Author.CreateDMChannelAsync() : msg.Channel;
|
||||
|
||||
// have no perms to speak in that channel
|
||||
if (channel is ITextChannel tc && !cu.GetPermissions(tc).SendMessages)
|
||||
return false;
|
||||
|
||||
var sentMsg = await Send(expr, msg, channel);
|
||||
|
||||
var reactions = expr.GetReactions();
|
||||
foreach (var reaction in reactions)
|
||||
|
@ -336,6 +344,47 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
public string ResolveTriggerString(string str)
|
||||
=> str.Replace("%bot.mention%", _client.CurrentUser.Mention, StringComparison.Ordinal);
|
||||
|
||||
public async Task<IUserMessage> Send(
|
||||
EllieExpression cr,
|
||||
IUserMessage ctx,
|
||||
IMessageChannel channel
|
||||
)
|
||||
{
|
||||
var trigger = ResolveTriggerString(cr.Trigger);
|
||||
var substringIndex = trigger.Length;
|
||||
if (cr.ContainsAnywhere)
|
||||
{
|
||||
var pos = ctx.Content.AsSpan().GetWordPosition(trigger);
|
||||
if (pos == WordPosition.Start)
|
||||
substringIndex += 1;
|
||||
else if (pos == WordPosition.End)
|
||||
substringIndex = ctx.Content.Length;
|
||||
else if (pos == WordPosition.Middle)
|
||||
substringIndex += ctx.Content.IndexOf(trigger, StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
var canMentionEveryone = (ctx.Author as IGuildUser)?.GuildPermissions.MentionEveryone ?? true;
|
||||
|
||||
var repCtx = new ReplacementContext(client: _client,
|
||||
guild: (ctx.Channel as ITextChannel)?.Guild as SocketGuild,
|
||||
channel: ctx.Channel,
|
||||
user: ctx.Author
|
||||
)
|
||||
.WithOverride("%target%",
|
||||
() => canMentionEveryone
|
||||
? ctx.Content[substringIndex..].Trim()
|
||||
: ctx.Content[substringIndex..].Trim().SanitizeMentions(true));
|
||||
|
||||
var text = SmartText.CreateFrom(cr.Response);
|
||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||
|
||||
return await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
||||
}
|
||||
|
||||
public async Task ResetExprReactions(ulong? maybeGuildId, int id)
|
||||
{
|
||||
EllieExpression expr;
|
||||
|
|
|
@ -14,13 +14,13 @@ public class VoteModel
|
|||
public class VoteRewardService : IEService, IReadyExecutor
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly ICurrencyService _currencyService;
|
||||
private readonly GamblingConfigService _gamb;
|
||||
|
||||
public VoteRewardService(
|
||||
DiscordSocketClient client,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
ICurrencyService currencyService,
|
||||
GamblingConfigService gamb)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ public class WaifuService : IEService, IReadyExecutor
|
|||
private readonly ICurrencyService _cs;
|
||||
private readonly IBotCache _cache;
|
||||
private readonly GamblingConfigService _gss;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public WaifuService(
|
||||
|
@ -23,7 +23,7 @@ public class WaifuService : IEService, IReadyExecutor
|
|||
ICurrencyService cs,
|
||||
IBotCache cache,
|
||||
GamblingConfigService gss,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
DiscordSocketClient client)
|
||||
{
|
||||
_db = db;
|
||||
|
|
|
@ -19,7 +19,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IPermissionChecker _perms;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly GamesConfigService _gcs;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
@ -32,7 +32,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
IBot bot,
|
||||
IPatronageService ps,
|
||||
IHttpClientFactory factory,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
GamesConfigService gcs,
|
||||
IMessageSenderService sender,
|
||||
DbService db)
|
||||
|
|
|
@ -12,9 +12,9 @@ public sealed partial class Music
|
|||
{
|
||||
private static readonly SemaphoreSlim _playlistLock = new(1, 1);
|
||||
private readonly DbService _db;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
|
||||
public PlaylistCommands(DbService db, IBotCredentials creds)
|
||||
public PlaylistCommands(DbService db, IBotCreds creds)
|
||||
{
|
||||
_db = db;
|
||||
_creds = creds;
|
||||
|
|
|
@ -16,11 +16,11 @@ public class CryptoService : IEService
|
|||
{
|
||||
private readonly IBotCache _cache;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
|
||||
private readonly SemaphoreSlim _getCryptoLock = new(1, 1);
|
||||
|
||||
public CryptoService(IBotCache cache, IHttpClientFactory httpFactory, IBotCredentials creds)
|
||||
public CryptoService(IBotCache cache, IHttpClientFactory httpFactory, IBotCreds creds)
|
||||
{
|
||||
_cache = cache;
|
||||
_httpFactory = httpFactory;
|
||||
|
|
|
@ -9,10 +9,10 @@ public partial class Searches
|
|||
[Group]
|
||||
public partial class OsuCommands : EllieModule<OsuService>
|
||||
{
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
|
||||
public OsuCommands(IBotCredentials creds, IHttpClientFactory factory)
|
||||
public OsuCommands(IBotCreds creds, IHttpClientFactory factory)
|
||||
{
|
||||
_creds = creds;
|
||||
_httpFactory = factory;
|
||||
|
|
|
@ -7,9 +7,9 @@ namespace EllieBot.Modules.Searches;
|
|||
public sealed class OsuService : IEService
|
||||
{
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
|
||||
public OsuService(IHttpClientFactory httpFactory, IBotCredentials creds)
|
||||
public OsuService(IHttpClientFactory httpFactory, IBotCreds creds)
|
||||
{
|
||||
_httpFactory = httpFactory;
|
||||
_creds = creds;
|
||||
|
|
|
@ -13,14 +13,14 @@ namespace EllieBot.Modules.Searches;
|
|||
|
||||
public partial class Searches : EllieModule<SearchesService>
|
||||
{
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly IGoogleApiService _google;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ITimezoneService _tzSvc;
|
||||
|
||||
public Searches(
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
IGoogleApiService google,
|
||||
IHttpClientFactory factory,
|
||||
IMemoryCache cache,
|
||||
|
|
|
@ -11,7 +11,7 @@ public sealed class GiveawayService : IEService, IReadyExecutor
|
|||
public static string GiveawayEmoji = "🎉";
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly IBotStrings _strings;
|
||||
|
@ -20,7 +20,7 @@ public sealed class GiveawayService : IEService, IReadyExecutor
|
|||
private SortedSet<GiveawayModel> _giveawayCache = new SortedSet<GiveawayModel>();
|
||||
private readonly EllieRandom _rng;
|
||||
|
||||
public GiveawayService(DbService db, IBotCredentials creds, DiscordSocketClient client,
|
||||
public GiveawayService(DbService db, IBotCreds creds, DiscordSocketClient client,
|
||||
IMessageSenderService sender, IBotStrings strings, ILocalization localization, IMemoryCache cache)
|
||||
{
|
||||
_db = db;
|
||||
|
|
|
@ -17,14 +17,14 @@ public class RemindService : IEService, IReadyExecutor, IRemindService
|
|||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly DbService _db;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public RemindService(
|
||||
DiscordSocketClient client,
|
||||
DbService db,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_client = client;
|
||||
|
|
|
@ -12,7 +12,7 @@ public sealed class RepeaterService : IReadyExecutor, IEService
|
|||
|
||||
private readonly DbService _db;
|
||||
private readonly IReplacementService _repSvc;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly LinkedList<RunningRepeater> _repeaterQueue;
|
||||
private readonly ConcurrentHashSet<int> _noRedundant;
|
||||
|
@ -25,7 +25,7 @@ public sealed class RepeaterService : IReadyExecutor, IEService
|
|||
DiscordSocketClient client,
|
||||
DbService db,
|
||||
IReplacementService repSvc,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_db = db;
|
||||
|
|
|
@ -34,7 +34,7 @@ public partial class Utility : EllieModule
|
|||
private readonly DiscordSocketClient _client;
|
||||
private readonly ICoordinator _coord;
|
||||
private readonly IStatsService _stats;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DownloadTracker _tracker;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly VerboseErrorsService _veService;
|
||||
|
@ -45,7 +45,7 @@ public partial class Utility : EllieModule
|
|||
DiscordSocketClient client,
|
||||
ICoordinator coord,
|
||||
IStatsService stats,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
DownloadTracker tracker,
|
||||
IHttpClientFactory httpFactory,
|
||||
VerboseErrorsService veService,
|
||||
|
|
|
@ -183,27 +183,26 @@ public partial class Xp : EllieModule<XpService>
|
|||
|
||||
await ctx.Channel.TriggerTypingAsync();
|
||||
|
||||
|
||||
async Task<IReadOnlyCollection<UserXpStats>> GetPageItems(int curPage)
|
||||
{
|
||||
var socketGuild = (SocketGuild)ctx.Guild;
|
||||
var allCleanUsers = new List<UserXpStats>();
|
||||
if (opts.Clean)
|
||||
{
|
||||
await ctx.Channel.TriggerTypingAsync();
|
||||
await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
|
||||
|
||||
allCleanUsers = (await _service.GetTopUserXps(ctx.Guild.Id, 1000))
|
||||
.Where(user => socketGuild.GetUser(user.UserId) is not null)
|
||||
.ToList();
|
||||
return await _service.GetTopUserXps(ctx.Guild.Id,
|
||||
socketGuild.Users.Select(x => x.Id).ToList(),
|
||||
curPage);
|
||||
}
|
||||
|
||||
var res = opts.Clean
|
||||
? Response()
|
||||
.Paginated()
|
||||
.Items(allCleanUsers)
|
||||
: Response()
|
||||
.Paginated()
|
||||
.PageItems((curPage) => _service.GetUserXps(ctx.Guild.Id, curPage));
|
||||
return await _service.GetUserXps(ctx.Guild.Id, curPage);
|
||||
}
|
||||
|
||||
await res
|
||||
await Response()
|
||||
.Paginated()
|
||||
.PageItems(GetPageItems)
|
||||
.PageSize(9)
|
||||
.CurrentPage(page)
|
||||
.Page((users, curPage) =>
|
||||
|
|
|
@ -12,6 +12,7 @@ using SixLabors.ImageSharp.PixelFormats;
|
|||
using SixLabors.ImageSharp.Processing;
|
||||
using System.Threading.Channels;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using LinqToDB.Tools;
|
||||
using EllieBot.Modules.Patronage;
|
||||
using Color = SixLabors.ImageSharp.Color;
|
||||
using Exception = System.Exception;
|
||||
|
@ -25,7 +26,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
private readonly IImageCache _images;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly FontProvider _fonts;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly ICurrencyService _cs;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly XpConfigService _xpConfig;
|
||||
|
@ -55,7 +56,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
IImageCache images,
|
||||
IBotCache c,
|
||||
FontProvider fonts,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
ICurrencyService cs,
|
||||
IHttpClientFactory http,
|
||||
XpConfigService xpConfig,
|
||||
|
@ -566,13 +567,24 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
public async Task<IReadOnlyCollection<UserXpStats>> GetUserXps(ulong guildId, int page)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
return await uow.Set<UserXpStats>().GetUsersFor(guildId, page);
|
||||
return await uow
|
||||
.UserXpStats
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderByDescending(x => x.Xp + x.AwardedXp)
|
||||
.Skip(page * 9)
|
||||
.Take(9)
|
||||
.ToArrayAsyncLinqToDB();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<UserXpStats>> GetTopUserXps(ulong guildId, int count)
|
||||
public async Task<IReadOnlyCollection<UserXpStats>> GetTopUserXps(ulong guildId, List<ulong> users, int curPage)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
return await uow.Set<UserXpStats>().GetTopUserXps(guildId, count);
|
||||
return await uow.Set<UserXpStats>()
|
||||
.Where(x => x.GuildId == guildId && x.UserId.In(users))
|
||||
.OrderByDescending(x => x.Xp + x.AwardedXp)
|
||||
.Skip(curPage * 9)
|
||||
.Take(9)
|
||||
.ToArrayAsyncLinqToDB();
|
||||
}
|
||||
|
||||
public Task<IReadOnlyCollection<DiscordUser>> GetUserXps(int page, int perPage = 9)
|
||||
|
@ -1249,9 +1261,9 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
if (template.Club.Icon.Show)
|
||||
await DrawClubImage(img, stats);
|
||||
|
||||
// #if GLOBAL_ELLIE
|
||||
// #if GLOBAL_ELLIE
|
||||
await DrawFrame(img, stats.User.UserId);
|
||||
// #endif
|
||||
// #endif
|
||||
|
||||
var outputSize = template.OutputSize;
|
||||
if (outputSize.X != img.Width || outputSize.Y != img.Height)
|
||||
|
@ -1309,7 +1321,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
if (frame is not null)
|
||||
img.Mutate(x => x.DrawImage(frame, new Point(0, 0), new GraphicsOptions()));
|
||||
}
|
||||
// #endif
|
||||
// #endif
|
||||
|
||||
private void DrawXpBar(float percent, XpBar info, Image<Rgba32> img)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
var pid = Environment.ProcessId;
|
||||
|
||||
var shardId = 0;
|
||||
var shardId = 0;
|
||||
int? totalShards = null; // 0 to read from creds.yml
|
||||
if (args.Length > 0 && args[0] != "run")
|
||||
{
|
||||
|
@ -22,7 +20,5 @@ if (args.Length > 0 && args[0] != "run")
|
|||
}
|
||||
}
|
||||
|
||||
LogSetup.SetupLogger(shardId);
|
||||
Log.Information("Pid: {ProcessId}", pid);
|
||||
|
||||
await new Bot(shardId, totalShards, Environment.GetEnvironmentVariable("EllieBot__creds")).RunAndBlockAsync();
|
|
@ -31,7 +31,7 @@ public class GrpcApiService : IEService, IReadyExecutor
|
|||
public Task OnReadyAsync()
|
||||
{
|
||||
var creds = _creds.GetCreds();
|
||||
if (creds.GrpcApi is null || creds.GrpcApi.Enabled)
|
||||
if (creds.GrpcApi is null || !creds.GrpcApi.Enabled)
|
||||
return Task.CompletedTask;
|
||||
|
||||
try
|
||||
|
|
|
@ -6,9 +6,9 @@ namespace Ellie.Common;
|
|||
|
||||
public static class LogSetup
|
||||
{
|
||||
public static void SetupLogger(object source)
|
||||
public static void SetupLogger(object source, IBotCreds creds)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration().MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
var config = new LoggerConfiguration().MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
.MinimumLevel.Override("System", LogEventLevel.Information)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
|
||||
.Enrich.FromLogContext()
|
||||
|
@ -16,7 +16,12 @@ public static class LogSetup
|
|||
theme: GetTheme(),
|
||||
outputTemplate:
|
||||
"[{Timestamp:HH:mm:ss} {Level:u3}] | #{LogSource} | {Message:lj}{NewLine}{Exception}")
|
||||
.Enrich.WithProperty("LogSource", source)
|
||||
.Enrich.WithProperty("LogSource", source);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(creds.Seq.Url))
|
||||
config = config.WriteTo.Seq(creds.Seq.Url, apiKey: creds.Seq.ApiKey);
|
||||
|
||||
Log.Logger = config
|
||||
.CreateLogger();
|
||||
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#nullable disable
|
||||
namespace EllieBot;
|
||||
|
||||
public interface IBotCredentials
|
||||
public interface IBotCreds
|
||||
{
|
||||
string Token { get; }
|
||||
string EllieAiToken { get; }
|
||||
|
@ -30,6 +30,7 @@ public interface IBotCredentials
|
|||
GoogleApiConfig Google { get; set; }
|
||||
BotCacheImplemenation BotCache { get; set; }
|
||||
Creds.GrpcApiConfig GrpcApi { get; set; }
|
||||
SeqConfig Seq { get; set; }
|
||||
}
|
||||
|
||||
public interface IVotesSettings
|
|
@ -3,6 +3,6 @@
|
|||
public interface IBotCredsProvider
|
||||
{
|
||||
public void Reload();
|
||||
public IBotCredentials GetCreds();
|
||||
public void ModifyCredsFile(Action<IBotCredentials> func);
|
||||
public IBotCreds GetCreds();
|
||||
public void ModifyCredsFile(Action<IBotCreds> func);
|
||||
}
|
|
@ -28,7 +28,7 @@ public sealed partial class BotConfig : ICloneable<BotConfig>
|
|||
public CultureInfo DefaultLocale { get; set; }
|
||||
|
||||
[Comment("""
|
||||
Style in which executed commands will show up in the console.
|
||||
Style in which executed commands will show up in the logs.
|
||||
Allowed values: Simple, Normal, None
|
||||
""")]
|
||||
public ConsoleOutputType ConsoleOutputType { get; set; }
|
||||
|
|
|
@ -3,10 +3,10 @@ using EllieBot.Common.Yml;
|
|||
|
||||
namespace EllieBot.Common;
|
||||
|
||||
public sealed class Creds : IBotCredentials
|
||||
public sealed class Creds : IBotCreds
|
||||
{
|
||||
[Comment("""DO NOT CHANGE""")]
|
||||
public int Version { get; set; } = 10;
|
||||
public int Version { get; set; } = 12;
|
||||
|
||||
[Comment("""Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/""")]
|
||||
public string Token { get; set; }
|
||||
|
@ -164,6 +164,11 @@ public sealed class Creds : IBotCredentials
|
|||
""")]
|
||||
public GrpcApiConfig GrpcApi { get; set; }
|
||||
|
||||
[Comment("""
|
||||
Url and api key to a seq server. If url is set, bot will try to send logs to it.
|
||||
""")]
|
||||
public SeqConfig Seq { get; set; }
|
||||
|
||||
public Creds()
|
||||
{
|
||||
Token = string.Empty;
|
||||
|
@ -189,7 +194,8 @@ public sealed class Creds : IBotCredentials
|
|||
RestartCommand = new RestartConfig();
|
||||
Google = new GoogleApiConfig();
|
||||
|
||||
GrpcApi = new GrpcApiConfig();
|
||||
GrpcApi = new();
|
||||
Seq = new();
|
||||
}
|
||||
|
||||
public class DbOptions
|
||||
|
@ -294,6 +300,12 @@ public sealed class Creds : IBotCredentials
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class SeqConfig
|
||||
{
|
||||
public string Url { get; init; }
|
||||
public string ApiKey { get; init; }
|
||||
}
|
||||
|
||||
public class GoogleApiConfig : IGoogleApiConfig
|
||||
{
|
||||
public string SearchId { get; init; }
|
||||
|
|
|
@ -119,7 +119,7 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
|||
}
|
||||
}
|
||||
|
||||
public void ModifyCredsFile(Action<IBotCredentials> func)
|
||||
public void ModifyCredsFile(Action<IBotCreds> func)
|
||||
{
|
||||
var ymlData = File.ReadAllText(CREDS_FILE_NAME);
|
||||
var creds = Yaml.Deserializer.Deserialize<Creds>(ymlData);
|
||||
|
@ -137,18 +137,18 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
|||
var creds = Yaml.Deserializer.Deserialize<Creds>(File.ReadAllText(CREDS_FILE_NAME));
|
||||
if (creds.Version <= 5)
|
||||
{
|
||||
creds.BotCache = BotCacheImplemenation.Redis;
|
||||
creds.BotCache = BotCacheImplemenation.Memory;
|
||||
}
|
||||
|
||||
if (creds.Version <= 9)
|
||||
if (creds.Version < 12)
|
||||
{
|
||||
creds.Version = 10;
|
||||
creds.Version = 12;
|
||||
File.WriteAllText(CREDS_FILE_NAME, Yaml.Serializer.Serialize(creds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IBotCredentials GetCreds()
|
||||
public IBotCreds GetCreds()
|
||||
{
|
||||
lock (_reloadLock)
|
||||
{
|
||||
|
|
|
@ -4,11 +4,11 @@ namespace EllieBot.Common;
|
|||
|
||||
public sealed class RedisPubSub : IPubSub
|
||||
{
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly ConnectionMultiplexer _multi;
|
||||
private readonly ISeria _serializer;
|
||||
|
||||
public RedisPubSub(ConnectionMultiplexer multi, ISeria serializer, IBotCredentials creds)
|
||||
public RedisPubSub(ConnectionMultiplexer multi, ISeria serializer, IBotCreds creds)
|
||||
{
|
||||
_multi = multi;
|
||||
_serializer = serializer;
|
||||
|
|
|
@ -15,13 +15,13 @@ public class RedisBotStringsProvider : IBotStringsProvider
|
|||
|
||||
private readonly ConnectionMultiplexer _redis;
|
||||
private readonly IStringsSource _source;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
|
||||
public RedisBotStringsProvider(
|
||||
ConnectionMultiplexer redis,
|
||||
DiscordSocketClient discordClient,
|
||||
IStringsSource source,
|
||||
IBotCredentials creds)
|
||||
IBotCreds creds)
|
||||
{
|
||||
_redis = redis;
|
||||
_source = source;
|
||||
|
|
|
@ -11,7 +11,7 @@ public class RemoteGrpcCoordinator : ICoordinator, IReadyExecutor
|
|||
private readonly Coordinator.Coordinator.CoordinatorClient _coordClient;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public RemoteGrpcCoordinator(IBotCredentials creds, DiscordSocketClient client)
|
||||
public RemoteGrpcCoordinator(IBotCreds creds, DiscordSocketClient client)
|
||||
{
|
||||
var coordUrl = string.IsNullOrWhiteSpace(creds.CoordinatorUrl) ? "http://localhost:3442" : creds.CoordinatorUrl;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public static class ServiceCollectionExtensions
|
|||
return svcs;
|
||||
}
|
||||
|
||||
public static IContainer AddCache(this IContainer cont, IBotCredentials creds)
|
||||
public static IContainer AddCache(this IContainer cont, IBotCreds creds)
|
||||
{
|
||||
if (creds.BotCache == BotCacheImplemenation.Redis)
|
||||
{
|
||||
|
|
|
@ -14,12 +14,12 @@ public sealed class BlacklistService : IExecOnMessage
|
|||
|
||||
private readonly DbService _db;
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private IReadOnlyList<BlacklistEntry> blacklist;
|
||||
|
||||
private readonly TypedKey<BlacklistEntry[]> _blPubKey = new("blacklist.reload");
|
||||
|
||||
public BlacklistService(DbService db, IPubSub pubSub, IBotCredentials creds)
|
||||
public BlacklistService(DbService db, IPubSub pubSub, IBotCreds creds)
|
||||
{
|
||||
_db = db;
|
||||
_pubSub = pubSub;
|
||||
|
|
|
@ -5,10 +5,10 @@ namespace EllieBot.Services;
|
|||
|
||||
public class SingleProcessCoordinator : ICoordinator
|
||||
{
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public SingleProcessCoordinator(IBotCredentials creds, DiscordSocketClient client)
|
||||
public SingleProcessCoordinator(IBotCreds creds, DiscordSocketClient client)
|
||||
{
|
||||
_creds = creds;
|
||||
_client = client;
|
||||
|
|
|
@ -29,7 +29,7 @@ public sealed class StatsService : IStatsService, IReadyExecutor, IEService
|
|||
|
||||
private readonly Process _currentProcess = Process.GetCurrentProcess();
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IBotCreds _creds;
|
||||
private readonly DateTime _started;
|
||||
|
||||
private long textChannels;
|
||||
|
@ -42,7 +42,7 @@ public sealed class StatsService : IStatsService, IReadyExecutor, IEService
|
|||
public StatsService(
|
||||
DiscordSocketClient client,
|
||||
CommandHandler cmdHandler,
|
||||
IBotCredentials creds,
|
||||
IBotCreds creds,
|
||||
IHttpClientFactory factory)
|
||||
{
|
||||
_client = client;
|
||||
|
|
|
@ -2,9 +2,9 @@ namespace EllieBot.Extensions;
|
|||
|
||||
public static class BotCredentialsExtensions
|
||||
{
|
||||
public static bool IsOwner(this IBotCredentials creds, IUser user)
|
||||
public static bool IsOwner(this IBotCreds creds, IUser user)
|
||||
=> creds.IsOwner(user.Id);
|
||||
|
||||
public static bool IsOwner(this IBotCredentials creds, ulong userId)
|
||||
public static bool IsOwner(this IBotCreds creds, ulong userId)
|
||||
=> creds.OwnerIds.Contains(userId);
|
||||
}
|
|
@ -103,7 +103,7 @@ public static class Extensions
|
|||
/// <summary>
|
||||
/// First 10 characters of teh bot token.
|
||||
/// </summary>
|
||||
public static string RedisKey(this IBotCredentials bc)
|
||||
public static string RedisKey(this IBotCreds bc)
|
||||
=> bc.Token[..10];
|
||||
|
||||
public static bool IsAuthor(this IMessage msg, IDiscordClient client)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# DO NOT CHANGE
|
||||
version: 1
|
||||
# List of marmalades automatically loaded at startup
|
||||
loaded:
|
||||
- ngrpc
|
||||
loaded: []
|
||||
|
|
Loading…
Reference in a new issue