From 2a69a51571fb65cb184358594ad976ec97e44b7e Mon Sep 17 00:00:00 2001 From: Passive Date: Thu, 21 Nov 2019 14:40:58 +1100 Subject: [PATCH] random documentation stuff --- Extensions/Extensions.cs | 5 ++++ Handlers/ELOEventHandler.cs | 53 +++++++++++++++++-------------------- Handlers/ELOScheduler.cs | 11 +++++--- Program.cs | 4 +++ Services/ELOJobs.cs | 4 +++ 5 files changed, 45 insertions(+), 32 deletions(-) diff --git a/Extensions/Extensions.cs b/Extensions/Extensions.cs index 4adbe00..f520bc1 100644 --- a/Extensions/Extensions.cs +++ b/Extensions/Extensions.cs @@ -11,16 +11,20 @@ public static class Extensions public static bool IsRegistered(this SocketGuildUser user, out Player player, bool required = true) { + //Create a new db session. using (var db = new Database()) { + //Ensure there is a cached value for the user in question if (!RegistrationCache.ContainsKey(user.Guild.Id)) { RegistrationCache.Add(user.Guild.Id, new Dictionary()); } + //Find the cache for the specified guild var guildCache = RegistrationCache[user.Guild.Id]; if (guildCache.TryGetValue(user.Id, out var registered)) { + //Check cache to avoid initial db query if (registered) { //Query db here @@ -43,6 +47,7 @@ public static bool IsRegistered(this SocketGuildUser user, out Player player, bo } else { + //The user is not cached so populate the cache with if they are registered or not player = db.Players.Find(user.Guild.Id, user.Id); if (player == null) { diff --git a/Handlers/ELOEventHandler.cs b/Handlers/ELOEventHandler.cs index 78936f5..3be5704 100644 --- a/Handlers/ELOEventHandler.cs +++ b/Handlers/ELOEventHandler.cs @@ -20,8 +20,9 @@ public ELOEventHandler(ConfigManager configManager, IServiceProvider provider) : LogHandler = provider.GetService() ?? new Logger(); Logger.Message += async (m, l) => LogHandler.Log(m, l); - GuildSchedule.Provider = provider; - GuildSchedule.Service = provider.GetRequiredService(); + //Set commandschedule variables so they don't need to be injected + CommandSchedule.Provider = provider; + CommandSchedule.Service = provider.GetRequiredService(); } public ConfigManager ConfigManager { get; } @@ -29,20 +30,25 @@ public ELOEventHandler(ConfigManager configManager, IServiceProvider provider) : public override async Task JoinedGuildAsync(SocketGuild guild) { + //Check server whitelist if (!ConfigManager.LastConfig.IsAcceptable(guild.Id)) { return; } + //Try to find a channel the bot can send messages to with it's current permissions var firstChannel = guild.TextChannels.Where(x => { var permissions = guild.CurrentUser?.GetPermissions(x); return permissions.HasValue ? permissions.Value.ViewChannel && permissions.Value.SendMessages : false; }).OrderBy(c => c.Position).FirstOrDefault(); + //Let the server know the help command name (assuming default prefix) await firstChannel?.SendMessageAsync("", false, new EmbedBuilder() { Title = $"{Client.CurrentUser.Username}", + //TODO: In case that server has a custom prefix (set it, removed bot and then re-invited bot) + //Show custom prefix instead Description = $"Get started by using the help command: `{ConfigManager.LastConfig.Prefix}help`", Color = Color.Green }.Build()); @@ -65,6 +71,7 @@ public override async Task MessageReceivedAsync(SocketMessage discordMessage) } else { + //Still ignore messages from the bot to avoid recursive commands if (message.Author.Id == Client.CurrentUser.Id) { return; @@ -77,18 +84,20 @@ public override async Task MessageReceivedAsync(SocketMessage discordMessage) guildId = gChannel.GuildId; } - var _ = Task.Run(async () => + //Ensure the server is whitelisted or whitelist disabled + if (!ConfigManager.LastConfig.IsAcceptable(guildId)) { - if (!ConfigManager.LastConfig.IsAcceptable(guildId)) - { - return; - } + return; + } + var _ = Task.Run(async () => + { var context = new ShardedCommandContext(Client, message); var argPos = 0; if (guildId != 0 && !ConfigManager.LastConfig.Developer) { + //Check that the message was from a server and try to use a custom set prefix if available. using (var db = new Database()) { var comp = db.GetOrCreateCompetition(guildId); @@ -101,38 +110,24 @@ public override async Task MessageReceivedAsync(SocketMessage discordMessage) } else { + //If the bot is in developer mode or dms use regular prefix or dev override prefix if (!message.HasStringPrefix(ConfigManager.LastConfig.Developer ? ConfigManager.LastConfig.DeveloperPrefix : ConfigManager.LastConfig.Prefix, ref argPos, StringComparison.InvariantCultureIgnoreCase)) { return; } } - if (guildId != 0) - { - if (!GuildScheduler.ContainsKey(guildId)) - { - GuildScheduler[guildId] = new GuildSchedule - { - GuildId = guildId - }; - } - GuildScheduler[guildId].AddTask(context, argPos); - } - else + //NOTE: Since guildId is 0 for dms, they have their own command queue. + if (!CommandScheduler.ContainsKey(guildId)) { - if (!GuildScheduler.ContainsKey(0)) + CommandScheduler[guildId] = new CommandSchedule { - GuildScheduler[0] = new GuildSchedule - { - GuildId = 0 - }; - } - - GuildScheduler[0].AddTask(context, argPos); - //Should dm commands also just have a global queue - //var result = await CommandService.ExecuteAsync(context, argPos, Provider).ConfigureAwait(false); + GuildId = guildId + }; } + + CommandScheduler[guildId].AddTask(context, argPos); }); } diff --git a/Handlers/ELOScheduler.cs b/Handlers/ELOScheduler.cs index 17d07f7..1dc5092 100644 --- a/Handlers/ELOScheduler.cs +++ b/Handlers/ELOScheduler.cs @@ -9,8 +9,8 @@ namespace ELO.Handlers { public partial class ELOEventHandler { - public Dictionary GuildScheduler = new Dictionary(); - public class GuildSchedule + public Dictionary CommandScheduler = new Dictionary(); + public class CommandSchedule { public static CommandService Service; public static IServiceProvider Provider; @@ -31,10 +31,12 @@ public void AddTask(ICommandContext message, int argPos) } } + //Command is synchronous so add to guild queue Queue.Enqueue((message, argPos)); + //Check and attempt to run the command processor if (!Running) - { + { Task.Run(() => RunProcessor()); } } @@ -45,10 +47,12 @@ public async Task RunProcessor() Running = true; try { + //Continue getting commands until there are none left while (Queue.TryDequeue(out var context)) { try { + //Wait for either the command to finish or 30 seconds to pass. Task.WaitAny(Service.ExecuteAsync(context.Item1, context.Item2, Provider), Task.Delay(30000)); } catch (Exception e) @@ -63,6 +67,7 @@ public async Task RunProcessor() } finally { + //Ensure running is set to false on exit so commands are not lost Running = false; } } diff --git a/Program.cs b/Program.cs index 0114fdc..1f66532 100644 --- a/Program.cs +++ b/Program.cs @@ -29,6 +29,7 @@ public static void Main(string[] args) public virtual async Task RunAsync(string[] args = null) { + //Parse cl arguments and set the variables if (args != null) { Parser.Default.ParseArguments(args) @@ -41,6 +42,7 @@ public virtual async Task RunAsync(string[] args = null) }); } + //Initialize new default required configs var localManagement = new ConfigManager(); localManagement.GetConfig(); var socketConfig = localManagement.LastConfig.GetConfig("SocketConfig")?.ToConfig(); @@ -77,6 +79,7 @@ public virtual async Task RunAsync(string[] args = null) } Database.Config = dbConfig; + //Ensure the database is created. This should also verify connection using (var db = new Database()) { db.Database.EnsureCreated(); @@ -104,6 +107,7 @@ public virtual async Task RunAsync(string[] args = null) try { + //Initialize the event handler await Provider.GetRequiredService().InitializeAsync(localManagement.GetConfig().Token); } catch (Exception e) diff --git a/Services/ELOJobs.cs b/Services/ELOJobs.cs index a9edf23..dae98d6 100644 --- a/Services/ELOJobs.cs +++ b/Services/ELOJobs.cs @@ -13,6 +13,7 @@ public class ELOJobs public ELOJobs(DiscordShardedClient client) { Client = client; + //Setup a timer that fires every 5 minutes CompetitionUpdateTimer = new Timer(RunQueueChecks, null, 60000, 1000 * 60 * 5); } @@ -26,6 +27,7 @@ public void RunQueueChecks(object stateInfo = null) using (var db = new Database()) { var now = DateTime.UtcNow; + //TODO: Avoid querying ALL queued players var queuedPlayers = db.QueuedPlayers.ToArray(); var guildGroups = queuedPlayers.GroupBy(x => x.GuildId); foreach (var group in guildGroups) @@ -38,7 +40,9 @@ public void RunQueueChecks(object stateInfo = null) //Too much time has passed, user is to be removed from queue. if (player.QueuedAt + comp.QueueTimeout.Value < now) { + //Remove player from queue db.QueuedPlayers.Remove(player); + //Ensure lobby channel still exists and announce the user is removed from queue var channel = Client.GetChannel(player.ChannelId) as SocketTextChannel; if (channel != null) {