Alerts ChatBot: Support trigger on weather change

This commit is contained in:
BruceChen 2022-10-03 11:53:27 +08:00 committed by GitHub
commit ccb4ce51cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 152 additions and 19 deletions

View file

@ -11,15 +11,21 @@ namespace MinecraftClient.ChatBots
private string[] dictionary = Array.Empty<string>(); private string[] dictionary = Array.Empty<string>();
private string[] excludelist = Array.Empty<string>(); private string[] excludelist = Array.Empty<string>();
private bool logToFile = false; private bool logToFile = false;
float curRainLevel = 0;
float curThunderLevel = 0;
const float threshold = 0.2f;
/// <summary> /// <summary>
/// Intitialize the Alerts bot /// Intitialize the Alerts bot
/// </summary> /// </summary>
public override void Initialize() public override void Initialize()
{ {
dictionary = LoadDistinctEntriesFromFile(Settings.Alerts_MatchesFile); if (Settings.Alerts_Trigger_By_Words)
excludelist = LoadDistinctEntriesFromFile(Settings.Alerts_ExcludesFile); {
logToFile = Settings.Alerts_File_Logging; dictionary = LoadDistinctEntriesFromFile(Settings.Alerts_MatchesFile);
excludelist = LoadDistinctEntriesFromFile(Settings.Alerts_ExcludesFile);
logToFile = Settings.Alerts_File_Logging;
}
} }
/// <summary> /// <summary>
@ -28,28 +34,87 @@ namespace MinecraftClient.ChatBots
/// <param name="text">Received text</param> /// <param name="text">Received text</param>
public override void GetText(string text) public override void GetText(string text)
{ {
//Remove color codes and convert to lowercase if (Settings.Alerts_Trigger_By_Words)
text = GetVerbatim(text).ToLower();
//Proceed only if no exclusions are found in text
if (!excludelist.Any(exclusion => text.Contains(exclusion)))
{ {
//Show an alert for each alert item found in text, if any //Remove color codes and convert to lowercase
foreach (string alert in dictionary.Where(alert => text.Contains(alert))) text = GetVerbatim(text).ToLower();
//Proceed only if no exclusions are found in text
if (!excludelist.Any(exclusion => text.Contains(exclusion)))
{ {
if (Settings.Alerts_Beep_Enabled) //Show an alert for each alert item found in text, if any
Console.Beep(); //Text found ! foreach (string alert in dictionary.Where(alert => text.Contains(alert)))
ConsoleIO.WriteLine(text.Replace(alert, "§c" + alert + "§r"));
if (logToFile && Settings.Alerts_LogFile.Length > 0)
{ {
DateTime now = DateTime.Now; if (Settings.Alerts_Beep_Enabled)
string TimeStamp = "[" + now.Year + '/' + now.Month + '/' + now.Day + ' ' + now.Hour + ':' + now.Minute + ']'; Console.Beep(); //Text found !
System.IO.File.AppendAllText(Settings.Alerts_LogFile, TimeStamp + " " + GetVerbatim(text) + "\n");
ConsoleIO.WriteLine(text.Replace(alert, "§c" + alert + "§r"));
if (logToFile && Settings.Alerts_LogFile.Length > 0)
{
DateTime now = DateTime.Now;
string TimeStamp = "[" + now.Year + '/' + now.Month + '/' + now.Day + ' ' + now.Hour + ':' + now.Minute + ']';
System.IO.File.AppendAllText(Settings.Alerts_LogFile, TimeStamp + " " + GetVerbatim(text) + "\n");
}
} }
} }
} }
} }
public override void OnRainLevelChange(float level)
{
if (curRainLevel < threshold && level >= threshold)
{
if (Settings.Alerts_Trigger_By_Rain)
{
if (Settings.Alerts_Beep_Enabled)
{
Console.Beep();
Console.Beep();
}
LogToConsole(Translations.TryGet("bot.alerts.start_rain"));
}
}
else if (curRainLevel >= threshold && level < threshold)
{
if (Settings.Alerts_Trigger_By_Rain)
{
if (Settings.Alerts_Beep_Enabled)
{
Console.Beep();
}
LogToConsole(Translations.TryGet("bot.alerts.end_rain"));
}
}
curRainLevel = level;
}
public override void OnThunderLevelChange(float level)
{
if (curThunderLevel < threshold && level >= threshold)
{
if (Settings.Alerts_Trigger_By_Thunderstorm)
{
if (Settings.Alerts_Beep_Enabled)
{
Console.Beep();
Console.Beep();
}
LogToConsole(Translations.TryGet("bot.alerts.start_thunderstorm"));
}
}
else if (curThunderLevel >= threshold && level < threshold)
{
if (Settings.Alerts_Trigger_By_Thunderstorm)
{
if (Settings.Alerts_Beep_Enabled)
{
Console.Beep();
}
LogToConsole(Translations.TryGet("bot.alerts.end_thunderstorm"));
}
}
curThunderLevel = level;
}
} }
} }

