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..4e50d81 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,9 +13,9 @@ 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) + public static async void AddXp(SocketCommandContext context) { try { @@ -29,45 +27,50 @@ 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(); - - if(DateTime.Now >= usrNewXp.LastUpdated.AddMinutes(1)) + usrNewXp = new Experience { - usrNewXp.Amount = usrNewXp.Amount + Convert.ToUInt64(new Random().Next(15, 26)); + Amount = 0, + DiscordGuildId = context.Guild.Id, + DiscordUserId = context.User.Id, + LastUpdated = DateTime.UnixEpoch, + Level = 0 + }; - 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; - - 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 { - 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 = CheckLevel(usrNewXp); + + 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)) + if (!Convert.ToBoolean(ConfigurationRepository.GetValue("LevelUp:MentionUser", context.Guild.Id, "true"))) { mentionString = context.User.Username; if (context.User is IGuildUser guildUser) @@ -75,67 +78,38 @@ 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>"); } } } catch (Exception ex) { - _logger.Error( + Logger.Error( $"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>."); } } - public static async Task checkLevel(Experience usrExperience, SocketCommandContext context) + private static ulong CheckLevel(Experience usrExperience) { - 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; + ulong nextLevelXP = 5 * usrExperience.Level ^ 3 + 95 * usrExperience.Level; + if (curXP > nextLevelXP) + return curLevel + 1; return curLevel; } }