From 7b4967f1cab0cdd1efc71f9192c0a79fa9e3d4b8 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 29 Jan 2019 14:28:47 +0100 Subject: [PATCH] Added system to give/take points from users per server, added new joke controller that removes points from users if they say owo, uwu, etc --- DeukBot4/Database/BirthdayHandler.cs | 6 +- DeukBot4/Database/PointHandler.cs | 58 +++++++++ .../Commands/GeneralCommands.cs | 23 ++++ .../JokeHandling/OwoHandler.cs | 33 +++++ DeukBot4/MessageHandlers/MainHandler.cs | 1 + .../MessageHandlers/PointsMessageHandler.cs | 117 ++++++++++++++++++ 6 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 DeukBot4/Database/PointHandler.cs create mode 100644 DeukBot4/MessageHandlers/JokeHandling/OwoHandler.cs create mode 100644 DeukBot4/MessageHandlers/PointsMessageHandler.cs diff --git a/DeukBot4/Database/BirthdayHandler.cs b/DeukBot4/Database/BirthdayHandler.cs index bab5772..1a36155 100644 --- a/DeukBot4/Database/BirthdayHandler.cs +++ b/DeukBot4/Database/BirthdayHandler.cs @@ -19,7 +19,11 @@ namespace DeukBot4.Database DateTime bday = DateTime.MinValue; foreach (var bdayEntry in bdayEntries) { - if (bdayEntry.Name == "birthday") bday = DateTime.FromBinary(long.Parse(bdayEntry.Value)); + if (bdayEntry.Name == "birthday") + { + bday = DateTime.FromBinary(long.Parse(bdayEntry.Value)); + break; + } } return bday; } diff --git a/DeukBot4/Database/PointHandler.cs b/DeukBot4/Database/PointHandler.cs new file mode 100644 index 0000000..ccacc3c --- /dev/null +++ b/DeukBot4/Database/PointHandler.cs @@ -0,0 +1,58 @@ +using System; +using System.Threading.Tasks; +using StackExchange.Redis; + +namespace DeukBot4.Database +{ + public static class PointHandler + { + public static async Task GetPoints(ulong serverId, ulong userId) + { + var key = $"{serverId:D}-{userId:D}"; + try + { + var db = ReminderHandler.Redis.GetDatabase(); + var exists = db.HashGet("points", (RedisValue) key); + if (!exists.HasValue) + { + return 0; + } + var points = long.Parse(exists); + return points; + } + catch ( Exception e) + { + Logger.Main.LogError(e); + return null; + } + } + + public static async Task ChangePoints(ulong serverId, ulong userId, long deltaPoints) + { + var key = $"{serverId:D}-{userId:D}"; + try + { + var db = ReminderHandler.Redis.GetDatabase(); + var exists = db.HashGet("points", (RedisValue) key); + if (!exists.HasValue) + { + db.HashSet("points", (RedisValue) key, deltaPoints); + return deltaPoints; + } + + var points = long.Parse(exists); + + points += deltaPoints; + if (points < -100) + points = -100; + db.HashSet("points", (RedisValue) key, points); + return points; + } + catch ( Exception e) + { + Logger.Main.LogError(e); + return null; + } + } + } +} \ No newline at end of file diff --git a/DeukBot4/MessageHandlers/CommandHandler/Commands/GeneralCommands.cs b/DeukBot4/MessageHandlers/CommandHandler/Commands/GeneralCommands.cs index 17d13c2..00943e3 100644 --- a/DeukBot4/MessageHandlers/CommandHandler/Commands/GeneralCommands.cs +++ b/DeukBot4/MessageHandlers/CommandHandler/Commands/GeneralCommands.cs @@ -321,5 +321,28 @@ namespace DeukBot4.MessageHandlers.CommandHandler } request.SendSimpleEmbed("Hug!", message); } + + [Command("points", PermissionLevel.Everyone)] + [CommandParameters(ParameterMatcher.ParameterType.User)] + [BlockUsageInPm] + public async Task GetPoints(CommandRequest request) + { + if (!(request.OriginalMessage.Channel is IGuildChannel guildChannel)) + return; + + var user = (IGuildUser) request.OriginalMessage.Author; + if (request.Parameters.Length > 0) + { + var u = await request.Parameters[0].AsDiscordGuildUser(guildChannel.Guild); + if (u != null) + user = u; + } + + var points = await PointHandler.GetPoints(guildChannel.GuildId, user.Id); + if (points.HasValue) + { + request.SendSimpleEmbed("Points", $"You currently have {points.Value} points."); + } + } } } \ No newline at end of file diff --git a/DeukBot4/MessageHandlers/JokeHandling/OwoHandler.cs b/DeukBot4/MessageHandlers/JokeHandling/OwoHandler.cs new file mode 100644 index 0000000..7a4d1a1 --- /dev/null +++ b/DeukBot4/MessageHandlers/JokeHandling/OwoHandler.cs @@ -0,0 +1,33 @@ +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using DeukBot4.Database; +using DeukBot4.MessageHandlers.CommandHandler; +using Discord; +using Discord.WebSocket; + +namespace DeukBot4.MessageHandlers.JokeHandling +{ + public class OwoHandler : IJokeController + { + public string Id => "owo-warn"; + public string Name => "Owo Warnings"; + + private static readonly Regex Matcher = new Regex(@"(?:^|\s).w.(?:\s|$)", RegexOptions.IgnoreCase); + + public async Task Run(SocketMessage message) + { + if (!(message.Channel is IGuildChannel serverChannel)) + return; + + if (!Matcher.Match(message.Content).Success) + return; + + var changePoints = await PointHandler.ChangePoints(serverChannel.GuildId, message.Author.Id, -100); + var embed = EmbedFactory.GetStandardEmbedBuilder(); + embed.Title = "No Owoing"; + embed.Description = + $"{message.Author.Mention}, you were fined by -100 points. Your new score is {changePoints}."; + message.Channel.SendMessageAsync("", embed: embed.Build()); + } + } +} \ No newline at end of file diff --git a/DeukBot4/MessageHandlers/MainHandler.cs b/DeukBot4/MessageHandlers/MainHandler.cs index dd12016..1c8b149 100644 --- a/DeukBot4/MessageHandlers/MainHandler.cs +++ b/DeukBot4/MessageHandlers/MainHandler.cs @@ -24,6 +24,7 @@ namespace DeukBot4.MessageHandlers ReminderHandler.HandleReminder(message); ImageBackupHandler.Backup(message); JokeHandler.RunJokes(message); + PointsMessageHandler.HandleMessage(message); #pragma warning restore 4014 } catch (Exception e) diff --git a/DeukBot4/MessageHandlers/PointsMessageHandler.cs b/DeukBot4/MessageHandlers/PointsMessageHandler.cs new file mode 100644 index 0000000..71468f6 --- /dev/null +++ b/DeukBot4/MessageHandlers/PointsMessageHandler.cs @@ -0,0 +1,117 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using DeukBot4.Database; +using DeukBot4.MessageHandlers.CommandHandler; +using DeukBot4.MessageHandlers.Permissions; +using Discord; +using Discord.WebSocket; + +namespace DeukBot4.MessageHandlers +{ + public static class PointsMessageHandler + { + private static readonly Regex Matcher = + new Regex(@"(?'amount'-?\d+) *points? *(?'unary'to|from) *(?:<@!*(?'id'\d+)>|(?'username'\w+))", RegexOptions.IgnoreCase); + + private static long MaxPoints(PermissionLevel level) + { + switch (level) + { + case PermissionLevel.Banned: + case PermissionLevel.Bot: + case PermissionLevel.Everyone: + return 0; + case PermissionLevel.Helper: + return 10; + case PermissionLevel.Moderator: + return 50; + case PermissionLevel.Admin: + return 100; + case PermissionLevel.ServerOwner: + return 1000; + case PermissionLevel.BotCreator: + return long.MaxValue; + default: + throw new ArgumentOutOfRangeException(nameof(level), level, null); + } + } + + public static async Task HandleMessage(SocketMessage message) + { + if (!(message.Channel is IGuildChannel serverChannel)) + return; + + var permission = await PermissionValidator.GetUserPermissionLevel(message); + if (permission < PermissionLevel.Helper) + return; + + var match = Matcher.Match(message.Content); + if (!match.Success) + return; + var points = long.Parse(match.Groups["amount"].Value); + + var embed = EmbedFactory.GetStandardEmbedBuilder(); + embed.Title = "Points"; + + var maxPoints = MaxPoints(permission); + if (points > maxPoints) + { + embed.Description = $"You're not allowed to give that many points. Your max is {maxPoints}"; + message.Channel.SendMessageAsync("", embed: embed.Build()); + return; + } + + var unary = match.Groups["unary"].Value; + if (string.Equals(unary, "from")) + points = -points; + if (points == 0) + return; + IGuildUser user; + if (match.Groups["id"].Success) + { + var userId = ulong.Parse(match.Groups["id"].Value); + user = await serverChannel.Guild.GetUserAsync(userId); + } + else if (match.Groups["username"].Success) + { + var username = match.Groups["username"].Value; + var users = await serverChannel.Guild.GetUsersAsync(); + user = users.FirstOrDefault(x => + string.Equals(x.Username, username, StringComparison.InvariantCultureIgnoreCase)); + } + else + { + Logger.Main.LogError("Neither id nor username set"); + return; + } + + if (user == null) + { + embed.Description = "Can't find that user"; + message.Channel.SendMessageAsync("", embed: embed.Build()); + return; + } + + if (user.Id == message.Author.Id) + { + embed.Description = $"You're not allowed to give yourself points."; + message.Channel.SendMessageAsync("", embed: embed.Build()); + return; + } + + + var newPoints = await PointHandler.ChangePoints(serverChannel.GuildId, user.Id, points); + if (!newPoints.HasValue) + { + Logger.Main.LogError("Error"); + return; + } + embed.Description = points < 0 + ? $"{-points} points from {user.Mention}! Their total points is now {newPoints}!" + : $"{points} points to {user.Mention}! Their total points is now {newPoints}!"; + message.Channel.SendMessageAsync("", embed: embed.Build()); + } + } +} \ No newline at end of file