From 509cce362b240b23767c9464ba868bb00c4d9491 Mon Sep 17 00:00:00 2001 From: InFTord Date: Sun, 2 Jul 2023 00:38:40 +0500 Subject: [PATCH] refactoring :3 --- UPBot Code/Actions/DiscordStatus.cs | 60 ----- UPBot Code/Config.cs | 230 ----------------- UPBot.csproj | 19 -- UPBot.sln | 2 +- {UPBot Code => src}/Actions/CheckSpam.cs | 6 +- src/Actions/DiscordStatus.cs | 60 +++++ .../Actions/MembersTracking.cs | 15 +- {UPBot Code => src}/Commands/Delete.cs | 1 + {UPBot Code => src}/Commands/Game.cs | 86 +++--- {UPBot Code => src}/Commands/Logs.cs | 13 +- {UPBot Code => src}/Commands/Ping.cs | 129 +++++---- {UPBot Code => src}/Commands/Refactor.cs | 244 +++++++++--------- {UPBot Code => src}/Commands/Setup.cs | 94 +++---- {UPBot Code => src}/Commands/Stats.cs | 22 +- {UPBot Code => src}/Commands/Tag.cs | 30 +-- {UPBot Code => src}/Commands/Timezone.cs | 4 +- {UPBot Code => src}/Commands/UnityDocs.cs | 1 + {UPBot Code => src}/Commands/Version.cs | 1 + {UPBot Code => src}/Commands/WhoIs.cs | 16 +- src/Config.cs | 232 +++++++++++++++++ {UPBot Code => src}/DataClasses/AdminRole.cs | 0 {UPBot Code => src}/DataClasses/Entity.cs | 4 +- .../DataClasses/ExampleEntity.cs | 4 +- {UPBot Code => src}/DataClasses/SpamLink.cs | 0 .../DataClasses/SpamProtection.cs | 4 +- {UPBot Code => src}/DataClasses/TagBase.cs | 0 {UPBot Code => src}/DataClasses/Timezone.cs | 5 +- .../DataClasses/TrackChannel.cs | 4 +- {UPBot Code => src}/Database.cs | 149 ++++++----- {UPBot Code => src}/Program.cs | 8 +- {UPBot Code => src}/StringDistance.cs | 49 ++-- {UPBot Code => src}/Utils.cs | 33 +-- 32 files changed, 777 insertions(+), 748 deletions(-) delete mode 100644 UPBot Code/Actions/DiscordStatus.cs delete mode 100644 UPBot Code/Config.cs delete mode 100644 UPBot.csproj rename {UPBot Code => src}/Actions/CheckSpam.cs (98%) create mode 100644 src/Actions/DiscordStatus.cs rename {UPBot Code => src}/Actions/MembersTracking.cs (91%) rename {UPBot Code => src}/Commands/Delete.cs (99%) rename {UPBot Code => src}/Commands/Game.cs (86%) rename {UPBot Code => src}/Commands/Logs.cs (89%) rename {UPBot Code => src}/Commands/Ping.cs (66%) rename {UPBot Code => src}/Commands/Refactor.cs (65%) rename {UPBot Code => src}/Commands/Setup.cs (87%) rename {UPBot Code => src}/Commands/Stats.cs (93%) rename {UPBot Code => src}/Commands/Tag.cs (96%) rename {UPBot Code => src}/Commands/Timezone.cs (99%) rename {UPBot Code => src}/Commands/UnityDocs.cs (99%) rename {UPBot Code => src}/Commands/Version.cs (97%) rename {UPBot Code => src}/Commands/WhoIs.cs (92%) create mode 100644 src/Config.cs rename {UPBot Code => src}/DataClasses/AdminRole.cs (100%) rename {UPBot Code => src}/DataClasses/Entity.cs (87%) rename {UPBot Code => src}/DataClasses/ExampleEntity.cs (73%) rename {UPBot Code => src}/DataClasses/SpamLink.cs (100%) rename {UPBot Code => src}/DataClasses/SpamProtection.cs (74%) rename {UPBot Code => src}/DataClasses/TagBase.cs (100%) rename {UPBot Code => src}/DataClasses/Timezone.cs (74%) rename {UPBot Code => src}/DataClasses/TrackChannel.cs (90%) rename {UPBot Code => src}/Database.cs (78%) rename {UPBot Code => src}/Program.cs (97%) rename {UPBot Code => src}/StringDistance.cs (84%) rename {UPBot Code => src}/Utils.cs (95%) diff --git a/UPBot Code/Actions/DiscordStatus.cs b/UPBot Code/Actions/DiscordStatus.cs deleted file mode 100644 index 750d3d3..0000000 --- a/UPBot Code/Actions/DiscordStatus.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using DSharpPlus; -using DSharpPlus.Entities; - -/// -/// Choosing Custom Status for bot! ("Playing CS:GO!") -/// author: J0nathan550 -/// - -namespace UPBot.DiscordRPC { - public class DiscordStatus { - struct ActivityStatus { - public string status; - public ActivityType type; - } - - async static void DiscordUpdateStatusFunction(DiscordClient client, CancellationToken token) { - List activityStatusString = new() { - new() { type = ActivityType.Playing, status = "Visual Studio to code algorithms!" }, - new() { type = ActivityType.Playing, status = "a random game" }, - new() { type = ActivityType.Playing, status = "happily with my toys" }, - new() { type = ActivityType.Streaming, status = "the whole life" }, - new() { type = ActivityType.Streaming, status = "a bunch of solution" }, - new() { type = ActivityType.Streaming, status = "programming tutorials" }, - new() { type = ActivityType.Streaming, status = "some lights in the channels" }, - new() { type = ActivityType.ListeningTo, status = "Ode to Joy" }, - new() { type = ActivityType.ListeningTo, status = "your complaints" }, - new() { type = ActivityType.ListeningTo, status = "sounds in my head" }, - new() { type = ActivityType.ListeningTo, status = "the falling rain" }, - new() { type = ActivityType.Watching, status = "you!" }, - new() { type = ActivityType.Watching, status = "all users" }, - new() { type = ActivityType.Watching, status = "for nitro fakes" }, - new() { type = ActivityType.Watching, status = "to reformat code" }, - new() { type = ActivityType.Watching, status = "water boil" }, - new() { type = ActivityType.Watching, status = "grass grow" }, - new() { type = ActivityType.Competing, status = "with other bots" }, - new() { type = ActivityType.Competing, status = "performance review" }, - new() { type = ActivityType.Competing, status = "performance optimization" } - }; - - Random random = new(); - while (!token.IsCancellationRequested) { - int activity = random.Next(0, activityStatusString.Count); - ActivityStatus activityStatus = activityStatusString[activity]; - - await client.UpdateStatusAsync(new DiscordActivity(activityStatus.status, activityStatus.type)); - - await Task.Delay(TimeSpan.FromSeconds(60 + random.Next(0, 180)), token); - } - } - - internal static void Start(DiscordClient client) { - Task statusUpdateTask = new(() => DiscordUpdateStatusFunction(client, new CancellationToken())); - statusUpdateTask.Start(); - } - } -} diff --git a/UPBot Code/Config.cs b/UPBot Code/Config.cs deleted file mode 100644 index af1f3e3..0000000 --- a/UPBot Code/Config.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using DSharpPlus.Entities; -using DSharpPlus.EventArgs; - -namespace UPBot { - public class TempSetRole { - public DiscordRole role; - public CancellationTokenSource cancel; - public ulong user; - internal ulong channel; - internal ulong message; - internal ulong emojiid; - internal string emojiname; - - public TempSetRole(ulong usr, DiscordRole r) { - user = usr; - role = r; - cancel = new CancellationTokenSource(); - channel = 0; - message = 0; - emojiid = 0; - emojiname = null; - } - } - - /// - /// This command is used to configure the bot, so roles and messages can be set for other servers. - /// author: CPU - /// - public class Configs { - readonly private static Dictionary Guilds = new(); - readonly public static Dictionary TrackChannels = new(); - readonly public static Dictionary> AdminRoles = new(); - readonly public static Dictionary SpamProtections = new(); - readonly public static Dictionary> Tags = new(); - readonly public static Dictionary> SpamLinks = new(); - readonly public static Dictionary> WhiteListLinks = new(); - - readonly public static Dictionary TempRoleSelected = new(); - - public readonly static Regex emjSnowflakeRE = new(@"<:[a-z0-9_]+:([0-9]+)>", RegexOptions.IgnoreCase | RegexOptions.Compiled); - public readonly static Regex roleSnowflakeRR = new("<@[^0-9]+([0-9]*)>", RegexOptions.Compiled); - public readonly static Regex emjUnicodeRE = new(@"[#*0-9]\uFE0F?\u20E3|©\uFE0F?|[®\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA]\uFE0F?|[\u231A\u231B]|[\u2328\u23CF]\uFE0F?|[\u23E9-\u23EC]|[\u23ED-\u23EF]\uFE0F?|\u23F0|[\u23F1\u23F2]\uFE0F?|\u23F3|[\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC]\uFE0F?|[\u25FD\u25FE]|[\u2600-\u2604\u260E\u2611]\uFE0F?|[\u2614\u2615]|\u2618\uFE0F?|\u261D(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642]\uFE0F?|[\u2648-\u2653]|[\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E]\uFE0F?|\u267F|\u2692\uFE0F?|\u2693|[\u2694-\u2697\u2699\u269B\u269C\u26A0]\uFE0F?|\u26A1|\u26A7\uFE0F?|[\u26AA\u26AB]|[\u26B0\u26B1]\uFE0F?|[\u26BD\u26BE\u26C4\u26C5]|\u26C8\uFE0F?|\u26CE|[\u26CF\u26D1\u26D3]\uFE0F?|\u26D4|\u26E9\uFE0F?|\u26EA|[\u26F0\u26F1]\uFE0F?|[\u26F2\u26F3]|\u26F4\uFE0F?|\u26F5|[\u26F7\u26F8]\uFE0F?|\u26F9(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\uFE0F(?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\u26FA\u26FD]|\u2702\uFE0F?|\u2705|[\u2708\u2709]\uFE0F?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|\u270F\uFE0F?|[\u2712\u2714\u2716\u271D\u2721]\uFE0F?|\u2728|[\u2733\u2734\u2744\u2747]\uFE0F?|[\u274C\u274E\u2753-\u2755\u2757]|\u2763\uFE0F?|\u2764(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uFE0F(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?)?|[\u2795-\u2797]|\u27A1\uFE0F?|[\u27B0\u27BF]|[\u2934\u2935\u2B05-\u2B07]\uFE0F?|[\u2B1B\u2B1C\u2B50\u2B55]|[\u3030\u303D\u3297\u3299]\uFE0F?|\uD83C(?:[\uDC04\uDCCF]|[\uDD70\uDD71\uDD7E\uDD7F]\uFE0F?|[\uDD8E\uDD91-\uDD9A]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDE01|\uDE02\uFE0F?|[\uDE1A\uDE2F\uDE32-\uDE36]|\uDE37\uFE0F?|[\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20]|[\uDF21\uDF24-\uDF2C]\uFE0F?|[\uDF2D-\uDF35]|\uDF36\uFE0F?|[\uDF37-\uDF7C]|\uDF7D\uFE0F?|[\uDF7E-\uDF84]|\uDF85(?:\uD83C[\uDFFB-\uDFFF])?|[\uDF86-\uDF93]|[\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F]\uFE0F?|[\uDFA0-\uDFC1]|\uDFC2(?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC3\uDFC4](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDFC5\uDFC6]|\uDFC7(?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC8\uDFC9]|\uDFCA(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDFCB\uDFCC](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\uFE0F(?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDFCD\uDFCE]\uFE0F?|[\uDFCF-\uDFD3]|[\uDFD4-\uDFDF]\uFE0F?|[\uDFE0-\uDFF0]|\uDFF3(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08)|\uFE0F(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?)?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?|[\uDFF5\uDFF7]\uFE0F?|[\uDFF8-\uDFFF])|\uD83D(?:[\uDC00-\uDC07]|\uDC08(?:\u200D\u2B1B)?|[\uDC09-\uDC14]|\uDC15(?:\u200D\uD83E\uDDBA)?|[\uDC16-\uDC3A]|\uDC3B(?:\u200D\u2744\uFE0F?)?|[\uDC3C-\uDC3E]|\uDC3F\uFE0F?|\uDC40|\uDC41(?:\u200D\uD83D\uDDE8\uFE0F?|\uFE0F(?:\u200D\uD83D\uDDE8\uFE0F?)?)?|[\uDC42\uDC43](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC44\uDC45]|[\uDC46-\uDC50](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC51-\uDC65]|[\uDC66\uDC67](?:\uD83C[\uDFFB-\uDFFF])?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|\uDC6A|[\uDC6B-\uDC6D](?:\uD83C[\uDFFB-\uDFFF])?|\uDC6E(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDC70\uDC71](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC72(?:\uD83C[\uDFFB-\uDFFF])?|\uDC73(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDC74-\uDC76](?:\uD83C[\uDFFB-\uDFFF])?|\uDC77(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC78(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC79-\uDC7B]|\uDC7C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC7D-\uDC80]|[\uDC81\uDC82](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC83(?:\uD83C[\uDFFB-\uDFFF])?|\uDC84|\uDC85(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC86\uDC87](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDC88-\uDC8E]|\uDC8F(?:\uD83C[\uDFFB-\uDFFF])?|\uDC90|\uDC91(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC92-\uDCA9]|\uDCAA(?:\uD83C[\uDFFB-\uDFFF])?|[\uDCAB-\uDCFC]|\uDCFD\uFE0F?|[\uDCFF-\uDD3D]|[\uDD49\uDD4A]\uFE0F?|[\uDD4B-\uDD4E\uDD50-\uDD67]|[\uDD6F\uDD70\uDD73]\uFE0F?|\uDD74(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|\uDD75(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\uFE0F(?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDD76-\uDD79]\uFE0F?|\uDD7A(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD87\uDD8A-\uDD8D]\uFE0F?|\uDD90(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDD95\uDD96](?:\uD83C[\uDFFB-\uDFFF])?|\uDDA4|[\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA]\uFE0F?|[\uDDFB-\uDE2D]|\uDE2E(?:\u200D\uD83D\uDCA8)?|[\uDE2F-\uDE34]|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|[\uDE37-\uDE44]|[\uDE45-\uDE47](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDE48-\uDE4A]|\uDE4B(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDE4C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDE4D\uDE4E](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDE4F(?:\uD83C[\uDFFB-\uDFFF])?|[\uDE80-\uDEA2]|\uDEA3(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDEA4-\uDEB3]|[\uDEB4-\uDEB6](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDEB7-\uDEBF]|\uDEC0(?:\uD83C[\uDFFB-\uDFFF])?|[\uDEC1-\uDEC5]|\uDECB\uFE0F?|\uDECC(?:\uD83C[\uDFFB-\uDFFF])?|[\uDECD-\uDECF]\uFE0F?|[\uDED0-\uDED2\uDED5-\uDED7]|[\uDEE0-\uDEE5\uDEE9]\uFE0F?|[\uDEEB\uDEEC]|[\uDEF0\uDEF3]\uFE0F?|[\uDEF4-\uDEFC\uDFE0-\uDFEB])|\uD83E(?:\uDD0C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD0D\uDD0E]|\uDD0F(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD10-\uDD17]|[\uDD18-\uDD1C](?:\uD83C[\uDFFB-\uDFFF])?|\uDD1D|[\uDD1E\uDD1F](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD20-\uDD25]|\uDD26(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDD27-\uDD2F]|[\uDD30-\uDD34](?:\uD83C[\uDFFB-\uDFFF])?|\uDD35(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDD36(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD37-\uDD39](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDD3A|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD3D\uDD3E](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDD3F-\uDD45\uDD47-\uDD76]|\uDD77(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD78\uDD7A-\uDDB4]|[\uDDB5\uDDB6](?:\uD83C[\uDFFB-\uDFFF])?|\uDDB7|[\uDDB8\uDDB9](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDDBA|\uDDBB(?:\uD83C[\uDFFB-\uDFFF])?|[\uDDBC-\uDDCB]|[\uDDCD-\uDDCF](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDDD0|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1|[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|[\uDDD2\uDDD3](?:\uD83C[\uDFFB-\uDFFF])?|\uDDD4(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDDD5(?:\uD83C[\uDFFB-\uDFFF])?|[\uDDD6-\uDDDD](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])", RegexOptions.Compiled); - public readonly static Regex chnnelRefRE = new(@"<#([0-9]+)>", RegexOptions.Compiled); - public readonly static Regex iconURLRE = new(@"http[s]{0,1}://[^\.\s]+\.[^\.\s]+\.[^\.\s]+/[^\.\s]+\.[^\s]+", RegexOptions.Compiled); - - private static ulong botId; - public static ulong BotId { get { return botId; } } - - internal static void LoadParams() { - try { - foreach (var g in Utils.GetClient().Guilds.Values) { - Guilds[g.Id] = g; - } - - // Admin Roles - List allAdminRoles = Database.GetAll(); - if (allAdminRoles != null) { - foreach (var r in allAdminRoles) { - ulong gid = r.Guild; - if (!AdminRoles.ContainsKey(gid)) AdminRoles[gid] = new List(); - AdminRoles[gid].Add(r.Role); - } - } - - // Tracking channels - List allTrackChannels = Database.GetAll(); - if (allTrackChannels != null) { - foreach (var r in allTrackChannels) { - TrackChannels[r.Guild] = r; - if (!Guilds.ContainsKey(r.Guild) && TryGetGuild(r.Guild) == null) continue; // Guild is missing - DiscordChannel ch = Guilds[r.Guild].GetChannel(r.ChannelId); - if (ch == null) { - Utils.Log("Missing track channel id " + r.ChannelId + " from Guild " + Guilds[r.Guild].Name, Guilds[r.Guild].Name); - TrackChannels[r.Guild] = null; - } - else { - r.channel = ch; - } - } - } - - // Tags - List allTags = Database.GetAll(); - if (allTags != null) { - foreach (var t in allTags) { - ulong gid = t.Guild; - if (!Tags.ContainsKey(gid)) Tags[gid] = new List(); - Tags[gid].Add(t); - } - } - - // SpamProtection - List spamProtections = Database.GetAll(); - if (spamProtections != null) { - foreach (var sp in spamProtections) { - SpamProtections[sp.Guild] = sp; - } - } - List links = Database.GetAll(); - if (links != null) { - foreach (var sl in links) { - if (sl.whitelist) { - if (!WhiteListLinks.ContainsKey(sl.Guild)) WhiteListLinks[sl.Guild] = new List(); - WhiteListLinks[sl.Guild].Add(sl.link); - } - else { - if (!SpamLinks.ContainsKey(sl.Guild)) SpamLinks[sl.Guild] = new List(); - SpamLinks[sl.Guild].Add(sl.link); - } - } - } - - // Fill all missing guilds - foreach (var g in Guilds.Keys) { - if (!TrackChannels.ContainsKey(g)) TrackChannels[g] = null; - if (!AdminRoles.ContainsKey(g)) AdminRoles[g] = new List(); - if (!SpamProtections.ContainsKey(g)) SpamProtections[g] = null; - if (!Tags.ContainsKey(g)) Tags[g] = new List(); - if (!TempRoleSelected.ContainsKey(g)) TempRoleSelected[g] = null; - if (!SpamLinks.ContainsKey(g)) SpamLinks[g] = new List(); - if (!WhiteListLinks.ContainsKey(g)) WhiteListLinks[g] = new List(); - } - - - botId = Utils.GetClient().CurrentUser.Id; - - Utils.Log("Params fully loaded. " + SpamProtections.Count + " Discord servers found", null); - } catch (Exception ex) { - Utils.Log("Error in ConfigLoadParams:" + ex.Message, null); - } - } - - - public static DiscordGuild TryGetGuild(ulong id) { - if (Guilds.ContainsKey(id)) return Guilds[id]; - - Task.Delay(1000); - int t = 0; - - // 10 secs max for client - while (Utils.GetClient() == null) { - t++; Task.Delay(t); - if (t > 10) { - Utils.Log("We are not connecting! (no client)", null); - throw new Exception("No discord client"); - } - } - - // 10 secs max for guilds - t = 0; - while (Utils.GetClient().Guilds == null) { - t++; Task.Delay(t); - if (t > 10) { - Utils.Log("We are not connecting! (no guilds)", null); - throw new Exception("No guilds avilable"); - } - } - - // 30 secs max for guilds coubnt - t = 0; - while (Utils.GetClient().Guilds.Count == 0) { - t++; Task.Delay(t); - if (t > 30) { - Utils.Log("We are not connecting! (guilds count is zero)", null); - throw new Exception("The bot seems to be in no guild"); - } - } - - IReadOnlyDictionary cguilds = Utils.GetClient().Guilds; - foreach (var guildId in cguilds.Keys) { - if (!Guilds.ContainsKey(guildId)) Guilds[guildId] = cguilds[guildId]; - } - if (Guilds.ContainsKey(id)) return Guilds[id]; - - return null; - } - - - - internal static Task NewGuildAdded(DSharpPlus.DiscordClient _, GuildCreateEventArgs e) { - DiscordGuild g = e.Guild; - ulong gid = g.Id; - // Do we have the guild? - if (TryGetGuild(gid) == null) { // No, that is a problem. - Utils.Log("Impossible to connect to a new Guild: " + g.Name, null); - return Task.FromResult(0); - } - // Fill all values - TrackChannels[gid] = null; - AdminRoles[gid] = new List(); - SpamProtections[gid] = null; - Tags[gid] = new List(); - TempRoleSelected[gid] = null; - Utils.Log("Guild " + g.Name + " joined", g.Name); - Utils.Log("Guild " + g.Name + " joined", null); - - return Task.FromResult(0); - } - - internal static bool IsAdminRole(ulong guild, DiscordRole role) { - if (AdminRoles[guild].Contains(role.Id)) return true; - return (role.Permissions.HasFlag(DSharpPlus.Permissions.Administrator)); // Fall back - } - internal static bool HasAdminRole(ulong guild, IEnumerable roles, bool withManageMessages) { - if (AdminRoles[guild] == null || AdminRoles[guild].Count == 0) return true; - foreach (var r in roles) - if (AdminRoles[guild].Contains(r.Id)) return true; - foreach (var r in roles) - if (r.Permissions.HasFlag(DSharpPlus.Permissions.Administrator) || (withManageMessages && r.Permissions.HasFlag(DSharpPlus.Permissions.ManageMessages))) return true; - return false; - } - - internal static string GetAdminsMentions(ulong gid) { - if (!AdminRoles.ContainsKey(gid) || AdminRoles[gid].Count == 0) return "Admins"; - string res = ""; - foreach (var rid in AdminRoles[gid]) { - DiscordRole r = Guilds[gid].GetRole(rid); - if (r != null) res += r.Mention + " "; - } - if (res.Length > 0) return res[0..^1]; - return "Admins"; - } - - } -} \ No newline at end of file diff --git a/UPBot.csproj b/UPBot.csproj deleted file mode 100644 index 44a35ba..0000000 --- a/UPBot.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - Exe - net6.0 - true - - - - - - - - - - - - - diff --git a/UPBot.sln b/UPBot.sln index 81d6007..d0b4925 100644 --- a/UPBot.sln +++ b/UPBot.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31424.327 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UPBot", "UPBot.csproj", "{BC7DB5DA-E2FA-4F77-8A9C-A5451977B14E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UPBot", "src/UPBot.csproj", "{BC7DB5DA-E2FA-4F77-8A9C-A5451977B14E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/UPBot Code/Actions/CheckSpam.cs b/src/Actions/CheckSpam.cs similarity index 98% rename from UPBot Code/Actions/CheckSpam.cs rename to src/Actions/CheckSpam.cs index 14a9747..36af0aa 100644 --- a/UPBot Code/Actions/CheckSpam.cs +++ b/src/Actions/CheckSpam.cs @@ -4,14 +4,16 @@ using System.Text.RegularExpressions; using DSharpPlus; using DSharpPlus.EventArgs; +using UPBot.UPBot_Code; + /// /// Command used to check for false nitro links and spam links /// author: CPU /// namespace UPBot { public class CheckSpam { - readonly static Regex linkRE = new(@"http[s]?://([^/]+)/"); - readonly static Regex wwwRE = new(@"^w[^\.]{0,3}.\."); + static readonly Regex linkRE = new(@"http[s]?://([^/]+)/"); + static readonly Regex wwwRE = new(@"^w[^\.]{0,3}.\."); public static DiscordUser SpamCheckTimeout = null; readonly string[] testLinks = { "discord.com", "discordapp.com", "discord.gg", diff --git a/src/Actions/DiscordStatus.cs b/src/Actions/DiscordStatus.cs new file mode 100644 index 0000000..024fb67 --- /dev/null +++ b/src/Actions/DiscordStatus.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using DSharpPlus; +using DSharpPlus.Entities; + +/// +/// Choosing Custom Status for bot! ("Playing CS:GO!") +/// author: J0nathan550 +/// + +namespace UPBot.DiscordRPC { + public class DiscordStatus { + struct ActivityStatus { + public string status; + public ActivityType type; + } + + static async void DiscordUpdateStatusFunction(DiscordClient client, CancellationToken token) { + List activityStatusString = new() { + new ActivityStatus { type = ActivityType.Playing, status = "Visual Studio to code algorithms!" }, + new ActivityStatus { type = ActivityType.Playing, status = "a random game" }, + new ActivityStatus { type = ActivityType.Playing, status = "happily with my toys" }, + new ActivityStatus { type = ActivityType.Streaming, status = "the whole life" }, + new ActivityStatus { type = ActivityType.Streaming, status = "a bunch of solution" }, + new ActivityStatus { type = ActivityType.Streaming, status = "programming tutorials" }, + new ActivityStatus { type = ActivityType.Streaming, status = "some lights in the channels" }, + new ActivityStatus { type = ActivityType.ListeningTo, status = "Ode to Joy" }, + new ActivityStatus { type = ActivityType.ListeningTo, status = "your complaints" }, + new ActivityStatus { type = ActivityType.ListeningTo, status = "sounds in my head" }, + new ActivityStatus { type = ActivityType.ListeningTo, status = "the falling rain" }, + new ActivityStatus { type = ActivityType.Watching, status = "you!" }, + new ActivityStatus { type = ActivityType.Watching, status = "all users" }, + new ActivityStatus { type = ActivityType.Watching, status = "for nitro fakes" }, + new ActivityStatus { type = ActivityType.Watching, status = "to reformat code" }, + new ActivityStatus { type = ActivityType.Watching, status = "water boil" }, + new ActivityStatus { type = ActivityType.Watching, status = "grass grow" }, + new ActivityStatus { type = ActivityType.Competing, status = "with other bots" }, + new ActivityStatus { type = ActivityType.Competing, status = "performance review" }, + new ActivityStatus { type = ActivityType.Competing, status = "performance optimization" } + }; + + Random random = new(); + while (!token.IsCancellationRequested) { + int activity = random.Next(0, activityStatusString.Count); + ActivityStatus activityStatus = activityStatusString[activity]; + + await client.UpdateStatusAsync(new DiscordActivity(activityStatus.status, activityStatus.type)); + + await Task.Delay(TimeSpan.FromSeconds(60 + random.Next(0, 180)), token); + } + } + + internal static void Start(DiscordClient client) { + Task statusUpdateTask = new(() => DiscordUpdateStatusFunction(client, new CancellationToken())); + statusUpdateTask.Start(); + } + } +} diff --git a/UPBot Code/Actions/MembersTracking.cs b/src/Actions/MembersTracking.cs similarity index 91% rename from UPBot Code/Actions/MembersTracking.cs rename to src/Actions/MembersTracking.cs index c20beba..ad7c506 100644 --- a/UPBot Code/Actions/MembersTracking.cs +++ b/src/Actions/MembersTracking.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using UPBot.UPBot_Code; +using UPBot.UPBot_Code.DataClasses; namespace UPBot { public class MembersTracking { @@ -12,7 +14,7 @@ public static async Task DiscordMemberRemoved(DiscordClient _, DSharpPlus.EventA try { TrackChannel trackChannel = Configs.TrackChannels[args.Guild.Id]; if (trackChannel == null || trackChannel.channel == null || !trackChannel.trackLeave) return; - if (tracking == null) tracking = new Dictionary(); + tracking ??= new Dictionary(); int daysJ = (int)(DateTime.Now - args.Member.JoinedAt.DateTime).TotalDays; if (daysJ > 10000) daysJ = -1; // User is probably destroyed. So the value will be not valid @@ -46,7 +48,7 @@ public static async Task DiscordMemberAdded(DiscordClient _client, DSharpPlus.Ev try { TrackChannel trackChannel = Configs.TrackChannels[args.Guild.Id]; if (trackChannel == null || trackChannel.channel == null || !trackChannel.trackJoin) return; - if (tracking == null) tracking = new Dictionary(); + tracking ??= new Dictionary(); tracking[args.Member.Id] = DateTime.Now; _ = SomethingAsync(trackChannel.channel, args.Member.Id, args.Member.DisplayName, args.Member.Mention, args.Guild.MemberCount); @@ -62,7 +64,7 @@ public static async Task DiscordMemberUpdated(DiscordClient _, DSharpPlus.EventA try { TrackChannel trackChannel = Configs.TrackChannels[args.Guild.Id]; if (trackChannel == null || trackChannel.channel == null || !trackChannel.trackRoles) return; - if (tracking == null) tracking = new Dictionary(); + tracking ??= new Dictionary(); IReadOnlyList rolesBefore = args.RolesBefore; IReadOnlyList rolesAfter = args.RolesAfter; @@ -79,11 +81,10 @@ public static async Task DiscordMemberUpdated(DiscordClient _, DSharpPlus.EventA } if (addedRole) rolesAdded.Add(r1); } - string msgC; - string msgL; + if (rolesBefore.Count > 0 && rolesAdded.Count > 0) { - msgC = "User " + args.Member.Mention + " has the new role" + (rolesAdded.Count > 1 ? "s:" : ":"); - msgL = "User \"" + args.Member.DisplayName + "\" has the new role" + (rolesAdded.Count > 1 ? "s:" : ":"); + var msgC = "User " + args.Member.Mention + " has the new role" + (rolesAdded.Count > 1 ? "s:" : ":"); + var msgL = "User \"" + args.Member.DisplayName + "\" has the new role" + (rolesAdded.Count > 1 ? "s:" : ":"); foreach (DiscordRole r in rolesAdded) { msgC += r.Mention; msgL += r.Name; diff --git a/UPBot Code/Commands/Delete.cs b/src/Commands/Delete.cs similarity index 99% rename from UPBot Code/Commands/Delete.cs rename to src/Commands/Delete.cs index 6aca5ec..f8e21ac 100644 --- a/UPBot Code/Commands/Delete.cs +++ b/src/Commands/Delete.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using DSharpPlus.Entities; using DSharpPlus.SlashCommands; +using UPBot.UPBot_Code; /// /// This command will delete the last x messages diff --git a/UPBot Code/Commands/Game.cs b/src/Commands/Game.cs similarity index 86% rename from UPBot Code/Commands/Game.cs rename to src/Commands/Game.cs index 7602062..d1da0fd 100644 --- a/UPBot Code/Commands/Game.cs +++ b/src/Commands/Game.cs @@ -4,6 +4,7 @@ using DSharpPlus.Entities; using DSharpPlus.Interactivity.Extensions; using DSharpPlus.SlashCommands; +using UPBot.UPBot_Code; /// @@ -123,22 +124,22 @@ public enum RPSLSTypes { // 🪨📄✂️🦎🖖 enum RPSRes { First, Second, Draw } readonly RPSRes[][] rpslsRes = { // Rock Paper Scissors Lizard Spock - /* Rock */ new RPSRes[] {RPSRes.Draw, RPSRes.Second, RPSRes.First, RPSRes.First, RPSRes.Second }, - /* Paper */ new RPSRes[] {RPSRes.First, RPSRes.Draw, RPSRes.Second, RPSRes.Second, RPSRes.First }, - /* Scissors */ new RPSRes[] {RPSRes.Second, RPSRes.First, RPSRes.Draw, RPSRes.First, RPSRes.Second }, - /* Lizard */ new RPSRes[] {RPSRes.Second, RPSRes.First, RPSRes.Second, RPSRes.Draw, RPSRes.First }, - /* Spock */ new RPSRes[] {RPSRes.First, RPSRes.Second, RPSRes.First, RPSRes.Second, RPSRes.Draw } + /* Rock */ new[] {RPSRes.Draw, RPSRes.Second, RPSRes.First, RPSRes.First, RPSRes.Second }, + /* Paper */ new[] {RPSRes.First, RPSRes.Draw, RPSRes.Second, RPSRes.Second, RPSRes.First }, + /* Scissors */ new[] {RPSRes.Second, RPSRes.First, RPSRes.Draw, RPSRes.First, RPSRes.Second }, + /* Lizard */ new[] {RPSRes.Second, RPSRes.First, RPSRes.Second, RPSRes.Draw, RPSRes.First }, + /* Spock */ new[] {RPSRes.First, RPSRes.Second, RPSRes.First, RPSRes.Second, RPSRes.Draw } }; readonly string[][] rpslsMsgs = { // Rock Paper Scissors Lizard Spock - /* Rock */ new string[] {"Draw", "Paper covers Rock", "rock crushes scissors", "Rock crushes Lizard", "Spock vaporizes Rock"}, - /* Paper */ new string[] {"Paper covers Rock", "Draw", "Scissors cuts Paper", "Lizard eats Paper", "Paper disproves Spock" }, - /* Scissors */ new string[] {"Rock crushes scissors", "Scissors cuts Paper", "Draw", "Scissors decapitates Lizard", "Spock smashes Scissors" }, - /* Lizard */ new string[] {"Rock crushes Lizard", "Lizard eats Paper", "Scissors decapitates Lizard", "Draw", "Lizard poisons Spock" }, - /* Spock */ new string[] {"Spock vaporizes Rock", "Paper disproves Spock", "Spock smashes Scissors", "Lizard poisons Spock", "Draw" } + /* Rock */ new[] {"Draw", "Paper covers Rock", "rock crushes scissors", "Rock crushes Lizard", "Spock vaporizes Rock"}, + /* Paper */ new[] {"Paper covers Rock", "Draw", "Scissors cuts Paper", "Lizard eats Paper", "Paper disproves Spock" }, + /* Scissors */ new[] {"Rock crushes scissors", "Scissors cuts Paper", "Draw", "Scissors decapitates Lizard", "Spock smashes Scissors" }, + /* Lizard */ new[] {"Rock crushes Lizard", "Lizard eats Paper", "Scissors decapitates Lizard", "Draw", "Lizard poisons Spock" }, + /* Spock */ new[] {"Spock vaporizes Rock", "Paper disproves Spock", "Spock smashes Scissors", "Lizard poisons Spock", "Draw" } }; - static private string GetChoice(RPSLSTypes? move) { + private static string GetChoice(RPSLSTypes? move) { return move switch { RPSLSTypes.Rock => "🪨 Rock", RPSLSTypes.Paper => "📄 Paper", @@ -189,11 +190,15 @@ public async Task RPSLKCommand(InteractionContext ctx, [Option("yourmove", "Rock var result = await interact.WaitForButtonAsync(msg, TimeSpan.FromMinutes(2)); var interRes = result.Result; if (interRes != null) { - if (result.Result.Id == "bRock") yourmove = RPSLSTypes.Rock; - else if (result.Result.Id == "bPaper") yourmove = RPSLSTypes.Paper; - else if (result.Result.Id == "bScissors") yourmove = RPSLSTypes.Scissors; - else if (result.Result.Id == "bLizard") yourmove = RPSLSTypes.Lizard; - else if (result.Result.Id == "bSpock") yourmove = RPSLSTypes.Spock; + yourmove = result.Result.Id switch + { + "bRock" => RPSLSTypes.Rock, + "bPaper" => RPSLSTypes.Paper, + "bScissors" => RPSLSTypes.Scissors, + "bLizard" => RPSLSTypes.Lizard, + "bSpock" => RPSLSTypes.Spock, + _ => yourmove + }; string resmsg = rpslsMsgs[(int)yourmove][(int)botChoice]; switch (rpslsRes[(int)yourmove][(int)botChoice]) { case RPSRes.First: @@ -281,9 +286,12 @@ private string PrintBoard(int[] grid) { for (int y = 0; y < 3; y++) { for (int x = 0; x < 3; x++) { int pos = x + 3 * y; - if (grid[pos] == 1) board += ":o:"; - else if (grid[pos] == 2) board += ":x:"; - else board += ":black_large_square:"; + board += grid[pos] switch + { + 1 => ":o:", + 2 => ":x:", + _ => ":black_large_square:" + }; board += "¹²³⁴⁵⁶⁷⁸⁹"[pos]; } board += "\n"; @@ -299,7 +307,7 @@ public static void CleanupTicTacToe() { [SlashCommand("tictactoe", "Play Tic-Tac-Toe game with someone or aganinst the bot.")] public async Task TicTacToeGame(InteractionContext ctx, [Option("opponent", "Select a Discord user to play with (keep empty to play with the bot)")] DiscordUser opponent = null) { Utils.LogUserCommand(ctx); - int[] grid = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int[] grid = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; DiscordMember player = ctx.Member; bool oMoves = true; @@ -348,7 +356,7 @@ public async Task TicTacToeGame(InteractionContext ctx, [Option("opponent", "Sel // Print the board - message = new(); + message = new DiscordEmbedBuilder(); if (opponent == null || opponent.Id == Utils.GetClient().CurrentUser.Id || opponent.Id == ctx.Member.Id) { message.Title = $"Tic-Tac-Toe Game {player.DisplayName}/Bot"; if (oMoves) message.Description = $"{player.DisplayName}: Type a number between 1 and 9 to make a move.\n\n{PrintBoard(grid)}"; @@ -375,21 +383,19 @@ public async Task TicTacToeGame(InteractionContext ctx, [Option("opponent", "Sel } if (oMoves || opponent != null) { // Get the answer from the current user - var answer = await interact.WaitForMessageAsync((dm) => { - return (opponent == null || !oMoves ? - dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id : dm.Channel == ctx.Channel && dm.Author.Id == opponent.Id - ); - }, TimeSpan.FromMinutes(1)); + var answer = await interact.WaitForMessageAsync(dm => opponent == null || !oMoves ? + dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id : dm.Channel == ctx.Channel && dm.Author.Id == opponent.Id, TimeSpan.FromMinutes(1)); if (answer.Result == null) { - message = new() { + message = new DiscordEmbedBuilder + { Title = "Time expired!", Color = DiscordColor.Red, Description = $"You took too much time to type your move. Game is ended!", Timestamp = DateTime.Now }; if (board != null) await board.DeleteAsync(); - board = await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); + await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); if (opponent!=null) tttPlayers.Remove(opponent.Id); tttPlayers.Remove(ctx.Member.Id); @@ -447,26 +453,29 @@ public async Task TicTacToeGame(InteractionContext ctx, [Option("opponent", "Sel } if (oWins) { - message = new() { + message = new DiscordEmbedBuilder + { Title = $"Tic-Tac-Toe Game: :o: ({(opponent == null ? player.Username : opponent.Username)}) Wins!", Description = $"**Game is ended!**\n\n{PrintBoard(grid)}", Color = DiscordColor.Red, Timestamp = DateTime.Now }; if (board != null) await board.DeleteAsync(); - board = await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); + await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); if (opponent != null) tttPlayers.Remove(opponent.Id); tttPlayers.Remove(ctx.Member.Id); return; } if (xWins) { - message = new(); - message.Title = ((opponent == null) ? $"Tic-Tac-Toe Game: :x: (Bot) Wins!" : $"Tic-Tac-Toe Game: :x: ({player.Username}) Wins!"); - message.Description = $"**Game is ended!**\n\n{PrintBoard(grid)}"; - message.Color = DiscordColor.Red; - message.Timestamp = DateTime.Now; + message = new DiscordEmbedBuilder + { + Title = opponent == null ? $"Tic-Tac-Toe Game: :x: (Bot) Wins!" : $"Tic-Tac-Toe Game: :x: ({player.Username}) Wins!", + Description = $"**Game is ended!**\n\n{PrintBoard(grid)}", + Color = DiscordColor.Red, + Timestamp = DateTime.Now + }; if (board != null) await board.DeleteAsync(); - board = await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); + await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); if (opponent != null) tttPlayers.Remove(opponent.Id); tttPlayers.Remove(ctx.Member.Id); return; @@ -481,14 +490,15 @@ public async Task TicTacToeGame(InteractionContext ctx, [Option("opponent", "Sel } } if (draw) { - message = new() { + message = new DiscordEmbedBuilder + { Title = "Tic-Tac-Toe Game: Draw!", Description = $"**Game is ended!**\n\n{PrintBoard(grid)}", Color = DiscordColor.Red, Timestamp = DateTime.Now }; if (board != null) await board.DeleteAsync(); - board = await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); + await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(message)); if (opponent != null) tttPlayers.Remove(opponent.Id); tttPlayers.Remove(ctx.Member.Id); return; diff --git a/UPBot Code/Commands/Logs.cs b/src/Commands/Logs.cs similarity index 89% rename from UPBot Code/Commands/Logs.cs rename to src/Commands/Logs.cs index ef3c246..390bfa7 100644 --- a/UPBot Code/Commands/Logs.cs +++ b/src/Commands/Logs.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Compression; using System.Threading.Tasks; +using UPBot.UPBot_Code; /// /// This command implements a Logs command. @@ -25,10 +26,10 @@ public async Task LogsCommand(InteractionContext ctx, [Option("NumerOflines", "H } List lines = new(); - using (var fs = new FileStream(logs, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { + await using (var fs = new FileStream(logs, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using var sr = new StreamReader(fs); while (!sr.EndOfStream) { - lines.Add(sr.ReadLine()); + lines.Add(await sr.ReadLineAsync()); } } @@ -56,11 +57,11 @@ public async Task LogsSaveCommand(InteractionContext ctx) { return; } string logsFolder = Utils.GetLastLogsFolder(ctx.Guild.Name, logs); - string outfile = logsFolder[0..^1] + ".zip"; + string outfile = logsFolder[..^1] + ".zip"; ZipFile.CreateFromDirectory(logsFolder, outfile); - using (FileStream fs = new(outfile, FileMode.Open, FileAccess.Read)) + await using (FileStream fs = new(outfile, FileMode.Open, FileAccess.Read)) await ctx.CreateResponseAsync(new DiscordInteractionResponseBuilder().WithContent("Zipped log in attachment").AddFile(fs)); await Utils.DeleteFileDelayed(30, outfile); await Utils.DeleteFolderDelayed(30, logsFolder); @@ -73,10 +74,10 @@ public async Task LogsSaveAllCommand(InteractionContext ctx) { string logsFolder = Utils.GetAllLogsFolder(ctx.Guild.Name); - string outfile = logsFolder[0..^1] + ".zip"; + string outfile = logsFolder[..^1] + ".zip"; ZipFile.CreateFromDirectory(logsFolder, outfile); - using (FileStream fs = new(outfile, FileMode.Open, FileAccess.Read)) + await using (FileStream fs = new(outfile, FileMode.Open, FileAccess.Read)) await ctx.CreateResponseAsync(new DiscordInteractionResponseBuilder().WithContent("Zipped logs in attachment").AddFile(fs)); await Utils.DeleteFileDelayed(30, outfile); await Utils.DeleteFolderDelayed(30, logsFolder); diff --git a/UPBot Code/Commands/Ping.cs b/src/Commands/Ping.cs similarity index 66% rename from UPBot Code/Commands/Ping.cs rename to src/Commands/Ping.cs index ff7b857..63c4b4f 100644 --- a/UPBot Code/Commands/Ping.cs +++ b/src/Commands/Ping.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using DSharpPlus.Entities; using DSharpPlus.SlashCommands; +using UPBot.UPBot_Code; /// /// This command implements a basic ping command. @@ -66,7 +67,7 @@ async Task GeneratePong(InteractionContext ctx) { annoyedLevel = lastRequest.AddRequest(); } if (annoyedLevel == -1) { - Task t = ctx.CreateResponseAsync("..."); + await ctx.CreateResponseAsync("..."); DiscordMessage empty = ctx.GetOriginalResponseAsync().Result; await empty.DeleteAsync(); // No answer return; @@ -107,7 +108,7 @@ public LastRequestByMember(ulong memberId) { internal int AddRequest() { // remove all items older than 10 minutes for (int i = 0; i < requestTimes.Length; i++) { - if ((DateTime.Now - requestTimes[i]) > tenMins) + if (DateTime.Now - requestTimes[i] > tenMins) requestTimes[i] = DateTime.MinValue; } // Move to have the first not null in first place @@ -147,66 +148,102 @@ internal int AddRequest() { switch (num) { case 1: break; case 2: - if (averageBetweenRequests < 3) index = 2; // Testing? - else if (averageBetweenRequests < 10) index = 1; // Again? + index = averageBetweenRequests switch + { + < 3 => 2, + < 10 => 1, + _ => index + }; break; case 3: - if (averageBetweenRequests < 5) index = 3; // Light annoyed - else if (averageBetweenRequests < 10) index = 2; // Testing? - else if (averageBetweenRequests < 20) index = 1; // Again? + index = averageBetweenRequests switch + { + < 5 => 3, + < 10 => 2, + < 20 => 1, + _ => index + }; break; case 4: - if (averageBetweenRequests < 5) index = 4; // Menacing - else if (averageBetweenRequests < 10) index = 3; // Light annoyed - else if (averageBetweenRequests < 20) index = 2; // Testing? - else if (averageBetweenRequests < 30) index = 1; // Again? + index = averageBetweenRequests switch + { + < 5 => 4, + < 10 => 3, + < 20 => 2, + < 30 => 1, + _ => index + }; break; case 5: - if (averageBetweenRequests < 5) index = 5; // Punishment - else if (averageBetweenRequests < 20) index = 4; // Menacing - else if (averageBetweenRequests < 30) index = 3; // Light annoyed - else if (averageBetweenRequests < 40) index = 2; // Testing? - else if (averageBetweenRequests < 50) index = 1; // Again? + index = averageBetweenRequests switch + { + < 5 => 5, + < 20 => 4, + < 30 => 3, + < 40 => 2, + < 50 => 1, + _ => index + }; break; case 6: - if (averageBetweenRequests < 5) index = -1; // no answer - else if (averageBetweenRequests < 20) index = 5; // Punishment - else if (averageBetweenRequests < 30) index = 4; // Menacing - else if (averageBetweenRequests < 40) index = 3; // Light annoyed - else if (averageBetweenRequests < 50) index = 2; // Testing? - else if (averageBetweenRequests < 60) index = 1; // Again? + index = averageBetweenRequests switch + { + < 5 => -1, + < 20 => 5, + < 30 => 4, + < 40 => 3, + < 50 => 2, + < 60 => 1, + _ => index + }; break; case 7: - if (averageBetweenRequests < 5) index = -1; // no answer - else if (averageBetweenRequests < 10) index = 5; // Punishment - else if (averageBetweenRequests < 20) index = 4; // Menacing - else if (averageBetweenRequests < 30) index = 3; // Light annoyed - else if (averageBetweenRequests < 40) index = 2; // Testing? - else if (averageBetweenRequests < 50) index = 1; // Again? + index = averageBetweenRequests switch + { + < 5 => -1, + < 10 => 5, + < 20 => 4, + < 30 => 3, + < 40 => 2, + < 50 => 1, + _ => index + }; break; case 8: - if (averageBetweenRequests < 10) index = -1; // no answer - else if (averageBetweenRequests < 20) index = 5; // Punishment - else if (averageBetweenRequests < 30) index = 4; // Menacing - else if (averageBetweenRequests < 40) index = 3; // Light annoyed - else if (averageBetweenRequests < 50) index = 2; // Testing? - else if (averageBetweenRequests < 60) index = 1; // Again? + index = averageBetweenRequests switch + { + < 10 => -1, + < 20 => 5, + < 30 => 4, + < 40 => 3, + < 50 => 2, + < 60 => 1, + _ => index + }; break; case 9: - if (averageBetweenRequests < 10) index = -1; // no answer - else if (averageBetweenRequests < 15) index = 5; // Punishment - else if (averageBetweenRequests < 20) index = 4; // Menacing - else if (averageBetweenRequests < 25) index = 3; // Light annoyed - else if (averageBetweenRequests < 30) index = 2; // Testing? - else if (averageBetweenRequests < 35) index = 1; // Again? + index = averageBetweenRequests switch + { + < 10 => -1, + < 15 => 5, + < 20 => 4, + < 25 => 3, + < 30 => 2, + < 35 => 1, + _ => index + }; break; default: - if (averageBetweenRequests < 10) index = -1; // no answer - else if (averageBetweenRequests < 20) index = 5; // Punishment - else if (averageBetweenRequests < 30) index = 4; // Menacing - else if (averageBetweenRequests < 38) index = 3; // Light annoyed - else if (averageBetweenRequests < 46) index = 2; // Testing? - else if (averageBetweenRequests < 54) index = 1; // Again? + index = averageBetweenRequests switch + { + < 10 => -1, + < 20 => 5, + < 30 => 4, + < 38 => 3, + < 46 => 2, + < 54 => 1, + _ => index + }; break; } diff --git a/UPBot Code/Commands/Refactor.cs b/src/Commands/Refactor.cs similarity index 65% rename from UPBot Code/Commands/Refactor.cs rename to src/Commands/Refactor.cs index 5b9676c..1c41175 100644 --- a/UPBot Code/Commands/Refactor.cs +++ b/src/Commands/Refactor.cs @@ -5,6 +5,7 @@ using DSharpPlus.SlashCommands; using System.Text.RegularExpressions; using DSharpPlus; +using UPBot.UPBot_Code; /// /// Command used to refactor as codeblock some code pasted by a user @@ -38,15 +39,16 @@ public async Task CheckLanguage(InteractionContext ctx, [Option("Member", "The u DiscordMessage m = msgs[i]; if (usrId != 0 && m.Author.Id != usrId) continue; Langs lang = GetBestMatch(m.Content, out int weightCs, out int weightCp, out int weightJv, out int weightJs, out int weightPy, out int weightUn); - string guessed = "no one"; - switch (lang) { - case Langs.cs: guessed = "<:csharp:831465428214743060> C#"; break; - case Langs.js: guessed = "<:Javascript:876103767068647435> Javascript"; break; - case Langs.cpp: guessed = "<:cpp:831465408874676273> C++"; break; - case Langs.java: guessed = "<:java:875852276017815634> Java"; break; - case Langs.python: guessed = "<:python:831465381016895500> Python"; break; - case Langs.Unity: guessed = "<:Unity:968043486379143168> Unity C#"; break; - } + string guessed = lang switch + { + Langs.cs => "<:csharp:831465428214743060> C#", + Langs.js => "<:Javascript:876103767068647435> Javascript", + Langs.cpp => "<:cpp:831465408874676273> C++", + Langs.java => "<:java:875852276017815634> Java", + Langs.python => "<:python:831465381016895500> Python", + Langs.Unity => "<:Unity:968043486379143168> Unity C#", + _ => "no one" + }; string usrname = user == null ? "last code" : user.Username + "'s code"; await ctx.CreateResponseAsync($"Best guess for the language in {usrname} is: {guessed}\nC# = {weightCs} C++ = {weightCp} Java = {weightJv} Javascript = {weightJs} Python = {weightPy} Unity C# = {weightUn}"); } @@ -149,7 +151,7 @@ private Langs GetCodeBlock(string content, Langs lang, bool removeEmtpyLines, ou if (nl != '\r' && nl != '\r') { // We have a possible language int nlPos1 = code.IndexOf('\n'); int nlPos2 = code.IndexOf('\r'); - int pos = (nlPos1 != -1) ? nlPos1 : -1; + int pos = nlPos1 != -1 ? nlPos1 : -1; if (nlPos2 != -1 && (nlPos2 < pos || pos == -1)) pos = nlPos2; if (pos != -1) { writtenLang = code[..pos].Trim(' ', '\t', '\r', '\n'); @@ -162,27 +164,30 @@ private Langs GetCodeBlock(string content, Langs lang, bool removeEmtpyLines, ou if (removeEmtpyLines) { code = emptyLines.Replace(code, "\n"); } - if (writtenLang != null) { // Do another best match with the given language - Langs bl = Langs.NONE; - switch (writtenLang.ToLowerInvariant()) { - case "ph": bl = Langs.python; break; - case "phy": bl = Langs.python; break; - case "phyton": bl = Langs.python; break; - case "pt": bl = Langs.python; break; - case "c": bl = Langs.cpp; break; - case "c++": bl = Langs.cpp; break; - case "cp": bl = Langs.cpp; break; - case "cpp": bl = Langs.cpp; break; - case "cs": bl = Langs.cs; break; - case "csharp": bl = Langs.cs; break; - case "c#": bl = Langs.cs; break; - case "jv": bl = Langs.java; break; - case "java": bl = Langs.java; break; - case "js": bl = Langs.js; break; - case "json": bl = Langs.js; break; - case "jscript": bl = Langs.js; break; - case "javascript": bl = Langs.js; break; - } + if (writtenLang != null) + { + // Do another best match with the given language + Langs bl = writtenLang.ToLowerInvariant() switch + { + "ph" => Langs.python, + "phy" => Langs.python, + "phyton" => Langs.python, + "pt" => Langs.python, + "c" => Langs.cpp, + "c++" => Langs.cpp, + "cp" => Langs.cpp, + "cpp" => Langs.cpp, + "cs" => Langs.cs, + "csharp" => Langs.cs, + "c#" => Langs.cs, + "jv" => Langs.java, + "java" => Langs.java, + "js" => Langs.js, + "json" => Langs.js, + "jscript" => Langs.js, + "javascript" => Langs.js, + _ => Langs.NONE + }; return GetBestMatchWithHint(code, bl); } return lang; @@ -440,85 +445,85 @@ private Langs GetBestMatch(string code, out int weightCs, out int weightCp, out readonly Regex emptyLines = new("(\\r?\\n\\s*){1,}(\\r?\\n)", RegexOptions.Singleline, TimeSpan.FromSeconds(10)); readonly LangKWord[] keywords = { - new LangKWord{regexp = new("getline", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("cin", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("cout", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("endl", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("size_t", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("if\\s*\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("for\\s*\\([^;]+;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("for\\s*\\([^:;]+:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("foreach\\s*\\([^;]+in", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("for_each\\s*\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("while\\s*\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("\\.Equals\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 1, wJv = 3, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("switch\\s*\\([a-z\\s]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("break;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("[a-z\\)];", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("string\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 1 }, - new LangKWord{regexp = new("int\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 1 }, - new LangKWord{regexp = new("long\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 1 }, - new LangKWord{regexp = new("float\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 1 }, - new LangKWord{regexp = new("bool\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 1 }, - new LangKWord{regexp = new("boolean\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 1, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("Vector2\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Vector3\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("GameObject\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("MonoBehaviour", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("ScriptableObject", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Transform\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Rigidbody\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Rigidbody2D\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Quaternion\\.", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Start\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 1, wJs = 1, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Awake\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 1, wJs = 1, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Update\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 1, wJs = 1, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("Debug\\.Log\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("OnTriggerEnter\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("OnTriggerEnter2D\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("OnCollisionEnter\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("OnCollisionEnter2D\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, - new LangKWord{regexp = new("\\.position", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("\\.rotation", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("\\.Count", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("\\.Length", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("\\.length", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 2, wJv = 0, wJs = 3, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("[a-z0-9]\\([^\n]*\\)", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("\\{.*\\}", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("\\[.*\\]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("#include\\s+[\"<]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("#define\\s+", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("[^#]include\\s+[\"<]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("using((?!::).)*;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 9, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("using unityengine;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 20 }, - new LangKWord{regexp = new("using[^;]+::[^;]+;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("std::", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("[!=]==", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 9, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("auto", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("public\\s+[a-z0-9<>]+\\s[a-z0-9]+\\s*;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 9, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("private\\s+[a-z0-9<>]+\\s[a-z0-9]+\\s*;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 9, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, - new LangKWord{regexp = new("public\\s", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("public:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("private:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("private\\s", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("\\};", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 2, wJv = 2, wJs = 1, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("let\\s+[a-z0-9_]+\\s*=", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 9, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("import\\s[a-z][a-z0-9]+", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, - new LangKWord{regexp = new("'''[\\sa-z0-9]+", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, - new LangKWord{regexp = new("for\\s[a-z][a-z0-9]*\\sin.+:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, - new LangKWord{regexp = new("print\\(\"", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, - new LangKWord{regexp = new("Console\\.Write", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("console\\.log", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("else:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 8, wUn = 0 }, - new LangKWord{regexp = new("\\[(\\s*[0-9]+\\s*\\,{0,1})+\\s*\\]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 5, wUn = 0 }, - new LangKWord{regexp = new("\\[(\\s*\"[^\"]*\"\\s*\\,{0,1})+\\s*\\]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 5, wUn = 0 }, - new LangKWord{regexp = new("while[\\sa-z0-9\\(\\)]+:\\n", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 5, wUn = 0 }, - new LangKWord{regexp = new("\\s*#\\s*[a-z0-9]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 6, wUn = 0 }, - new LangKWord{regexp = new("\\{.+\"{0,1}[a-z0-9_]+\"{0,1}\\s*:\\s*((\".*\")|[0-9\\.]+)\\s*[,\\}]", RegexOptions.IgnoreCase | RegexOptions.Singleline, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 9, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("System\\.out\\.println", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("String\\[\\]", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("\\?\\.", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, - new LangKWord{regexp = new("\\-\\>", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("getline", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("cin", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("cout", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("endl", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("size_t", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("if\\s*\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("for\\s*\\([^;]+;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("for\\s*\\([^:;]+:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("foreach\\s*\\([^;]+in", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("for_each\\s*\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("while\\s*\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("\\.Equals\\(", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 1, wJv = 3, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("switch\\s*\\([a-z\\s]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("break;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("[a-z\\)];", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("string\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 1 }, + new() {regexp = new Regex("int\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 1 }, + new() {regexp = new Regex("long\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 1 }, + new() {regexp = new Regex("float\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 1 }, + new() {regexp = new Regex("bool\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 1 }, + new() {regexp = new Regex("boolean\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 1, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("Vector2\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Vector3\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("GameObject\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("MonoBehaviour", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("ScriptableObject", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Transform\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Rigidbody\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Rigidbody2D\\s+[a-z]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Quaternion\\.", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Start\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 1, wJs = 1, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Awake\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 1, wJs = 1, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Update\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 3, wCp = 3, wJv = 1, wJs = 1, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("Debug\\.Log\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("OnTriggerEnter\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("OnTriggerEnter2D\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("OnCollisionEnter\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("OnCollisionEnter2D\\(", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 4, wCp = 3, wJv = 0, wJs = 0, wPy = 0, wUn = 10 }, + new() {regexp = new Regex("\\.position", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("\\.rotation", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("\\.Count", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("\\.Length", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("\\.length", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 2, wJv = 0, wJs = 3, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("[a-z0-9]\\([^\n]*\\)", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("\\{.*\\}", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 2, wJv = 2, wJs = 2, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("\\[.*\\]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("#include\\s+[\"<]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("#define\\s+", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("[^#]include\\s+[\"<]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("using((?!::).)*;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 9, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("using unityengine;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 20 }, + new() {regexp = new Regex("using[^;]+::[^;]+;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("std::", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("[!=]==", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 9, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("auto", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("public\\s+[a-z0-9<>]+\\s[a-z0-9]+\\s*;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 9, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("private\\s+[a-z0-9<>]+\\s[a-z0-9]+\\s*;", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 9, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 2 }, + new() {regexp = new Regex("public\\s", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("public:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("private:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 5, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("private\\s", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 1, wCp = 1, wJv = 1, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("\\};", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 2, wJv = 2, wJs = 1, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("let\\s+[a-z0-9_]+\\s*=", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 9, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("import\\s[a-z][a-z0-9]+", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, + new() {regexp = new Regex("'''[\\sa-z0-9]+", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, + new() {regexp = new Regex("for\\s[a-z][a-z0-9]*\\sin.+:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, + new() {regexp = new Regex("print\\(\"", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 0, wJv = 0, wJs = 0, wPy = 4, wUn = 0 }, + new() {regexp = new Regex("Console\\.Write", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("console\\.log", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("else:", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 8, wUn = 0 }, + new() {regexp = new Regex("\\[(\\s*[0-9]+\\s*\\,{0,1})+\\s*\\]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 5, wUn = 0 }, + new() {regexp = new Regex("\\[(\\s*\"[^\"]*\"\\s*\\,{0,1})+\\s*\\]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 4, wPy = 5, wUn = 0 }, + new() {regexp = new Regex("while[\\sa-z0-9\\(\\)]+:\\n", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 5, wUn = 0 }, + new() {regexp = new Regex("\\s*#\\s*[a-z0-9]", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 0, wPy = 6, wUn = 0 }, + new() {regexp = new Regex("\\{.+\"{0,1}[a-z0-9_]+\"{0,1}\\s*:\\s*((\".*\")|[0-9\\.]+)\\s*[,\\}]", RegexOptions.IgnoreCase | RegexOptions.Singleline, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 0, wJs = 9, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("System\\.out\\.println", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("String\\[\\]", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 0, wJv = 9, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("\\?\\.", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 2, wCp = 0, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, + new() {regexp = new Regex("\\-\\>", RegexOptions.None, TimeSpan.FromSeconds(10)), wCs = 0, wCp = 9, wJv = 0, wJs = 0, wPy = 0, wUn = 0 }, }; public class LangKWord { @@ -558,15 +563,16 @@ public async Task AddLineNumbers(InteractionContext ctx, [Option("Member", "The } lang = GetCodeBlock(msg.Content, lang, false, out string srccode); - string lmd = ""; - switch (lang) { - case Langs.cs: lmd = "cs"; break; - case Langs.Unity: lmd = "cs"; break; - case Langs.js: lmd = "js"; break; - case Langs.cpp: lmd = "cpp"; break; - case Langs.java: lmd = "java"; break; - case Langs.python: lmd = "python"; break; - } + string lmd = lang switch + { + Langs.cs => "cs", + Langs.Unity => "cs", + Langs.js => "js", + Langs.cpp => "cpp", + Langs.java => "java", + Langs.python => "python", + _ => "" + }; string[] codelines = srccode.Split('\n'); string code = "```" + lmd + "\n"; diff --git a/UPBot Code/Commands/Setup.cs b/src/Commands/Setup.cs similarity index 87% rename from UPBot Code/Commands/Setup.cs rename to src/Commands/Setup.cs index 568ef30..8cc69e2 100644 --- a/UPBot Code/Commands/Setup.cs +++ b/src/Commands/Setup.cs @@ -6,6 +6,8 @@ using DSharpPlus.Entities; using DSharpPlus.Interactivity.Extensions; using DSharpPlus.SlashCommands; +using UPBot.UPBot_Code; +using UPBot.UPBot_Code.DataClasses; namespace UPBot { /// @@ -45,8 +47,8 @@ public async Task SetupCommand(InteractionContext ctx, [Option("Command", "Show, else if (command == SetupCommandItem.Save) { string theList = GenerateSetupList(g, gid); string rndName = "SetupList" + DateTime.Now.Second + "Tmp" + DateTime.Now.Millisecond + ".txt"; - File.WriteAllText(rndName, theList); - using var fs = new FileStream(rndName, FileMode.Open, FileAccess.Read); + await File.WriteAllTextAsync(rndName, theList); + await using var fs = new FileStream(rndName, FileMode.Open, FileAccess.Read); await ctx.CreateResponseAsync(new DiscordInteractionResponseBuilder().WithContent("Setup List in attachment").AddFile(fs)); await Utils.DeleteFileDelayed(30, rndName); } @@ -87,9 +89,7 @@ async Task HandleSetupInteraction(InteractionContext ctx, ulong gid) { else if (cmdId == "idroleadd") { await ctx.Channel.DeleteMessageAsync(msg); DiscordMessage prompt = await ctx.Channel.SendMessageAsync(ctx.Member.Mention + ", please mention the roles to add (_type anything else to close_)"); - var answer = await interact.WaitForMessageAsync((dm) => { - return (dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id); - }, TimeSpan.FromMinutes(2)); + var answer = await interact.WaitForMessageAsync(dm => dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id, TimeSpan.FromMinutes(2)); if (answer.Result != null) { if (answer.Result.MentionedRoles.Count > 0) { foreach (var dr in answer.Result.MentionedRoles) { @@ -117,7 +117,7 @@ async Task HandleSetupInteraction(InteractionContext ctx, ulong gid) { } // *********************************************************** DefAdmins.RemRole ******************************************************************************* - else if (cmdId.Length > 8 && cmdId[0..9] == "idrolerem") { + else if (cmdId.Length > 8 && cmdId[..9] == "idrolerem") { await ctx.Channel.DeleteMessageAsync(msg); if (int.TryParse(cmdId[9..], out int rpos)) { ulong rid = Configs.AdminRoles[ctx.Guild.Id][rpos]; ; @@ -137,9 +137,7 @@ async Task HandleSetupInteraction(InteractionContext ctx, ulong gid) { else if (cmdId == "idchangetrackch") { await ctx.Channel.DeleteMessageAsync(msg); DiscordMessage prompt = await ctx.Channel.SendMessageAsync(ctx.Member.Mention + ", please mention the channel (_use: **#**_) as tracking channel\nType _remove_ to remove the tracking channel"); - var answer = await interact.WaitForMessageAsync((dm) => { - return (dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id && (dm.MentionedChannels.Count > 0 || dm.Content.Contains("remove", StringComparison.InvariantCultureIgnoreCase))); - }, TimeSpan.FromMinutes(2)); + var answer = await interact.WaitForMessageAsync(dm => dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id && (dm.MentionedChannels.Count > 0 || dm.Content.Contains("remove", StringComparison.InvariantCultureIgnoreCase)), TimeSpan.FromMinutes(2)); if (answer.Result == null || (answer.Result.MentionedChannels.Count == 0 && !answer.Result.Content.Contains("remove", StringComparison.InvariantCultureIgnoreCase))) { await interRes.Interaction.CreateResponseAsync(DSharpPlus.InteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().WithContent("Config timed out")); return; @@ -223,14 +221,12 @@ async Task HandleSetupInteraction(InteractionContext ctx, ulong gid) { else if (cmdId == "idfeatrespamprotectwl") { msg = CreateSpamWhiteListInteraction(ctx, msg); } - else if (cmdId.Length > 21 && cmdId[0..22] == "idfeatrespamprotectadd") { // Ask for the link, clean it up, and add it + else if (cmdId.Length > 21 && cmdId[..22] == "idfeatrespamprotectadd") { // Ask for the link, clean it up, and add it await ctx.Channel.DeleteMessageAsync(msg); - bool whitelist = (cmdId == "idfeatrespamprotectaddwl"); + bool whitelist = cmdId == "idfeatrespamprotectaddwl"; - DiscordMessage prompt = await ctx.Channel.SendMessageAsync($"{ctx.Member.Mention}, type the url that should be {(whitelist ? "white listed" : "considered spam")}"); - var answer = await interact.WaitForMessageAsync((dm) => { - return (dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id); - }, TimeSpan.FromMinutes(2)); + await ctx.Channel.SendMessageAsync($"{ctx.Member.Mention}, type the url that should be {(whitelist ? "white listed" : "considered spam")}"); + var answer = await interact.WaitForMessageAsync(dm => dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id, TimeSpan.FromMinutes(2)); if (string.IsNullOrWhiteSpace(answer.Result.Content) || !answer.Result.Content.Contains('.')) { await interRes.Interaction.CreateResponseAsync(DSharpPlus.InteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().WithContent("Config timed out")); return; @@ -271,7 +267,7 @@ async Task HandleSetupInteraction(InteractionContext ctx, ulong gid) { } msg = CreateSpamProtectInteraction(ctx, msg); } - else if (cmdId.Length > 27 && cmdId[0..27] == "idfeatrespamprotectremovebl") { + else if (cmdId.Length > 27 && cmdId[..27] == "idfeatrespamprotectremovebl") { if (int.TryParse(cmdId[27..], out int num)) { string link = Configs.SpamLinks[gid][num]; Configs.SpamLinks[gid].RemoveAt(num); @@ -279,7 +275,7 @@ async Task HandleSetupInteraction(InteractionContext ctx, ulong gid) { } msg = CreateSpamProtectInteraction(ctx, msg); } - else if (cmdId.Length > 27 && cmdId[0..27] == "idfeatrespamprotectremovewl") { + else if (cmdId.Length > 27 && cmdId[..27] == "idfeatrespamprotectremovewl") { if (int.TryParse(cmdId[27..], out int num)) { string link = Configs.WhiteListLinks[gid][num]; Configs.WhiteListLinks[gid].RemoveAt(num); @@ -315,7 +311,7 @@ static string GenerateSetupList(DiscordGuild g, ulong gid) { // list if (r != null) part += r.Name + ", "; } if (part.Length == 0) msg += "**AdminRoles**: _no roles defined. Owner and roles with Admin flag will be considered bot Admins_\n"; - else msg += "**AdminRoles**: " + part[0..^2] + "\n"; + else msg += "**AdminRoles**: " + part[..^2] + "\n"; } // TrackingChannel ****************************************************** @@ -487,7 +483,7 @@ private DiscordMessage CreateAdminsInteraction(InteractionContext ctx, DiscordMe one = true; } } - if (one) desc = desc[0..^2]; + if (one) desc = desc[..^2]; else desc += "_**No admin roles defined.** Owner and server Admins will be used_"; } eb.Description = desc; @@ -523,8 +519,8 @@ private DiscordMessage CreateAdminsInteraction(InteractionContext ctx, DiscordMe // - Exit // - Back actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idback", "Back", false, el) + new(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), + new(DSharpPlus.ButtonStyle.Secondary, "idback", "Back", false, el) }; builder.AddComponents(actions); @@ -550,14 +546,13 @@ private DiscordMessage CreateTrackingInteraction(InteractionContext ctx, Discord eb.WithImageUrl(ctx.Guild.BannerUrl); eb.WithFooter("Member that started the configuration is: " + ctx.Member.DisplayName, ctx.Member.AvatarUrl); - List actions; var builder = new DiscordMessageBuilder(); builder.AddEmbed(eb.Build()); // - Change channel - actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Primary, "idchangetrackch", "Change channel", false, ok) - }; + var actions = new List { + new(DSharpPlus.ButtonStyle.Primary, "idchangetrackch", "Change channel", false, ok) + }; if (Configs.TrackChannels[ctx.Guild.Id] != null) actions.Add(new DiscordButtonComponent(DSharpPlus.ButtonStyle.Primary, "idremtrackch", "Remove channel", false, ko)); builder.AddComponents(actions); @@ -577,8 +572,8 @@ private DiscordMessage CreateTrackingInteraction(InteractionContext ctx, Discord // - Exit // - Back actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idback", "Back", false, el) + new(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), + new(DSharpPlus.ButtonStyle.Secondary, "idback", "Back", false, el) }; builder.AddComponents(actions); @@ -606,28 +601,27 @@ private DiscordMessage CreateSpamProtectInteraction(InteractionContext ctx, Disc eb.WithImageUrl(ctx.Guild.BannerUrl); eb.WithFooter("Member that started the configuration is: " + ctx.Member.DisplayName, ctx.Member.AvatarUrl); - List actions; var builder = new DiscordMessageBuilder(); builder.AddEmbed(eb.Build()); - actions = new List { - new DiscordButtonComponent(edisc ? DSharpPlus.ButtonStyle.Success : DSharpPlus.ButtonStyle.Danger, "idfeatrespamprotect0", "Discord Nitro", false, edisc ? ey : en), - new DiscordButtonComponent(esteam ? DSharpPlus.ButtonStyle.Success : DSharpPlus.ButtonStyle.Danger, "idfeatrespamprotect1", "Steam", false, esteam ? ey : en), - new DiscordButtonComponent(eepic ? DSharpPlus.ButtonStyle.Success : DSharpPlus.ButtonStyle.Danger, "idfeatrespamprotect2", "Epic", false, eepic ? ey : en) - }; + var actions = new List { + new(edisc ? DSharpPlus.ButtonStyle.Success : DSharpPlus.ButtonStyle.Danger, "idfeatrespamprotect0", "Discord Nitro", false, edisc ? ey : en), + new(esteam ? DSharpPlus.ButtonStyle.Success : DSharpPlus.ButtonStyle.Danger, "idfeatrespamprotect1", "Steam", false, esteam ? ey : en), + new(eepic ? DSharpPlus.ButtonStyle.Success : DSharpPlus.ButtonStyle.Danger, "idfeatrespamprotect2", "Epic", false, eepic ? ey : en) + }; builder.AddComponents(actions); actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectbl", "Manage Black List", false, er), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectwl", "Manage White List", false, er) + new(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectbl", "Manage Black List", false, er), + new(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectwl", "Manage White List", false, er) }; builder.AddComponents(actions); // - Exit // - Back actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idback", "Back to Main", false, el) + new(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), + new(DSharpPlus.ButtonStyle.Secondary, "idback", "Back to Main", false, el) }; builder.AddComponents(actions); @@ -648,13 +642,12 @@ private DiscordMessage CreateSpamWhiteListInteraction(InteractionContext ctx, Di eb.WithImageUrl(ctx.Guild.BannerUrl); eb.WithFooter("Member that started the configuration is: " + ctx.Member.DisplayName, ctx.Member.AvatarUrl); - List actions; var builder = new DiscordMessageBuilder(); builder.AddEmbed(eb.Build()); - actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectaddwl", "Add custom non spam url", false, ok) - }; + var actions = new List { + new(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectaddwl", "Add custom non spam url", false, ok) + }; builder.AddComponents(actions); // List all custom spam links @@ -675,9 +668,9 @@ private DiscordMessage CreateSpamWhiteListInteraction(InteractionContext ctx, Di // - Exit // - Back actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idback", "Back to Main", false, el), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idbackspam", "Back to Spam Protection", false, el) + new(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), + new(DSharpPlus.ButtonStyle.Secondary, "idback", "Back to Main", false, el), + new(DSharpPlus.ButtonStyle.Secondary, "idbackspam", "Back to Spam Protection", false, el) }; builder.AddComponents(actions); @@ -698,13 +691,12 @@ private DiscordMessage CreateSpamBlackListInteraction(InteractionContext ctx, Di eb.WithImageUrl(ctx.Guild.BannerUrl); eb.WithFooter("Member that started the configuration is: " + ctx.Member.DisplayName, ctx.Member.AvatarUrl); - List actions; var builder = new DiscordMessageBuilder(); builder.AddEmbed(eb.Build()); - actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectaddbl", "Add custom spam url", false, ok) - }; + var actions = new List { + new(DSharpPlus.ButtonStyle.Success, "idfeatrespamprotectaddbl", "Add custom spam url", false, ok) + }; builder.AddComponents(actions); // List all custom spam links @@ -725,9 +717,9 @@ private DiscordMessage CreateSpamBlackListInteraction(InteractionContext ctx, Di // - Exit // - Back actions = new List { - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idback", "Back to Main", false, el), - new DiscordButtonComponent(DSharpPlus.ButtonStyle.Secondary, "idbackspam", "Back to Spam Protection", false, el) + new(DSharpPlus.ButtonStyle.Danger, "idexitconfig", "Exit", false, ec), + new(DSharpPlus.ButtonStyle.Secondary, "idback", "Back to Main", false, el), + new(DSharpPlus.ButtonStyle.Secondary, "idbackspam", "Back to Spam Protection", false, el) }; builder.AddComponents(actions); diff --git a/UPBot Code/Commands/Stats.cs b/src/Commands/Stats.cs similarity index 93% rename from UPBot Code/Commands/Stats.cs rename to src/Commands/Stats.cs index 935834a..32a76f2 100644 --- a/UPBot Code/Commands/Stats.cs +++ b/src/Commands/Stats.cs @@ -3,6 +3,7 @@ using DSharpPlus.SlashCommands; using DSharpPlus.Entities; using System.Collections.Generic; +using UPBot.UPBot_Code; /// /// Provide some server stats @@ -96,11 +97,11 @@ static DiscordEmbedBuilder GenerateStatsEmbed(InteractionContext ctx) { int? m1 = g.ApproximateMemberCount; int m2 = g.MemberCount; int? m3 = g.MaxMembers; - string members = (m1 == null) ? m2.ToString() : (m1 + "/" + m2 + "/" + m3 + "max"); + string members = m1 == null ? m2.ToString() : m1 + "/" + m2 + "/" + m3 + "max"; e.AddField("Members", members + (g.IsLarge ? " (large)" : ""), true); int? p1 = g.ApproximatePresenceCount; int? p2 = g.MaxPresences; - if (p1 != null) e.AddField("Presence", p1.ToString() + (p2 != null ? "/" + p2 : ""), true); + if (p1 != null) e.AddField("Presence", p1 + (p2 != null ? "/" + p2 : ""), true); int? s1 = g.PremiumSubscriptionCount; if (s1 != null) e.AddField("Boosters", s1.ToString(), true); @@ -120,17 +121,16 @@ static DiscordEmbedBuilder GenerateStatsEmbed(InteractionContext ctx) { else numtc++; } - if (g.IsNSFW) e.AddField("NSFW", "NSFW server\nFilter level: " + g.ExplicitContentFilter.ToString() + "\nNSFW restriction type: " + g.NsfwLevel.ToString(), true); + if (g.IsNSFW) e.AddField("NSFW", "NSFW server\nFilter level: " + g.ExplicitContentFilter + "\nNSFW restriction type: " + g.NsfwLevel, true); e.AddField("Roles:", g.Roles.Count + " roles", true); e.AddField("Cannels", numtc + " text, " + numvc + " voice" + (numnc > 0 ? ", " + numnc + " nsfw" : "") + (g.SystemChannel == null ? "" : "\nSystem channel: " + g.SystemChannel.Mention) + - (g.RulesChannel == null ? "" : "\nRules channel: " + g.RulesChannel.Mention), false); + (g.RulesChannel == null ? "" : "\nRules channel: " + g.RulesChannel.Mention)); - string emojis; if (g.Emojis.Count > 0) { - emojis = g.Emojis.Count + " custom emojis: "; + var emojis = g.Emojis.Count + " custom emojis: "; foreach (var emj in g.Emojis.Values) emojis += Utils.GetEmojiSnowflakeID(emj) + " "; e.AddField("Emojis:", emojis, true); } @@ -152,7 +152,7 @@ static async Task CalculateEmojis(InteractionContext ctx) { } List> list = new(); foreach (var k in count.Keys) list.Add(new KeyValuePair(k, count[k])); - list.Sort((a, b) => { return b.Value.CompareTo(a.Value); }); + list.Sort((a, b) => b.Value.CompareTo(a.Value)); string res = "\n_Used emojis_: used " + list.Count + " different emojis(as reactions):\n "; for (int i = 0; i < 25 && i < list.Count; i++) { @@ -182,7 +182,7 @@ static async Task CalculateUserMentions(InteractionContext ctx) { } List> list = new(); foreach (var k in count.Keys) list.Add(new KeyValuePair(k, count[k])); - list.Sort((a, b) => { return b.Value.CompareTo(a.Value); }); + list.Sort((a, b) => b.Value.CompareTo(a.Value)); List> listask = new(); foreach (var k in askers.Keys) { @@ -190,7 +190,7 @@ static async Task CalculateUserMentions(InteractionContext ctx) { if (u == null) continue; listask.Add(new KeyValuePair(u.Username, askers[k])); } - listask.Sort((a, b) => { return b.Value.CompareTo(a.Value); }); + listask.Sort((a, b) => b.Value.CompareTo(a.Value)); string res = "\n_Mentioned users_: " + list.Count + " users have been mentioned:\n "; for (int i = 0; i < 25 && i < list.Count; i++) { @@ -227,7 +227,7 @@ static async Task CalculateRoleMentions(InteractionContext ctx) { } List> list = new(); foreach (var k in count.Keys) list.Add(new KeyValuePair(k, count[k])); - list.Sort((a, b) => { return b.Value.CompareTo(a.Value); }); + list.Sort((a, b) => b.Value.CompareTo(a.Value)); List> listask = new(); foreach (var k in askers.Keys) { @@ -235,7 +235,7 @@ static async Task CalculateRoleMentions(InteractionContext ctx) { if (u == null) continue; listask.Add(new KeyValuePair(u.Username, askers[k])); } - listask.Sort((a, b) => { return b.Value.CompareTo(a.Value); }); + listask.Sort((a, b) => b.Value.CompareTo(a.Value)); string res = "\n_Mentioned roles_: " + list.Count + " roles have been mentioned:\n "; for (int i = 0; i < 25 && i < list.Count; i++) { diff --git a/UPBot Code/Commands/Tag.cs b/src/Commands/Tag.cs similarity index 96% rename from UPBot Code/Commands/Tag.cs rename to src/Commands/Tag.cs index 6542205..808c37a 100644 --- a/UPBot Code/Commands/Tag.cs +++ b/src/Commands/Tag.cs @@ -3,6 +3,7 @@ using DSharpPlus.SlashCommands; using DSharpPlus.Entities; using DSharpPlus.Interactivity.Extensions; +using UPBot.UPBot_Code; namespace UPBot { /// @@ -86,11 +87,10 @@ public async Task TagCommand(InteractionContext ctx, [Option("tagname", "Tag to if (count < Configs.Tags[ctx.Guild.Id].Count - 1) result += ", \n"; else result += "."; } - count = 0; } embed.Title = "List of tags"; embed.Color = DiscordColor.Blurple; - embed.Description = result[0..^2]; + embed.Description = result[..^2]; embed.Timestamp = DateTime.Now; await ctx.CreateResponseAsync(embed); } catch (Exception ex) { @@ -154,7 +154,7 @@ public static TagBase FindTag(ulong gid, string name, bool getClosest) { } readonly Random rand = new(); - readonly public static DiscordColor[] discordColors = { + public static readonly DiscordColor[] discordColors = { DiscordColor.Aquamarine, DiscordColor.Azure, DiscordColor.Blurple, @@ -243,7 +243,7 @@ public async Task TagAddCommand(InteractionContext ctx, [Option("tagname", "Tag tagname.Equals(topics.Alias3, StringComparison.InvariantCultureIgnoreCase)) { embed.Title = "The Tag exists already!"; embed.Color = DiscordColor.Red; - embed.Description = ($"You are trying to add Tag {tagname} that already exists!\nIf you want to edit the Tag use: `tagedit ` - to edit"); + embed.Description = $"You are trying to add Tag {tagname} that already exists!\nIf you want to edit the Tag use: `tagedit ` - to edit"; embed.Timestamp = DateTime.Now; await ctx.CreateResponseAsync(embed, true); return; @@ -257,9 +257,7 @@ public async Task TagAddCommand(InteractionContext ctx, [Option("tagname", "Tag await ctx.CreateResponseAsync(embed); var interact = ctx.Client.GetInteractivity(); - var answer = await interact.WaitForMessageAsync((dm) => { - return (dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id); - }, TimeSpan.FromMinutes(5)); + var answer = await interact.WaitForMessageAsync(dm => dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id, TimeSpan.FromMinutes(5)); if (answer.Result == null) { embed.Title = "Time expired!"; @@ -275,7 +273,7 @@ public async Task TagAddCommand(InteractionContext ctx, [Option("tagname", "Tag embed.Title = "Tag added"; embed.Color = DiscordColor.Green; - embed.Description = ($"The topic: {tagname}, has been created"); + embed.Description = $"The topic: {tagname}, has been created"; embed.Timestamp = DateTime.Now; await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(embed)); } catch (Exception ex) { @@ -305,7 +303,7 @@ public async Task TagRemoveCommand(InteractionContext ctx, [Option("tagname", "T embed.Title = "Topic deleted"; embed.Color = DiscordColor.DarkRed; - embed.Description = ($"Tag `{tagname}` has been deleted by {ctx.Member.DisplayName}"); + embed.Description = $"Tag `{tagname}` has been deleted by {ctx.Member.DisplayName}"; embed.Timestamp = DateTime.Now; await ctx.CreateResponseAsync(embed, true); } catch (Exception ex) { @@ -333,7 +331,7 @@ public async Task TagListCommand(InteractionContext ctx) { } embed.Title = "List of tags"; embed.Color = DiscordColor.Blurple; - embed.Description = result[0..^2]; + embed.Description = result[..^2]; embed.Timestamp = DateTime.Now; await ctx.CreateResponseAsync(embed); } catch (Exception ex) { @@ -414,19 +412,17 @@ public async Task TagEditCommand(InteractionContext ctx, [Option("tagname", "Tag embed.Title = $"Editing {tagname}"; embed.Color = DiscordColor.Purple; - embed.Description = ($"You are editing the {tagname.ToUpperInvariant()}.\nBetter to copy previous text, and edit inside of message."); + embed.Description = $"You are editing the {tagname.ToUpperInvariant()}.\nBetter to copy previous text, and edit inside of message."; embed.Timestamp = DateTime.Now; await ctx.CreateResponseAsync(embed); var interact = ctx.Client.GetInteractivity(); - var answer = await interact.WaitForMessageAsync((dm) => { - return (dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id); - }, TimeSpan.FromMinutes(5)); + var answer = await interact.WaitForMessageAsync(dm => dm.Channel == ctx.Channel && dm.Author.Id == ctx.Member.Id, TimeSpan.FromMinutes(5)); if (answer.Result == null || string.IsNullOrWhiteSpace(answer.Result.Content)) { embed.Title = "Time expired!"; embed.Color = DiscordColor.Red; - embed.Description = ($"You took too much time to answer. :KO:"); + embed.Description = $"You took too much time to answer. :KO:"; embed.Timestamp = DateTime.Now; await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(embed)); return; @@ -624,7 +620,7 @@ public async Task TagImageRemoving(InteractionContext ctx, [Option("tagName", "T await ctx.CreateResponseAsync(embed, true); return; } - if (toEdit.thumbnailLink == null || toEdit.thumbnailLink == "") { + if (string.IsNullOrEmpty(toEdit.thumbnailLink)) { embed.Title = "Tag does not have any Thumbnail!"; embed.Color = DiscordColor.Red; embed.Description = $"Tag does not have any Thumbnail!"; @@ -693,7 +689,7 @@ public async Task TagThumbnailRemoving(InteractionContext ctx, [Option("tagname" await ctx.CreateResponseAsync(embed, true); return; } - if (toEdit.thumbnailLink == null || toEdit.thumbnailLink == "") { + if (string.IsNullOrEmpty(toEdit.thumbnailLink)) { embed.Title = "Tag does not have any Thumbnail!"; embed.Color = DiscordColor.Red; embed.Description = $"Tag does not have any Thumbnail!"; diff --git a/UPBot Code/Commands/Timezone.cs b/src/Commands/Timezone.cs similarity index 99% rename from UPBot Code/Commands/Timezone.cs rename to src/Commands/Timezone.cs index acfe0e8..7951078 100644 --- a/UPBot Code/Commands/Timezone.cs +++ b/src/Commands/Timezone.cs @@ -4,6 +4,8 @@ using DSharpPlus.Entities; using DSharpPlus.SlashCommands; using TimeZoneConverter; +using UPBot.UPBot_Code; + /// /// This command implements a table for the timezones of the users /// Users can define their own timezone and can see the local time of other users that defined the timezone @@ -203,7 +205,7 @@ List CheckProx(string inp) { } } } - res.Sort((a, b) => { return b.Score.CompareTo(a.Score); }); + res.Sort((a, b) => b.Score.CompareTo(a.Score)); if (res.Count == 0) return null; diff --git a/UPBot Code/Commands/UnityDocs.cs b/src/Commands/UnityDocs.cs similarity index 99% rename from UPBot Code/Commands/UnityDocs.cs rename to src/Commands/UnityDocs.cs index 668e9cb..d4b7095 100644 --- a/UPBot Code/Commands/UnityDocs.cs +++ b/src/Commands/UnityDocs.cs @@ -3,6 +3,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using UPBot.UPBot_Code; /// /// This command tried to find a link to Unity script documentation from a pre-defined list of terms diff --git a/UPBot Code/Commands/Version.cs b/src/Commands/Version.cs similarity index 97% rename from UPBot Code/Commands/Version.cs rename to src/Commands/Version.cs index feaa41b..77f5ad6 100644 --- a/UPBot Code/Commands/Version.cs +++ b/src/Commands/Version.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using DSharpPlus.SlashCommands; +using UPBot.UPBot_Code; /// /// This command implements a Version command. diff --git a/UPBot Code/Commands/WhoIs.cs b/src/Commands/WhoIs.cs similarity index 92% rename from UPBot Code/Commands/WhoIs.cs rename to src/Commands/WhoIs.cs index 7a255ab..79e87d3 100644 --- a/UPBot Code/Commands/WhoIs.cs +++ b/src/Commands/WhoIs.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using DSharpPlus.Entities; using DSharpPlus.SlashCommands; +using UPBot.UPBot_Code; /// /// This command implements a WhoIs command. @@ -17,14 +18,9 @@ public async Task WhoIsCommand(InteractionContext ctx, [Option("user", "The user Utils.LogUserCommand(ctx); try { - DiscordMember m = null; + DiscordMember m; - if (user == null) { // If we do not have a user we use the member that invoked the command - m = ctx.Member; - } - else { - m = ctx.Guild.GetMemberAsync(user.Id).Result; - } + m = user == null ? ctx.Member : ctx.Guild.GetMemberAsync(user.Id).Result; // If we do not have a user we use the member that invoked the command bool you = m == ctx.Member; DateTimeOffset jdate = m.JoinedAt.UtcDateTime; @@ -66,9 +62,9 @@ public async Task WhoIsCommand(InteractionContext ctx, [Option("user", "The user num++; } if (num == 1) - embed.AddField("Role", roles, false); + embed.AddField("Role", roles); else if (num != 0) - embed.AddField(num + " Roles", roles, false); + embed.AddField(num + " Roles", roles); string perms = ""; // Not all permissions are shown if (m.Permissions.HasFlag(DSharpPlus.Permissions.CreateInstantInvite)) perms += ", Invite"; @@ -88,7 +84,7 @@ public async Task WhoIsCommand(InteractionContext ctx, [Option("user", "The user if (m.Permissions.HasFlag(DSharpPlus.Permissions.ManageEmojis)) perms += ", Manage Emojis"; if (m.Permissions.HasFlag(DSharpPlus.Permissions.UseApplicationCommands)) perms += ", Use Bot"; if (m.Permissions.HasFlag(DSharpPlus.Permissions.CreatePublicThreads)) perms += ", Use Threads"; - if (perms.Length > 0) embed.AddField("Permissions", perms[2..], false); + if (perms.Length > 0) embed.AddField("Permissions", perms[2..]); await ctx.CreateResponseAsync(embed.Build()); } catch (Exception ex) { diff --git a/src/Config.cs b/src/Config.cs new file mode 100644 index 0000000..727b175 --- /dev/null +++ b/src/Config.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using DSharpPlus.Entities; +using DSharpPlus.EventArgs; +using UPBot.UPBot_Code.DataClasses; + +namespace UPBot.UPBot_Code; + +public class TempSetRole { + public DiscordRole role; + public CancellationTokenSource cancel; + public ulong user; + internal ulong channel; + internal ulong message; + internal ulong emojiid; + internal string emojiname; + + public TempSetRole(ulong usr, DiscordRole r) { + user = usr; + role = r; + cancel = new CancellationTokenSource(); + channel = 0; + message = 0; + emojiid = 0; + emojiname = null; + } +} + +/// +/// This command is used to configure the bot, so roles and messages can be set for other servers. +/// author: CPU +/// +public class Configs { + private static readonly Dictionary Guilds = new(); + public static readonly Dictionary TrackChannels = new(); + public static readonly Dictionary> AdminRoles = new(); + public static readonly Dictionary SpamProtections = new(); + public static readonly Dictionary> Tags = new(); + public static readonly Dictionary> SpamLinks = new(); + public static readonly Dictionary> WhiteListLinks = new(); + + public static readonly Dictionary TempRoleSelected = new(); + + public static readonly Regex emjSnowflakeRE = new(@"<:[a-z0-9_]+:([0-9]+)>", RegexOptions.IgnoreCase | RegexOptions.Compiled); + public static readonly Regex roleSnowflakeRR = new("<@[^0-9]+([0-9]*)>", RegexOptions.Compiled); + public static readonly Regex emjUnicodeRE = new(@"[#*0-9]\uFE0F?\u20E3|©\uFE0F?|[®\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA]\uFE0F?|[\u231A\u231B]|[\u2328\u23CF]\uFE0F?|[\u23E9-\u23EC]|[\u23ED-\u23EF]\uFE0F?|\u23F0|[\u23F1\u23F2]\uFE0F?|\u23F3|[\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC]\uFE0F?|[\u25FD\u25FE]|[\u2600-\u2604\u260E\u2611]\uFE0F?|[\u2614\u2615]|\u2618\uFE0F?|\u261D(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642]\uFE0F?|[\u2648-\u2653]|[\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E]\uFE0F?|\u267F|\u2692\uFE0F?|\u2693|[\u2694-\u2697\u2699\u269B\u269C\u26A0]\uFE0F?|\u26A1|\u26A7\uFE0F?|[\u26AA\u26AB]|[\u26B0\u26B1]\uFE0F?|[\u26BD\u26BE\u26C4\u26C5]|\u26C8\uFE0F?|\u26CE|[\u26CF\u26D1\u26D3]\uFE0F?|\u26D4|\u26E9\uFE0F?|\u26EA|[\u26F0\u26F1]\uFE0F?|[\u26F2\u26F3]|\u26F4\uFE0F?|\u26F5|[\u26F7\u26F8]\uFE0F?|\u26F9(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\uFE0F(?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\u26FA\u26FD]|\u2702\uFE0F?|\u2705|[\u2708\u2709]\uFE0F?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|\u270F\uFE0F?|[\u2712\u2714\u2716\u271D\u2721]\uFE0F?|\u2728|[\u2733\u2734\u2744\u2747]\uFE0F?|[\u274C\u274E\u2753-\u2755\u2757]|\u2763\uFE0F?|\u2764(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uFE0F(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?)?|[\u2795-\u2797]|\u27A1\uFE0F?|[\u27B0\u27BF]|[\u2934\u2935\u2B05-\u2B07]\uFE0F?|[\u2B1B\u2B1C\u2B50\u2B55]|[\u3030\u303D\u3297\u3299]\uFE0F?|\uD83C(?:[\uDC04\uDCCF]|[\uDD70\uDD71\uDD7E\uDD7F]\uFE0F?|[\uDD8E\uDD91-\uDD9A]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDE01|\uDE02\uFE0F?|[\uDE1A\uDE2F\uDE32-\uDE36]|\uDE37\uFE0F?|[\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20]|[\uDF21\uDF24-\uDF2C]\uFE0F?|[\uDF2D-\uDF35]|\uDF36\uFE0F?|[\uDF37-\uDF7C]|\uDF7D\uFE0F?|[\uDF7E-\uDF84]|\uDF85(?:\uD83C[\uDFFB-\uDFFF])?|[\uDF86-\uDF93]|[\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F]\uFE0F?|[\uDFA0-\uDFC1]|\uDFC2(?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC3\uDFC4](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDFC5\uDFC6]|\uDFC7(?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC8\uDFC9]|\uDFCA(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDFCB\uDFCC](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\uFE0F(?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDFCD\uDFCE]\uFE0F?|[\uDFCF-\uDFD3]|[\uDFD4-\uDFDF]\uFE0F?|[\uDFE0-\uDFF0]|\uDFF3(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08)|\uFE0F(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?)?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?|[\uDFF5\uDFF7]\uFE0F?|[\uDFF8-\uDFFF])|\uD83D(?:[\uDC00-\uDC07]|\uDC08(?:\u200D\u2B1B)?|[\uDC09-\uDC14]|\uDC15(?:\u200D\uD83E\uDDBA)?|[\uDC16-\uDC3A]|\uDC3B(?:\u200D\u2744\uFE0F?)?|[\uDC3C-\uDC3E]|\uDC3F\uFE0F?|\uDC40|\uDC41(?:\u200D\uD83D\uDDE8\uFE0F?|\uFE0F(?:\u200D\uD83D\uDDE8\uFE0F?)?)?|[\uDC42\uDC43](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC44\uDC45]|[\uDC46-\uDC50](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC51-\uDC65]|[\uDC66\uDC67](?:\uD83C[\uDFFB-\uDFFF])?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF]|\uDC8B\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|\uDC6A|[\uDC6B-\uDC6D](?:\uD83C[\uDFFB-\uDFFF])?|\uDC6E(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDC70\uDC71](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC72(?:\uD83C[\uDFFB-\uDFFF])?|\uDC73(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDC74-\uDC76](?:\uD83C[\uDFFB-\uDFFF])?|\uDC77(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC78(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC79-\uDC7B]|\uDC7C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC7D-\uDC80]|[\uDC81\uDC82](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDC83(?:\uD83C[\uDFFB-\uDFFF])?|\uDC84|\uDC85(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC86\uDC87](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDC88-\uDC8E]|\uDC8F(?:\uD83C[\uDFFB-\uDFFF])?|\uDC90|\uDC91(?:\uD83C[\uDFFB-\uDFFF])?|[\uDC92-\uDCA9]|\uDCAA(?:\uD83C[\uDFFB-\uDFFF])?|[\uDCAB-\uDCFC]|\uDCFD\uFE0F?|[\uDCFF-\uDD3D]|[\uDD49\uDD4A]\uFE0F?|[\uDD4B-\uDD4E\uDD50-\uDD67]|[\uDD6F\uDD70\uDD73]\uFE0F?|\uDD74(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|\uDD75(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\uFE0F(?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDD76-\uDD79]\uFE0F?|\uDD7A(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD87\uDD8A-\uDD8D]\uFE0F?|\uDD90(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDD95\uDD96](?:\uD83C[\uDFFB-\uDFFF])?|\uDDA4|[\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA]\uFE0F?|[\uDDFB-\uDE2D]|\uDE2E(?:\u200D\uD83D\uDCA8)?|[\uDE2F-\uDE34]|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|[\uDE37-\uDE44]|[\uDE45-\uDE47](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDE48-\uDE4A]|\uDE4B(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDE4C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDE4D\uDE4E](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDE4F(?:\uD83C[\uDFFB-\uDFFF])?|[\uDE80-\uDEA2]|\uDEA3(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDEA4-\uDEB3]|[\uDEB4-\uDEB6](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDEB7-\uDEBF]|\uDEC0(?:\uD83C[\uDFFB-\uDFFF])?|[\uDEC1-\uDEC5]|\uDECB\uFE0F?|\uDECC(?:\uD83C[\uDFFB-\uDFFF])?|[\uDECD-\uDECF]\uFE0F?|[\uDED0-\uDED2\uDED5-\uDED7]|[\uDEE0-\uDEE5\uDEE9]\uFE0F?|[\uDEEB\uDEEC]|[\uDEF0\uDEF3]\uFE0F?|[\uDEF4-\uDEFC\uDFE0-\uDFEB])|\uD83E(?:\uDD0C(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD0D\uDD0E]|\uDD0F(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD10-\uDD17]|[\uDD18-\uDD1C](?:\uD83C[\uDFFB-\uDFFF])?|\uDD1D|[\uDD1E\uDD1F](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD20-\uDD25]|\uDD26(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDD27-\uDD2F]|[\uDD30-\uDD34](?:\uD83C[\uDFFB-\uDFFF])?|\uDD35(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDD36(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD37-\uDD39](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDD3A|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD3D\uDD3E](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDD3F-\uDD45\uDD47-\uDD76]|\uDD77(?:\uD83C[\uDFFB-\uDFFF])?|[\uDD78\uDD7A-\uDDB4]|[\uDDB5\uDDB6](?:\uD83C[\uDFFB-\uDFFF])?|\uDDB7|[\uDDB8\uDDB9](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDDBA|\uDDBB(?:\uD83C[\uDFFB-\uDFFF])?|[\uDDBC-\uDDCB]|[\uDDCD-\uDDCF](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDDD0|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1|[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF-\uDDB3\uDDBC\uDDBD])))?))?|[\uDDD2\uDDD3](?:\uD83C[\uDFFB-\uDFFF])?|\uDDD4(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|\uDDD5(?:\uD83C[\uDFFB-\uDFFF])?|[\uDDD6-\uDDDD](?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])", RegexOptions.Compiled); + public static readonly Regex chnnelRefRE = new(@"<#([0-9]+)>", RegexOptions.Compiled); + public static readonly Regex iconURLRE = new(@"http[s]{0,1}://[^\.\s]+\.[^\.\s]+\.[^\.\s]+/[^\.\s]+\.[^\s]+", RegexOptions.Compiled); + + private static ulong botId; + public static ulong BotId { get { return botId; } } + + internal static void LoadParams() { + try { + foreach (var g in Utils.GetClient().Guilds.Values) { + Guilds[g.Id] = g; + } + + // Admin Roles + List allAdminRoles = Database.GetAll(); + if (allAdminRoles != null) { + foreach (var r in allAdminRoles) { + ulong gid = r.Guild; + if (!AdminRoles.ContainsKey(gid)) AdminRoles[gid] = new List(); + AdminRoles[gid].Add(r.Role); + } + } + + // Tracking channels + List allTrackChannels = Database.GetAll(); + if (allTrackChannels != null) { + foreach (var r in allTrackChannels) { + TrackChannels[r.Guild] = r; + if (!Guilds.ContainsKey(r.Guild) && TryGetGuild(r.Guild) == null) continue; // Guild is missing + DiscordChannel ch = Guilds[r.Guild].GetChannel(r.ChannelId); + if (ch == null) { + Utils.Log("Missing track channel id " + r.ChannelId + " from Guild " + Guilds[r.Guild].Name, Guilds[r.Guild].Name); + TrackChannels[r.Guild] = null; + } + else { + r.channel = ch; + } + } + } + + // Tags + List allTags = Database.GetAll(); + if (allTags != null) { + foreach (var t in allTags) { + ulong gid = t.Guild; + if (!Tags.ContainsKey(gid)) Tags[gid] = new List(); + Tags[gid].Add(t); + } + } + + // SpamProtection + List spamProtections = Database.GetAll(); + if (spamProtections != null) { + foreach (var sp in spamProtections) { + SpamProtections[sp.Guild] = sp; + } + } + List links = Database.GetAll(); + if (links != null) { + foreach (var sl in links) { + if (sl.whitelist) { + if (!WhiteListLinks.ContainsKey(sl.Guild)) WhiteListLinks[sl.Guild] = new List(); + WhiteListLinks[sl.Guild].Add(sl.link); + } + else { + if (!SpamLinks.ContainsKey(sl.Guild)) SpamLinks[sl.Guild] = new List(); + SpamLinks[sl.Guild].Add(sl.link); + } + } + } + + // Fill all missing guilds + foreach (var g in Guilds.Keys) { + TrackChannels.TryAdd(g, null); + if (!AdminRoles.ContainsKey(g)) AdminRoles[g] = new List(); + SpamProtections.TryAdd(g, null); + if (!Tags.ContainsKey(g)) Tags[g] = new List(); + TempRoleSelected.TryAdd(g, null); + if (!SpamLinks.ContainsKey(g)) SpamLinks[g] = new List(); + if (!WhiteListLinks.ContainsKey(g)) WhiteListLinks[g] = new List(); + } + + + botId = Utils.GetClient().CurrentUser.Id; + + Utils.Log("Params fully loaded. " + SpamProtections.Count + " Discord servers found", null); + } catch (Exception ex) { + Utils.Log("Error in ConfigLoadParams:" + ex.Message, null); + } + } + + + public static DiscordGuild TryGetGuild(ulong id) { + if (Guilds.TryGetValue(id, out var guild)) return guild; + + Task.Delay(1000); + int t = 0; + + // 10 secs max for client + while (Utils.GetClient() == null) { + t++; Task.Delay(t); + if (t > 10) { + Utils.Log("We are not connecting! (no client)", null); + throw new Exception("No discord client"); + } + } + + // 10 secs max for guilds + t = 0; + while (Utils.GetClient().Guilds == null) { + t++; Task.Delay(t); + if (t > 10) { + Utils.Log("We are not connecting! (no guilds)", null); + throw new Exception("No guilds avilable"); + } + } + + // 30 secs max for guilds coubnt + t = 0; + while (Utils.GetClient().Guilds.Count == 0) { + t++; Task.Delay(t); + if (t > 30) { + Utils.Log("We are not connecting! (guilds count is zero)", null); + throw new Exception("The bot seems to be in no guild"); + } + } + + IReadOnlyDictionary cguilds = Utils.GetClient().Guilds; + foreach (var guildId in cguilds.Keys) + { + Guilds.TryAdd(guildId, cguilds[guildId]); + } + if (Guilds.TryGetValue(id, out var getGuild)) return getGuild; + + return null; + } + + + + internal static Task NewGuildAdded(DSharpPlus.DiscordClient _, GuildCreateEventArgs e) { + DiscordGuild g = e.Guild; + ulong gid = g.Id; + // Do we have the guild? + if (TryGetGuild(gid) == null) { // No, that is a problem. + Utils.Log("Impossible to connect to a new Guild: " + g.Name, null); + return Task.FromResult(0); + } + // Fill all values + TrackChannels[gid] = null; + AdminRoles[gid] = new List(); + SpamProtections[gid] = null; + Tags[gid] = new List(); + TempRoleSelected[gid] = null; + Utils.Log("Guild " + g.Name + " joined", g.Name); + Utils.Log("Guild " + g.Name + " joined", null); + + return Task.FromResult(0); + } + + internal static bool IsAdminRole(ulong guild, DiscordRole role) { + if (AdminRoles[guild].Contains(role.Id)) return true; + return role.Permissions.HasFlag(DSharpPlus.Permissions.Administrator); // Fall back + } + internal static bool HasAdminRole(ulong guild, IEnumerable roles, bool withManageMessages) { + if (AdminRoles[guild] == null || AdminRoles[guild].Count == 0) return true; + foreach (var r in roles) + if (AdminRoles[guild].Contains(r.Id)) return true; + foreach (var r in roles) + if (r.Permissions.HasFlag(DSharpPlus.Permissions.Administrator) || (withManageMessages && r.Permissions.HasFlag(DSharpPlus.Permissions.ManageMessages))) return true; + return false; + } + + internal static string GetAdminsMentions(ulong gid) { + if (!AdminRoles.ContainsKey(gid) || AdminRoles[gid].Count == 0) return "Admins"; + string res = ""; + foreach (var rid in AdminRoles[gid]) { + DiscordRole r = Guilds[gid].GetRole(rid); + if (r != null) res += r.Mention + " "; + } + if (res.Length > 0) return res[..^1]; + return "Admins"; + } + +} \ No newline at end of file diff --git a/UPBot Code/DataClasses/AdminRole.cs b/src/DataClasses/AdminRole.cs similarity index 100% rename from UPBot Code/DataClasses/AdminRole.cs rename to src/DataClasses/AdminRole.cs diff --git a/UPBot Code/DataClasses/Entity.cs b/src/DataClasses/Entity.cs similarity index 87% rename from UPBot Code/DataClasses/Entity.cs rename to src/DataClasses/Entity.cs index 1f719e0..7957e2b 100644 --- a/UPBot Code/DataClasses/Entity.cs +++ b/src/DataClasses/Entity.cs @@ -6,11 +6,11 @@ public class Entity { public void Debug() { Type t = GetType(); - string msg = t.ToString() + "\n"; + string msg = t + "\n"; foreach (var a in t.GetFields()) { msg += "- " + a.Name + " " + a.FieldType.Name; foreach (CustomAttributeData attr in a.CustomAttributes) - msg += " " + attr.ToString(); + msg += " " + attr; msg += "\n"; } diff --git a/UPBot Code/DataClasses/ExampleEntity.cs b/src/DataClasses/ExampleEntity.cs similarity index 73% rename from UPBot Code/DataClasses/ExampleEntity.cs rename to src/DataClasses/ExampleEntity.cs index b748e8c..521d7e5 100644 --- a/UPBot Code/DataClasses/ExampleEntity.cs +++ b/src/DataClasses/ExampleEntity.cs @@ -1,6 +1,4 @@ -using System; - -public class ExampleEntity : Entity { +public class ExampleEntity : Entity { [Key] public int id; public string name; diff --git a/UPBot Code/DataClasses/SpamLink.cs b/src/DataClasses/SpamLink.cs similarity index 100% rename from UPBot Code/DataClasses/SpamLink.cs rename to src/DataClasses/SpamLink.cs diff --git a/UPBot Code/DataClasses/SpamProtection.cs b/src/DataClasses/SpamProtection.cs similarity index 74% rename from UPBot Code/DataClasses/SpamProtection.cs rename to src/DataClasses/SpamProtection.cs index 2810030..f9bed86 100644 --- a/UPBot Code/DataClasses/SpamProtection.cs +++ b/src/DataClasses/SpamProtection.cs @@ -1,6 +1,4 @@ -using DSharpPlus.Entities; - -public class SpamProtection : Entity { +public class SpamProtection : Entity { [Key] public ulong Guild; public bool protectDiscord; public bool protectSteam; diff --git a/UPBot Code/DataClasses/TagBase.cs b/src/DataClasses/TagBase.cs similarity index 100% rename from UPBot Code/DataClasses/TagBase.cs rename to src/DataClasses/TagBase.cs diff --git a/UPBot Code/DataClasses/Timezone.cs b/src/DataClasses/Timezone.cs similarity index 74% rename from UPBot Code/DataClasses/Timezone.cs rename to src/DataClasses/Timezone.cs index 4eb8cef..e39951d 100644 --- a/UPBot Code/DataClasses/Timezone.cs +++ b/src/DataClasses/Timezone.cs @@ -1,7 +1,4 @@ -using System; -using System.Text.RegularExpressions; - -public class Timezone : Entity { +public class Timezone : Entity { [Key] public ulong User; // Timezones are not related to guilds public float UtcOffset; diff --git a/UPBot Code/DataClasses/TrackChannel.cs b/src/DataClasses/TrackChannel.cs similarity index 90% rename from UPBot Code/DataClasses/TrackChannel.cs rename to src/DataClasses/TrackChannel.cs index 04cbe6f..007c069 100644 --- a/UPBot Code/DataClasses/TrackChannel.cs +++ b/src/DataClasses/TrackChannel.cs @@ -1,5 +1,7 @@ using DSharpPlus.Entities; +namespace UPBot.UPBot_Code.DataClasses; + public class TrackChannel : Entity { [Key] public ulong Guild; public ulong ChannelId; @@ -18,4 +20,4 @@ public TrackChannel(ulong guild, ulong channel) { ChannelId = channel; } -} +} \ No newline at end of file diff --git a/UPBot Code/Database.cs b/src/Database.cs similarity index 78% rename from UPBot Code/Database.cs rename to src/Database.cs index 08c8aa3..b9376a5 100644 --- a/UPBot Code/Database.cs +++ b/src/Database.cs @@ -1,8 +1,10 @@ using System; -using System.IO; +using System.Collections.Generic; using System.Data.SQLite; +using System.IO; using System.Reflection; -using System.Collections.Generic; + +namespace UPBot.UPBot_Code; public class Database { static SQLiteConnection connection = null; @@ -139,26 +141,26 @@ public static void AddTable(Type t) { if (blob) sql += field.Name + " BLOB"; else switch (field.FieldType.Name.ToLowerInvariant()) { - case "int8": sql += field.Name + " SMALLINT"; break; - case "uint8": sql += field.Name + " SMALLINT"; break; - case "byte": sql += field.Name + " SMALLINT"; break; - case "int32": sql += field.Name + " INT"; break; - case "int64": sql += field.Name + " BIGINT"; break; - case "uint64": sql += field.Name + " UNSIGNED BIG INT"; break; - case "string": { - if (comment) sql += field.Name + " TEXT"; - else sql += field.Name + " VARCHAR(256)"; - break; - } - case "bool": sql += field.Name + " TINYINT"; break; - case "boolean": sql += field.Name + " TINYINT"; break; - case "datetime": sql += field.Name + " NUMERIC"; break; - case "single": sql += field.Name + " REAL"; break; - case "double": sql += field.Name + " REAL"; break; - case "byte[]": sql += field.Name + " BLOB"; break; - default: - throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); + case "int8": sql += field.Name + " SMALLINT"; break; + case "uint8": sql += field.Name + " SMALLINT"; break; + case "byte": sql += field.Name + " SMALLINT"; break; + case "int32": sql += field.Name + " INT"; break; + case "int64": sql += field.Name + " BIGINT"; break; + case "uint64": sql += field.Name + " UNSIGNED BIG INT"; break; + case "string": { + if (comment) sql += field.Name + " TEXT"; + else sql += field.Name + " VARCHAR(256)"; + break; } + case "bool": sql += field.Name + " TINYINT"; break; + case "boolean": sql += field.Name + " TINYINT"; break; + case "datetime": sql += field.Name + " NUMERIC"; break; + case "single": sql += field.Name + " REAL"; break; + case "double": sql += field.Name + " REAL"; break; + case "byte[]": sql += field.Name + " BLOB"; break; + default: + throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); + } if (notnull) sql += " NOT NULL"; sql += ", "; } @@ -194,26 +196,26 @@ public static void AddTable(Type t) { if (blob) sql += field.Name + " BLOB"; else switch (field.FieldType.Name.ToLowerInvariant()) { - case "int8": sql += field.Name + " SMALLINT"; break; - case "uint8": sql += field.Name + " SMALLINT"; break; - case "byte": sql += field.Name + " SMALLINT"; break; - case "int32": sql += field.Name + " INT"; break; - case "int64": sql += field.Name + " BIGINT"; break; - case "uint64": sql += field.Name + " UNSIGNED BIG INT"; break; - case "string": { - if (comment) sql += field.Name + " TEXT"; - else sql += field.Name + " VARCHAR(256)"; - break; - } - case "bool": sql += field.Name + " TINYINT"; break; - case "boolean": sql += field.Name + " TINYINT"; break; - case "datetime": sql += field.Name + " NUMERIC"; break; - case "single": sql += field.Name + " REAL"; break; - case "double": sql += field.Name + " REAL"; break; - case "byte[]": sql += field.Name + " BLOB"; break; - default: - throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); + case "int8": sql += field.Name + " SMALLINT"; break; + case "uint8": sql += field.Name + " SMALLINT"; break; + case "byte": sql += field.Name + " SMALLINT"; break; + case "int32": sql += field.Name + " INT"; break; + case "int64": sql += field.Name + " BIGINT"; break; + case "uint64": sql += field.Name + " UNSIGNED BIG INT"; break; + case "string": { + if (comment) sql += field.Name + " TEXT"; + else sql += field.Name + " VARCHAR(256)"; + break; } + case "bool": sql += field.Name + " TINYINT"; break; + case "boolean": sql += field.Name + " TINYINT"; break; + case "datetime": sql += field.Name + " NUMERIC"; break; + case "single": sql += field.Name + " REAL"; break; + case "double": sql += field.Name + " REAL"; break; + case "byte[]": sql += field.Name + " BLOB"; break; + default: + throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); + } if (notnull) sql += " NOT NULL"; sql += ";"; command.CommandText = sql; @@ -221,7 +223,6 @@ public static void AddTable(Type t) { // We need to fill the default value - sql = null; switch (field.FieldType.Name.ToLowerInvariant()) { case "int8": case "uint8": @@ -234,11 +235,11 @@ public static void AddTable(Type t) { case "datetime": case "single": case "double": - sql = "UPDATE " + t.ToString() + " SET " + field.Name + "= 0;"; break; + sql = "UPDATE " + t + " SET " + field.Name + "= 0;"; break; case "string": case "byte[]": - sql = "UPDATE " + t.ToString() + " SET " + field.Name + "= NULL;"; break; + sql = "UPDATE " + t + " SET " + field.Name + "= NULL;"; break; default: throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); @@ -268,26 +269,26 @@ public static void AddTable(Type t) { } if (blob) ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.ByteArray, index = -1 }; else switch (field.FieldType.Name.ToLowerInvariant()) { - case "int8": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Byte, index = -1 }; break; - case "uint8": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Byte, index = -1 }; break; - case "byte": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Byte, index = -1 }; break; - case "int32": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Int, index = -1 }; break; - case "int64": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Long, index = -1 }; break; - case "uint64": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.ULong, index = -1 }; break; - case "string": { - if (blob) ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Blob, index = -1 }; - else ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.String, index = -1 }; - break; - } - case "bool": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Bool, index = -1 }; break; - case "boolean": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Bool, index = -1 }; break; - case "datetime": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Date, index = -1 }; break; - case "single": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Float, index = -1 }; break; - case "double": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Double, index = -1 }; break; - case "byte[]": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.ByteArray, index = -1 }; break; - default: - throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); + case "int8": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Byte, index = -1 }; break; + case "uint8": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Byte, index = -1 }; break; + case "byte": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Byte, index = -1 }; break; + case "int32": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Int, index = -1 }; break; + case "int64": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Long, index = -1 }; break; + case "uint64": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.ULong, index = -1 }; break; + case "string": { + if (blob) ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Blob, index = -1 }; + else ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.String, index = -1 }; + break; } + case "bool": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Bool, index = -1 }; break; + case "boolean": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Bool, index = -1 }; break; + case "datetime": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Date, index = -1 }; break; + case "single": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Float, index = -1 }; break; + case "double": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.Double, index = -1 }; break; + case "byte[]": ed.fields[field.Name] = new ColDef { name = field.Name, ft = FieldType.ByteArray, index = -1 }; break; + default: + throw new Exception("Unmanaged type: " + field.FieldType.Name + " for class " + t.Name); + } } if (keygens.Count == 0) throw new Exception("Missing key for class " + t); ed.keys = keygens.ToArray(); @@ -301,15 +302,15 @@ public static void AddTable(Type t) { keynum++; } - ed.count = "SELECT Count(*) FROM " + t.ToString() + " WHERE " + theKey; - ed.select = "SELECT * FROM " + t.ToString(); + ed.count = "SELECT Count(*) FROM " + t + " WHERE " + theKey; + ed.select = "SELECT * FROM " + t; ed.delete = "DELETE FROM " + t.Name + " WHERE " + theKey; - ed.selectOne = "SELECT * FROM " + t.ToString() + " WHERE " + theKey; + ed.selectOne = "SELECT * FROM " + t + " WHERE " + theKey; // Insert, Update - string insert = "INSERT INTO " + t.ToString() + " ("; + string insert = "INSERT INTO " + t + " ("; string insertpost = ") VALUES ("; - string update = "UPDATE " + t.ToString() + " SET "; + string update = "UPDATE " + t + " SET "; bool donefirst = false; foreach (FieldInfo field in t.GetFields()) { bool ignore = false; @@ -437,7 +438,6 @@ public static T GetByKey(params object[] keys) { Type t = typeof(T); if (reader.Read()) { T val = (T)Activator.CreateInstance(t); - num = 0; foreach (FieldInfo field in t.GetFields()) { ColDef cd = ed.fields[field.Name]; num = cd.index; @@ -477,7 +477,7 @@ public static List GetAll() { List res = new List(); while (reader.Read()) { T val = (T)Activator.CreateInstance(t); - int num = 0; + int num; foreach (FieldInfo field in t.GetFields()) { ColDef cd = ed.fields[field.Name]; num = cd.index; @@ -511,16 +511,16 @@ public static List GetAll() { /* - GetValue - GetAllValues +GetValue +GetAllValues - */ + */ class EntityDef { public Type type; public FieldInfo[] keys; - public Dictionary fields = new Dictionary(); + public Dictionary fields = new(); public string count; public string select; public string insert; @@ -550,5 +550,4 @@ public enum FieldType { Blob, ByteArray, } -} - +} \ No newline at end of file diff --git a/UPBot Code/Program.cs b/src/Program.cs similarity index 97% rename from UPBot Code/Program.cs rename to src/Program.cs index 474df9c..6a6a149 100644 --- a/UPBot Code/Program.cs +++ b/src/Program.cs @@ -7,6 +7,8 @@ using DSharpPlus.Interactivity.Extensions; using DSharpPlus.SlashCommands; using UPBot.DiscordRPC; +using UPBot.UPBot_Code; +using UPBot.UPBot_Code.DataClasses; namespace UPBot { class Program { @@ -36,7 +38,7 @@ static void Main(string[] args) { } } - readonly private static CancellationTokenSource exitToken = new(); + private static readonly CancellationTokenSource exitToken = new(); static async Task MainAsync(string token) { try { @@ -113,12 +115,12 @@ static async Task MainAsync(string token) { if (t++ > 10) { Console.ForegroundColor = ConsoleColor.Red; Utils.Log("CRITICAL ERROR: We are not connecting! (no guilds)", null); - Console.WriteLine("CRITICAL ERROR: No guilds avilable"); + Console.WriteLine("CRITICAL ERROR: No guilds available"); return; } } - // 30 secs max for guilds coubnt + // 30 secs max for guilds count t = 0; while (Utils.GetClient().Guilds.Count == 0) { await Task.Delay(1000); diff --git a/UPBot Code/StringDistance.cs b/src/StringDistance.cs similarity index 84% rename from UPBot Code/StringDistance.cs rename to src/StringDistance.cs index bf6254d..ba62573 100644 --- a/UPBot Code/StringDistance.cs +++ b/src/StringDistance.cs @@ -1,16 +1,18 @@ using System; +namespace UPBot.UPBot_Code; + public static class StringDistance { /* The Winkler modification will not be applied unless the - * percent match was at or above the mWeightThreshold percent - * without the modification. - * Winkler's paper used a default value of 0.7 - */ + * percent match was at or above the mWeightThreshold percent + * without the modification. + * Winkler's paper used a default value of 0.7 + */ private static readonly double mWeightThreshold = 0.55; /* Size of the prefix to be concidered by the Winkler modification. - * Winkler's paper used a default value of 4 - */ + * Winkler's paper used a default value of 4 + */ private static readonly int mNumChars = 5; @@ -73,8 +75,8 @@ public static double JWProximity(string aString1, string aString2) { // System.Diagnostics.Debug.WriteLine("numCommon=" + numCommon + " numTransposed=" + numTransposed); double lNumCommonD = lNumCommon; double lWeight = (lNumCommonD / lLen1 - + lNumCommonD / lLen2 - + (lNumCommon - lNumTransposed) / lNumCommonD) / 3.0; + + lNumCommonD / lLen2 + + (lNumCommon - lNumTransposed) / lNumCommonD) / 3.0; if (lWeight <= mWeightThreshold) return lWeight; int lMax = Math.Min(mNumChars, Math.Min(aString1.Length, aString2.Length)); @@ -125,12 +127,13 @@ public static int DLDistance(string s, string t) { int[,] matrix = new int[bounds.Height, bounds.Width]; - for (int height = 0; height < bounds.Height; height++) { matrix[height, 0] = height; }; - for (int width = 0; width < bounds.Width; width++) { matrix[0, width] = width; }; + for (int height = 0; height < bounds.Height; height++) { matrix[height, 0] = height; } + + for (int width = 0; width < bounds.Width; width++) { matrix[0, width] = width; } for (int height = 1; height < bounds.Height; height++) { for (int width = 1; width < bounds.Width; width++) { - int cost = (s[height - 1] == t[width - 1]) ? 0 : 1; + int cost = s[height - 1] == t[width - 1] ? 0 : 1; int insertion = matrix[height, width - 1] + 1; int deletion = matrix[height - 1, width] + 1; int substitution = matrix[height - 1, width - 1] + cost; @@ -155,7 +158,7 @@ public static int Distance(string a, string b) { double jw = JWDistance(a, b); float dl = DLDistance(a, b) / len; float xtra = (10 + Math.Abs(a.Length - b.Length)) / (float)Math.Sqrt(len); - float cont = (a.IndexOf(b) != -1 || b.IndexOf(a) != -1) ? .1f : 1; + float cont = a.IndexOf(b) != -1 || b.IndexOf(a) != -1 ? .1f : 1; return (int)(1000 * jw * dl * xtra * cont); } @@ -173,18 +176,18 @@ public static int DistancePart(string a, string b) { // one part is the same or contained or close enough to another part foreach (string p1 in pa) - foreach (string p2 in pb) { - if (p1 == p2) dist *= .1f; - else if (p2.Length > 2 && p1.Length > p2.Length && p1.IndexOf(p2) != -1) dist *= .5f; - else if (p1.Length > 2 && p2.Length > p1.Length && p2.IndexOf(p1) != -1) dist *= .5f; - else { - float minLen = Math.Min(p1.Length, p2.Length); - float dld = DLDistance(p1, p2) / minLen; - if (dld < .05f) dld = .05f; - if (dld > 2) dld = 2; - dist *= dld; - } + foreach (string p2 in pb) { + if (p1 == p2) dist *= .1f; + else if (p2.Length > 2 && p1.Length > p2.Length && p1.IndexOf(p2) != -1) dist *= .5f; + else if (p1.Length > 2 && p2.Length > p1.Length && p2.IndexOf(p1) != -1) dist *= .5f; + else { + float minLen = Math.Min(p1.Length, p2.Length); + float dld = DLDistance(p1, p2) / minLen; + if (dld < .05f) dld = .05f; + if (dld > 2) dld = 2; + dist *= dld; } + } if (dist < 0) dist = 0; else { float minLen = Math.Min(a.Length, b.Length); diff --git a/UPBot Code/Utils.cs b/src/Utils.cs similarity index 95% rename from UPBot Code/Utils.cs rename to src/Utils.cs index 6c31d9a..fb8b759 100644 --- a/UPBot Code/Utils.cs +++ b/src/Utils.cs @@ -1,11 +1,13 @@ -using DSharpPlus; -using DSharpPlus.Entities; -using DSharpPlus.SlashCommands; using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Threading.Tasks; +using DSharpPlus; +using DSharpPlus.Entities; +using DSharpPlus.SlashCommands; + +namespace UPBot.UPBot_Code; /// /// Utility functions that don't belong to a specific class or a specific command @@ -15,7 +17,7 @@ public static class Utils { public const int vmajor = 0, vminor = 3, vbuild = 4; public const char vrev = 'c'; public static string LogsFolder = "./"; - public readonly static System.Diagnostics.StackTrace sttr = new(); + public static readonly System.Diagnostics.StackTrace sttr = new(); /// /// Common colors @@ -34,7 +36,7 @@ private class LogInfo { public string path; } - readonly private static Dictionary logs = new(); + private static readonly Dictionary logs = new(); public static string GetVersion() { return vmajor + "." + vminor + "." + vbuild + vrev + " - 2023/01/08"; @@ -74,14 +76,13 @@ public static void InitClient(DiscordClient c) { public static void InitLogs(string guild) { string logPath = Path.Combine(LogsFolder, "BotLogs " + guild + " " + DateTime.Now.ToString("yyyyMMdd") + ".logs"); LogInfo l; - if (logs.ContainsKey(guild)) l = logs[guild]; + if (logs.TryGetValue(guild, out var log)) l = log; else { l = new LogInfo(); logs[guild] = l; } l.path = logPath; - if (File.Exists(logPath)) logs[guild].sw = new StreamWriter(logPath, append: true); - else logs[guild].sw = File.CreateText(logPath); + logs[guild].sw = File.Exists(logPath) ? new StreamWriter(logPath, append: true) : File.CreateText(logPath); } public static string GetLogsPath(string guild) { @@ -120,8 +121,8 @@ public static int DeleteAllLogs(string guild) { } } LogInfo li = null; - if (logs.ContainsKey(guild)) { - li = logs[guild]; + if (logs.TryGetValue(guild, out var log)) { + li = log; li.sw.Close(); li.sw = null; } @@ -266,7 +267,7 @@ public static string GetEmojiURL(EmojiEnum emoji) { public static string GetEmojiSnowflakeID(EmojiEnum emoji) { int index = (int)emoji; if (index < 0 || index >= emojiNames.Length) { - return "<" + thinkingAsError.GetDiscordName() + thinkingAsError.Id.ToString() + ">"; + return "<" + thinkingAsError.GetDiscordName() + thinkingAsError.Id + ">"; } if (!string.IsNullOrEmpty(emojiSnowflakes[index])) return emojiSnowflakes[index]; @@ -276,7 +277,7 @@ public static string GetEmojiSnowflakeID(EmojiEnum emoji) { Console.ForegroundColor = ConsoleColor.White; return thinkingAsError; } - emojiSnowflakes[index] = "<" + res.GetDiscordName() + res.Id.ToString() + ">"; + emojiSnowflakes[index] = "<" + res.GetDiscordName() + res.Id + ">"; return emojiSnowflakes[index]; } @@ -287,7 +288,7 @@ public static string GetEmojiSnowflakeID(EmojiEnum emoji) { /// A string representation of the emoji that can be used in a message public static string GetEmojiSnowflakeID(DiscordEmoji emoji) { if (emoji == null) return ""; - return "<" + emoji.GetDiscordName() + emoji.Id.ToString() + ">"; + return "<" + emoji.GetDiscordName() + emoji.Id + ">"; } internal static void LogUserCommand(InteractionContext ctx) { @@ -305,7 +306,7 @@ internal static void LogUserCommand(InteractionContext ctx) { /// /// internal static void Log(string msg, string guild) { - if (guild == null) guild = "GLOBAL"; + guild ??= "GLOBAL"; Console.WriteLine($"{guild}: {msg}"); try { if (!logs.ContainsKey(guild)) InitLogs(guild); @@ -373,7 +374,7 @@ static void DelayAfterAWhile(DiscordMessage msg, int delay) { } catch (Exception) { } } - internal async static void DefaultNotAllowed(InteractionContext ctx) { + internal static async void DefaultNotAllowed(InteractionContext ctx) { await ctx.CreateResponseAsync($"The command {ctx.CommandName} is not allowed."); await DeleteDelayed(15, ctx.GetOriginalResponseAsync().Result); } @@ -399,4 +400,4 @@ public enum EmojiEnum { AutoRefactored = 13, CodeMonkey = 14, TaroDev = 15, -} +} \ No newline at end of file