diff --git a/MinecraftClient/Bots.cs b/MinecraftClient/Bots.cs index 3739f479..afb7af46 100644 --- a/MinecraftClient/Bots.cs +++ b/MinecraftClient/Bots.cs @@ -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 } } + /// + /// Trigger scripts on specific events + /// + + 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 triggerOnTime_Times = new List(); + public bool alreadyTriggered = false; + } + + private static bool firstlogin_done = false; + + private string tasksfile; + private bool serverlogin_done; + private List tasks = new List(); + 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--; + } + } + /// /// Allow to perform operations using whispers to the bot /// diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 558aff92..0a0f8240 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -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 != "") diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index e693f330..e0061b16 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -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 }; /// /// 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);