Compare commits

...

2 commits

Author SHA1 Message Date
487c7865cb
Fixed greet/bye messages showing wrong message in the wrong server sometimes
Fixed the check for updates service
Version upped to 5.1.12. Updated CHANGELOG.md
2024-10-05 11:44:44 +13:00
3ba1d06fd0
expressions will no longer cause exceptions if the bot doesn't have perms to write in the target channel
Cleaned up expr code a little bit
2024-10-05 11:17:12 +13:00
40 changed files with 181 additions and 148 deletions

View file

@ -2,6 +2,16 @@
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o
## [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 another bug in `.greet` / `.bye` system, which caused it to show wrong message on a wrong server occasionally
## [5.1.11] - 03.10.2024 ## [5.1.11] - 03.10.2024
### Added ### Added

View file

@ -25,7 +25,7 @@ public sealed class Bot : IBot
public bool IsReady { get; private set; } public bool IsReady { get; private set; }
public int ShardId { get; set; } public int ShardId { get; set; }
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly CommandService _commandService; private readonly CommandService _commandService;
private readonly DbService _db; private readonly DbService _db;
@ -42,6 +42,9 @@ public sealed class Bot : IBot
_credsProvider = new BotCredsProvider(totalShards, credPath); _credsProvider = new BotCredsProvider(totalShards, credPath);
_creds = _credsProvider.GetCreds(); _creds = _credsProvider.GetCreds();
LogSetup.SetupLogger(shardId, _creds);
Log.Information("Pid: {ProcessId}", Environment.ProcessId);
_db = new EllieDbService(_credsProvider); _db = new EllieDbService(_credsProvider);
var messageCacheSize = var messageCacheSize =
@ -115,7 +118,7 @@ public sealed class Bot : IBot
// svcs.Components.Remove<IPlanner, Planner>(); // svcs.Components.Remove<IPlanner, Planner>();
// svcs.Components.Add<IPlanner, RemovablePlanner>(); // svcs.Components.Add<IPlanner, RemovablePlanner>();
svcs.AddSingleton<IBotCredentials>(_ => _credsProvider.GetCreds()); svcs.AddSingleton<IBotCreds>(_ => _credsProvider.GetCreds());
svcs.AddSingleton<DbService, DbService>(_db); svcs.AddSingleton<DbService, DbService>(_db);
svcs.AddSingleton<IBotCredsProvider>(_credsProvider); svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
svcs.AddSingleton<DiscordSocketClient>(Client); svcs.AddSingleton<DiscordSocketClient>(Client);

View file

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings> <ImplicitUsings>true</ImplicitUsings>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages> <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<Version>5.1.11</Version> <Version>5.1.12</Version>
<!-- Output/build --> <!-- Output/build -->
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory> <RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>

View file

@ -208,11 +208,11 @@ public class GreetService : IEService, IReadyExecutor
return Task.CompletedTask; return Task.CompletedTask;
} }
private TypedKey<GreetSettings?> GreetSettingsKey(GreetType type) private TypedKey<GreetSettings?> GreetSettingsKey(ulong gid, GreetType type)
=> new($"greet_settings:{type}"); => new($"greet_settings:{gid}:{type}");
public async Task<GreetSettings?> GetGreetSettingsAsync(ulong gid, GreetType 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), () => InternalGetGreetSettingsAsync(gid, type),
TimeSpan.FromSeconds(3)); TimeSpan.FromSeconds(3));

View file

