diff --git a/CompatBot/Commands/ForcedNicknames.cs b/CompatBot/Commands/ForcedNicknames.cs
index 94f48397..4278ed7a 100644
--- a/CompatBot/Commands/ForcedNicknames.cs
+++ b/CompatBot/Commands/ForcedNicknames.cs
@@ -202,6 +202,14 @@ namespace CompatBot.Commands
}
await ctx.RespondAsync(result).ConfigureAwait(false);
}
+
+ [Command("generate"), Aliases("gen", "suggest")]
+ [Description("Generates random name for specified user")]
+ public async Task Generate(CommandContext ctx, [Description("Discord user to dump")] DiscordUser discordUser)
+ {
+ var newName = UsernameZalgoMonitor.GenerateRandomName(discordUser.Id);
+ await ctx.RespondAsync(newName).ConfigureAwait(false);
+ }
[Command("list")]
[Description("Lists all users who has restricted nickname.")]
diff --git a/CompatBot/CompatBot.csproj b/CompatBot/CompatBot.csproj
index 32eccab1..0b0450f1 100644
--- a/CompatBot/CompatBot.csproj
+++ b/CompatBot/CompatBot.csproj
@@ -43,7 +43,9 @@
+
+
diff --git a/CompatBot/EventHandlers/UsernameZalgoMonitor.cs b/CompatBot/EventHandlers/UsernameZalgoMonitor.cs
index 44f2d743..2f7fcf9b 100644
--- a/CompatBot/EventHandlers/UsernameZalgoMonitor.cs
+++ b/CompatBot/EventHandlers/UsernameZalgoMonitor.cs
@@ -113,7 +113,7 @@ namespace CompatBot.EventHandlers
{
displayName = displayName.Normalize(normalizationForm).TrimEager();
if (string.IsNullOrEmpty(displayName))
- return "Rule #7 Breaker #" + userId.GetHashCode().ToString("x8");
+ return GenerateRandomName(userId);
var builder = new StringBuilder();
bool skipLowSurrogate = false;
@@ -150,9 +150,17 @@ namespace CompatBot.EventHandlers
}
var result = builder.ToString().TrimEager();
if (string.IsNullOrEmpty(result))
- return "Rule #7 Breaker #" + userId.GetHashCode().ToString("x8");
+ return GenerateRandomName(userId);
return result;
}
+
+ public static string GenerateRandomName(ulong userId)
+ {
+ var hash = userId.GetHashCode();
+ var rng = new Random(hash);
+ var name = NamesPool.List[rng.Next(NamesPool.NameCount)];
+ return $"{name}{NamesPool.NameSuffix} #{hash:x8}";
+ }
}
}
diff --git a/README.md b/README.md
index 9dc955b9..4f871f76 100644
--- a/README.md
+++ b/README.md
@@ -66,3 +66,4 @@ External resources that need manual updates
* [Unicode Confusables](http://www.unicode.org/Public/security/latest/confusables.txt), for Homoglyph checks
* [Windows Error Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/), for error decoding on non-Windows host
* Optionally [Redump disc key database](http://redump.org/downloads/) in text format (requires membership)
+* Optionally pool of names (one name per line), files named as `names_.txt`
diff --git a/SourceGenerators/NamesSourceGenerator.cs b/SourceGenerators/NamesSourceGenerator.cs
new file mode 100644
index 00000000..c3793594
--- /dev/null
+++ b/SourceGenerators/NamesSourceGenerator.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Text;
+
+namespace SourceGenerators
+{
+ [Generator]
+ public class NamesSourceGenerator : ISourceGenerator
+ {
+ private const string Indent = " ";
+ private const string NameSuffix = " the Rule 7 Breaker";
+ private const int DiscordUsernameLengthLimit = 32-10; //" #12345678"
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+ }
+
+ public void Execute(GeneratorExecutionContext context)
+ {
+ var resources = context.AdditionalFiles.Where(f => Path.GetFileName(f.Path).ToLower().StartsWith("names_") && f.Path.ToLower().EndsWith(".txt")).ToList();
+ if (resources.Count == 0)
+ return;
+
+ var names = new HashSet();
+ foreach (var resource in resources)
+ {
+ using var stream = File.Open(resource.Path, FileMode.Open, FileAccess.Read, FileShare.Read);
+ using var reader = new StreamReader(stream);
+ while (reader.ReadLine() is string line)
+ {
+ if (line.Length < 2 || line.StartsWith("#"))
+ continue;
+
+ var commentPos = line.IndexOf(" (");
+ if (commentPos > 1)
+ line = line.Substring(0, commentPos);
+ line = line.Trim();
+ if (line.Length + NameSuffix.Length > DiscordUsernameLengthLimit)
+ line = line.Split(' ')[0];
+ if (line.Length + NameSuffix.Length > DiscordUsernameLengthLimit)
+ continue;
+
+ names.Add(line);
+ if (line.Contains(' '))
+ names.Add(line.Split(' ')[0]);
+ }
+ }
+
+ if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.RootNamespace", out var ns))
+ ns = context.Compilation.AssemblyName;
+ var cn = "NamesPool";
+ var result = new StringBuilder()
+ .AppendLine("using System.Collections.Generic;")
+ .AppendLine()
+ .AppendLine($"namespace {ns}")
+ .AppendLine("{")
+ .AppendLine($"{Indent}public static class {cn}")
+ .AppendLine($"{Indent}{{")
+ .AppendLine($"{Indent}{Indent}public const string NameSuffix = \"{NameSuffix}\";")
+ .AppendLine()
+ .AppendLine($"{Indent}{Indent}public const int NameCount = {names.Count};")
+ .AppendLine()
+ .AppendLine($"{Indent}{Indent}public static readonly List List = new()")
+ .AppendLine($"{Indent}{Indent}{{");
+ foreach (var name in names.OrderBy(n => n))
+ result.AppendLine($"{Indent}{Indent}{Indent}\"{name}\",");
+ result.AppendLine($"{Indent}{Indent}}};")
+ .AppendLine($"{Indent}}}")
+ .AppendLine("}");
+
+ context.AddSource($"{cn}.Generated.cs", SourceText.From(result.ToString(), Encoding.UTF8));
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/names_anime.txt b/names_anime.txt
new file mode 100644
index 00000000..cd663d96
--- /dev/null
+++ b/names_anime.txt
@@ -0,0 +1,380 @@
+# https://en.wikipedia.org/wiki/Category:Male_characters_in_anime_and_manga
+Renji Abarai
+Sōsuke Aizen
+Alucard (Hellsing)
+Android 17
+Alex Louis Armstrong
+Hao Asakura
+Yoh Asakura
+Astro Boy (character)
+Shinn Asuka
+Char Aznable
+B
+Bardock
+Batou
+Beerus
+Beyond the Grave (Gungrave)
+Black Jack (manga character)
+Black Star (Soul Eater)
+Legato Bluesummers
+King Bradley
+Dio Brando
+Brock (Pokémon)
+Broly
+C
+Cell (Dragon Ball)
+Cross Marian
+D
+Osamu Dazai (Bungo Stray Dogs)
+Doraemon (character)
+Natsu Dragneel
+E
+Ryoma Echizen
+Makoto Edamura
+Alphonse Elric
+Edward Elric
+Kiritsugu Emiya
+Shirou Emiya
+F
+Luke fon Fabre
+Fai D. Flowright
+Father (Fullmetal Alchemist)
+Frieza
+Akira Fudo
+G
+Gaara
+Gourry Gabriev
+Gohan
+Goku
+Hayato Gokudera
+Griffith (Berserk)
+H
+Tadashi Hamada
+Mitsukuni Haninozuka
+Captain Harlock
+Haseo
+Kakashi Hatake
+Kyoya Hibari
+Himura Kenshin
+Saito Hiraga
+Yoichi Hiruma
+Tōshirō Hitsugaya
+Van Hohenheim
+Bertolt Hoover
+Maes Hughes
+Cygnus Hyoga
+I
+Hikaru Ichijyo
+Gin Ichimaru
+Gendo Ikari
+Shinji Ikari
+Phoenix Ikki
+Inuyasha (character)
+Matt Ishida
+Uryū Ishida
+Goemon Ishikawa XIII
+Shinichi Izumi
+J
+Jadeite (character)
+Daisuke Jigen
+Jiraiya (Naruto)
+Jiren (Dragon Ball)
+Jonathan Joestar
+Joseph Joestar
+Jotaro Kujo
+K
+Seto Kaiba
+Kaito Kuroba
+Tanjiro Kamado
+Tai Kamiya
+Yu Kanda
+Kawaki
+Kenshiro
+Ash Ketchum
+Kirito (Sword Art Online)
+Yusaku Kitamura
+Sena Kobayakawa
+Susumu Kodai
+Shinya Kogami
+Koji Kabuto
+Krillin
+Byakuya Kuchiki
+Jimmy Kudo
+Kurogane (Tsubasa: Reservoir Chronicle)
+Kei Kurono
+Ichigo Kurosaki
+Suzaku Kururugi
+Kimihito Kurusu
+L
+L (Death Note)
+Lambo (Reborn!)
+Lelouch Lamperouge
+Lavi (D.Gray-man)
+Rock Lee
+Yuri Lowell
+Arsène Lupin III
+M
+Majin Buu
+Shogo Makishima
+Manji (Blade of the Immortal)
+Mello (Death Note)
+Mifune (Soul Eater)
+Teru Mikami
+Mikoto Mikoshiba
+Millennium Earl
+Mitsuki (Naruto)
+Monkey D. Luffy
+Fuma Monou
+Takashi Morinozuka
+Keiichi Morisato
+Ataru Moroboshi
+Roy Mustang
+Yugi Mutou
+Myōjin Yahiko
+N
+Nagato (Naruto)
+User:3474816aaa/sandbox2
+Kaworu Nagisa
+Atsushi Nakajima (Bungo Stray Dogs)
+Naofumi Iwatani
+Shikamaru Nara
+Subaru Natsuki
+Nea D. Campbell
+Nobita Nobi
+Umetarō Nozaki
+O
+Rintaro Okabe
+Orochimaru (Naruto)
+Ovan
+P
+Professor Ochanomizu
+R
+Raoh
+Amuro Ray
+Robita
+Rock (manga)
+Mukuro Rokudo
+Roronoa Zoro
+Ryuk (Death Note)
+S
+Yasutora Sado
+Toshiyuki Saejima
+Sagara Sanosuke
+Saitō Hajime (Rurouni Kenshin)
+Gintoki Sakata
+Shinichi Sakurai
+Seishiro Sakurazuka
+Genma Saotome
+Ranma Saotome
+Ryohei Sasagawa
+Tsuna Sawada
+Scar (Fullmetal Alchemist)
+Setsuna F. Seiei
+Pegasus Seiya
+Seta Sōjirō
+Hosuke Sharaku
+Arata Shindo
+Shinomori Aoshi
+Kamui Shiro
+Dragon Shiryū
+Shishio Makoto
+Andromeda Shun
+Spike Spiegel
+Strider Hiryu
+Subaru Sumeragi
+Syaoran (Tsubasa: Reservoir Chronicle, clone)
+Syaoran (Tsubasa: Reservoir Chronicle, original)
+T
+Ryuji Takasu
+Soun Tendo
+Dr. Tenma
+Kunimitsu Tezuka
+Laurent Thierry
+Tien Shinhan
+Togusa
+Kaname Tōsen
+Trunks (Dragon Ball)
+Tsubasa Oozora
+Shou Tucker
+Tuxedo Mask
+U
+Itachi Uchiha
+Madara Uchiha
+Obito Uchiha
+Sasuke Uchiha
+Ryūnosuke Uryū
+Boruto Uzumaki
+Naruto Uzumaki
+V
+Vash the Stampede
+Vegeta
+Waver Velvet
+Viewtiful Joe (character)
+W
+Allen Walker
+Kimihiro Watanuki
+Leonardo Watch
+Nicholas D. Wolfwood
+X
+Xellos
+Y
+Light Yagami
+Takeshi Yamamoto
+Kira Yamato
+Yamcha
+Eren Yeager
+Youji Itami
+Yukishiro Enishi
+Z
+Athrun Zala
+Zamasu
+Kenpachi Zaraki
+Kiyo Takamine and Zatch Bell
+Koichi Zenigata
+
+# https://en.wikipedia.org/wiki/Category:Female_characters_in_anime_and_manga
+Yūko Aioi
+Taiga Aisaka
+Moka Akashiya
+Homura Akemi
+Alita (Battle Angel Alita)
+Misa Amane
+Android 18
+Asuna (Sword Art Online)
+Athena (Saint Seiya)
+Cagalli Yula Athha
+Rei Ayanami
+B
+Belldandy
+Queen Beryl
+Bulma
+C
+C.C. (Code Geass)
+Chi (Chobits)
+Chi-Chi (Dragon Ball)
+Lacus Clyne
+D
+Dejiko
+Chrome Dokuro
+E
+Edward (Cowboy Bebop)
+Ami Enan
+Erza Scarlet
+F
+Faye Valentine
+Haruhi Fujioka
+Chika Fujiwara
+G
+Yuno Gasai
+Golden Darkness
+Rias Gremory
+H
+Sakura Haruno
+Hatsune Miku
+Misa Hayase
+Lucy Heartfilia
+Hestia (character)
+Hinako (anime character)
+Tohru Honda
+Hinata Hyuga
+I
+Yuko Ichihara
+Orihime Inoue
+Lum Invader
+Konata Izumi
+Sagiri Izumi
+J
+Yumeko Jabami
+Oscar François de Jarjayes
+Abigail Jones
+K
+K.R.T. Girls
+Kamiya Kaoru
+Madoka Kaname
+Urumi Kanzaki
+Yuu Kashima
+Misato Katsuragi
+Tomie Kawakami
+Ami Kawashima
+Miyuki Kobayakawa
+Yuri Koigakubo
+Yotsuba Koiwai
+Kirino Kosaka
+Rukia Kuchiki
+Motoko Kusanagi
+Minori Kushieda
+Anna Kyoyama
+L
+Lala Satalin Deviluke
+Nunnally Lamperouge
+Leafa
+Lenalee Lee
+Lillie (Pokémon)
+Lina Inverse
+M
+Makimachi Misao
+Hitomi Manaka
+Wendy Marvell
+Sakura Matou
+Michiko & Hatchin
+Sayaka Miki
+Milia Fallyna Jenius
+Mai Minakami
+Fujiko Mine
+Lynn Minmay
+Mikoto Misaka
+Misty (Pokémon)
+Momo Belia Deviluke
+Kirari Momobami
+Satomi Murano
+N
+Naga the Serpent
+Mio Naganohara
+Tsubaki Nakatsukasa
+Nami (One Piece)
+Naru Narusegawa
+Nausicaä (Nausicaä of the Valley of the Wind)
+Queen Nehelenia
+Nico Robin
+Himari Noihara
+Arale Norimaki
+O
+Origami Tobiichi
+P
+Paninya
+Portrayals of Alice in Wonderland
+Projekt Melody
+R
+Yomiko Readman
+Winry Rockbell
+Roll (Mega Man)
+S
+Saber (Fate/stay night)
+Haruna Sairenji
+Sakura (Tsubasa: Reservoir Chronicle)
+Chiyo Sakura
+Kyoko Sakura
+Izumi Sakurai
+Ranma Saotome
+Yuzuki Seo
+Mika Shimotsuki
+Hakase Shinonome
+Sinon (Sword Art Online)
+Skuld (Oh My Goddess!)
+Asuka Langley Soryu
+Kallen Stadtfeld
+Celty Sturluson
+Super Sonico
+Haruhi Suzumiya (character)
+T
+Kiyomi Takada
+Utena Tenjou
+Rin Tohsaka
+Mami Tomoe
+Akane Tsunemori
+U
+Sarada Uchiha
+Urd (Oh My Goddess!)
+Hana Uzaki
+Z
+Zero Two