mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
AutoRespond: Support for per-match cooldown (#593)
Prevent a match from triggering too often using a cooldown By default, matches do not have a cooldown (it's opt-in) Also add translation support and more debug messages
This commit is contained in:
parent
e6b2b87366
commit
b9935ab8fa
4 changed files with 87 additions and 16 deletions
|
|
@ -35,6 +35,8 @@ namespace MinecraftClient.ChatBots
|
|||
private string actionPrivate;
|
||||
private string actionOther;
|
||||
private bool ownersOnly;
|
||||
private TimeSpan cooldown;
|
||||
private DateTime cooldownExpiration;
|
||||
|
||||
/// <summary>
|
||||
/// Create a respond rule from a regex and a reponse message or command
|
||||
|
|
@ -44,7 +46,8 @@ namespace MinecraftClient.ChatBots
|
|||
/// <param name="actionPrivate">Internal command to run for private messages</param>
|
||||
/// <param name="actionOther">Internal command to run for any other messages</param>
|
||||
/// <param name="ownersOnly">Only match messages from bot owners</param>
|
||||
public RespondRule(Regex regex, string actionPublic, string actionPrivate, string actionOther, bool ownersOnly)
|
||||
/// <param name="cooldown">Minimal cooldown between two matches</param>
|
||||
public RespondRule(Regex regex, string actionPublic, string actionPrivate, string actionOther, bool ownersOnly, TimeSpan cooldown)
|
||||
{
|
||||
this.regex = regex;
|
||||
this.match = null;
|
||||
|
|
@ -52,6 +55,8 @@ namespace MinecraftClient.ChatBots
|
|||
this.actionPrivate = actionPrivate;
|
||||
this.actionOther = actionOther;
|
||||
this.ownersOnly = ownersOnly;
|
||||
this.cooldown = cooldown;
|
||||
this.cooldownExpiration = DateTime.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -61,7 +66,8 @@ namespace MinecraftClient.ChatBots
|
|||
/// <param name="actionPublic">Internal command to run for public messages</param>
|
||||
/// <param name="actionPrivate">Internal command to run for private messages</param>
|
||||
/// <param name="ownersOnly">Only match messages from bot owners</param>
|
||||
public RespondRule(string match, string actionPublic, string actionPrivate, string actionOther, bool ownersOnly)
|
||||
/// <param name="cooldown">Minimal cooldown between two matches</param>
|
||||
public RespondRule(string match, string actionPublic, string actionPrivate, string actionOther, bool ownersOnly, TimeSpan cooldown)
|
||||
{
|
||||
this.regex = null;
|
||||
this.match = match;
|
||||
|
|
@ -69,6 +75,8 @@ namespace MinecraftClient.ChatBots
|
|||
this.actionPrivate = actionPrivate;
|
||||
this.actionOther = actionOther;
|
||||
this.ownersOnly = ownersOnly;
|
||||
this.cooldown = cooldown;
|
||||
this.cooldownExpiration = DateTime.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -81,6 +89,9 @@ namespace MinecraftClient.ChatBots
|
|||
/// <returns>Internal command to run as a response to this user, or null if no match has been detected</returns>
|
||||
public string Match(string username, string message, MessageType msgType, Dictionary<string, object> localVars)
|
||||
{
|
||||
if (DateTime.Now < cooldownExpiration)
|
||||
return null;
|
||||
|
||||
string toSend = null;
|
||||
|
||||
if (ownersOnly && (String.IsNullOrEmpty(username) || !Settings.Bots_Owners.Contains(username.ToLower())))
|
||||
|
|
@ -100,6 +111,7 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
if (regex.IsMatch(message))
|
||||
{
|
||||
cooldownExpiration = DateTime.Now + cooldown;
|
||||
Match regexMatch = regex.Match(message);
|
||||
localVars["match_0"] = regexMatch.Groups[0].Value;
|
||||
for (int i = regexMatch.Groups.Count - 1; i >= 1; i--)
|
||||
|
|
@ -116,6 +128,7 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
if (message.ToLower().Contains(match.ToLower()))
|
||||
{
|
||||
cooldownExpiration = DateTime.Now + cooldown;
|
||||
localVars["match_0"] = message;
|
||||
localVars["match_u"] = username;
|
||||
return toSend.Replace("$u", username);
|
||||
|
|
@ -124,6 +137,24 @@ namespace MinecraftClient.ChatBots
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the RespondRule
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Translations.Get(
|
||||
"bot.autoRespond.match",
|
||||
match,
|
||||
regex,
|
||||
actionPublic,
|
||||
actionPrivate,
|
||||
actionOther,
|
||||
ownersOnly,
|
||||
(int)cooldown.TotalSeconds
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -139,10 +170,10 @@ namespace MinecraftClient.ChatBots
|
|||
string matchActionPrivate = null;
|
||||
string matchActionOther = null;
|
||||
bool ownersOnly = false;
|
||||
TimeSpan cooldown = TimeSpan.Zero;
|
||||
respondRules = new List<RespondRule>();
|
||||
|
||||
if (Settings.DebugMessages)
|
||||
LogToConsole("Loading matches from file: " + System.IO.Path.GetFullPath(matchesFile));
|
||||
LogDebugToConsoleTranslated("bot.autoRespond.loading", System.IO.Path.GetFullPath(matchesFile));
|
||||
|
||||
foreach (string lineRAW in File.ReadAllLines(matchesFile, Encoding.UTF8))
|
||||
{
|
||||
|
|
@ -154,13 +185,14 @@ namespace MinecraftClient.ChatBots
|
|||
switch (line.Substring(1, line.Length - 2).ToLower())
|
||||
{
|
||||
case "match":
|
||||
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly);
|
||||
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly, cooldown);
|
||||
matchRegex = null;
|
||||
matchString = null;
|
||||
matchAction = null;
|
||||
matchActionPrivate = null;
|
||||
matchActionOther = null;
|
||||
ownersOnly = false;
|
||||
cooldown = TimeSpan.Zero;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -178,16 +210,17 @@ namespace MinecraftClient.ChatBots
|
|||
case "actionprivate": matchActionPrivate = argValue; break;
|
||||
case "actionother": matchActionOther = argValue; break;
|
||||
case "ownersonly": ownersOnly = Settings.str2bool(argValue); break;
|
||||
case "cooldown": cooldown = TimeSpan.FromSeconds(Settings.str2int(argValue)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly);
|
||||
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly, cooldown);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToConsole("File not found: '" + System.IO.Path.GetFullPath(matchesFile) + "'");
|
||||
LogToConsoleTranslated("bot.autoRespond.file_not_found", System.IO.Path.GetFullPath(matchesFile));
|
||||
UnloadBot(); //No need to keep the bot active
|
||||
}
|
||||
}
|
||||
|
|
@ -200,21 +233,32 @@ namespace MinecraftClient.ChatBots
|
|||
/// <param name="matchAction">Action if the matching message is public</param>
|
||||
/// <param name="matchActionPrivate">Action if the matching message is private</param>
|
||||
/// <param name="ownersOnly">Only match messages from bot owners</param>
|
||||
private void CheckAddMatch(Regex matchRegex, string matchString, string matchAction, string matchActionPrivate, string matchActionOther, bool ownersOnly)
|
||||
/// <param name="cooldown">Minimal cooldown between two matches</param>
|
||||
private void CheckAddMatch(Regex matchRegex, string matchString, string matchAction, string matchActionPrivate, string matchActionOther, bool ownersOnly, TimeSpan cooldown)
|
||||
{
|
||||
if (matchRegex != null || matchString != null || matchAction != null || matchActionPrivate != null || matchActionOther != null || ownersOnly || cooldown != TimeSpan.Zero)
|
||||
{
|
||||
RespondRule rule = matchRegex != null
|
||||
? new RespondRule(matchRegex, matchAction, matchActionPrivate, matchActionOther, ownersOnly, cooldown)
|
||||
: new RespondRule(matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly, cooldown);
|
||||
|
||||
if (matchAction != null || matchActionPrivate != null || matchActionOther != null)
|
||||
{
|
||||
if (matchRegex != null)
|
||||
if (matchRegex != null || matchString != null)
|
||||
{
|
||||
respondRules.Add(new RespondRule(matchRegex, matchAction, matchActionPrivate, matchActionOther, ownersOnly));
|
||||
respondRules.Add(rule);
|
||||
LogDebugToConsoleTranslated("bot.autoRespond.loaded_match", rule);
|
||||
}
|
||||
else if (matchString != null)
|
||||
{
|
||||
respondRules.Add(new RespondRule(matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly));
|
||||
else LogDebugToConsoleTranslated("bot.autoRespond.no_trigger", rule);
|
||||
}
|
||||
else LogDebugToConsoleTranslated("bot.autoRespond.no_action", rule);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process messages from the server and test them against all matches
|
||||
/// </summary>
|
||||
/// <param name="text">Text from the server</param>
|
||||
public override void GetText(string text)
|
||||
{
|
||||
//Remove colour codes
|
||||
|
|
@ -239,7 +283,7 @@ namespace MinecraftClient.ChatBots
|
|||
if (!String.IsNullOrEmpty(toPerform))
|
||||
{
|
||||
string response = null;
|
||||
LogToConsole(toPerform);
|
||||
LogToConsoleTranslated("bot.autoRespond.match_run", toPerform);
|
||||
PerformInternalCommand(toPerform, ref response, localVars);
|
||||
if (!String.IsNullOrEmpty(response))
|
||||
LogToConsole(response);
|
||||
|
|
|
|||
|
|
@ -429,6 +429,15 @@ bot.autoRelog.reconnect=Nachricht enhält '{0}'. Verbinde erneut.
|
|||
bot.autoRelog.reconnect_ignore=Kick Nachricht enthält keine Schlüsselwörter. Wird ignoriert!
|
||||
bot.autoRelog.wait=Warte {0} Sekunden vor erneuter Verbindung...
|
||||
|
||||
# AutoRespond
|
||||
bot.autoRespond.loading=Loading matches from '{0}'
|
||||
bot.autoRespond.file_not_found=File not found: '{0}'
|
||||
bot.autoRespond.loaded_match=Loaded match:\n{0}
|
||||
bot.autoRespond.no_trigger=This match will never trigger:\n{0}
|
||||
bot.autoRespond.no_action=No action for match:\n{0}
|
||||
bot.autoRespond.match_run=Running action: {0}
|
||||
bot.autoRespond.match=match: {0}\nregex: {1}\naction: {2}\nactionPrivate: {3}\nactionOther: {4}\nownersOnly: {5}\ncooldown: {6}
|
||||
|
||||
# ChatLog
|
||||
bot.chatLog.invalid_file=Pfad '{0}' enthält ungültige Zeichen.
|
||||
|
||||
|
|
|
|||
|
|
@ -429,6 +429,15 @@ bot.autoRelog.reconnect=Message contains '{0}'. Reconnecting.
|
|||
bot.autoRelog.reconnect_ignore=Message not containing any defined keywords. Ignoring.
|
||||
bot.autoRelog.wait=Waiting {0} seconds before reconnecting...
|
||||
|
||||
# AutoRespond
|
||||
bot.autoRespond.loading=Loading matches from '{0}'
|
||||
bot.autoRespond.file_not_found=File not found: '{0}'
|
||||
bot.autoRespond.loaded_match=Loaded match:\n{0}
|
||||
bot.autoRespond.no_trigger=This match will never trigger:\n{0}
|
||||
bot.autoRespond.no_action=No action for match:\n{0}
|
||||
bot.autoRespond.match_run=Running action: {0}
|
||||
bot.autoRespond.match=match: {0}\nregex: {1}\naction: {2}\nactionPrivate: {3}\nactionOther: {4}\nownersOnly: {5}\ncooldown: {6}
|
||||
|
||||
# ChatLog
|
||||
bot.chatLog.invalid_file=Path '{0}' contains invalid characters.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
# You can define an action if the match was not sent by a player
|
||||
# Regex matches are also supported eg $1, $2, $3.. in actions
|
||||
# Matches can optionally be restricted to bot owners only
|
||||
# Matches can have a cooldown, specified in seconds
|
||||
|
||||
# When running a script from an AutoRespond match,
|
||||
# additional %variables% are available from within your script:
|
||||
|
|
@ -23,6 +24,7 @@ action=send hi, $u!
|
|||
actionprivate=send /tell $u Hello!
|
||||
actionother=log detected "hi" message
|
||||
ownersonly=false
|
||||
cooldown=0
|
||||
|
||||
# You do not need to specify all the "action" fields
|
||||
# Only one of them is required for each match
|
||||
|
|
@ -54,5 +56,12 @@ match=gohome
|
|||
actionprivate=send /home
|
||||
ownersonly=true
|
||||
|
||||
# Example of match with 1-minute cooldown
|
||||
|
||||
[Match]
|
||||
match=hello
|
||||
action=send hello!
|
||||
cooldown=60
|
||||
|
||||
# Enjoy!
|
||||
# - ORelio
|
||||
Loading…
Add table
Add a link
Reference in a new issue