From 4732c62d2028e9925c90a950edc8cf69e6e2ab95 Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Sun, 31 Mar 2024 13:46:24 +0200 Subject: [PATCH] some prepwork --- .../build/Dockerfile-MareSynchronosServices | 2 +- .../MareWizardModule.AprilFools2024.cs | 211 ++++++++++++++++++ .../Discord/MareWizardModule.cs | 12 +- .../MareSynchronosServices/Startup.cs | 1 - .../Utils/ServicesConfiguration.cs | 2 + 5 files changed, 225 insertions(+), 3 deletions(-) create mode 100644 MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.AprilFools2024.cs diff --git a/Docker/build/Dockerfile-MareSynchronosServices b/Docker/build/Dockerfile-MareSynchronosServices index 7dc8d35..5c6f385 100644 --- a/Docker/build/Dockerfile-MareSynchronosServices +++ b/Docker/build/Dockerfile-MareSynchronosServices @@ -7,7 +7,7 @@ COPY MareSynchronosServer/MareSynchronosServices /server/MareSynchronosServer/Ma WORKDIR /server/MareSynchronosServer/MareSynchronosServices/ RUN dotnet publish \ - --configuration=Release \ + --configuration=Debug \ --os=linux \ --output=/build \ MareSynchronosServices.csproj diff --git a/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.AprilFools2024.cs b/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.AprilFools2024.cs new file mode 100644 index 0000000..e493aee --- /dev/null +++ b/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.AprilFools2024.cs @@ -0,0 +1,211 @@ +using Discord; +using Discord.Interactions; +using MareSynchronosShared.Utils; +using System.Text.Json; + +namespace MareSynchronosServices.Discord; + +public partial class MareWizardModule : InteractionModuleBase +{ + private const int _totalAprilFoolsRoles = 200; + private const string _persistentFileName = "april2024.json"; + + private static readonly SemaphoreSlim _fileSemaphore = new(1, 1); + + [ComponentInteraction("wizard-fools")] + public async Task ComponentFools() + { + if (!(await ValidateInteraction().ConfigureAwait(false))) return; + + _logger.LogInformation("{method}:{userId}", nameof(ComponentFools), Context.Interaction.User.Id); + + EmbedBuilder eb = new(); + eb.WithTitle("WorryCoin™ and MareToken© Balance"); + eb.WithColor(Color.Gold); + eb.WithDescription("You currently have" + Environment.NewLine + Environment.NewLine + + "**200000** MaTE©" + Environment.NewLine + + "**0** WorryCoin™" + Environment.NewLine + Environment.NewLine + + "You have no payment method set up. Press the button below to add a payment method."); + ComponentBuilder cb = new(); + AddHome(cb); + cb.WithButton("Add Payment Method", "wizard-fools-start", ButtonStyle.Primary, emote: new Emoji("💲")); + await ModifyInteraction(eb, cb).ConfigureAwait(false); + } + + [ComponentInteraction("wizard-fools-start")] + public async Task ComponentFoolsStart() + { + if (!(await ValidateInteraction().ConfigureAwait(false))) return; + + _logger.LogInformation("{method}:{userId}", nameof(ComponentFoolsStart), Context.Interaction.User.Id); + + EmbedBuilder eb = new(); + var user = await Context.Guild.GetUserAsync(Context.User.Id).ConfigureAwait(false); + bool userIsInPermanentVanityRole = _botServices.VanityRoles.Where(v => !v.Value.Contains('$', StringComparison.Ordinal)) + .Select(v => v.Key).Any(u => user.RoleIds.Contains(u.Id)) || !_botServices.VanityRoles.Any(); + ComponentBuilder cb = new(); + AddHome(cb); + + var participatedUsers = await GetParticipants().ConfigureAwait(false); + var remainingRoles = _totalAprilFoolsRoles - participatedUsers.Count(c => c.Value == true); + + if (userIsInPermanentVanityRole) + { + eb.WithColor(Color.Green); + eb.WithTitle("Happy April Fools!"); + eb.WithDescription("Thank you for participating in Mares 2024 April Fools event." + + Environment.NewLine + Environment.NewLine + + "As you might have already guessed from the post, nothing that was written there had any truth behind it." + + Environment.NewLine + Environment.NewLine + + "This entire thing was a jab at the ridiculousness of cryptocurrency, microtransactions and games featuring multiple currencies. I hope you enjoyed the announcement post!" + + Environment.NewLine + Environment.NewLine + + "__As you already have a role that gives you a permanent Vanity ID, you cannot win another one here. " + + "However, tell your friends as this bot will give them a chance to win one of " + _totalAprilFoolsRoles + " lifetime vanity roles.__"); + } + else if (participatedUsers.ContainsKey(Context.User.Id)) + { + eb.WithColor(Color.Orange); + eb.WithTitle("Happy April Fools!"); + eb.WithDescription("Thank you for participating in Mares 2024 April Fools event." + + Environment.NewLine + Environment.NewLine + + "As you might have already guessed from the post, nothing that was written there had any truth behind it." + + Environment.NewLine + Environment.NewLine + + "This entire thing was a jab at the ridiculousness of cryptocurrency, microtransactions and games featuring multiple currencies. I hope you enjoyed the announcement post!" + + Environment.NewLine + Environment.NewLine + + "__You already participated in the giveaway of the permanent Vanity roles and therefore cannot participate again. Better luck next time!__"); + } + else if (remainingRoles > 0) + { + eb.WithColor(Color.Green); + eb.WithTitle("Happy April Fools!"); + eb.WithDescription("Thank you for participating in Mares 2024 April Fools event." + + Environment.NewLine + Environment.NewLine + + "As you might have already guessed from the post, nothing that was written there had any truth behind it." + + Environment.NewLine + Environment.NewLine + + "This entire thing was a jab at the ridiculousness of cryptocurrency, microtransactions and games featuring multiple currencies. I hope you enjoyed the announcement post!" + + Environment.NewLine + Environment.NewLine + + "You have currently no permanent role that allows you to set a Vanity ID, however I am giving away a total of " + _totalAprilFoolsRoles + " permanent vanity roles " + + "(" + remainingRoles + " still remain) and you can win one using this bot!" + + Environment.NewLine + Environment.NewLine + + "To win you simply have to pick one of the buttons labeled \"Win\" below this post. Which button will win is random. " + + "There is a 1 in 5 chance that you can win the role. __You can only participate once.__"); + cb.WithButton("Win", "wizard-fools-win:1", ButtonStyle.Primary, new Emoji("1️⃣")); + cb.WithButton("Win", "wizard-fools-win:2", ButtonStyle.Primary, new Emoji("2️⃣")); + cb.WithButton("Win", "wizard-fools-win:3", ButtonStyle.Primary, new Emoji("3️⃣")); + cb.WithButton("Win", "wizard-fools-win:4", ButtonStyle.Primary, new Emoji("4️⃣")); + cb.WithButton("Win", "wizard-fools-win:5", ButtonStyle.Primary, new Emoji("5️⃣")); + } + else + { + eb.WithColor(Color.Orange); + eb.WithTitle("Happy April Fools!"); + eb.WithDescription("Thank you for participating in Mares 2024 April Fools event." + + Environment.NewLine + Environment.NewLine + + "As you might have already guessed from the post, nothing that was written there had any truth behind it." + + Environment.NewLine + Environment.NewLine + + "This entire thing was a jab at the ridiculousness of cryptocurrency, microtransactions and games featuring multiple currencies. I hope you enjoyed the announcement post!" + + Environment.NewLine + Environment.NewLine + + "__I have been giving away " + _totalAprilFoolsRoles + " permanent Vanity ID roles for this server, however you are sadly too late as they ran out by now. " + + "Better luck next year with whatever I will come up with!__"); + } + await ModifyInteraction(eb, cb).ConfigureAwait(false); + } + + [ComponentInteraction("wizard-fools-win:*")] + public async Task ComponentFoolsWin(int number) + { + if (!(await ValidateInteraction().ConfigureAwait(false))) return; + + _logger.LogInformation("{method}:{userId}", nameof(ComponentFoolsWin), Context.Interaction.User.Id); + + var winningNumber = new Random().Next(1, 6); + EmbedBuilder eb = new(); + ComponentBuilder cb = new(); + AddHome(cb); + bool hasWon = winningNumber == number; + + await WriteParticipants(Context.Interaction.User.Id, hasWon).ConfigureAwait(false); + + if (hasWon) + { + eb.WithColor(Color.Gold); + eb.WithTitle("Congratulations you are winner!"); + eb.WithDescription("You, by pure accident and sheer luck, picked the right number and have won yourself a lifetime Vanity ID role on this server!" + + Environment.NewLine + Environment.NewLine + + "The role will remain as long as you remain on this server, if you happen to leave it you will not get the role back." + + Environment.NewLine + Environment.NewLine + + "Head over to Home and to the Vanity IDs section to set it up for your account!" + + Environment.NewLine + Environment.NewLine + + "Once again, thank you for participating and have a great day."); + + var user = await Context.Guild.GetUserAsync(Context.User.Id).ConfigureAwait(false); + await user.AddRoleAsync(_mareServicesConfiguration.GetValue(nameof(ServicesConfiguration.DiscordRoleAprilFools2024)).Value).ConfigureAwait(false); + } + else + { + eb.WithColor(Color.Red); + eb.WithTitle("Fortune did not bless you"); + eb.WithDescription("You, through sheer misfortune, sadly did not pick the right number. (The winning number was " + winningNumber + ")" + + Environment.NewLine + Environment.NewLine + + "Better luck next time!" + + Environment.NewLine + Environment.NewLine + + "Once again, thank you for participating and regardless, have a great day."); + } + + await ModifyInteraction(eb, cb).ConfigureAwait(false); + } + + private async Task> GetParticipants() + { + await _fileSemaphore.WaitAsync().ConfigureAwait(false); + + try + { + if (!File.Exists(_persistentFileName)) + { + return new(); + } + + var json = await File.ReadAllTextAsync(_persistentFileName).ConfigureAwait(false); + return JsonSerializer.Deserialize>(json); + } + catch + { + return new(); + } + finally + { + _fileSemaphore.Release(); + } + } + + private async Task WriteParticipants(ulong participant, bool win) + { + await _fileSemaphore.WaitAsync().ConfigureAwait(false); + + try + { + Dictionary participants = new(); + if (File.Exists(_persistentFileName)) + { + try + { + var json = await File.ReadAllTextAsync(_persistentFileName).ConfigureAwait(false); + participants = JsonSerializer.Deserialize>(json); + } + catch + { + // probably empty file just deal with it + } + } + + participants[participant] = win; + + await File.WriteAllTextAsync(_persistentFileName, JsonSerializer.Serialize(participants)).ConfigureAwait(false); + } + finally + { + _fileSemaphore.Release(); + } + } +} \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.cs b/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.cs index 5035cbc..e4aa95f 100644 --- a/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.cs +++ b/MareSynchronosServer/MareSynchronosServices/Discord/MareWizardModule.cs @@ -6,7 +6,6 @@ using MareSynchronosShared.Models; using MareSynchronosShared.Services; using MareSynchronosShared.Utils; using Microsoft.EntityFrameworkCore; -using Microsoft.Win32; using StackExchange.Redis; using System.Text.RegularExpressions; @@ -59,6 +58,12 @@ public partial class MareWizardModule : InteractionModuleBase return; } } +#if !DEBUG + bool isInAprilFoolsMode = _mareServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordRoleAprilFools2024), null) != null + && DateTime.UtcNow.Month == 4 && DateTime.UtcNow.Day == 1 && DateTime.UtcNow.Year == 2024 && DateTime.UtcNow.Hour >= 12; +#elif DEBUG + bool isInAprilFoolsMode = true; +#endif EmbedBuilder eb = new(); eb.WithTitle("Welcome to the Mare Synchronos Service Bot for this server"); @@ -69,6 +74,7 @@ public partial class MareWizardModule : InteractionModuleBase + (hasAccount ? string.Empty : ("- If you have changed your Discord account press \"🔗 Relink\"" + Environment.NewLine)) + (!hasAccount ? string.Empty : ("- Create a secondary UIDs press \"2️⃣ Secondary UID\"" + Environment.NewLine)) + (!hasAccount ? string.Empty : ("- Set a Vanity UID press \"💅 Vanity IDs\"" + Environment.NewLine)) + + (!hasAccount ? string.Empty : (!isInAprilFoolsMode ? string.Empty : ("- Check your WorryCoin™ and MareToken© balance and add payment options" + Environment.NewLine))) + (!hasAccount ? string.Empty : ("- Delete your primary or secondary accounts with \"⚠️ Delete\"")) ); eb.WithColor(Color.Blue); @@ -84,6 +90,10 @@ public partial class MareWizardModule : InteractionModuleBase cb.WithButton("Recover", "wizard-recover", ButtonStyle.Secondary, new Emoji("🏥")); cb.WithButton("Secondary UID", "wizard-secondary", ButtonStyle.Secondary, new Emoji("2️⃣")); cb.WithButton("Vanity IDs", "wizard-vanity", ButtonStyle.Secondary, new Emoji("💅")); + if (isInAprilFoolsMode) + { + cb.WithButton("WorryCoin™ and MareToken© management", "wizard-fools", ButtonStyle.Primary, new Emoji("💲")); + } cb.WithButton("Delete", "wizard-delete", ButtonStyle.Danger, new Emoji("⚠️")); } if (init) diff --git a/MareSynchronosServer/MareSynchronosServices/Startup.cs b/MareSynchronosServer/MareSynchronosServices/Startup.cs index a0a9b20..a6d135c 100644 --- a/MareSynchronosServer/MareSynchronosServices/Startup.cs +++ b/MareSynchronosServer/MareSynchronosServices/Startup.cs @@ -10,7 +10,6 @@ using MareSynchronosShared.Services; using StackExchange.Redis; using MessagePack.Resolvers; using MessagePack; -using Microsoft.AspNetCore.Authorization; namespace MareSynchronosServices; diff --git a/MareSynchronosServer/MareSynchronosShared/Utils/ServicesConfiguration.cs b/MareSynchronosServer/MareSynchronosShared/Utils/ServicesConfiguration.cs index 448cb76..938d6d6 100644 --- a/MareSynchronosServer/MareSynchronosShared/Utils/ServicesConfiguration.cs +++ b/MareSynchronosServer/MareSynchronosShared/Utils/ServicesConfiguration.cs @@ -8,6 +8,7 @@ public class ServicesConfiguration : MareConfigurationBase public ulong? DiscordChannelForMessages { get; set; } = null; public ulong? DiscordChannelForReports { get; set; } = null; public ulong? DiscordChannelForCommands { get; set; } = null; + public ulong? DiscordRoleAprilFools2024 { get; set; } = null; public Uri MainServerGrpcAddress { get; set; } = null; public Dictionary VanityRoles { get; set; } = new Dictionary(); @@ -20,6 +21,7 @@ public class ServicesConfiguration : MareConfigurationBase sb.AppendLine($"{nameof(DiscordChannelForMessages)} => {DiscordChannelForMessages}"); sb.AppendLine($"{nameof(DiscordChannelForReports)} => {DiscordChannelForReports}"); sb.AppendLine($"{nameof(DiscordChannelForCommands)} => {DiscordChannelForCommands}"); + sb.AppendLine($"{nameof(DiscordRoleAprilFools2024)} => {DiscordRoleAprilFools2024}"); foreach (var role in VanityRoles) { sb.AppendLine($"{nameof(VanityRoles)} => {role.Key} = {role.Value}");