From 7b722a45cbaa51d64fd8a693b33fa351f3be9603 Mon Sep 17 00:00:00 2001 From: Macintosh II <95250141+mctaylors@users.noreply.github.com> Date: Mon, 24 Jul 2023 19:51:05 +0300 Subject: [PATCH] Rename users who attempt to hoist themselves (#53) Signed-off-by: Octol1ttle Signed-off-by: mctaylors <95250141+mctaylors@users.noreply.github.com> Co-authored-by: nrdk Co-authored-by: Octol1ttle --- locale/Messages.resx | 3 ++ locale/Messages.ru.resx | 3 ++ locale/Messages.tt-ru.resx | 3 ++ src/Commands/SettingsCommandGroup.cs | 1 + src/Data/GuildSettings.cs | 5 +++ src/Services/GuildUpdateService.cs | 51 +++++++++++++++++++++++++--- 6 files changed, 61 insertions(+), 5 deletions(-) diff --git a/locale/Messages.resx b/locale/Messages.resx index c2988e0..b701495 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -558,4 +558,7 @@ is now + + Rename members who attempt to hoist themselves + diff --git a/locale/Messages.ru.resx b/locale/Messages.ru.resx index 2173cb0..22bf3a9 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -558,4 +558,7 @@ теперь имеет значение + + Переименовывать участников, которые пытаются поднять себя + diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index 6e5666c..dca7f71 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -558,4 +558,7 @@ стало + + переобувать шизоидов пытающихся поднять себя в табе + diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 37dca6d..c4ea21b 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -31,6 +31,7 @@ public class SettingsCommandGroup : CommandGroup { GuildSettings.RemoveRolesOnMute, GuildSettings.ReturnRolesOnRejoin, GuildSettings.AutoStartEvents, + GuildSettings.RenameHoistedUsers, GuildSettings.PublicFeedbackChannel, GuildSettings.PrivateFeedbackChannel, GuildSettings.EventNotificationChannel, diff --git a/src/Data/GuildSettings.cs b/src/Data/GuildSettings.cs index 07e43a6..bd5757d 100644 --- a/src/Data/GuildSettings.cs +++ b/src/Data/GuildSettings.cs @@ -40,6 +40,11 @@ public static class GuildSettings { public static readonly BoolOption AutoStartEvents = new("AutoStartEvents", false); + /// + /// Controls whether or not users who try to hoist themselves should be renamed. + /// + public static readonly BoolOption RenameHoistedUsers = new("RenameHoistedUsers", false); + /// /// Controls what channel should all public messages be sent to. /// diff --git a/src/Services/GuildUpdateService.cs b/src/Services/GuildUpdateService.cs index 866fcb8..c743b8e 100644 --- a/src/Services/GuildUpdateService.cs +++ b/src/Services/GuildUpdateService.cs @@ -1,4 +1,5 @@ using System.Text.Json.Nodes; +using System.Text.RegularExpressions; using Boyfriend.Data; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -19,7 +20,7 @@ namespace Boyfriend.Services; /// /// Handles executing guild updates (also called "ticks") once per second. /// -public class GuildUpdateService : BackgroundService { +public partial class GuildUpdateService : BackgroundService { private static readonly (string Name, TimeSpan Duration)[] SongList = { ("UNDEAD CORPORATION - The Empress", new TimeSpan(0, 4, 34)), ("UNDEAD CORPORATION - Everything will freeze", new TimeSpan(0, 3, 17)), @@ -30,6 +31,16 @@ public class GuildUpdateService : BackgroundService { ("Camellia - Flamewall", new TimeSpan(0, 6, 50)) }; + private static readonly string[] GenericNicknames = { + "Albatross", "Alpha", "Anchor", "Banjo", "Bell", "Beta", "Blackbird", "Bulldog", "Canary", + "Cat", "Calf", "Cyclone", "Daisy", "Dalmatian", "Dart", "Delta", "Diamond", "Donkey", "Duck", + "Emu", "Eclipse", "Flamingo", "Flute", "Frog", "Goose", "Hatchet", "Heron", "Husky", "Hurricane", + "Iceberg", "Iguana", "Kiwi", "Kite", "Lamb", "Lily", "Macaw", "Manatee", "Maple", "Mask", + "Nautilus", "Ostrich", "Octopus", "Pelican", "Puffin", "Pyramid", "Rattle", "Robin", "Rose", + "Salmon", "Seal", "Shark", "Sheep", "Snake", "Sonar", "Stump", "Sparrow", "Toaster", "Toucan", + "Torus", "Violet", "Vortex", "Vulture", "Wagon", "Whale", "Woodpecker", "Zebra", "Zigzag" + }; + private readonly List _activityList = new(1) { new Activity("with Remora.Discord", ActivityType.Game) }; private readonly IDiscordRestChannelAPI _channelApi; @@ -119,10 +130,11 @@ public class GuildUpdateService : BackgroundService { var defaultRole = GuildSettings.DefaultRole.Get(data.Settings); foreach (var memberData in data.MemberData.Values) { - var userResult = await _userApi.GetUserAsync(memberData.Id.ToSnowflake(), ct); - if (!userResult.IsDefined(out var user)) return; + var guildMemberResult = await _guildApi.GetGuildMemberAsync(guildId, memberData.Id.ToSnowflake(), ct); + if (!guildMemberResult.IsDefined(out var guildMember)) return; + if (!guildMember.User.IsDefined(out var user)) return; - await TickMemberAsync(guildId, user, memberData, defaultRole, ct); + await TickMemberAsync(guildId, user, guildMember, memberData, defaultRole, data.Settings, ct); } var eventsResult = await _eventApi.ListScheduledEventsForGuildAsync(guildId, ct: ct); @@ -201,7 +213,8 @@ public class GuildUpdateService : BackgroundService { } private async Task TickMemberAsync( - Snowflake guildId, IUser user, MemberData memberData, Snowflake defaultRole, CancellationToken ct) { + Snowflake guildId, IUser user, IGuildMember member, MemberData memberData, Snowflake defaultRole, + JsonNode cfg, CancellationToken ct) { if (defaultRole.Value is not 0 && !memberData.Roles.Contains(defaultRole.Value)) _ = _guildApi.AddGuildMemberRoleAsync( guildId, user.ID, defaultRole, ct: ct); @@ -218,8 +231,36 @@ public class GuildUpdateService : BackgroundService { for (var i = memberData.Reminders.Count - 1; i >= 0; i--) await TickReminderAsync(memberData.Reminders[i], user, memberData, ct); + if (GuildSettings.RenameHoistedUsers.Get(cfg)) await FilterNicknameAsync(guildId, user, member, ct); } + private Task FilterNicknameAsync(Snowflake guildId, IUser user, IGuildMember member, CancellationToken ct) { + var currentNickname = member.Nickname.IsDefined(out var nickname) + ? nickname + : user.GlobalName ?? user.Username; + var characterList = currentNickname.ToList(); + var usernameChanged = false; + foreach (var character in currentNickname) + if (IllegalCharsRegex().IsMatch(character.ToString())) { + characterList.Remove(character); + usernameChanged = true; + } else { break; } + + if (!usernameChanged) return Task.CompletedTask; + var newNickname = string.Concat(characterList.ToArray()); + + _ = _guildApi.ModifyGuildMemberAsync( + guildId, user.ID, + !string.IsNullOrWhiteSpace(newNickname) + ? newNickname + : GenericNicknames[Random.Shared.Next(GenericNicknames.Length)], + ct: ct); + return Task.CompletedTask; + } + + [GeneratedRegex("[^0-9A-zЁА-яё]")] + private static partial Regex IllegalCharsRegex(); + private async Task TickReminderAsync(Reminder reminder, IUser user, MemberData memberData, CancellationToken ct) { if (DateTimeOffset.UtcNow < reminder.At) return;