Add 'other' messages support in AutoRespond

This commit is contained in:
ORelio 2015-08-02 12:20:51 +02:00
parent 12b94996c7
commit de4322458a
2 changed files with 57 additions and 31 deletions

View file

@ -12,6 +12,7 @@ namespace MinecraftClient.ChatBots
{ {
private string matchesFile; private string matchesFile;
private List<RespondRule> respondRules; private List<RespondRule> respondRules;
private enum MessageType { Public, Private, Other };
/// <summary> /// <summary>
/// Create a new AutoRespond bot /// Create a new AutoRespond bot
@ -31,6 +32,7 @@ namespace MinecraftClient.ChatBots
private string match; private string match;
private string actionPublic; private string actionPublic;
private string actionPrivate; private string actionPrivate;
private string actionOther;
/// <summary> /// <summary>
/// Create a respond rule from a regex and a reponse message or command /// Create a respond rule from a regex and a reponse message or command
@ -38,12 +40,14 @@ namespace MinecraftClient.ChatBots
/// <param name="regex">Regex</param> /// <param name="regex">Regex</param>
/// <param name="actionPublic">Internal command to run for public messages</param> /// <param name="actionPublic">Internal command to run for public messages</param>
/// <param name="actionPrivate">Internal command to run for private messages</param> /// <param name="actionPrivate">Internal command to run for private messages</param>
public RespondRule(Regex regex, string actionPublic, string actionPrivate) /// <param name="actionOther">Internal command to run for any other messages</param>
public RespondRule(Regex regex, string actionPublic, string actionPrivate, string actionOther)
{ {
this.regex = regex; this.regex = regex;
this.match = null; this.match = null;
this.actionPublic = actionPublic; this.actionPublic = actionPublic;
this.actionPrivate = actionPrivate; this.actionPrivate = actionPrivate;
this.actionOther = actionOther;
} }
/// <summary> /// <summary>
@ -52,12 +56,13 @@ namespace MinecraftClient.ChatBots
/// <param name="match">Match string</param> /// <param name="match">Match string</param>
/// <param name="actionPublic">Internal command to run for public messages</param> /// <param name="actionPublic">Internal command to run for public messages</param>
/// <param name="actionPrivate">Internal command to run for private messages</param> /// <param name="actionPrivate">Internal command to run for private messages</param>
public RespondRule(string match, string actionPublic, string actionPrivate) public RespondRule(string match, string actionPublic, string actionPrivate, string actionOther)
{ {
this.regex = null; this.regex = null;
this.match = match; this.match = match;
this.actionPublic = actionPublic; this.actionPublic = actionPublic;
this.actionPrivate = actionPrivate; this.actionPrivate = actionPrivate;
this.actionOther = actionOther;
} }
/// <summary> /// <summary>
@ -65,16 +70,27 @@ namespace MinecraftClient.ChatBots
/// </summary> /// </summary>
/// <param name="username">Player who have sent the message</param> /// <param name="username">Player who have sent the message</param>
/// <param name="message">Message to match against the regex or match string</param> /// <param name="message">Message to match against the regex or match string</param>
/// <param name="privateMsg">True if the provided message was sent privately eg with /tell</param> /// <param name="msgType">Type of the message public/private message, or other message</param>
/// <returns>Internal command to run as a response to this user, or null if no match has been detected</returns> /// <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, bool privateMsg) public string Match(string username, string message, MessageType msgType)
{ {
string toSend = null;
switch (msgType)
{
case MessageType.Public: toSend = actionPublic; break;
case MessageType.Private: toSend = actionPrivate; break;
case MessageType.Other: toSend = actionOther; break;
}
if (String.IsNullOrEmpty(toSend))
return null;
if (regex != null) if (regex != null)
{ {
if (regex.IsMatch(message)) if (regex.IsMatch(message))
{ {
Match regexMatch = regex.Match(message); Match regexMatch = regex.Match(message);
string toSend = privateMsg ? actionPrivate : actionPublic;
for (int i = regexMatch.Groups.Count - 1; i >= 1; i--) for (int i = regexMatch.Groups.Count - 1; i >= 1; i--)
toSend = toSend.Replace("$" + i, regexMatch.Groups[i].Value); toSend = toSend.Replace("$" + i, regexMatch.Groups[i].Value);
toSend = toSend.Replace("$u", username); toSend = toSend.Replace("$u", username);
@ -85,11 +101,10 @@ namespace MinecraftClient.ChatBots
{ {
if (message.ToLower().Contains(match.ToLower())) if (message.ToLower().Contains(match.ToLower()))
{ {
return (privateMsg return toSend.Replace("$u", username);
? actionPrivate
: actionPublic).Replace("$u", username);
} }
} }
return null; return null;
} }
} }
@ -105,6 +120,7 @@ namespace MinecraftClient.ChatBots
string matchString = null; string matchString = null;
string matchAction = null; string matchAction = null;
string matchActionPrivate = null; string matchActionPrivate = null;
string matchActionOther = null;
respondRules = new List<RespondRule>(); respondRules = new List<RespondRule>();
foreach (string lineRAW in File.ReadAllLines(matchesFile)) foreach (string lineRAW in File.ReadAllLines(matchesFile))
@ -117,11 +133,12 @@ namespace MinecraftClient.ChatBots
switch (line.Substring(1, line.Length - 2).ToLower()) switch (line.Substring(1, line.Length - 2).ToLower())
{ {
case "match": case "match":
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate); CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther);
matchRegex = null; matchRegex = null;
matchString = null; matchString = null;
matchAction = null; matchAction = null;
matchActionPrivate = null; matchActionPrivate = null;
matchActionOther = null;
break; break;
} }
} }
@ -137,12 +154,13 @@ namespace MinecraftClient.ChatBots
case "match": matchString = argValue; break; case "match": matchString = argValue; break;
case "action": matchAction = argValue; break; case "action": matchAction = argValue; break;
case "actionprivate": matchActionPrivate = argValue; break; case "actionprivate": matchActionPrivate = argValue; break;
case "actionother": matchActionOther = argValue; break;
} }
} }
} }
} }
} }
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate); CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther);
} }
else else
{ {
@ -158,22 +176,17 @@ namespace MinecraftClient.ChatBots
/// <param name="matchString">Matching string</param> /// <param name="matchString">Matching string</param>
/// <param name="matchAction">Action if the matching message is public</param> /// <param name="matchAction">Action if the matching message is public</param>
/// <param name="matchActionPrivate">Action if the matching message is private</param> /// <param name="matchActionPrivate">Action if the matching message is private</param>
private void CheckAddMatch(Regex matchRegex, string matchString, string matchAction, string matchActionPrivate) private void CheckAddMatch(Regex matchRegex, string matchString, string matchAction, string matchActionPrivate, string matchActionOther)
{ {
if (matchAction != null || matchActionPrivate != null) if (matchAction != null || matchActionPrivate != null || matchActionOther != null)
{ {
if (matchActionPrivate == null)
{
matchActionPrivate = matchAction;
}
if (matchRegex != null) if (matchRegex != null)
{ {
respondRules.Add(new RespondRule(matchRegex, matchAction, matchActionPrivate)); respondRules.Add(new RespondRule(matchRegex, matchAction, matchActionPrivate, matchActionOther));
} }
else if (matchString != null) else if (matchString != null)
{ {
respondRules.Add(new RespondRule(matchString, matchAction, matchActionPrivate)); respondRules.Add(new RespondRule(matchString, matchAction, matchActionPrivate, matchActionOther));
} }
} }
} }
@ -183,20 +196,21 @@ namespace MinecraftClient.ChatBots
//Remove colour codes //Remove colour codes
text = GetVerbatim(text); text = GetVerbatim(text);
//Check if this is a valid message //Get Message type
string sender = "", message = ""; string sender = "", message = "";
bool chatMessage = IsChatMessage(text, ref message, ref sender); MessageType msgType = MessageType.Other;
bool privateMessage = false; if (IsChatMessage(text, ref message, ref sender))
if (!chatMessage) msgType = MessageType.Public;
privateMessage = IsPrivateMessage(text, ref message, ref sender); else if (IsPrivateMessage(text, ref message, ref sender))
msgType = MessageType.Private;
//Process only chat messages sent by another user //Do not process messages sent by the bot itself
if ((chatMessage || privateMessage) && sender != Settings.Username) if (msgType == MessageType.Other || sender != Settings.Username)
{ {
foreach (RespondRule rule in respondRules) foreach (RespondRule rule in respondRules)
{ {
string toPerform = rule.Match(sender, message, privateMessage); string toPerform = rule.Match(sender, message, msgType);
if (toPerform != null) if (!String.IsNullOrEmpty(toPerform))
{ {
string response = null; string response = null;
LogToConsole(toPerform); LogToConsole(toPerform);

View file

@ -4,8 +4,9 @@
# Structure of a match: [Match] Followed by the match and action # Structure of a match: [Match] Followed by the match and action
# The match can be a simple match or an advanced regular expression # The match can be a simple match or an advanced regular expression
# You can define a different action if the match was in a private message
# You can use $u for username of the player triggering the match # You can use $u for username of the player triggering the match
# You can define an action if the match was in a private message
# 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 # Regex matches are also supported eg $1, $2, $3.. in actions
# Simple example: Respond to a message containing a keyword # Simple example: Respond to a message containing a keyword
@ -14,19 +15,30 @@
match=hi match=hi
action=send hi, $u! action=send hi, $u!
actionprivate=send /tell $u Hello! actionprivate=send /tell $u Hello!
actionother=log detected "hi" message
# You do not need to specify all the "action" fields
# Only one of them is required for each match
# Advanced example: Use a regular expression # Advanced example: Use a regular expression
# Here a "regex" field is used instead of "match" field
# Do not use both "regex" and "match" fields...
[Match] [Match]
regex=^.*hello ([a-zA-Z0-9_]+).*$ regex=^.*hello ([a-zA-Z0-9_]+).*$
action=send hello too, $1! action=send hello too, $1!
# You can also use any other internal command # Example of using a script
# Private action is optional
[Match] [Match]
match=dotest match=dotest
action=script test action=script test
# Example of matching a server announcement
[Match]
match=server is restarting
actionother=script restart
# Enjoy! # Enjoy!
# - ORelio # - ORelio