Skip to content

Commit 9108e20

Browse files
authored
Merge pull request #369 from Unity-Developer-Community/hariedo-patch-1
Preliminary support for fuzz strings and groundwork for fuzz tables, starting with a test in the Miku topic detector for Reenaki.
2 parents 7db8c9e + 8ed3bfd commit 9108e20

2 files changed

Lines changed: 71 additions & 3 deletions

File tree

DiscordBot/Data/FuzzTable.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// FuzzTable.cs
2+
//
3+
using System;
4+
using System.Text.RegularExpressions;
5+
6+
namespace DiscordBot.Data;
7+
8+
public class FuzzTable
9+
{
10+
private static Random random = new();
11+
private static Regex parenContents = null;
12+
private static TimeSpan timeout = new(10*10000/*x10nanoseconds*/);
13+
14+
//TODO: an instance keeps an array of alternates and an MRU list
15+
16+
// Evaluate a single fuzz string.
17+
// "(He|She|They) (picked|selected) a (green|red|blue) (ball|block)."
18+
// "She picked a red ball."
19+
// Replace any parenthetical phrase with one of its choices at random.
20+
// Allows for nesting of choices. There's currently no way to escape
21+
// parentheses or vertical bars so strings must not include strays.
22+
// Returns one permutation from all choice alternatives given.
23+
// Does not remember what choices were given.
24+
//
25+
public static string Evaluate(string fuzz)
26+
{
27+
if (string.IsNullOrEmpty(fuzz))
28+
return "";
29+
if (parenContents == null)
30+
parenContents =
31+
new(@"\( ( [^(]*? ) \)",
32+
RegexOptions.IgnorePatternWhitespace |
33+
RegexOptions.Compiled,
34+
timeout);
35+
string before = null;
36+
while (fuzz != before)
37+
{
38+
before = fuzz;
39+
try
40+
{
41+
fuzz = parenContents.Replace(fuzz,
42+
(m) => PickAlternate(m.Groups[1].ToString()));
43+
}
44+
catch (RegexMatchTimeoutException)
45+
{
46+
break;
47+
}
48+
}
49+
return fuzz;
50+
}
51+
52+
private static string PickAlternate(string fuzz)
53+
{
54+
if (string.IsNullOrEmpty(fuzz))
55+
return "";
56+
string[] alternates = fuzz.Split('|');
57+
if (alternates == null || alternates.Length == 0)
58+
return "";
59+
int pick = random.Next(0, alternates.Length);
60+
return alternates[pick];
61+
}
62+
63+
}

DiscordBot/Services/UserService.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using DiscordBot.Domain;
88
using DiscordBot.Settings;
99
using DiscordBot.Skin;
10+
using DiscordBot.Data;
1011
using ImageMagick;
1112
using Newtonsoft.Json;
1213

@@ -115,11 +116,14 @@ Init thanks
115116
Init Miku
116117
Gag feature has no external settings, hardcoded userid refers to Reenaki/Kiki.
117118
*/
118-
_mikuMentioned = DateTime.Now;
119119
_mikuCooldownTime = new TimeSpan(0, 39, 0); // 39min
120120
//_mikuCooldownTime = new TimeSpan(0, 0, 39); // test 39sec
121+
_mikuMentioned = DateTime.Now - _mikuCooldownTime;
121122
_mikuRegex = @"(?i)\b(miku|hatsune|初音ミク|初音|ミク)\b";
122-
_mikuReply = ":three: :nine: Oi, mite, mite, <@358915848515354626> -chan!";
123+
_mikuReply =
124+
"(:three: :nine:|:microphone:|:notes:|:musical_note:|:musical_keyboard:|:mirror_ball:) " +
125+
"(Oi, mite, mite,|Heya,|Hey, look,|Did someone mention Miku?) " +
126+
"<@358915848515354626> (-chan|)!";
123127
//_mikuReply = "Oi, mite, mite, <@427306565184389132> ! :three: :nine:"; // test
124128

125129
/*
@@ -541,7 +545,8 @@ public async Task MikuCheck(SocketMessage messageParam)
541545
return;
542546

543547
_mikuMentioned = now;
544-
await messageParam.Channel.SendMessageAsync(_mikuReply);
548+
var reply = FuzzTable.Evaluate(_mikuReply);
549+
await messageParam.Channel.SendMessageAsync(reply);
545550
}
546551

547552
public async Task CodeCheck(SocketMessage messageParam)

0 commit comments

Comments
 (0)