Add ScriptScheduler bot

- Allow to launch script on various events
- Removed startup script, now part of ScriptScheduler
- ScriptScheduler is configured using its own INI file
- Can launch scripts on first login, login and/or specific time
This commit is contained in:
ORelio 2014-05-06 22:41:14 +02:00
parent 3c84c5813e
commit 22c47e99c2
3 changed files with 176 additions and 31 deletions

View file

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace MinecraftClient
{
@ -866,41 +867,46 @@ namespace MinecraftClient
owner = ownername;
}
public override void Initialize()
public static bool lookForScript(ref string filename)
{
//Load the given file from the startup parameters
//Automatically look in subfolders and try to add ".txt" file extension
string[] files = new string[]
{
file,
file + ".txt",
"scripts\\" + file,
"scripts\\" + file + ".txt",
"config\\" + file,
"config\\" + file + ".txt",
filename,
filename + ".txt",
"scripts\\" + filename,
"scripts\\" + filename + ".txt",
"config\\" + filename,
"config\\" + filename + ".txt",
};
bool file_found = false;
foreach (string possible_file in files)
{
if (System.IO.File.Exists(possible_file))
{
lines = System.IO.File.ReadAllLines(possible_file);
file_found = true;
break;
filename = possible_file;
return true;
}
}
if (!file_found)
return false;
}
public override void Initialize()
{
//Load the given file from the startup parameters
if (lookForScript(ref file))
{
lines = System.IO.File.ReadAllLines(file);
if (owner != null) { SendPrivateMessage(owner, "Script '" + file + "' loaded."); }
}
else
{
LogToConsole("File not found: '" + file + "'");
if (owner != null)
SendPrivateMessage(owner, "File not found: '" + file + "'");
UnloadBot(); //No need to keep the bot active
}
else if (owner != null)
SendPrivateMessage(owner, "Script '" + file + "' loaded.");
}
public override void Update()
@ -963,6 +969,140 @@ namespace MinecraftClient
}
}
/// <summary>
/// Trigger scripts on specific events
/// </summary>
public class ScriptScheduler : ChatBot
{
private class TaskDesc
{
public string script_file = null;
public bool triggerOnFirstLogin = false;
public bool triggerOnLogin = false;
public bool triggerOnTime = false;
public List<DateTime> triggerOnTime_Times = new List<DateTime>();
public bool alreadyTriggered = false;
}
private static bool firstlogin_done = false;
private string tasksfile;
private bool serverlogin_done;
private List<TaskDesc> tasks = new List<TaskDesc>();
private int verifytasks_timeleft = 10;
private int verifytasks_delay = 10;
public ScriptScheduler(string tasksfile)
{
this.tasksfile = tasksfile;
serverlogin_done = false;
}
public override void Initialize()
{
//Load the given file from the startup parameters
if (System.IO.File.Exists(tasksfile))
{
TaskDesc current_task = null;
String[] lines = System.IO.File.ReadAllLines(tasksfile);
foreach (string lineRAW in lines)
{
string line = lineRAW.Split('#')[0].Trim();
if (line.Length > 0)
{
if (line[0] == '[' && line[line.Length - 1] == ']')
{
switch (line.Substring(1, line.Length - 2).ToLower())
{
case "task":
checkAddTask(current_task);
current_task = new TaskDesc(); //Create a blank task
break;
}
}
else if (current_task != null)
{
string argName = line.Split('=')[0];
if (line.Length > (argName.Length + 1))
{
string argValue = line.Substring(argName.Length + 1);
switch (argName.ToLower())
{
case "triggeronfirstlogin": current_task.triggerOnFirstLogin = Settings.str2bool(argValue); break;
case "triggeronlogin": current_task.triggerOnLogin = Settings.str2bool(argValue); break;
case "triggerontime": current_task.triggerOnTime = Settings.str2bool(argValue); break;
case "timevalue": try { current_task.triggerOnTime_Times.Add(DateTime.ParseExact(argValue, "HH:mm", CultureInfo.InvariantCulture)); } catch { } break;
case "script": current_task.script_file = argValue; break;
}
}
}
}
}
checkAddTask(current_task);
}
else
{
LogToConsole("File not found: '" + tasksfile + "'");
UnloadBot(); //No need to keep the bot active
}
}
private void checkAddTask(TaskDesc current_task)
{
if (current_task != null)
{
//Check if we built a valid task before adding it
if (current_task.script_file != null && Script.lookForScript(ref current_task.script_file) //Check if file exists
&& (current_task.triggerOnLogin || (current_task.triggerOnTime && current_task.triggerOnTime_Times.Count > 0))) //Look for a valid trigger
{
tasks.Add(current_task);
}
}
}
public override void Update()
{
if (verifytasks_timeleft <= 0)
{
verifytasks_timeleft = verifytasks_delay;
if (serverlogin_done)
{
foreach (TaskDesc task in tasks)
{
if (task.triggerOnTime)
{
foreach (DateTime time in task.triggerOnTime_Times)
{
if (time.Hour == DateTime.Now.Hour && time.Minute == DateTime.Now.Minute)
{
if (!task.alreadyTriggered)
{
task.alreadyTriggered = true;
RunScript(task.script_file);
}
}
}
}
else task.alreadyTriggered = false;
}
}
else
{
foreach (TaskDesc task in tasks)
{
if (task.triggerOnLogin || (firstlogin_done == false && task.triggerOnFirstLogin))
RunScript(task.script_file);
}
firstlogin_done = true;
serverlogin_done = true;
}
}
else verifytasks_timeleft--;
}
}
/// <summary>
/// Allow to perform operations using whispers to the bot
/// </summary>

