public void BotLoad(ChatBot b) { b.SetHandler(this); bots.Add(b); b.Initialize(); if (this.handler != null) { b.AfterGameJoined(); } Settings.SingleCommand = ""; }
/// <summary> /// Unload a bot /// </summary> public void BotUnLoad(ChatBot b) { bots.RemoveAll(item => object.ReferenceEquals(item, b)); // ToList is needed to avoid an InvalidOperationException from modfiying the list while it's being iterated upon. var botRegistrations = registeredBotPluginChannels.Where(entry => entry.Value.Contains(b)).ToList(); foreach (var entry in botRegistrations) { UnregisterPluginChannel(entry.Key, b); } }
/// <summary> /// Triggered when a new player joins the game /// </summary> /// <param name="uuid">UUID of the player</param> /// <param name="name">Name of the player</param> public void OnPlayerJoin(Guid uuid, string name) { //Ignore placeholders eg 0000tab# from TabListPlus if (!ChatBot.IsValidName(name)) { return; } lock (onlinePlayers) { onlinePlayers[uuid] = name; } }
/// <summary> /// Unregisters the given plugin channel for the given bot. /// </summary> /// <param name="channel">The channel to unregister.</param> /// <param name="bot">The bot to unregister the channel for.</param> public void UnregisterPluginChannel(string channel, ChatBot bot) { if (registeredBotPluginChannels.ContainsKey(channel)) { List <ChatBot> registeredBots = registeredBotPluginChannels[channel]; registeredBots.RemoveAll(item => object.ReferenceEquals(item, bot)); if (registeredBots.Count == 0) { registeredBotPluginChannels.Remove(channel); SendPluginChannelMessage("UNREGISTER", Encoding.UTF8.GetBytes(channel), true); } } }
/// <summary> /// Registers the given plugin channel for the given bot. /// </summary> /// <param name="channel">The channel to register.</param> /// <param name="bot">The bot to register the channel for.</param> public void RegisterPluginChannel(string channel, ChatBot bot) { if (registeredBotPluginChannels.ContainsKey(channel)) { registeredBotPluginChannels[channel].Add(bot); } else { List <ChatBot> bots = new List <ChatBot>(); bots.Add(bot); registeredBotPluginChannels[channel] = bots; SendPluginChannelMessage("REGISTER", Encoding.UTF8.GetBytes(channel), true); } }
/// <summary> /// Triggered when a new player joins the game /// </summary> /// <param name="uuid">UUID of the player</param> /// <param name="name">Name of the player</param> public void OnPlayerJoin(Guid uuid, string name) { //Ignore placeholders eg 0000tab# from TabListPlus if (!ChatBot.IsValidName(name)) { return; } if (Telegram.data.getTimestamp() > vars.logInTimestamp) { Telegram.data.loginData(name, "last_online", Telegram.data.getTimestamp()); OnLogin.Protect(name); } lock (onlinePlayers) { onlinePlayers[uuid] = name; } }
public bool OnConnectionLost(ChatBot.DisconnectReason reason, string reason_message) { if (!connectionlost) { connectionlost = true; for (int i = 0; i < bots.Count; i++) { if (bots[i].OnDisconnect(reason, reason_message)) { return true; //The client is about to restart } } } return false; }
/// <summary> /// Create a new C# API Wrapper /// </summary> /// <param name="apiHandler">ChatBot API Handler</param> /// <param name="tickHandler">ChatBot tick handler</param> public CSharpAPI(ChatBot apiHandler, ManualResetEvent tickHandler) { SetMaster(apiHandler); this.tickHandler = tickHandler; }
public void BotUnLoad(ChatBot b) { bots.RemoveAll(item => object.ReferenceEquals(item, b)); // ToList is needed to avoid an InvalidOperationException from modfiying the list while it's being iterated upon. var botRegistrations = registeredBotPluginChannels.Where(entry => entry.Value.Contains(b)).ToList(); foreach (var entry in botRegistrations) { UnregisterPluginChannel(entry.Key, b); } }
public void BotUnLoad(ChatBot b) { bots.RemoveAll(item => object.ReferenceEquals(item, b)); }
/// <summary> /// Load the provided ChatBot object /// </summary> /// <param name="bot">Bot to load</param> new public void LoadBot(ChatBot bot) { base.LoadBot(bot); tickHandler.WaitOne(); }
/// <summary> /// Run the specified C# script file /// </summary> /// <param name="apiHandler">ChatBot handler for accessing ChatBot API</param> /// <param name="tickHandler">Tick handler for waiting after some API calls</param> /// <param name="lines">Lines of the script file to run</param> /// <param name="args">Arguments to pass to the script</param> /// <param name="run">Set to false to compile and cache the script without launching it</param> /// <exception cref="CSharpException">Thrown if an error occured</exception> /// <returns>Result of the execution, returned by the script</returns> public static object Run(ChatBot apiHandler, ManualResetEvent tickHandler, string[] lines, string[] args, bool run = true) { //Script compatibility check for handling future versions differently if (lines.Length < 1 || lines[0] != "//MCCScript 1.0") throw new CSharpException(CSErrorType.InvalidScript, new InvalidDataException("The provided script does not have a valid MCCScript header")); //Script hash for determining if it was previously compiled ulong scriptHash = QuickHash(lines); Assembly assembly = null; //No need to compile two scripts at the same time lock (CompileCache) { ///Process and compile script only if not already compiled if (!Settings.CacheScripts || !CompileCache.ContainsKey(scriptHash)) { //Process different sections of the script file bool scriptMain = true; List<string> script = new List<string>(); List<string> extensions = new List<string>(); foreach (string line in lines) { if (line.StartsWith("//MCCScript")) { if (line.EndsWith("Extensions")) scriptMain = false; } else if (scriptMain) script.Add(line); else extensions.Add(line); } //Add return statement if missing if (script.All(line => !line.StartsWith("return ") && !line.Contains(" return "))) script.Add("return null;"); //Generate a class from the given script string code = String.Join("\n", new string[] { "using System;", "using System.Collections.Generic;", "using System.Text.RegularExpressions;", "using System.Linq;", "using System.Text;", "using System.IO;", "using System.Threading;", "using MinecraftClient;", "using MinecraftClient.Mapping;", "namespace ScriptLoader {", "public class Script {", "public CSharpAPI MCC;", "public object __run(CSharpAPI __apiHandler, string[] args) {", "this.MCC = __apiHandler;", String.Join("\n", script), "}", String.Join("\n", extensions), "}}", }); //Compile the C# class in memory using all the currently loaded assemblies CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); parameters.ReferencedAssemblies .AddRange(AppDomain.CurrentDomain .GetAssemblies() .Where(a => !a.IsDynamic) .Select(a => a.Location).ToArray()); parameters.CompilerOptions = "/t:library"; parameters.GenerateInMemory = true; CompilerResults result = compiler.CompileAssemblyFromSource(parameters, code); //Process compile warnings and errors if (result.Errors.Count > 0) throw new CSharpException(CSErrorType.LoadError, new InvalidOperationException(result.Errors[0].ErrorText)); //Retrieve compiled assembly assembly = result.CompiledAssembly; if (Settings.CacheScripts) CompileCache[scriptHash] = result.CompiledAssembly; } else if (Settings.CacheScripts) assembly = CompileCache[scriptHash]; } //Run the compiled assembly with exception handling if (run) { try { object compiledScript = CompileCache[scriptHash].CreateInstance("ScriptLoader.Script"); return compiledScript .GetType() .GetMethod("__run") .Invoke(compiledScript, new object[] { new CSharpAPI(apiHandler, tickHandler), args }); } catch (Exception e) { throw new CSharpException(CSErrorType.RuntimeError, e); } } else return null; }
/// <summary> /// Create a new C# API Wrapper /// </summary> /// <param name="apiHandler">ChatBot API Handler</param> /// <param name="tickHandler">ChatBot tick handler</param> /// <param name="localVars">Local variables passed along with the script</param> public CSharpAPI(ChatBot apiHandler, ManualResetEvent tickHandler, Dictionary <string, object> localVars) { SetMaster(apiHandler); this.tickHandler = tickHandler; this.localVars = localVars; }
protected void LoadBot(ChatBot bot) { Handler.BotUnLoad(bot); Handler.BotLoad(bot); }
/// <summary> /// Registers the given plugin channel for the given bot. /// </summary> /// <param name="channel">The channel to register.</param> /// <param name="bot">The bot to register the channel for.</param> public void RegisterPluginChannel(string channel, ChatBot bot) { if (registeredBotPluginChannels.ContainsKey(channel)) { registeredBotPluginChannels[channel].Add(bot); } else { List<ChatBot> bots = new List<ChatBot>(); bots.Add(bot); registeredBotPluginChannels[channel] = bots; SendPluginChannelMessage("REGISTER", Encoding.UTF8.GetBytes(channel), true); } }
/// <summary> /// When connection has been lost /// </summary> public void OnConnectionLost(ChatBot.DisconnectReason reason, string message) { bool will_restart = false; switch (reason) { case ChatBot.DisconnectReason.ConnectionLost: message = "Connection has been lost."; ConsoleIO.WriteLine(message); break; case ChatBot.DisconnectReason.InGameKick: ConsoleIO.WriteLine("Disconnected by Server :"); ConsoleIO.WriteLineFormatted(message); break; case ChatBot.DisconnectReason.LoginRejected: ConsoleIO.WriteLine("Login failed :"); ConsoleIO.WriteLineFormatted(message); break; } foreach (ChatBot bot in bots) will_restart |= bot.OnDisconnect(reason, message); if (!will_restart) { Program.OfflineCommandPrompt(); } }
protected void SetMaster(ChatBot master) { this.master = master; }
/// <summary> /// Unregisters the given plugin channel for the given bot. /// </summary> /// <param name="channel">The channel to unregister.</param> /// <param name="bot">The bot to unregister the channel for.</param> public void UnregisterPluginChannel(string channel, ChatBot bot) { if (registeredBotPluginChannels.ContainsKey(channel)) { List<ChatBot> registeredBots = registeredBotPluginChannels[channel]; registeredBots.RemoveAll(item => object.ReferenceEquals(item, bot)); if (registeredBots.Count == 0) { registeredBotPluginChannels.Remove(channel); SendPluginChannelMessage("UNREGISTER", Encoding.UTF8.GetBytes(channel), true); } } }
public void BotLoad(ChatBot b) { b.SetHandler(this); bots.Add(b); b.Initialize(); Settings.SingleCommand = ""; }
/// <summary> /// Create a new C# API Wrapper /// </summary> /// <param name="apiHandler">ChatBot API Handler</param> /// <param name="tickHandler">ChatBot tick handler</param> /// <param name="localVars">Local variables passed along with the script</param> public CSharpAPI(ChatBot apiHandler, Dictionary <string, object> localVars) { SetMaster(apiHandler); this.localVars = localVars; }
/// <summary> /// Write a Minecraft-Like formatted string to the standard output, using §c color codes /// See minecraft.gamepedia.com/Classic_server_protocol#Color_Codes for more info /// </summary> /// <param name="str">String to write</param> /// <param name="acceptnewlines">If false, space are printed instead of newlines</param> /// <param name="displayTimestamp"> /// If false, no timestamp is prepended. /// If true, "hh-mm-ss" timestamp will be prepended. /// If unspecified, value is retrieved from EnableTimestamps. /// </param> public static void WriteLineFormatted(string str, bool acceptnewlines = true, bool?displayTimestamp = null) { if (!String.IsNullOrEmpty(str)) { if (!acceptnewlines) { str = str.Replace('\n', ' '); } if (displayTimestamp == null) { displayTimestamp = EnableTimestamps; } if (displayTimestamp.Value) { int hour = DateTime.Now.Hour, minute = DateTime.Now.Minute, second = DateTime.Now.Second; ConsoleIO.Write(String.Format("{0}:{1}:{2} ", hour.ToString("00"), minute.ToString("00"), second.ToString("00"))); } if (BasicIO) { if (BasicIO_NoColor) { str = ChatBot.GetVerbatim(str); } Console.WriteLine(str); return; } string[] parts = str.Split(new char[] { '§' }); if (parts[0].Length > 0) { ConsoleIO.Write(parts[0]); } for (int i = 1; i < parts.Length; i++) { if (parts[i].Length > 0) { switch (parts[i][0]) { case '0': Console.ForegroundColor = ConsoleColor.Gray; break; //Should be Black but Black is non-readable on a black background case '1': Console.ForegroundColor = ConsoleColor.DarkBlue; break; case '2': Console.ForegroundColor = ConsoleColor.DarkGreen; break; case '3': Console.ForegroundColor = ConsoleColor.DarkCyan; break; case '4': Console.ForegroundColor = ConsoleColor.DarkRed; break; case '5': Console.ForegroundColor = ConsoleColor.DarkMagenta; break; case '6': Console.ForegroundColor = ConsoleColor.DarkYellow; break; case '7': Console.ForegroundColor = ConsoleColor.Gray; break; case '8': Console.ForegroundColor = ConsoleColor.DarkGray; break; case '9': Console.ForegroundColor = ConsoleColor.Blue; break; case 'a': Console.ForegroundColor = ConsoleColor.Green; break; case 'b': Console.ForegroundColor = ConsoleColor.Cyan; break; case 'c': Console.ForegroundColor = ConsoleColor.Red; break; case 'd': Console.ForegroundColor = ConsoleColor.Magenta; break; case 'e': Console.ForegroundColor = ConsoleColor.Yellow; break; case 'f': Console.ForegroundColor = ConsoleColor.White; break; case 'r': Console.ForegroundColor = ConsoleColor.Gray; break; } if (parts[i].Length > 1) { ConsoleIO.Write(parts[i].Substring(1, parts[i].Length - 1)); } } } Console.ForegroundColor = ConsoleColor.Gray; } ConsoleIO.Write('\n'); }
/// <summary> /// Load the provided ChatBot object /// </summary> /// <param name="bot">Bot to load</param> new public void LoadBot(ChatBot bot) { base.LoadBot(bot); }
/// <summary> /// Starts the main chat client, wich will login to the server using the MinecraftCom class. /// </summary> /// <param name="user">The chosen username of a premium Minecraft Account</param> /// <param name="sessionID">A valid sessionID obtained with MinecraftCom.GetLogin()</param> /// <param name="server_ip">The server IP</param> /// <param name="port">The server port to use</param> /// <param name="protocolversion">Minecraft protocol version to use</param> /// <param name="uuid">The player's UUID for online-mode authentication</param> /// <param name="singlecommand">If set to true, the client will send a single command and then disconnect from the server</param> /// <param name="command">The text or command to send. Will only be sent if singlecommand is set to true.</param> private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, bool singlecommand, string command) { this.sessionid = sessionID; this.uuid = uuid; this.username = user; this.host = server_ip; this.port = port; if (!singlecommand) { if (Settings.AntiAFK_Enabled) { BotLoad(new ChatBots.AntiAFK(Settings.AntiAFK_Delay)); } if (Settings.Hangman_Enabled) { BotLoad(new ChatBots.HangmanGame(Settings.Hangman_English)); } if (Settings.Alerts_Enabled) { BotLoad(new ChatBots.Alerts()); } if (Settings.ChatLog_Enabled) { BotLoad(new ChatBots.ChatLog(Settings.expandVars(Settings.ChatLog_File), Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); } if (Settings.PlayerLog_Enabled) { BotLoad(new ChatBots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.expandVars(Settings.PlayerLog_File))); } if (Settings.AutoRelog_Enabled) { BotLoad(new ChatBots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); } if (Settings.ScriptScheduler_Enabled) { BotLoad(new ChatBots.ScriptScheduler(Settings.expandVars(Settings.ScriptScheduler_TasksFile))); } if (Settings.RemoteCtrl_Enabled) { BotLoad(new ChatBots.RemoteControl()); } } try { client = ProxyHandler.newTcpClient(host, port); client.ReceiveBufferSize = 1024 * 1024; handler = Protocol.ProtocolHandler.getProtocolHandler(client, protocolversion, this); Console.WriteLine("Version is supported.\nLogging in..."); if (handler.Login()) { if (singlecommand) { handler.SendChatMessage(command); ConsoleIO.WriteLineFormatted("§7Command §8" + command + "§7 sent."); Thread.Sleep(5000); handler.Disconnect(); Thread.Sleep(1000); } else { foreach (ChatBot bot in scripts_on_hold) { bot.SetHandler(this); } bots.AddRange(scripts_on_hold); scripts_on_hold.Clear(); Console.WriteLine("Server was successfully joined.\nType '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "quit' to leave the server."); cmdprompt = new Thread(new ThreadStart(CommandPrompt)); cmdprompt.Name = "MCC Command prompt"; cmdprompt.Start(); } } } catch (SocketException) { Console.WriteLine("Failed to connect to this IP."); if (AttemptsLeft > 0) { ChatBot.LogToConsole("Waiting 5 seconds (" + AttemptsLeft + " attempts left)..."); Thread.Sleep(5000); AttemptsLeft--; Program.Restart(); } else if (!singlecommand) { Console.ReadLine(); } } }
/// <summary> /// Run the specified C# script file /// </summary> /// <param name="apiHandler">ChatBot handler for accessing ChatBot API</param> /// <param name="tickHandler">Tick handler for waiting after some API calls</param> /// <param name="lines">Lines of the script file to run</param> /// <param name="args">Arguments to pass to the script</param> /// <param name="run">Set to false to compile and cache the script without launching it</param> /// <exception cref="CSharpException">Thrown if an error occured</exception> /// <returns>Result of the execution, returned by the script</returns> public static object Run(ChatBot apiHandler, ManualResetEvent tickHandler, string[] lines, string[] args, bool run = true) { //Script compatibility check for handling future versions differently if (lines.Length < 1 || lines[0] != "//MCCScript 1.0") { throw new CSharpException(CSErrorType.InvalidScript, new InvalidDataException("The provided script does not have a valid MCCScript header")); } //Script hash for determining if it was previously compiled ulong scriptHash = QuickHash(lines); Assembly assembly = null; //No need to compile two scripts at the same time lock (CompileCache) { ///Process and compile script only if not already compiled if (!Settings.CacheScripts || !CompileCache.ContainsKey(scriptHash)) { //Process different sections of the script file bool scriptMain = true; List <string> script = new List <string>(); List <string> extensions = new List <string>(); foreach (string line in lines) { if (line.StartsWith("//MCCScript")) { if (line.EndsWith("Extensions")) { scriptMain = false; } } else if (scriptMain) { script.Add(line); } else { extensions.Add(line); } } //Add return statement if missing if (script.All(line => !line.StartsWith("return ") && !line.Contains(" return "))) { script.Add("return null;"); } //Generate a class from the given script string code = String.Join("\n", new string[] { "using System;", "using System.Collections.Generic;", "using System.Text.RegularExpressions;", "using System.Linq;", "using System.Text;", "using System.IO;", "using System.Threading;", "using MinecraftClient;", "using MinecraftClient.Mapping;", "namespace ScriptLoader {", "public class Script {", "public CSharpAPI MCC;", "public object __run(CSharpAPI __apiHandler, string[] args) {", "this.MCC = __apiHandler;", String.Join("\n", script), "}", String.Join("\n", extensions), "}}", }); //Compile the C# class in memory using all the currently loaded assemblies CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); parameters.ReferencedAssemblies .AddRange(AppDomain.CurrentDomain .GetAssemblies() .Where(a => !a.IsDynamic) .Select(a => a.Location).ToArray()); parameters.CompilerOptions = "/t:library"; parameters.GenerateInMemory = true; CompilerResults result = compiler.CompileAssemblyFromSource(parameters, code); //Process compile warnings and errors if (result.Errors.Count > 0) { throw new CSharpException(CSErrorType.LoadError, new InvalidOperationException(result.Errors[0].ErrorText)); } //Retrieve compiled assembly assembly = result.CompiledAssembly; if (Settings.CacheScripts) { CompileCache[scriptHash] = result.CompiledAssembly; } } else if (Settings.CacheScripts) { assembly = CompileCache[scriptHash]; } } //Run the compiled assembly with exception handling if (run) { try { object compiledScript = assembly.CreateInstance("ScriptLoader.Script"); return (compiledScript .GetType() .GetMethod("__run") .Invoke(compiledScript, new object[] { new CSharpAPI(apiHandler, tickHandler), args })); } catch (Exception e) { throw new CSharpException(CSErrorType.RuntimeError, e); } } else { return(null); } }
/// <summary> /// Load the provided ChatBot object /// </summary> /// <param name="bot">Bot to load</param> public new void LoadBot(ChatBot bot) { base.LoadBot(bot); tickHandler.WaitOne(); }