118 lines
4.7 KiB
C#
118 lines
4.7 KiB
C#
using System;
|
|
using System.Linq;
|
|
using ChaosBot.Discord.PreConditions;
|
|
using ChaosBot.Models;
|
|
using Discord;
|
|
using Discord.Commands;
|
|
using Discord.WebSocket;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Configuration = ChaosBot.ConfigHelpers.Configuration;
|
|
|
|
namespace ChaosBot.Discord.Services
|
|
{
|
|
public class ExperienceHandler
|
|
{
|
|
public static async void AddXp(SocketCommandContext context)
|
|
{
|
|
try
|
|
{
|
|
if (!CheckModuleEnabled.GetResult(context, "Experience")) return;
|
|
|
|
using (ChaosbotContext dbContext = new ChaosbotContext())
|
|
{
|
|
IQueryable<Experience> ctxUser = dbContext.ExperiencePoints;
|
|
IQueryable<Experience> usrXp = ctxUser
|
|
.Where(p => p.DiscordGuildId.Equals(context.Guild.Id))
|
|
.Where(p => p.DiscordUserId.Equals(context.User.Id));
|
|
|
|
Experience usrNewXp;
|
|
|
|
// Ensure there's an entry in the database, even if this is the first message ever sent
|
|
if (!usrXp.Any())
|
|
{
|
|
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 = 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
|
|
LoggingFacade.Info($"User leveled up [{context.User.Username}#{context.User.Discriminator} -> Level {newLevel}]");
|
|
Configuration config = new Configuration();
|
|
|
|
string channelToSendIn =
|
|
config.GetByKey<string>("LevelUp:Channel").GetValue(null, context.Guild.Id);
|
|
|
|
string mentionString = $"<@{context.User.Id}>";
|
|
if (!config.GetByKey<bool>("LevelUp:MentionUser").GetValue(context.Guild.Id))
|
|
{
|
|
mentionString = context.User.Username;
|
|
if (context.User is IGuildUser guildUser)
|
|
{
|
|
mentionString = guildUser.Nickname ?? mentionString;
|
|
}
|
|
}
|
|
|
|
ISocketMessageChannel messageChannel;
|
|
if (channelToSendIn != "false")
|
|
{
|
|
ulong channelId = Convert.ToUInt64(channelToSendIn.Substring(2, channelToSendIn.Length - 3));
|
|
messageChannel = context.Guild.GetTextChannel(channelId);
|
|
}
|
|
else
|
|
{
|
|
messageChannel = context.Channel;
|
|
}
|
|
|
|
await messageChannel.SendMessageAsync(
|
|
$"Grats {mentionString}! You have reached level {newLevel}! <:wot:740387232514572310>");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LoggingFacade.Exception(ex);
|
|
}
|
|
}
|
|
|
|
private static ulong CheckLevel(Experience usrExperience)
|
|
{
|
|
ulong curLevel = usrExperience.Level;
|
|
ulong curXp = usrExperience.Amount;
|
|
ulong nextLevelXp = 5 * curLevel * curLevel * curLevel + 95 * curLevel;
|
|
|
|
if (curXp > nextLevelXp)
|
|
return curLevel + 1;
|
|
return curLevel;
|
|
}
|
|
}
|
|
}
|