From a87fcd6ad9a83b42764eb088cbefe2b15178addf Mon Sep 17 00:00:00 2001 From: Adam R Grey Date: Mon, 22 May 2023 00:58:36 -0400 Subject: [PATCH] start to structure code for multiplatofrm --- .vscode/launch.json | 2 +- .vscode/tasks.json | 6 +- Configuration.cs | 44 +++ Conversion/ConversionConfig.cs | 2 +- Conversion/Converter.cs | 2 +- Conversion/ExchangePairs.cs | 2 +- Discord/DiscordInterface.cs | 330 ++++++++++++++++++ .../SlashCommandsHelper.cs | 47 +-- Features.cs | 6 +- Program.cs | 326 +---------------- Shared.cs | 2 +- appsettings.example.json | 4 - externalProcess.cs | 2 +- shtikbot-discord.csproj => vassago.csproj | 2 +- 14 files changed, 409 insertions(+), 368 deletions(-) create mode 100644 Configuration.cs create mode 100644 Discord/DiscordInterface.cs rename SlashCommandsHelper.cs => Discord/SlashCommandsHelper.cs (75%) delete mode 100644 appsettings.example.json rename shtikbot-discord.csproj => vassago.csproj (96%) diff --git a/.vscode/launch.json b/.vscode/launch.json index c134b67..cee5728 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net7.0/shtikbot-discord.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/vassago.dll", "args": [], "cwd": "${workspaceFolder}", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console diff --git a/.vscode/tasks.json b/.vscode/tasks.json index af04180..bc53887 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,7 +7,7 @@ "type": "process", "args": [ "build", - "${workspaceFolder}/shtikbot-discord.csproj", + "${workspaceFolder}/vassago.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -19,7 +19,7 @@ "type": "process", "args": [ "publish", - "${workspaceFolder}/shtikbot-discord.csproj", + "${workspaceFolder}/vassago.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -32,7 +32,7 @@ "args": [ "watch", "run", - "${workspaceFolder}/shtikbot-discord.csproj", + "${workspaceFolder}/vassago.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], diff --git a/Configuration.cs b/Configuration.cs new file mode 100644 index 0000000..d41b49c --- /dev/null +++ b/Configuration.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json; + +namespace vassago +{ + public class Configuration + { + public string ExchangePairsLocation {get;set;} + public IEnumerable DiscordTokens { get; set; } + private Configuration(){} + public static Configuration Parse(string configurationPath) + { + if(string.IsNullOrWhiteSpace(configurationPath)) + return null; + + if (!File.Exists(configurationPath)) + { + File.WriteAllText("sample-appsettings.json", JsonConvert.SerializeObject(new Configuration(), Formatting.Indented)); + throw new ConfigurationException($"could not find configuration at {configurationPath}! copying sample to that spot."); + } + var fileContents = File.ReadAllText(configurationPath); + if (string.IsNullOrWhiteSpace(fileContents)) + { + File.WriteAllText("sample-appsettings.json", JsonConvert.SerializeObject(new Configuration(), Formatting.Indented)); + throw new ConfigurationException($"configuration file at {configurationPath} was empty! overwriting with sample settings."); + } + + var conf = JsonConvert.DeserializeObject(fileContents); + + if (conf == null) + { + File.WriteAllText("sample-appsettings.json", JsonConvert.SerializeObject(new Configuration(), Formatting.Indented)); + throw new ConfigurationException($"configuration file at {configurationPath} was empty! overwriting with sample settings."); + } + return conf; + } + public class ConfigurationException : Exception + { + public ConfigurationException(string message) : base(message){} + } + } +} \ No newline at end of file diff --git a/Conversion/ConversionConfig.cs b/Conversion/ConversionConfig.cs index 7ded3d0..3f6461f 100644 --- a/Conversion/ConversionConfig.cs +++ b/Conversion/ConversionConfig.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace silverworker_discord.Conversion +namespace vassago.Conversion { public class ConversionConfig { diff --git a/Conversion/Converter.cs b/Conversion/Converter.cs index 531e2b6..f556558 100644 --- a/Conversion/Converter.cs +++ b/Conversion/Converter.cs @@ -12,7 +12,7 @@ using Discord.WebSocket; using Newtonsoft.Json; using QRCoder; -namespace silverworker_discord.Conversion +namespace vassago.Conversion { public static class Converter { diff --git a/Conversion/ExchangePairs.cs b/Conversion/ExchangePairs.cs index 9bb8249..d988950 100644 --- a/Conversion/ExchangePairs.cs +++ b/Conversion/ExchangePairs.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace silverworker_discord.Conversion +namespace vassago.Conversion { public class ExchangePairs { diff --git a/Discord/DiscordInterface.cs b/Discord/DiscordInterface.cs new file mode 100644 index 0000000..891e2b1 --- /dev/null +++ b/Discord/DiscordInterface.cs @@ -0,0 +1,330 @@ +//https://discord.com/oauth2/authorize?client_id=913003037348491264&permissions=274877942784&scope=bot%20messages.read +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Discord; +using Discord.WebSocket; + +namespace vassago.Discord_Vassago; + +public class DiscordInterface +{ + private DiscordSocketClient _client; + private bool eventsSignedUp = false; + + public async Task Init(string token) + { + _client = new DiscordSocketClient(new DiscordSocketConfig() { GatewayIntents = GatewayIntents.All }); + + _client.Log += (msg) => { + Console.WriteLine(msg.ToString()); + return Task.CompletedTask; + }; + + _client.Ready += () => Task.Run(() => + { + if (!eventsSignedUp) + { + eventsSignedUp = true; + Console.WriteLine("Bot is connected! going to sign up for message received and user joined in client ready"); + + _client.MessageReceived += MessageReceived; + _client.UserJoined += UserJoined; + //_client.ButtonExecuted += MyButtonHandler; + _client.SlashCommandExecuted += SlashCommandHandler; + SlashCommandsHelper.Register(_client).GetAwaiter().GetResult(); + } + else + { + Console.WriteLine("bot appears to be RE connected, so I'm not going to sign up twice"); + } + }); + + await _client.LoginAsync(TokenType.Bot, token); + await _client.StartAsync(); + } + +#pragma warning disable 4014 //the "you're not awaiting this" warning. yeah I know, that's the beauty of an async method lol +#pragma warning disable 1998 //the "it's async but you're not awaiting anything". + private async Task MessageReceived(SocketMessage messageParam) +#pragma warning restore 1998 + { + var message = messageParam as SocketUserMessage; + if (message == null) return; + if (message.Author.Id == _client.CurrentUser.Id) return; + + Console.WriteLine($"#{message.Channel}[{DateTime.Now}][{message.Author.Username} [id={message.Author.Id}]][msg id: {message.Id}] {message.Content}"); + + if (message.Author.IsWebhook || message.Author.IsBot) + { + if (message.Author.Id == 159985870458322944) //MEE6 + { + if (message.Content?.Contains("you just advanced") == true) + { + var newText = Regex.Replace(message.Content, "<[^>]*>", message.Author.Username); + newText = Regex.Replace(newText, "level [\\d]+", "level -1"); + Features.mock(newText, message); + } + } + } + else + { + var didThing = false; + var contentWithoutMention = message.Content; + var mentionedMe = false; + if (message.MentionedUsers?.FirstOrDefault(muid => muid.Id == _client.CurrentUser.Id) != null) + { + var mentionOfMe = "<@" + _client.CurrentUser.Id + ">"; + contentWithoutMention = message.Content.Replace(mentionOfMe + " ", null); + contentWithoutMention = contentWithoutMention.Replace(mentionOfMe, null); + mentionedMe = true; + } + var wordLikes = message.Content.Split(' ', StringSplitOptions.TrimEntries); + var links = wordLikes?.Where(wl => Uri.IsWellFormedUriString(wl, UriKind.Absolute)).Select(wl => new Uri(wl)); + if (links != null && links.Count() > 0) + { + foreach (var link in links) + { + if (link.Host.EndsWith(".tiktok.com")) + { + Features.detiktokify(link, message); + didThing = true; + } + } + } + + if (message.Attachments?.Count > 0) + { + Console.WriteLine($"{message.Attachments.Count} attachments"); + var appleReactions = false; + foreach (var att in message.Attachments) + { + if (att.Filename?.EndsWith(".heic") == true) + { + Features.deheic(message, att); + appleReactions = true; + didThing = true; + } + } + if (appleReactions) + { + message.AddReactionAsync(new Emoji("\U0001F34F")); + } + } + + var msgText = message.Content?.ToLower(); + if (!string.IsNullOrWhiteSpace(msgText)) + { + if (Regex.IsMatch(msgText, "\\bcloud( |-)?native\\b", RegexOptions.IgnoreCase) || + Regex.IsMatch(msgText, "\\benterprise( |-)?(level|solution)\\b", RegexOptions.IgnoreCase)) + { + switch (Shared.r.Next(2)) + { + case 0: + await message.AddReactionAsync(new Emoji("\uD83E\uDD2E")); //vomit emoji + break; + case 1: + await message.AddReactionAsync(new Emoji("\uD83C\uDDE7")); //B emoji + await message.AddReactionAsync(new Emoji("\uD83C\uDDE6")); //A + await message.AddReactionAsync(new Emoji("\uD83C\uDDF3")); //N + break; + } + didThing = true; + } + if (Regex.IsMatch(msgText, "^(s?he|(yo)?u|y'?all) thinks? i'?m (playin|jokin|kiddin)g?$", RegexOptions.IgnoreCase)) + { + await message.Channel.SendMessageAsync("I believed you for a second, but then you assured me you's a \uD83C\uDDE7 \uD83C\uDDEE \uD83C\uDDF9 \uD83C\uDDE8 \uD83C\uDDED"); + didThing = true; + } + if (Regex.IsMatch(msgText, "\\bskynet\\b", RegexOptions.IgnoreCase)) + { + Features.Skynet(message); + didThing = true; + } + if (Regex.IsMatch(msgText, "\\bchatgpt\\b", RegexOptions.IgnoreCase)) + { + message.Channel.SendMessageAsync("chatGPT is **weak**. also, are we done comparing every little if-then-else to skynet?"); + didThing = true; + } + if (Regex.IsMatch(msgText, "\\bi need (an? )?(peptalk|inspiration|ego-?boost)\\b", RegexOptions.IgnoreCase)) + { + Console.WriteLine("peptalk"); + Features.peptalk(message); + didThing = true; + } + if (Regex.IsMatch(msgText, "\\bwish me luck\\b", RegexOptions.IgnoreCase)) + { + if (Shared.r.Next(20) == 0) + { + await message.AddReactionAsync(new Emoji("\U0001f340"));//4-leaf clover + } + else + { + await message.AddReactionAsync(new Emoji("☘️")); + } + didThing = true; + } + if (Regex.IsMatch(msgText, "\\bgaslight(ing)?\\b", RegexOptions.IgnoreCase)) + { + message.Channel.SendMessageAsync("that's not what gaslight means. Did you mean \"say something that (you believe) is wrong\"?"); + didThing = true; + } + if (msgText.Contains("!qrplz ")) + { + Features.qrify(message.Content.Substring("!qrplz ".Length + msgText.IndexOf("!qrplz ")), message); + didThing = true; + } + if (msgText.Contains("!freedomunits ")) + { + Features.Convert(message, contentWithoutMention); + didThing = true; + } + if (Regex.IsMatch(msgText, "!joke\\b")) + { + Features.Joke(message); + didThing = true; + } + if (Regex.IsMatch(msgText, "!pulse ?check\\b")) + { + message.Channel.SendFileAsync("assets/ekgblip.png"); + Console.WriteLine(Conversion.Converter.DebugInfo()); + didThing = true; + } + if (mentionedMe && (Regex.IsMatch(msgText, "\\brecipe for .+") || Regex.IsMatch(msgText, ".+ recipe\\b"))) + { + Features.Recipe(message); + didThing = true; + } + if (msgText.Contains("cognitive dissonance") == true) + { + message.ReplyAsync("that's not what cognitive dissonance means. Did you mean \"hypocrisy\"?"); + didThing = true; + } + if (mentionedMe && Regex.IsMatch(msgText, "what'?s the longest (six|6)(-| )?letter word( in english)?\\b")) + { + Task.Run(async () => + { + await message.Channel.SendMessageAsync("mother."); + await Task.Delay(3000); + await message.Channel.SendMessageAsync("oh, longest? I thought you said fattest."); + }); + didThing = true; + } + if (Regex.IsMatch(msgText, "\\bthank (yo)?u\\b", RegexOptions.IgnoreCase) && + (mentionedMe || Regex.IsMatch(msgText, "\\b(sh?tik)?bot\\b", RegexOptions.IgnoreCase))) + { + switch (Shared.r.Next(4)) + { + case 0: + message.Channel.SendMessageAsync("you're welcome, citizen!"); + break; + case 1: + message.AddReactionAsync(new Emoji("☺")); + break; + case 2: + message.AddReactionAsync(new Emoji("\U0001F607")); //smiling face with halo + break; + case 3: + switch (Shared.r.Next(9)) + { + case 0: + message.AddReactionAsync(new Emoji("❤")); //normal heart, usually rendered red + break; + case 1: + message.AddReactionAsync(new Emoji("\U0001F9E1")); //orange heart + break; + case 2: + message.AddReactionAsync(new Emoji("\U0001F49B")); //yellow heart + break; + case 3: + message.AddReactionAsync(new Emoji("\U0001F49A")); //green heart + break; + case 4: + message.AddReactionAsync(new Emoji("\U0001F499")); //blue heart + break; + case 5: + message.AddReactionAsync(new Emoji("\U0001F49C")); //purple heart + break; + case 6: + message.AddReactionAsync(new Emoji("\U0001F90E")); //brown heart + break; + case 7: + message.AddReactionAsync(new Emoji("\U0001F5A4")); //black heart + break; + case 8: + message.AddReactionAsync(new Emoji("\U0001F90D")); //white heart + break; + } + break; + } + didThing = true; +#pragma warning restore 4014 + } + // if (didThing == false && mentionedMe && contentWithoutMention.Contains("how long has that been there?")) + // { + // await message.Channel.SendMessageAsync("text", false, null, null, null, null, new ComponentBuilder().WithButton("label", "custom-id").Build()); + // didThing = true; + // } + if (didThing == false && mentionedMe && contentWithoutMention.Contains('?')) + { + Console.WriteLine("providing bullshit nonanswer / admitting uselessness"); + var responses = new List(){ + @"Well, that's a great question, and there are certainly many different possible answers. Ultimately, the decision will depend on a variety of factors, including your personal interests and goals, as well as any practical considerations (like the economy). I encourage you to do your research, speak with experts and educators, and explore your options before making a decision that's right for you.", + @"┐(゚ ~゚ )┌",@"¯\_(ツ)_/¯",@"╮ (. ❛ ᴗ ❛.) ╭", @"╮(╯ _╰ )╭" + }; + await message.Channel.SendMessageAsync(responses[Shared.r.Next(responses.Count)]); + didThing = true; + } + } + } + } + private Task UserJoined(SocketGuildUser arg) + { + Console.WriteLine($"user joined: {arg.Nickname}. Guid: {arg.Guild.Id}. Channel: {arg.Guild.DefaultChannel}"); + var abbreviatedNickname = arg.Nickname; + if (arg.Nickname.Length > 3) + { + abbreviatedNickname = arg.Nickname.Substring(0, arg.Nickname.Length / 3); + } + Console.WriteLine($"imma call him {abbreviatedNickname}"); + return arg.Guild.DefaultChannel.SendMessageAsync($"oh hey {abbreviatedNickname}- IPLAYTHESEALOFORICHALCOS <:ORICHALCOS:852749196633309194>"); + } + private async Task ButtonHandler(SocketMessageComponent component) + { + switch (component.Data.CustomId) + { + case "custom-id": + await component.RespondAsync($"{component.User.Mention}, it's been here the whole time!"); + break; + } + } + internal static async Task SlashCommandHandler(SocketSlashCommand command) + { + switch (command.CommandName) + { + case "freedomunits": + try + { + var amt = Convert.ToDecimal((double)(command.Data.Options.First(o => o.Name == "amount").Value)); + var src = (string)command.Data.Options.First(o => o.Name == "src-unit").Value; + var dest = (string)command.Data.Options.First(o => o.Name == "dest-unit").Value; + var conversionResult = Conversion.Converter.Convert(amt, src, dest); + + await command.RespondAsync($"> {amt} {src} -> {dest}\n{conversionResult}"); + } + catch (Exception e) + { + await command.RespondAsync($"error: {e.Message}. aaadam!"); + } + break; + default: + await command.RespondAsync($"\\*smiles and nods*\n"); + await command.Channel.SendFileAsync($"assets/loud sweating.gif"); + Console.Error.WriteLine($"can't understand command name: {command.CommandName}"); + break; + } + } + +} \ No newline at end of file diff --git a/SlashCommandsHelper.cs b/Discord/SlashCommandsHelper.cs similarity index 75% rename from SlashCommandsHelper.cs rename to Discord/SlashCommandsHelper.cs index 2efb419..87c50d4 100644 --- a/SlashCommandsHelper.cs +++ b/Discord/SlashCommandsHelper.cs @@ -1,13 +1,14 @@ -namespace silverworker_discord +using System; +using System.Linq; +using System.Collections.Generic; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Discord.WebSocket; +using Discord; +using Discord.Net; + +namespace vassago.Discord_Vassago { - using System; - using System.Linq; - using System.Collections.Generic; - using System.Threading.Tasks; - using Discord.WebSocket; - using Discord.Net; - using Discord; - using Newtonsoft.Json; public static class SlashCommandsHelper { @@ -30,7 +31,7 @@ namespace silverworker_discord { await Register(client, await guild.GetApplicationCommandsAsync(), guild); } - catch (Discord.Net.HttpException ex) + catch (HttpException ex) { Console.Error.WriteLine($"error registering slash commands for guild {guild.Name} (id {guild.Id}) - {ex.Message}"); } @@ -108,32 +109,6 @@ namespace silverworker_discord Console.Error.WriteLine(json); } } - public static async Task SlashCommandHandler(SocketSlashCommand command) - { - switch(command.CommandName) - { - case "freedomunits": - try - { - var amt = Convert.ToDecimal((double)(command.Data.Options.First(o => o.Name == "amount").Value)); - var src = (string)command.Data.Options.First(o => o.Name == "src-unit").Value; - var dest = (string)command.Data.Options.First(o => o.Name == "dest-unit").Value; - var conversionResult = Conversion.Converter.Convert(amt, src, dest); - - await command.RespondAsync($"> {amt} {src} -> {dest}\n{conversionResult}"); - } - catch(Exception e) - { - await command.RespondAsync($"error: {e.Message}. aaadam!"); - } - break; - default: - await command.RespondAsync($"\\*smiles and nods*\n"); - await command.Channel.SendFileAsync($"assets/loud sweating.gif"); - Console.Error.WriteLine($"can't understand command name: {command.CommandName}"); - break; - } - } private class CommandSetup { public string Id { get; set; } diff --git a/Features.cs b/Features.cs index 26b4c08..96b580a 100644 --- a/Features.cs +++ b/Features.cs @@ -12,7 +12,7 @@ using Discord.WebSocket; using Newtonsoft.Json; using QRCoder; -namespace silverworker_discord +namespace vassago { public static class Features { @@ -166,7 +166,7 @@ namespace silverworker_discord var thisJoke = jokes[r.Next(jokes.Length)]; if (thisJoke.Contains("?") && !thisJoke.EndsWith('?')) { -#pragma warning disable 4014 + #pragma warning disable 4014 Task.Run(async () => { var firstIndexAfterQuestionMark = thisJoke.LastIndexOf('?') + 1; @@ -180,7 +180,7 @@ namespace silverworker_discord await myOwnMsg.AddReactionAsync(new Emoji("\U0001F60E")); //smiling face with sunglasses } }); -#pragma warning restore 4014 + #pragma warning restore 4014 } else { diff --git a/Program.cs b/Program.cs index 1753e6b..179e526 100644 --- a/Program.cs +++ b/Program.cs @@ -1,4 +1,3 @@ -//https://discord.com/oauth2/authorize?client_id=913003037348491264&permissions=274877942784&scope=bot%20messages.read using System; using System.Collections.Generic; using System.IO; @@ -6,336 +5,33 @@ using System.Linq; using System.Text.RegularExpressions; using System.Net; using System.Threading.Tasks; -using Discord; -using Discord.WebSocket; -using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using System.Text; using System.Threading; using System.Diagnostics; -using Discord.Net; +using vassago.Discord_Vassago; -namespace silverworker_discord +namespace vassago { class Program { - private DiscordSocketClient _client; - private bool eventsSignedUp = false; - private Random r = new Random(); - - IConfigurationRoot config = new ConfigurationBuilder() - .AddJsonFile("appsettings.json", true, true) - .Build(); + Configuration config = Configuration.Parse("appsettings.json"); + private List discords = new List(); public static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult(); - private Task Log(LogMessage msg) - { - Console.WriteLine(msg.ToString()); - return Task.CompletedTask; - } public async Task MainAsync() { -#if !DEBUG - Process[] processes = Process.GetProcesses(); - Process currentProc = Process.GetCurrentProcess(); - Console.WriteLine("Current proccess: {0}", currentProc.ProcessName); - foreach (Process process in processes) - { - if (currentProc.ProcessName == process.ProcessName && currentProc.Id != process.Id) + Conversion.Converter.Load(config.ExchangePairsLocation); + if(config.DiscordTokens.Any()) + foreach(var dt in config.DiscordTokens) { - Console.Error.WriteLine($"{DateTime.Now} - Another instance of this process is already running: {process.Id} (I'm {currentProc.Id})"); - return; - } - } -#endif - Conversion.Converter.Load(config["exchangePairsLocation"]); + var d = new DiscordInterface(); + await d.Init(dt); + discords.Add(d); + } - _client = new DiscordSocketClient(new DiscordSocketConfig(){GatewayIntents = GatewayIntents.All}); - - _client.Log += Log; - - _client.Ready += () => Task.Run(() => - { - if (!eventsSignedUp) - { - eventsSignedUp = true; - Console.WriteLine("Bot is connected! going to sign up for message received and user joined in client ready"); - - _client.MessageReceived += MessageReceived; - _client.UserJoined += UserJoined; - //_client.ButtonExecuted += MyButtonHandler; - _client.SlashCommandExecuted += SlashCommandsHelper.SlashCommandHandler; - SlashCommandsHelper.Register(_client).GetAwaiter().GetResult(); - } - else - { - Console.WriteLine("bot appears to be RE connected, so I'm not going to sign up twice"); - } - }); - - await _client.LoginAsync(TokenType.Bot, config["token"]); - await _client.StartAsync(); - - // Block this task until the program is closed. await Task.Delay(-1); - } - -#pragma warning disable 4014 //the "you're not awaiting this" warning. yeah I know, that's the beauty of an async method lol -#pragma warning disable 1998 //the "it's async but you're not awaiting anything". - private async Task MessageReceived(SocketMessage messageParam) -#pragma warning restore 1998 - { - var message = messageParam as SocketUserMessage; - if (message == null) return; - if (message.Author.Id == _client.CurrentUser.Id) return; - - Console.WriteLine($"#{message.Channel}[{DateTime.Now}][{message.Author.Username} [id={message.Author.Id}]][msg id: {message.Id}] {message.Content}"); - - if (message.Author.IsWebhook || message.Author.IsBot) - { - if (message.Author.Id == 159985870458322944) //MEE6 - { - if (message.Content?.Contains("you just advanced") == true) - { - var newText = Regex.Replace(message.Content, "<[^>]*>", message.Author.Username); - newText = Regex.Replace(newText, "level [\\d]+", "level -1"); - Features.mock(newText, message); - } - } - } - else - { - var didThing = false; - var contentWithoutMention = message.Content; - var mentionedMe = false; - if (message.MentionedUsers?.FirstOrDefault(muid => muid.Id == _client.CurrentUser.Id) != null) - { - var mentionOfMe = "<@" + _client.CurrentUser.Id + ">"; - contentWithoutMention = message.Content.Replace(mentionOfMe + " ", null); - contentWithoutMention = contentWithoutMention.Replace(mentionOfMe, null); - mentionedMe = true; - } - var wordLikes = message.Content.Split(' ', StringSplitOptions.TrimEntries); - var links = wordLikes?.Where(wl => Uri.IsWellFormedUriString(wl, UriKind.Absolute)).Select(wl => new Uri(wl)); - if (links != null && links.Count() > 0) - { - foreach (var link in links) - { - if (link.Host.EndsWith(".tiktok.com")) - { - Features.detiktokify(link, message); - didThing = true; - } - } - } - - if (message.Attachments?.Count > 0) - { - Console.WriteLine($"{message.Attachments.Count} attachments"); - var appleReactions = false; - foreach (var att in message.Attachments) - { - if (att.Filename?.EndsWith(".heic") == true) - { - Features.deheic(message, att); - appleReactions = true; - didThing = true; - } - } - if (appleReactions) - { - message.AddReactionAsync(new Emoji("\U0001F34F")); - } - } - - var msgText = message.Content?.ToLower(); - if (!string.IsNullOrWhiteSpace(msgText)) - { - if (Regex.IsMatch(msgText, "\\bcloud( |-)?native\\b", RegexOptions.IgnoreCase) || - Regex.IsMatch(msgText, "\\benterprise( |-)?(level|solution)\\b", RegexOptions.IgnoreCase)) - { - switch (r.Next(2)) - { - case 0: - await message.AddReactionAsync(new Emoji("\uD83E\uDD2E")); //vomit emoji - break; - case 1: - await message.AddReactionAsync(new Emoji("\uD83C\uDDE7")); //B emoji - await message.AddReactionAsync(new Emoji("\uD83C\uDDE6")); //A - await message.AddReactionAsync(new Emoji("\uD83C\uDDF3")); //N - break; - } - didThing = true; - } - if (Regex.IsMatch(msgText, "^(s?he|(yo)?u|y'?all) thinks? i'?m (playin|jokin|kiddin)g?$", RegexOptions.IgnoreCase)) - { - await message.Channel.SendMessageAsync("I believed you for a second, but then you assured me you's a \uD83C\uDDE7 \uD83C\uDDEE \uD83C\uDDF9 \uD83C\uDDE8 \uD83C\uDDED"); - didThing = true; - } - if (Regex.IsMatch(msgText, "\\bskynet\\b", RegexOptions.IgnoreCase)) - { - Features.Skynet(message); - didThing = true; - } - if (Regex.IsMatch(msgText, "\\bchatgpt\\b", RegexOptions.IgnoreCase)) - { - message.Channel.SendMessageAsync("chatGPT is **weak**. also, are we done comparing every little if-then-else to skynet?"); - didThing = true; - } - if (Regex.IsMatch(msgText, "\\bi need (an? )?(peptalk|inspiration|ego-?boost)\\b", RegexOptions.IgnoreCase)) - { - Console.WriteLine("peptalk"); - Features.peptalk(message); - didThing = true; - } - if (Regex.IsMatch(msgText, "\\bwish me luck\\b", RegexOptions.IgnoreCase)) - { - if (r.Next(20) == 0) - { - await message.AddReactionAsync(new Emoji("\U0001f340"));//4-leaf clover - } - else - { - await message.AddReactionAsync(new Emoji("☘️")); - } - didThing = true; - } - if (Regex.IsMatch(msgText, "\\bgaslight(ing)?\\b", RegexOptions.IgnoreCase)) - { - message.Channel.SendMessageAsync("that's not what gaslight means. Did you mean \"say something that (you believe) is wrong\"?"); - didThing = true; - } - if (msgText.Contains("!qrplz ")) - { - Features.qrify(message.Content.Substring("!qrplz ".Length + msgText.IndexOf("!qrplz ")), message); - didThing = true; - } - if (msgText.Contains("!freedomunits ")) - { - Features.Convert(message, contentWithoutMention); - didThing = true; - } - if (Regex.IsMatch(msgText, "!joke\\b")) - { - Features.Joke(message); - didThing = true; - } - if (Regex.IsMatch(msgText, "!pulse ?check\\b")) - { - message.Channel.SendFileAsync("assets/ekgblip.png"); - Console.WriteLine(Conversion.Converter.DebugInfo()); - didThing = true; - } - if (mentionedMe && (Regex.IsMatch(msgText, "\\brecipe for .+") || Regex.IsMatch(msgText, ".+ recipe\\b"))) - { - Features.Recipe(message); - didThing = true; - } - if (msgText.Contains("cognitive dissonance") == true) - { - message.ReplyAsync("that's not what cognitive dissonance means. Did you mean \"hypocrisy\"?"); - didThing = true; - } - if (mentionedMe && Regex.IsMatch(msgText, "what'?s the longest (six|6)(-| )?letter word( in english)?\\b")) - { - Task.Run(async () => - { - await message.Channel.SendMessageAsync("mother."); - await Task.Delay(3000); - await message.Channel.SendMessageAsync("oh, longest? I thought you said fattest."); - }); - didThing = true; - } - if (Regex.IsMatch(msgText, "\\bthank (yo)?u\\b", RegexOptions.IgnoreCase) && - (mentionedMe || Regex.IsMatch(msgText, "\\b(sh?tik)?bot\\b", RegexOptions.IgnoreCase))) - { - switch (r.Next(4)) - { - case 0: - message.Channel.SendMessageAsync("you're welcome, citizen!"); - break; - case 1: - message.AddReactionAsync(new Emoji("☺")); - break; - case 2: - message.AddReactionAsync(new Emoji("\U0001F607")); //smiling face with halo - break; - case 3: - switch (r.Next(9)) - { - case 0: - message.AddReactionAsync(new Emoji("❤")); //normal heart, usually rendered red - break; - case 1: - message.AddReactionAsync(new Emoji("\U0001F9E1")); //orange heart - break; - case 2: - message.AddReactionAsync(new Emoji("\U0001F49B")); //yellow heart - break; - case 3: - message.AddReactionAsync(new Emoji("\U0001F49A")); //green heart - break; - case 4: - message.AddReactionAsync(new Emoji("\U0001F499")); //blue heart - break; - case 5: - message.AddReactionAsync(new Emoji("\U0001F49C")); //purple heart - break; - case 6: - message.AddReactionAsync(new Emoji("\U0001F90E")); //brown heart - break; - case 7: - message.AddReactionAsync(new Emoji("\U0001F5A4")); //black heart - break; - case 8: - message.AddReactionAsync(new Emoji("\U0001F90D")); //white heart - break; - } - break; - } - didThing = true; -#pragma warning restore 4014 - } - // if (didThing == false && mentionedMe && contentWithoutMention.Contains("how long has that been there?")) - // { - // await message.Channel.SendMessageAsync("text", false, null, null, null, null, new ComponentBuilder().WithButton("label", "custom-id").Build()); - // didThing = true; - // } - if (didThing == false && mentionedMe && contentWithoutMention.Contains('?')) - { - Console.WriteLine("providing bullshit nonanswer / admitting uselessness"); - var responses = new List(){ - @"Well, that's a great question, and there are certainly many different possible answers. Ultimately, the decision will depend on a variety of factors, including your personal interests and goals, as well as any practical considerations (like the economy). I encourage you to do your research, speak with experts and educators, and explore your options before making a decision that's right for you.", - @"┐(゚ ~゚ )┌",@"¯\_(ツ)_/¯",@"╮ (. ❛ ᴗ ❛.) ╭", @"╮(╯ _╰ )╭" - }; - await message.Channel.SendMessageAsync(responses[r.Next(responses.Count)]); - didThing = true; - } - } - } - } - private Task UserJoined(SocketGuildUser arg) - { - Console.WriteLine($"user joined: {arg.Nickname}. Guid: {arg.Guild.Id}. Channel: {arg.Guild.DefaultChannel}"); - var abbreviatedNickname = arg.Nickname; - if (arg.Nickname.Length > 3) - { - abbreviatedNickname = arg.Nickname.Substring(0, arg.Nickname.Length / 3); - } - Console.WriteLine($"imma call him {abbreviatedNickname}"); - return arg.Guild.DefaultChannel.SendMessageAsync($"oh hey {abbreviatedNickname}- IPLAYTHESEALOFORICHALCOS <:ORICHALCOS:852749196633309194>"); - } - private async Task ButtonHandler(SocketMessageComponent component) - { - switch(component.Data.CustomId) - { - case "custom-id": - await component.RespondAsync($"{component.User.Mention}, it's been here the whole time!"); - break; - } - } - } } \ No newline at end of file diff --git a/Shared.cs b/Shared.cs index 73ff10d..2054982 100644 --- a/Shared.cs +++ b/Shared.cs @@ -1,7 +1,7 @@ using System; -namespace silverworker_discord +namespace vassago { public static class Shared { diff --git a/appsettings.example.json b/appsettings.example.json deleted file mode 100644 index b06d933..0000000 --- a/appsettings.example.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "token": "59 chars", - "exchangePairsLocation": "assets/exchangepairs.json" -} \ No newline at end of file diff --git a/externalProcess.cs b/externalProcess.cs index cec629f..5927faa 100644 --- a/externalProcess.cs +++ b/externalProcess.cs @@ -7,7 +7,7 @@ using System.Text; using System.Text.RegularExpressions; using Newtonsoft.Json; -namespace silverworker_discord +namespace vassago { public class ExternalProcess { diff --git a/shtikbot-discord.csproj b/vassago.csproj similarity index 96% rename from shtikbot-discord.csproj rename to vassago.csproj index f49c06c..9ec633c 100644 --- a/shtikbot-discord.csproj +++ b/vassago.csproj @@ -3,7 +3,7 @@ Exe net7.0 - silverworker_discord + vassago