View file

@ -3294,6 +3294,25 @@ namespace MinecraftClient
////handler.SetUserUUID(UUID); ////handler.SetUserUUID(UUID);
} }
/// <summary>
/// Used for a wide variety of game events, from weather to bed use to gamemode to demo messages.
/// </summary>
/// <param name="reason">Event type</param>
/// <param name="value">Depends on Reason</param>
public void OnGameEvent(byte reason, float value)
{
switch (reason)
{
case 7:
DispatchBotEvent(bot => bot.OnRainLevelChange(value));
break;
case 8:
DispatchBotEvent(bot => bot.OnThunderLevelChange(value));
break;
}
}
#endregion #endregion
} }
} }

View file

@ -1139,6 +1139,15 @@ namespace MinecraftClient.Protocol.Handlers
handler.GetWorld()[chunkX, chunkZ] = null; handler.GetWorld()[chunkX, chunkZ] = null;
} }
break; break;
case PacketTypesIn.ChangeGameState:
if (protocolVersion >= MC_1_15_2_Version)
{
byte reason = dataTypes.ReadNextByte(packetData);
float state = dataTypes.ReadNextFloat(packetData);
handler.OnGameEvent(reason, state);
}
break;
case PacketTypesIn.PlayerInfo: case PacketTypesIn.PlayerInfo:
if (protocolVersion >= MC_1_8_Version) if (protocolVersion >= MC_1_8_Version)
{ {

View file

@ -425,5 +425,12 @@ namespace MinecraftClient.Protocol
/// <param name="userName">The player's username received from the server</param> /// <param name="userName">The player's username received from the server</param>
/// <param name="playerProperty">Tuple<Name, Value, Signature(empty if there is no signature)></param> /// <param name="playerProperty">Tuple<Name, Value, Signature(empty if there is no signature)></param>
public void OnLoginSuccess(Guid uuid, string userName, Tuple<string, string, string>[]? playerProperty); public void OnLoginSuccess(Guid uuid, string userName, Tuple<string, string, string>[]? playerProperty);
/// <summary>
/// Used for a wide variety of game events, from weather to bed use to gamemode to demo messages.
/// </summary>
/// <param name="reason">Event type</param>
/// <param name="value">Depends on Reason</param>
public void OnGameEvent(byte reason, float value);
} }
} }

View file

@ -131,6 +131,9 @@ skin_pants_right=false
# Get alerted when specified words are detected in chat # Get alerted when specified words are detected in chat
# Useful for moderating your server or detecting when someone is talking to you # Useful for moderating your server or detecting when someone is talking to you
enabled=false enabled=false
trigger_by_words=false # Triggers an alert after receiving a specified keyword.
trigger_by_rain=false # Trigger alerts when it rains and when it stops.
trigger_by_thunderstorm=false # Triggers alerts at the beginning and end of thunderstorms.
alertsfile=alerts.txt # List of words/strings to alert you on, e.g. "Yourname" alertsfile=alerts.txt # List of words/strings to alert you on, e.g. "Yourname"
excludesfile=alerts-exclude.txt # List of words/strings to NOT alert you on, e.g. "<Yourname>" excludesfile=alerts-exclude.txt # List of words/strings to NOT alert you on, e.g. "<Yourname>"
beeponalert=true # Play a beep sound when a word is detected in addition to highlighting beeponalert=true # Play a beep sound when a word is detected in addition to highlighting

View file