@ -13,7 +13,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
{ {
private readonly DbService _db; private readonly DbService _db;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private ConcurrentDictionary<ulong, List<ReactionRoleV2>> _cache; private ConcurrentDictionary<ulong, List<ReactionRoleV2>> _cache;
private readonly object _cacheLock = new(); private readonly object _cacheLock = new();
@ -24,7 +24,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
DiscordSocketClient client, DiscordSocketClient client,
IPatronageService ps, IPatronageService ps,
DbService db, DbService db,
IBotCredentials creds) IBotCreds creds)
{ {
_db = db; _db = db;
_client = client; _client = client;

View file

@ -9,13 +9,13 @@ namespace EllieBot.Modules.Administration;
public sealed class StickyRolesService : IEService, IReadyExecutor public sealed class StickyRolesService : IEService, IReadyExecutor
{ {
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DbService _db; private readonly DbService _db;
private HashSet<ulong> _stickyRoles = new(); private HashSet<ulong> _stickyRoles = new();
public StickyRolesService( public StickyRolesService(
DiscordSocketClient client, DiscordSocketClient client,
IBotCredentials creds, IBotCreds creds,
DbService db) DbService db)
{ {
_client = client; _client = client;

View file

@ -19,7 +19,7 @@ public sealed class CheckForUpdatesService : IEService, IReadyExecutor
private readonly IMessageSenderService _sender; 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( public CheckForUpdatesService(
BotConfigService bcs, BotConfigService bcs,

View file

@ -15,7 +15,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
private readonly IBotStrings _strings; private readonly IBotStrings _strings;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private ImmutableDictionary<ulong, IDMChannel> ownerChannels = private ImmutableDictionary<ulong, IDMChannel> ownerChannels =
new Dictionary<ulong, IDMChannel>().ToImmutableDictionary(); new Dictionary<ulong, IDMChannel>().ToImmutableDictionary();
@ -36,7 +36,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
CommandHandler cmdHandler, CommandHandler cmdHandler,
DbService db, DbService db,
IBotStrings strings, IBotStrings strings,
IBotCredentials creds, IBotCreds creds,
IHttpClientFactory factory, IHttpClientFactory factory,
BotConfigService bss, BotConfigService bss,
IPubSub pubSub, IPubSub pubSub,

View file

@ -6,49 +6,6 @@ namespace EllieBot.Modules.EllieExpressions;
public static class EllieExpressionExtensions 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WordPosition GetWordPosition(this ReadOnlySpan<char> str, in ReadOnlySpan<char> word) public static WordPosition GetWordPosition(this ReadOnlySpan<char> str, in ReadOnlySpan<char> word)
{ {

View file

@ -11,10 +11,10 @@ public partial class EllieExpressions : EllieModule<EllieExpressionsService>
All All
} }
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly IHttpClientFactory _clientFactory; private readonly IHttpClientFactory _clientFactory;
public EllieExpressions(IBotCredentials creds, IHttpClientFactory clientFactory) public EllieExpressions(IBotCreds creds, IHttpClientFactory clientFactory)
{ {
_creds = creds; _creds = creds;
_clientFactory = clientFactory; _clientFactory = clientFactory;

View file

@ -249,8 +249,9 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
try try
{ {
if (guild is SocketGuild sg) if (guild is not SocketGuild sg)
{ return false;
var result = await _permChecker.CheckPermsAsync( var result = await _permChecker.CheckPermsAsync(
guild, guild,
msg.Channel, msg.Channel,
@ -286,9 +287,16 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
return true; 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(); var reactions = expr.GetReactions();
foreach (var reaction in reactions) foreach (var reaction in reactions)
@ -336,6 +344,47 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
return false; 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) public async Task ResetExprReactions(ulong? maybeGuildId, int id)
{ {
EllieExpression expr; EllieExpression expr;

View file

@ -14,13 +14,13 @@ public class VoteModel
public class VoteRewardService : IEService, IReadyExecutor public class VoteRewardService : IEService, IReadyExecutor
{ {
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly ICurrencyService _currencyService; private readonly ICurrencyService _currencyService;
private readonly GamblingConfigService _gamb; private readonly GamblingConfigService _gamb;
public VoteRewardService( public VoteRewardService(
DiscordSocketClient client, DiscordSocketClient client,
IBotCredentials creds, IBotCreds creds,
ICurrencyService currencyService, ICurrencyService currencyService,
GamblingConfigService gamb) GamblingConfigService gamb)
{ {

View file

@ -15,7 +15,7 @@ public class WaifuService : IEService, IReadyExecutor
private readonly ICurrencyService _cs; private readonly ICurrencyService _cs;
private readonly IBotCache _cache; private readonly IBotCache _cache;
private readonly GamblingConfigService _gss; private readonly GamblingConfigService _gss;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
public WaifuService( public WaifuService(
@ -23,7 +23,7 @@ public class WaifuService : IEService, IReadyExecutor
ICurrencyService cs, ICurrencyService cs,
IBotCache cache, IBotCache cache,
GamblingConfigService gss, GamblingConfigService gss,
IBotCredentials creds, IBotCreds creds,
DiscordSocketClient client) DiscordSocketClient client)
{ {
_db = db; _db = db;

View file

@ -19,7 +19,7 @@ public class ChatterBotService : IExecOnMessage
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IPermissionChecker _perms; private readonly IPermissionChecker _perms;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly GamesConfigService _gcs; private readonly GamesConfigService _gcs;
private readonly IMessageSenderService _sender; private readonly IMessageSenderService _sender;
@ -32,7 +32,7 @@ public class ChatterBotService : IExecOnMessage
IBot bot, IBot bot,
IPatronageService ps, IPatronageService ps,
IHttpClientFactory factory, IHttpClientFactory factory,
IBotCredentials creds, IBotCreds creds,
GamesConfigService gcs, GamesConfigService gcs,
IMessageSenderService sender, IMessageSenderService sender,
DbService db) DbService db)

View file

@ -12,9 +12,9 @@ public sealed partial class Music
{ {
private static readonly SemaphoreSlim _playlistLock = new(1, 1); private static readonly SemaphoreSlim _playlistLock = new(1, 1);
private readonly DbService _db; 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; _db = db;
_creds = creds; _creds = creds;

View file

@ -16,11 +16,11 @@ public class CryptoService : IEService
{ {
private readonly IBotCache _cache; private readonly IBotCache _cache;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly SemaphoreSlim _getCryptoLock = new(1, 1); 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; _cache = cache;
_httpFactory = httpFactory; _httpFactory = httpFactory;

View file

@ -9,10 +9,10 @@ public partial class Searches
[Group] [Group]
public partial class OsuCommands : EllieModule<OsuService> public partial class OsuCommands : EllieModule<OsuService>
{ {
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
public OsuCommands(IBotCredentials creds, IHttpClientFactory factory) public OsuCommands(IBotCreds creds, IHttpClientFactory factory)
{ {
_creds = creds; _creds = creds;
_httpFactory = factory; _httpFactory = factory;

View file

@ -7,9 +7,9 @@ namespace EllieBot.Modules.Searches;
public sealed class OsuService : IEService public sealed class OsuService : IEService
{ {
private readonly IHttpClientFactory _httpFactory; 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; _httpFactory = httpFactory;
_creds = creds; _creds = creds;

View file

@ -13,14 +13,14 @@ namespace EllieBot.Modules.Searches;
public partial class Searches : EllieModule<SearchesService> public partial class Searches : EllieModule<SearchesService>
{ {
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly IGoogleApiService _google; private readonly IGoogleApiService _google;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly IMemoryCache _cache; private readonly IMemoryCache _cache;
private readonly ITimezoneService _tzSvc; private readonly ITimezoneService _tzSvc;
public Searches( public Searches(
IBotCredentials creds, IBotCreds creds,
IGoogleApiService google, IGoogleApiService google,
IHttpClientFactory factory, IHttpClientFactory factory,
IMemoryCache cache, IMemoryCache cache,

View file

@ -11,7 +11,7 @@ public sealed class GiveawayService : IEService, IReadyExecutor
public static string GiveawayEmoji = "🎉"; public static string GiveawayEmoji = "🎉";
private readonly DbService _db; private readonly DbService _db;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IMessageSenderService _sender; private readonly IMessageSenderService _sender;
private readonly IBotStrings _strings; private readonly IBotStrings _strings;
@ -20,7 +20,7 @@ public sealed class GiveawayService : IEService, IReadyExecutor
private SortedSet<GiveawayModel> _giveawayCache = new SortedSet<GiveawayModel>(); private SortedSet<GiveawayModel> _giveawayCache = new SortedSet<GiveawayModel>();
private readonly EllieRandom _rng; 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) IMessageSenderService sender, IBotStrings strings, ILocalization localization, IMemoryCache cache)
{ {
_db = db; _db = db;

View file

@ -17,14 +17,14 @@ public class RemindService : IEService, IReadyExecutor, IRemindService
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly DbService _db; private readonly DbService _db;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly IMessageSenderService _sender; private readonly IMessageSenderService _sender;
private readonly CultureInfo _culture; private readonly CultureInfo _culture;
public RemindService( public RemindService(
DiscordSocketClient client, DiscordSocketClient client,
DbService db, DbService db,
IBotCredentials creds, IBotCreds creds,
IMessageSenderService sender) IMessageSenderService sender)
{ {
_client = client; _client = client;

View file

@ -12,7 +12,7 @@ public sealed class RepeaterService : IReadyExecutor, IEService
private readonly DbService _db; private readonly DbService _db;
private readonly IReplacementService _repSvc; private readonly IReplacementService _repSvc;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly LinkedList<RunningRepeater> _repeaterQueue; private readonly LinkedList<RunningRepeater> _repeaterQueue;
private readonly ConcurrentHashSet<int> _noRedundant; private readonly ConcurrentHashSet<int> _noRedundant;
@ -25,7 +25,7 @@ public sealed class RepeaterService : IReadyExecutor, IEService
DiscordSocketClient client, DiscordSocketClient client,
DbService db, DbService db,
IReplacementService repSvc, IReplacementService repSvc,
IBotCredentials creds, IBotCreds creds,
IMessageSenderService sender) IMessageSenderService sender)
{ {
_db = db; _db = db;

View file

@ -34,7 +34,7 @@ public partial class Utility : EllieModule
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly ICoordinator _coord; private readonly ICoordinator _coord;
private readonly IStatsService _stats; private readonly IStatsService _stats;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DownloadTracker _tracker; private readonly DownloadTracker _tracker;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly VerboseErrorsService _veService; private readonly VerboseErrorsService _veService;
@ -45,7 +45,7 @@ public partial class Utility : EllieModule
DiscordSocketClient client, DiscordSocketClient client,
ICoordinator coord, ICoordinator coord,
IStatsService stats, IStatsService stats,
IBotCredentials creds, IBotCreds creds,
DownloadTracker tracker, DownloadTracker tracker,
IHttpClientFactory httpFactory, IHttpClientFactory httpFactory,
VerboseErrorsService veService, VerboseErrorsService veService,

View file

@ -25,7 +25,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
private readonly IImageCache _images; private readonly IImageCache _images;
private readonly IBotStrings _strings; private readonly IBotStrings _strings;
private readonly FontProvider _fonts; private readonly FontProvider _fonts;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly ICurrencyService _cs; private readonly ICurrencyService _cs;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly XpConfigService _xpConfig; private readonly XpConfigService _xpConfig;
@ -55,7 +55,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
IImageCache images, IImageCache images,
IBotCache c, IBotCache c,
FontProvider fonts, FontProvider fonts,
IBotCredentials creds, IBotCreds creds,
ICurrencyService cs, ICurrencyService cs,
IHttpClientFactory http, IHttpClientFactory http,
XpConfigService xpConfig, XpConfigService xpConfig,

View file

@ -1,6 +1,4 @@
var pid = Environment.ProcessId; var shardId = 0;
var shardId = 0;
int? totalShards = null; // 0 to read from creds.yml int? totalShards = null; // 0 to read from creds.yml
if (args.Length > 0 && args[0] != "run") 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(); await new Bot(shardId, totalShards, Environment.GetEnvironmentVariable("EllieBot__creds")).RunAndBlockAsync();

View file

@ -6,9 +6,9 @@ namespace Ellie.Common;
public static class LogSetup 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("System", LogEventLevel.Information)
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.Enrich.FromLogContext() .Enrich.FromLogContext()
@ -16,7 +16,12 @@ public static class LogSetup
theme: GetTheme(), theme: GetTheme(),
outputTemplate: outputTemplate:
"[{Timestamp:HH:mm:ss} {Level:u3}] | #{LogSource} | {Message:lj}{NewLine}{Exception}") "[{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(); .CreateLogger();
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;

View file

@ -1,7 +1,7 @@
#nullable disable #nullable disable
namespace EllieBot; namespace EllieBot;
public interface IBotCredentials public interface IBotCreds
{ {
string Token { get; } string Token { get; }
string EllieAiToken { get; } string EllieAiToken { get; }
@ -30,6 +30,7 @@ public interface IBotCredentials
GoogleApiConfig Google { get; set; } GoogleApiConfig Google { get; set; }
BotCacheImplemenation BotCache { get; set; } BotCacheImplemenation BotCache { get; set; }
Creds.GrpcApiConfig GrpcApi { get; set; } Creds.GrpcApiConfig GrpcApi { get; set; }
SeqConfig Seq { get; set; }
} }
public interface IVotesSettings public interface IVotesSettings

View file

@ -3,6 +3,6 @@
public interface IBotCredsProvider public interface IBotCredsProvider
{ {
public void Reload(); public void Reload();
public IBotCredentials GetCreds(); public IBotCreds GetCreds();
public void ModifyCredsFile(Action<IBotCredentials> func); public void ModifyCredsFile(Action<IBotCreds> func);
} }

View file

@ -28,7 +28,7 @@ public sealed partial class BotConfig : ICloneable<BotConfig>
public CultureInfo DefaultLocale { get; set; } public CultureInfo DefaultLocale { get; set; }
[Comment(""" [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 Allowed values: Simple, Normal, None
""")] """)]
public ConsoleOutputType ConsoleOutputType { get; set; } public ConsoleOutputType ConsoleOutputType { get; set; }

View file

@ -3,10 +3,10 @@ using EllieBot.Common.Yml;
namespace EllieBot.Common; namespace EllieBot.Common;
public sealed class Creds : IBotCredentials public sealed class Creds : IBotCreds
{ {
[Comment("""DO NOT CHANGE""")] [Comment("""DO NOT CHANGE""")]
public int Version { get; set; } = 10; public int Version { get; set; } = 11;
[Comment("""Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/""")] [Comment("""Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/""")]
public string Token { get; set; } public string Token { get; set; }
@ -164,6 +164,11 @@ public sealed class Creds : IBotCredentials
""")] """)]
public GrpcApiConfig GrpcApi { get; set; } public GrpcApiConfig GrpcApi { get; set; }
[Comment("""
Url to
""")]
public SeqConfig Seq { get; set; }
public Creds() public Creds()
{ {
Token = string.Empty; Token = string.Empty;
@ -189,7 +194,8 @@ public sealed class Creds : IBotCredentials
RestartCommand = new RestartConfig(); RestartCommand = new RestartConfig();
Google = new GoogleApiConfig(); Google = new GoogleApiConfig();
GrpcApi = new GrpcApiConfig(); GrpcApi = new();
Seq = new();
} }
public class DbOptions 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 class GoogleApiConfig : IGoogleApiConfig
{ {
public string SearchId { get; init; } public string SearchId { get; init; }

View file

@ -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 ymlData = File.ReadAllText(CREDS_FILE_NAME);
var creds = Yaml.Deserializer.Deserialize<Creds>(ymlData); var creds = Yaml.Deserializer.Deserialize<Creds>(ymlData);
@ -148,7 +148,7 @@ public sealed class BotCredsProvider : IBotCredsProvider
} }
} }
public IBotCredentials GetCreds() public IBotCreds GetCreds()
{ {
lock (_reloadLock) lock (_reloadLock)
{ {

View file

@ -4,11 +4,11 @@ namespace EllieBot.Common;
public sealed class RedisPubSub : IPubSub public sealed class RedisPubSub : IPubSub
{ {
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly ConnectionMultiplexer _multi; private readonly ConnectionMultiplexer _multi;
private readonly ISeria _serializer; private readonly ISeria _serializer;
public RedisPubSub(ConnectionMultiplexer multi, ISeria serializer, IBotCredentials creds) public RedisPubSub(ConnectionMultiplexer multi, ISeria serializer, IBotCreds creds)
{ {
_multi = multi; _multi = multi;
_serializer = serializer; _serializer = serializer;

View file

@ -15,13 +15,13 @@ public class RedisBotStringsProvider : IBotStringsProvider
private readonly ConnectionMultiplexer _redis; private readonly ConnectionMultiplexer _redis;
private readonly IStringsSource _source; private readonly IStringsSource _source;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
public RedisBotStringsProvider( public RedisBotStringsProvider(
ConnectionMultiplexer redis, ConnectionMultiplexer redis,
DiscordSocketClient discordClient, DiscordSocketClient discordClient,
IStringsSource source, IStringsSource source,
IBotCredentials creds) IBotCreds creds)
{ {
_redis = redis; _redis = redis;
_source = source; _source = source;

View file

@ -11,7 +11,7 @@ public class RemoteGrpcCoordinator : ICoordinator, IReadyExecutor
private readonly Coordinator.Coordinator.CoordinatorClient _coordClient; private readonly Coordinator.Coordinator.CoordinatorClient _coordClient;
private readonly DiscordSocketClient _client; 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; var coordUrl = string.IsNullOrWhiteSpace(creds.CoordinatorUrl) ? "http://localhost:3442" : creds.CoordinatorUrl;

View file

@ -61,7 +61,7 @@ public static class ServiceCollectionExtensions
return svcs; 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) if (creds.BotCache == BotCacheImplemenation.Redis)
{ {

View file

@ -14,12 +14,12 @@ public sealed class BlacklistService : IExecOnMessage
private readonly DbService _db; private readonly DbService _db;
private readonly IPubSub _pubSub; private readonly IPubSub _pubSub;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private IReadOnlyList<BlacklistEntry> blacklist; private IReadOnlyList<BlacklistEntry> blacklist;
private readonly TypedKey<BlacklistEntry[]> _blPubKey = new("blacklist.reload"); 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; _db = db;
_pubSub = pubSub; _pubSub = pubSub;

View file

@ -5,10 +5,10 @@ namespace EllieBot.Services;
public class SingleProcessCoordinator : ICoordinator public class SingleProcessCoordinator : ICoordinator
{ {
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
public SingleProcessCoordinator(IBotCredentials creds, DiscordSocketClient client) public SingleProcessCoordinator(IBotCreds creds, DiscordSocketClient client)
{ {
_creds = creds; _creds = creds;
_client = client; _client = client;

View file

@ -29,7 +29,7 @@ public sealed class StatsService : IStatsService, IReadyExecutor, IEService
private readonly Process _currentProcess = Process.GetCurrentProcess(); private readonly Process _currentProcess = Process.GetCurrentProcess();
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IBotCredentials _creds; private readonly IBotCreds _creds;
private readonly DateTime _started; private readonly DateTime _started;
private long textChannels; private long textChannels;
@ -42,7 +42,7 @@ public sealed class StatsService : IStatsService, IReadyExecutor, IEService
public StatsService( public StatsService(
DiscordSocketClient client, DiscordSocketClient client,
CommandHandler cmdHandler, CommandHandler cmdHandler,
IBotCredentials creds, IBotCreds creds,
IHttpClientFactory factory) IHttpClientFactory factory)
{ {
_client = client; _client = client;

View file

@ -2,9 +2,9 @@ namespace EllieBot.Extensions;
public static class BotCredentialsExtensions 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); => 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); => creds.OwnerIds.Contains(userId);
} }

View file

@ -103,7 +103,7 @@ public static class Extensions
/// <summary> /// <summary>
/// First 10 characters of teh bot token. /// First 10 characters of teh bot token.
/// </summary> /// </summary>
public static string RedisKey(this IBotCredentials bc) public static string RedisKey(this IBotCreds bc)
=> bc.Token[..10]; => bc.Token[..10];
public static bool IsAuthor(this IMessage msg, IDiscordClient client) public static bool IsAuthor(this IMessage msg, IDiscordClient client)