From c0acf1ff797936b7f0aed4a9de64244ae0a01fef Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 11 Aug 2020 03:26:28 +0200 Subject: [PATCH 1/6] Rename AddXp function to proper naming convention --- ChaosBot/Discord/Services/CommandHandler.cs | 4 ++-- ChaosBot/Discord/Services/ExperienceHandler.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChaosBot/Discord/Services/CommandHandler.cs b/ChaosBot/Discord/Services/CommandHandler.cs index 8c461be..af9d4a3 100644 --- a/ChaosBot/Discord/Services/CommandHandler.cs +++ b/ChaosBot/Discord/Services/CommandHandler.cs @@ -66,12 +66,12 @@ namespace ChaosBot.Discord.Services if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) || message.HasStringPrefix(prefix, ref argPos))) { - ExperienceHandler.addXP(context); + ExperienceHandler.AddXp(context); return; } if(Convert.ToBoolean(ConfigurationRepository.GetValue("Experience:Commands", context.Guild.Id, "false"))) - ExperienceHandler.addXP(context); + ExperienceHandler.AddXp(context); await _commands.ExecuteAsync(context, argPos, _services); } diff --git a/ChaosBot/Discord/Services/ExperienceHandler.cs b/ChaosBot/Discord/Services/ExperienceHandler.cs index 99a5c82..2f890d1 100644 --- a/ChaosBot/Discord/Services/ExperienceHandler.cs +++ b/ChaosBot/Discord/Services/ExperienceHandler.cs @@ -17,7 +17,7 @@ namespace ChaosBot.Discord.Services { private static readonly ILogger _logger = Program.Logger; - public static async void addXP(SocketCommandContext context) + public static async void AddXp(SocketCommandContext context) { try { From ad0ea126e81b2aed836a484dd919295ae556654d Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 11 Aug 2020 03:28:58 +0200 Subject: [PATCH 2/6] Invert minute timeout check --- .../Discord/Services/ExperienceHandler.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ChaosBot/Discord/Services/ExperienceHandler.cs b/ChaosBot/Discord/Services/ExperienceHandler.cs index 2f890d1..89122bd 100644 --- a/ChaosBot/Discord/Services/ExperienceHandler.cs +++ b/ChaosBot/Discord/Services/ExperienceHandler.cs @@ -32,24 +32,24 @@ namespace ChaosBot.Discord.Services if (usrXp.Any()) { usrNewXp = usrXp.First(); + + // We don't want to update more than once every minute + if (DateTime.Now < usrNewXp.LastUpdated.AddMinutes(1)) return; - if(DateTime.Now >= usrNewXp.LastUpdated.AddMinutes(1)) - { - usrNewXp.Amount = usrNewXp.Amount + Convert.ToUInt64(new Random().Next(15, 26)); + usrNewXp.Amount = usrNewXp.Amount + Convert.ToUInt64(new Random().Next(15, 26)); - usrNewXp.DiscordGuildId = context.Guild.Id; - usrNewXp.DiscordUserId = context.User.Id; - usrNewXp.LastUpdated = DateTime.Now; - usrNewXp.Level = usrNewXp.Level; + usrNewXp.DiscordGuildId = context.Guild.Id; + usrNewXp.DiscordUserId = context.User.Id; + usrNewXp.LastUpdated = DateTime.Now; + usrNewXp.Level = usrNewXp.Level; - ulong newLevel = await checkLevel(usrNewXp, context); + ulong newLevel = await checkLevel(usrNewXp, context); - if(newLevel > usrNewXp.Level) - usrNewXp.Level = newLevel; + if(newLevel > usrNewXp.Level) + usrNewXp.Level = newLevel; - await dbContext.ExperiencePoints.Upsert(usrNewXp) - .On(x => new {x.DiscordGuildId, x.DiscordUserId}).RunAsync(); - } + await dbContext.ExperiencePoints.Upsert(usrNewXp) + .On(x => new {x.DiscordGuildId, x.DiscordUserId}).RunAsync(); } else { From 8bdacb53281c71b65236c955d6ef3090aeb636c0 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 11 Aug 2020 03:57:38 +0200 Subject: [PATCH 3/6] Refactor the levelup code to a more sensible order of operations --- .../Discord/Services/ExperienceHandler.cs | 126 +++++++----------- 1 file changed, 51 insertions(+), 75 deletions(-) diff --git a/ChaosBot/Discord/Services/ExperienceHandler.cs b/ChaosBot/Discord/Services/ExperienceHandler.cs index 89122bd..387b049 100644 --- a/ChaosBot/Discord/Services/ExperienceHandler.cs +++ b/ChaosBot/Discord/Services/ExperienceHandler.cs @@ -29,42 +29,47 @@ namespace ChaosBot.Discord.Services .Where(p => p.DiscordUserId.Equals(context.User.Id)); Experience usrNewXp; - if (usrXp.Any()) + + // Ensure there's an entry in the database, even if this is the first message ever sent + if (!usrXp.Any()) { - usrNewXp = usrXp.First(); - - // We don't want to update more than once every minute - if (DateTime.Now < usrNewXp.LastUpdated.AddMinutes(1)) return; - - usrNewXp.Amount = usrNewXp.Amount + Convert.ToUInt64(new Random().Next(15, 26)); - - usrNewXp.DiscordGuildId = context.Guild.Id; - usrNewXp.DiscordUserId = context.User.Id; - usrNewXp.LastUpdated = DateTime.Now; - usrNewXp.Level = usrNewXp.Level; - - ulong newLevel = await checkLevel(usrNewXp, context); - - if(newLevel > usrNewXp.Level) - usrNewXp.Level = newLevel; + usrNewXp = new Experience + { + Amount = 0, + DiscordGuildId = context.Guild.Id, + DiscordUserId = context.User.Id, + LastUpdated = DateTime.UnixEpoch, + Level = 0 + }; await dbContext.ExperiencePoints.Upsert(usrNewXp) .On(x => new {x.DiscordGuildId, x.DiscordUserId}).RunAsync(); } else { - usrNewXp = new Experience(); - usrNewXp.Amount = Convert.ToUInt64(new Random().Next(15, 26)); - - usrNewXp.DiscordGuildId = context.Guild.Id; - usrNewXp.DiscordUserId = context.User.Id; - usrNewXp.LastUpdated = DateTime.Now; - usrNewXp.Level = 1; - - await dbContext.ExperiencePoints.Upsert(usrNewXp) - .On(x => new { x.DiscordGuildId, x.DiscordUserId}).RunAsync(); - - string ConfigSet = ConfigurationRepository.GetValue("LevelUp:Channel", context.Guild.Id, "false"); + usrNewXp = usrXp.First(); + } + + // We want to throttle gaining experience + if (DateTime.Now < usrNewXp.LastUpdated.AddMinutes(1)) return; + usrNewXp.LastUpdated = DateTime.Now; + + usrNewXp.Amount += Convert.ToUInt64(new Random().Next(15, 26)); + + ulong oldLevel = usrNewXp.Level; + ulong newLevel = await CheckLevel(usrNewXp, context); + + if (newLevel > oldLevel) + usrNewXp.Level = newLevel; + + await dbContext.ExperiencePoints.Upsert(usrNewXp) + .On(x => new {x.DiscordGuildId, x.DiscordUserId}).RunAsync(); + + if (newLevel > oldLevel) + { + // The user has leveled up, we can send a message + string channelToSendIn = + ConfigurationRepository.GetValue("LevelUp:Channel", context.Guild.Id, "false"); string mentionString = $"<@{context.User.Id}>"; if (!ConfigurationRepository.GetValue("LevelUp:MentionUser", context.Guild.Id, true)) @@ -75,16 +80,20 @@ namespace ChaosBot.Discord.Services mentionString = guildUser.Nickname ?? mentionString; } } - - if (ConfigSet != "false") - { - ulong channelId = Convert.ToUInt64(ConfigSet.Substring(2, ConfigSet.Length - 3)); - await context.Guild.GetTextChannel(channelId).SendMessageAsync( - $"Grats {mentionString}! You have reached level 1 <:wot:740387232514572310>"); + ISocketMessageChannel messageChannel; + if (channelToSendIn != "false") + { + ulong channelId = Convert.ToUInt64(channelToSendIn.Substring(2, channelToSendIn.Length - 3)); + messageChannel = context.Guild.GetTextChannel(channelId); } else - await context.Channel.SendMessageAsync($"Grats {mentionString}! You have reached level 1! <:wot:740387232514572310>"); + { + messageChannel = context.Channel; + } + + await messageChannel.SendMessageAsync( + $"Grats {mentionString}! You have reached level {newLevel}! <:wot:740387232514572310>"); } } } @@ -95,47 +104,14 @@ namespace ChaosBot.Discord.Services } } - public static async Task checkLevel(Experience usrExperience, SocketCommandContext context) + public static async Task CheckLevel(Experience usrExperience, SocketCommandContext context) { - ulong curLevel = 1; - - try - { - // var nextLevelXP = 1 * usrExperience.Level * (2 * usrExperience.Level * usrExperience.Level + 27 * usrExperience.Level + 91); - var nextLevelXP = 5 * usrExperience.Level ^ 3 + 95 * usrExperience.Level; - - Console.WriteLine(nextLevelXP); - if (usrExperience.Amount > nextLevelXP) - { - curLevel = usrExperience.Level + 1; - string ConfigSet = ConfigurationRepository.GetValue("LevelUp:Channel", usrExperience.DiscordGuildId, "false"); - - string mentionString = $"<@{context.User.Id}>"; - if (!ConfigurationRepository.GetValue("LevelUp:MentionUser", context.Guild.Id, true)) - { - mentionString = context.User.Username; - if (context.User is IGuildUser guildUser) - { - mentionString = guildUser.Nickname ?? mentionString; - } - } - - if (ConfigSet != "false") - { - ulong channelId = Convert.ToUInt64(ConfigSet.Substring(2, ConfigSet.Length - 3)); - await context.Guild.GetTextChannel(channelId).SendMessageAsync( - $"Grats {mentionString}! You have reached level {curLevel} <:wot:740387232514572310>"); - } - else - await context.Channel.SendMessageAsync($"Grats {mentionString}! You have reached level {curLevel} <:wot:740387232514572310>"); - } - } - catch (Exception ex) - { - _logger.Error( - $"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>."); - } + ulong curLevel = usrExperience.Level; + ulong curXP = usrExperience.Amount; + var nextLevelXP = 5 * usrExperience.Level ^ 3 + 95 * usrExperience.Level; + if (curXP > nextLevelXP) + return curLevel + 1; return curLevel; } } From 4ed91ede81f519f1a57f449cf88bbee239e6dcd5 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 11 Aug 2020 03:58:35 +0200 Subject: [PATCH 4/6] Adjust CheckLevel signature to be a pure method --- ChaosBot/Discord/Services/ExperienceHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChaosBot/Discord/Services/ExperienceHandler.cs b/ChaosBot/Discord/Services/ExperienceHandler.cs index 387b049..d4abf42 100644 --- a/ChaosBot/Discord/Services/ExperienceHandler.cs +++ b/ChaosBot/Discord/Services/ExperienceHandler.cs @@ -57,7 +57,7 @@ namespace ChaosBot.Discord.Services usrNewXp.Amount += Convert.ToUInt64(new Random().Next(15, 26)); ulong oldLevel = usrNewXp.Level; - ulong newLevel = await CheckLevel(usrNewXp, context); + ulong newLevel = CheckLevel(usrNewXp); if (newLevel > oldLevel) usrNewXp.Level = newLevel; @@ -104,7 +104,7 @@ namespace ChaosBot.Discord.Services } } - public static async Task CheckLevel(Experience usrExperience, SocketCommandContext context) + private static ulong CheckLevel(Experience usrExperience) { ulong curLevel = usrExperience.Level; ulong curXP = usrExperience.Amount; From 23d8db2a4d0f1c3e30daa98204fa9964b5cb8ec2 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 11 Aug 2020 03:59:50 +0200 Subject: [PATCH 5/6] General type and naming scheme fixes --- ChaosBot/Discord/Services/ExperienceHandler.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ChaosBot/Discord/Services/ExperienceHandler.cs b/ChaosBot/Discord/Services/ExperienceHandler.cs index d4abf42..fb5c763 100644 --- a/ChaosBot/Discord/Services/ExperienceHandler.cs +++ b/ChaosBot/Discord/Services/ExperienceHandler.cs @@ -1,8 +1,6 @@ using System; using System.Linq; using System.Reflection; -using System.Threading.Channels; -using System.Threading.Tasks; using ChaosBot.Models; using ChaosBot.Repositories; using Discord; @@ -15,7 +13,7 @@ namespace ChaosBot.Discord.Services { public class ExperienceHandler { - private static readonly ILogger _logger = Program.Logger; + private static readonly ILogger Logger = Program.Logger; public static async void AddXp(SocketCommandContext context) { @@ -99,7 +97,7 @@ namespace ChaosBot.Discord.Services } catch (Exception ex) { - _logger.Error( + Logger.Error( $"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>."); } } @@ -108,7 +106,7 @@ namespace ChaosBot.Discord.Services { ulong curLevel = usrExperience.Level; ulong curXP = usrExperience.Amount; - var nextLevelXP = 5 * usrExperience.Level ^ 3 + 95 * usrExperience.Level; + ulong nextLevelXP = 5 * usrExperience.Level ^ 3 + 95 * usrExperience.Level; if (curXP > nextLevelXP) return curLevel + 1; From 79ff643a2e74d1664a0269581057318af5ef6ac9 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 11 Aug 2020 04:12:27 +0200 Subject: [PATCH 6/6] Fail-safe the type on the LevelUp:MentionUser tag --- ChaosBot/Discord/Services/ExperienceHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChaosBot/Discord/Services/ExperienceHandler.cs b/ChaosBot/Discord/Services/ExperienceHandler.cs index fb5c763..4e50d81 100644 --- a/ChaosBot/Discord/Services/ExperienceHandler.cs +++ b/ChaosBot/Discord/Services/ExperienceHandler.cs @@ -70,7 +70,7 @@ namespace ChaosBot.Discord.Services ConfigurationRepository.GetValue("LevelUp:Channel", context.Guild.Id, "false"); string mentionString = $"<@{context.User.Id}>"; - if (!ConfigurationRepository.GetValue("LevelUp:MentionUser", context.Guild.Id, true)) + if (!Convert.ToBoolean(ConfigurationRepository.GetValue("LevelUp:MentionUser", context.Guild.Id, "true"))) { mentionString = context.User.Username; if (context.User is IGuildUser guildUser)