@ -444,6 +444,12 @@ cmd.useitem.use=Used an item
[bot] [bot]
# ChatBots. Naming style: bot.<className>.<msg...> # ChatBots. Naming style: bot.<className>.<msg...>
# Alerts
bot.alerts.start_rain=§cWeather change: It's raining now.§r
bot.alerts.end_rain=§cWeather change: It's no longer raining.§r
bot.alerts.start_thunderstorm=§cWeather change: It's a thunderstorm.§r
bot.alerts.end_thunderstorm=§cWeather change: It's no longer a thunderstorm.§r
# Anti AFK # Anti AFK
bot.antiafk.not_using_terrain_handling=The terrain handling is not enabled in the settings of the client, enable it if you want to use it with this bot. Using alternative (command) method. bot.antiafk.not_using_terrain_handling=The terrain handling is not enabled in the settings of the client, enable it if you want to use it with this bot. Using alternative (command) method.
bot.antiafk.invalid_range_partial=Invalid time range provided, using the first part of the range {0} as the time! bot.antiafk.invalid_range_partial=Invalid time range provided, using the first part of the range {0} as the time!

View file

@ -376,6 +376,12 @@ cmd.useitem.use=使用了一个物品。
[bot] [bot]
# ChatBots. Naming style: bot.<className>.<msg...> # ChatBots. Naming style: bot.<className>.<msg...>
# Alerts
bot.alerts.start_rain=§c天气变化开始下雨了。§r
bot.alerts.end_rain=§c天气变化雨停了。§r
bot.alerts.start_thunderstorm=§c天气变化现在是雷雨天。§r
bot.alerts.end_thunderstorm=§c天气变化现在不再是雷雨天了。§r
# AutoAttack # AutoAttack
bot.autoAttack.mode=未知的攻击模式:{0},使用单一模式作为默认值。 bot.autoAttack.mode=未知的攻击模式:{0},使用单一模式作为默认值。
bot.autoAttack.priority=未知优先模式:{0},使用距离优先作为默认值。 bot.autoAttack.priority=未知优先模式:{0},使用距离优先作为默认值。

View file

@ -413,6 +413,18 @@ namespace MinecraftClient
/// <param name="isInbound">The packet is received from server or sent by client</param> /// <param name="isInbound">The packet is received from server or sent by client</param>
public virtual void OnNetworkPacket(int packetID, List<byte> packetData, bool isLogin, bool isInbound) { } public virtual void OnNetworkPacket(int packetID, List<byte> packetData, bool isLogin, bool isInbound) { }
/// <summary>
/// Called when the rain level have been changed
/// </summary>
/// <param name="level"></param>
public virtual void OnRainLevelChange(float level) { }
/// <summary>
/// Called when the thunder level have been changed
/// </summary>
/// <param name="level"></param>
public virtual void OnThunderLevelChange(float level) { }
/* =================================================================== */ /* =================================================================== */
/* ToolBox - Methods below might be useful while creating your bot. */ /* ToolBox - Methods below might be useful while creating your bot. */
/* You should not need to interact with other classes of the program. */ /* You should not need to interact with other classes of the program. */

View file

@ -152,6 +152,9 @@ namespace MinecraftClient
//Alerts Settings //Alerts Settings
public static bool Alerts_Enabled = false; public static bool Alerts_Enabled = false;
public static bool Alerts_Trigger_By_Words = false;
public static bool Alerts_Trigger_By_Rain = false;
public static bool Alerts_Trigger_By_Thunderstorm = false;
public static bool Alerts_Beep_Enabled = true; public static bool Alerts_Beep_Enabled = true;
public static bool Alerts_File_Logging = false; public static bool Alerts_File_Logging = false;
public static string Alerts_MatchesFile = "alerts.txt"; public static string Alerts_MatchesFile = "alerts.txt";
@ -585,6 +588,9 @@ namespace MinecraftClient
switch (ToLowerIfNeed(argName)) switch (ToLowerIfNeed(argName))
{ {
case "enabled": Alerts_Enabled = str2bool(argValue); return true; case "enabled": Alerts_Enabled = str2bool(argValue); return true;
case "trigger_by_words": Alerts_Trigger_By_Words = str2bool(argValue); return true;
case "trigger_by_rain": Alerts_Trigger_By_Rain = str2bool(argValue); return true;
case "trigger_by_thunderstorm": Alerts_Trigger_By_Thunderstorm = str2bool(argValue); return true;
case "alertsfile": Alerts_MatchesFile = argValue; return true; case "alertsfile": Alerts_MatchesFile = argValue; return true;
case "excludesfile": Alerts_ExcludesFile = argValue; return true; case "excludesfile": Alerts_ExcludesFile = argValue; return true;
case "beeponalert": Alerts_Beep_Enabled = str2bool(argValue); return true; case "beeponalert": Alerts_Beep_Enabled = str2bool(argValue); return true;