View file

@ -156,14 +156,15 @@ namespace MinecraftClient
handler.setVersion(protocolversion);
//Load & initialize bots if needed
if (Settings.AntiAFK_Enabled) { handler.BotLoad(new Bots.AntiAFK(Settings.AntiAFK_Delay)); }
if (Settings.Hangman_Enabled) { handler.BotLoad(new Bots.Pendu(Settings.Hangman_English)); }
if (Settings.Alerts_Enabled) { handler.BotLoad(new Bots.Alerts()); }
if (Settings.ChatLog_Enabled) { handler.BotLoad(new Bots.ChatLog(Settings.ChatLog_File, Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); }
if (Settings.PlayerLog_Enabled) { handler.BotLoad(new Bots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.PlayerLog_File)); }
if (Settings.AutoRelog_Enabled) { handler.BotLoad(new Bots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); }
if (Settings.StartupScript_Enabled) { handler.BotLoad(new Bots.Script(Settings.StartupScript_ScriptFile)); Settings.StartupScript_Enabled = false; }
if (Settings.RemoteCtrl_Enabled){ handler.BotLoad(new Bots.RemoteControl()); }
if (Settings.AntiAFK_Enabled) { handler.BotLoad(new Bots.AntiAFK(Settings.AntiAFK_Delay)); }
if (Settings.Hangman_Enabled) { handler.BotLoad(new Bots.Pendu(Settings.Hangman_English)); }
if (Settings.Alerts_Enabled) { handler.BotLoad(new Bots.Alerts()); }
if (Settings.ChatLog_Enabled) { handler.BotLoad(new Bots.ChatLog(Settings.ChatLog_File, Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); }
if (Settings.PlayerLog_Enabled) { handler.BotLoad(new Bots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.PlayerLog_File)); }
if (Settings.AutoRelog_Enabled) { handler.BotLoad(new Bots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); }
if (Settings.StartupScript_Enabled) { handler.BotLoad(new Bots.Script(Settings.StartupScript_ScriptFile)); Settings.StartupScript_Enabled = false; }
if (Settings.ScriptScheduler_Enabled) { handler.BotLoad(new Bots.ScriptScheduler(Settings.ScriptScheduler_TasksFile)); }
if (Settings.RemoteCtrl_Enabled) { handler.BotLoad(new Bots.RemoteControl()); }
//Start the main TCP client
if (Settings.SingleCommand != "")

View file

@ -68,10 +68,14 @@ namespace MinecraftClient
public static bool StartupScript_Enabled = false;
public static string StartupScript_ScriptFile = "script.txt";
//Script Scheduler Settings
public static bool ScriptScheduler_Enabled = false;
public static string ScriptScheduler_TasksFile = "tasks.ini";
//Remote Control
public static bool RemoteCtrl_Enabled = false;
private enum ParseMode { Default, Main, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, Scripting, RemoteControl };
private enum ParseMode { Default, Main, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl };
/// <summary>
/// Load settings from the give INI file
@ -101,7 +105,7 @@ namespace MinecraftClient
case "chatlog": pMode = ParseMode.ChatLog; break;
case "hangman": pMode = ParseMode.Hangman; break;
case "main": pMode = ParseMode.Main; break;
case "startupscript": pMode = ParseMode.Scripting; break;
case "scriptscheduler": pMode = ParseMode.ScriptScheduler; break;
case "remotecontrol": pMode = ParseMode.RemoteControl; break;
default: pMode = ParseMode.Default; break;
}
@ -180,11 +184,11 @@ namespace MinecraftClient
}
break;
case ParseMode.Scripting:
case ParseMode.ScriptScheduler:
switch (argName.ToLower())
{
case "enabled": StartupScript_Enabled = str2bool(argValue); break;
case "scriptfile": StartupScript_ScriptFile = argValue; break;
case "enabled": ScriptScheduler_Enabled = str2bool(argValue); break;
case "tasksfile": ScriptScheduler_TasksFile = argValue; break;
}
break;
@ -259,9 +263,9 @@ namespace MinecraftClient
+ "wordsfile=hangman-en.txt\r\n"
+ "fichiermots=hangman-fr.txt\r\n"
+ "\r\n"
+ "[StartupScript]\r\n"
+ "[ScriptScheduler]\r\n"
+ "enabled=false\r\n"
+ "scriptfile=testscript.txt\r\n"
+ "tasksfile=tasks.ini\r\n"
+ "\r\n"
+ "[RemoteControl]\r\n"
+ "enabled=false\r\n", Encoding.UTF8);