2013-07-18 09:27:19 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Net;
|
2014-05-31 01:59:03 +02:00
|
|
|
|
using MinecraftClient.Protocol;
|
|
|
|
|
|
using MinecraftClient.Proxy;
|
2013-07-18 09:27:19 +02:00
|
|
|
|
|
|
|
|
|
|
namespace MinecraftClient
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The main client class, used to connect to a Minecraft server.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
public class McTcpClient : IMinecraftComHandler
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-06-18 13:32:17 +02:00
|
|
|
|
private static List<string> cmd_names = new List<string>();
|
|
|
|
|
|
private static Dictionary<string, Command> cmds = new Dictionary<string, Command>();
|
2014-05-31 01:59:03 +02:00
|
|
|
|
private List<ChatBot> bots = new List<ChatBot>();
|
2015-05-19 15:36:20 +01:00
|
|
|
|
private readonly Dictionary<Guid, string> onlinePlayers = new Dictionary<Guid, string>();
|
2014-05-31 01:59:03 +02:00
|
|
|
|
private static List<ChatBots.Script> scripts_on_hold = new List<ChatBots.Script>();
|
|
|
|
|
|
public void BotLoad(ChatBot b) { b.SetHandler(this); bots.Add(b); b.Initialize(); Settings.SingleCommand = ""; }
|
|
|
|
|
|
public void BotUnLoad(ChatBot b) { bots.RemoveAll(item => object.ReferenceEquals(item, b)); }
|
|
|
|
|
|
public void BotClear() { bots.Clear(); }
|
|
|
|
|
|
|
2013-07-18 09:27:19 +02:00
|
|
|
|
public static int AttemptsLeft = 0;
|
|
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
private string host;
|
|
|
|
|
|
private int port;
|
|
|
|
|
|
private string username;
|
|
|
|
|
|
private string uuid;
|
|
|
|
|
|
private string sessionid;
|
|
|
|
|
|
|
2015-06-20 22:58:18 +02:00
|
|
|
|
public int GetServerPort() { return port; }
|
|
|
|
|
|
public string GetServerHost() { return host; }
|
|
|
|
|
|
public string GetUsername() { return username; }
|
|
|
|
|
|
public string GetUserUUID() { return uuid; }
|
|
|
|
|
|
public string GetSessionID() { return sessionid; }
|
2015-05-19 15:36:20 +01:00
|
|
|
|
|
2013-07-18 09:27:19 +02:00
|
|
|
|
TcpClient client;
|
2014-05-31 01:59:03 +02:00
|
|
|
|
IMinecraftCom handler;
|
2014-06-19 19:24:03 +02:00
|
|
|
|
Thread cmdprompt;
|
2013-07-18 09:27:19 +02:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2014-05-31 01:59:03 +02:00
|
|
|
|
/// Starts the main chat client
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="username">The chosen username of a premium Minecraft Account</param>
|
2014-06-13 16:50:55 +02:00
|
|
|
|
/// <param name="uuid">The player's UUID for online-mode authentication</param>
|
|
|
|
|
|
/// <param name="sessionID">A valid sessionID obtained after logging in</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>
|
2013-07-18 09:27:19 +02:00
|
|
|
|
|
2014-11-05 02:05:33 +11:00
|
|
|
|
public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, ushort port)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-06-13 16:50:55 +02:00
|
|
|
|
StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, "");
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2014-05-31 01:59:03 +02:00
|
|
|
|
/// Starts the main chat client in single command sending mode
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="username">The chosen username of a premium Minecraft Account</param>
|
2014-06-13 16:50:55 +02:00
|
|
|
|
/// <param name="uuid">The player's UUID for online-mode authentication</param>
|
|
|
|
|
|
/// <param name="sessionID">A valid sessionID obtained after logging in</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>
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// <param name="command">The text or command to send.</param>
|
|
|
|
|
|
|
2014-11-05 02:05:33 +11:00
|
|
|
|
public McTcpClient(string username, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, string command)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-06-13 16:50:55 +02:00
|
|
|
|
StartClient(username, uuid, sessionID, server_ip, port, protocolversion, true, command);
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <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>
|
2014-06-13 16:50:55 +02:00
|
|
|
|
/// <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>
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// <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>
|
|
|
|
|
|
|
2014-11-05 02:05:33 +11:00
|
|
|
|
private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, bool singlecommand, string command)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2015-04-06 11:42:43 +02:00
|
|
|
|
bool retry = false;
|
2014-05-31 01:59:03 +02:00
|
|
|
|
this.sessionid = sessionID;
|
|
|
|
|
|
this.uuid = uuid;
|
|
|
|
|
|
this.username = user;
|
2014-06-13 16:50:55 +02:00
|
|
|
|
this.host = server_ip;
|
|
|
|
|
|
this.port = port;
|
2013-07-18 09:27:19 +02:00
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
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()); }
|
2015-06-20 22:58:18 +02:00
|
|
|
|
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))); }
|
2014-05-31 01:59:03 +02:00
|
|
|
|
if (Settings.AutoRelog_Enabled) { BotLoad(new ChatBots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); }
|
2015-06-20 22:58:18 +02:00
|
|
|
|
if (Settings.ScriptScheduler_Enabled) { BotLoad(new ChatBots.ScriptScheduler(Settings.ExpandVars(Settings.ScriptScheduler_TasksFile))); }
|
2014-05-31 01:59:03 +02:00
|
|
|
|
if (Settings.RemoteCtrl_Enabled) { BotLoad(new ChatBots.RemoteControl()); }
|
2015-06-11 23:36:35 +02:00
|
|
|
|
if (Settings.AutoRespond_Enabled) { BotLoad(new ChatBots.AutoRespond(Settings.AutoRespond_Matches)); }
|
2014-05-31 01:59:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2013-07-18 09:27:19 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2014-05-31 01:59:03 +02:00
|
|
|
|
client = ProxyHandler.newTcpClient(host, port);
|
2013-07-18 09:27:19 +02:00
|
|
|
|
client.ReceiveBufferSize = 1024 * 1024;
|
2014-05-31 01:59:03 +02:00
|
|
|
|
handler = Protocol.ProtocolHandler.getProtocolHandler(client, protocolversion, this);
|
2014-05-31 12:56:54 +02:00
|
|
|
|
Console.WriteLine("Version is supported.\nLogging in...");
|
2015-04-06 11:42:43 +02:00
|
|
|
|
|
|
|
|
|
|
try
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2015-04-06 11:42:43 +02:00
|
|
|
|
if (handler.Login())
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2015-04-06 11:42:43 +02:00
|
|
|
|
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();
|
|
|
|
|
|
}
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2015-04-06 11:42:43 +02:00
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleIO.WriteLineFormatted("§8" + e.Message);
|
|
|
|
|
|
Console.WriteLine("Failed to join this server.");
|
|
|
|
|
|
retry = true;
|
|
|
|
|
|
}
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
2015-04-20 17:26:16 +02:00
|
|
|
|
catch (SocketException e)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2015-04-20 17:26:16 +02:00
|
|
|
|
ConsoleIO.WriteLineFormatted("§8" + e.Message);
|
2013-07-18 09:27:19 +02:00
|
|
|
|
Console.WriteLine("Failed to connect to this IP.");
|
2015-04-06 11:42:43 +02:00
|
|
|
|
retry = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (retry)
|
|
|
|
|
|
{
|
2013-07-18 09:27:19 +02:00
|
|
|
|
if (AttemptsLeft > 0)
|
|
|
|
|
|
{
|
2015-06-21 16:40:13 +02:00
|
|
|
|
ConsoleIO.WriteLogLine("Waiting 5 seconds (" + AttemptsLeft + " attempts left)...");
|
2013-07-18 09:27:19 +02:00
|
|
|
|
Thread.Sleep(5000); AttemptsLeft--; Program.Restart();
|
|
|
|
|
|
}
|
2015-03-25 22:50:20 +01:00
|
|
|
|
else if (!singlecommand && Settings.interactiveMode)
|
|
|
|
|
|
{
|
2015-04-22 10:27:53 +02:00
|
|
|
|
Program.HandleFailure();
|
2015-03-25 22:50:20 +01:00
|
|
|
|
}
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Allows the user to send chat messages, commands, and to leave the server.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
2014-06-19 19:24:03 +02:00
|
|
|
|
private void CommandPrompt()
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2014-05-31 01:59:03 +02:00
|
|
|
|
string text = "";
|
|
|
|
|
|
Thread.Sleep(500);
|
2014-01-12 13:38:52 +01:00
|
|
|
|
handler.SendRespawnPacket();
|
|
|
|
|
|
|
2013-07-18 09:27:19 +02:00
|
|
|
|
while (client.Client.Connected)
|
|
|
|
|
|
{
|
|
|
|
|
|
text = ConsoleIO.ReadLine();
|
2013-08-18 18:26:20 +02:00
|
|
|
|
if (ConsoleIO.basicIO && text.Length > 0 && text[0] == (char)0x00)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2013-08-18 18:26:20 +02:00
|
|
|
|
//Process a request from the GUI
|
|
|
|
|
|
string[] command = text.Substring(1).Split((char)0x00);
|
|
|
|
|
|
switch (command[0].ToLower())
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2013-08-18 18:26:20 +02:00
|
|
|
|
case "autocomplete":
|
|
|
|
|
|
if (command.Length > 1) { ConsoleIO.WriteLine((char)0x00 + "autocomplete" + (char)0x00 + handler.AutoComplete(command[1])); }
|
|
|
|
|
|
else Console.WriteLine((char)0x00 + "autocomplete" + (char)0x00);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2014-01-12 13:38:52 +01:00
|
|
|
|
text = text.Trim();
|
2014-06-14 13:20:15 +02:00
|
|
|
|
if (text.Length > 0)
|
2014-01-12 13:38:52 +01:00
|
|
|
|
{
|
2014-06-18 00:49:45 +02:00
|
|
|
|
if (Settings.internalCmdChar == ' ' || text[0] == Settings.internalCmdChar)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-06-14 18:48:43 +02:00
|
|
|
|
string response_msg = "";
|
2014-06-18 00:49:45 +02:00
|
|
|
|
string command = Settings.internalCmdChar == ' ' ? text : text.Substring(1);
|
2015-06-20 22:58:18 +02:00
|
|
|
|
if (!PerformInternalCommand(Settings.ExpandVars(command), ref response_msg) && Settings.internalCmdChar == '/')
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-06-19 19:24:03 +02:00
|
|
|
|
SendText(text);
|
2014-06-14 18:48:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
else if (response_msg.Length > 0)
|
|
|
|
|
|
{
|
2014-06-18 00:49:45 +02:00
|
|
|
|
ConsoleIO.WriteLineFormatted("§8MCC: " + response_msg);
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-06-19 19:24:03 +02:00
|
|
|
|
else SendText(text);
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (IOException) { }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-06-14 13:20:15 +02:00
|
|
|
|
/// <summary>
|
2014-06-19 19:24:03 +02:00
|
|
|
|
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
2014-06-14 13:20:15 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="command">The command</param>
|
|
|
|
|
|
/// <param name="interactive_mode">Set to true if command was sent by the user using the command prompt</param>
|
2014-06-14 18:48:43 +02:00
|
|
|
|
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
|
|
|
|
|
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
2014-06-14 13:20:15 +02:00
|
|
|
|
|
2015-06-20 22:58:18 +02:00
|
|
|
|
public bool PerformInternalCommand(string command, ref string response_msg)
|
2014-06-14 13:20:15 +02:00
|
|
|
|
{
|
2014-06-18 13:32:17 +02:00
|
|
|
|
/* Load commands from the 'Commands' namespace */
|
2014-06-14 13:20:15 +02:00
|
|
|
|
|
2014-06-18 13:32:17 +02:00
|
|
|
|
if (cmds.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Type[] cmds_classes = Program.GetTypesInNamespace("MinecraftClient.Commands");
|
|
|
|
|
|
foreach (Type type in cmds_classes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (type.IsSubclassOf(typeof(Command)))
|
2014-06-14 18:48:43 +02:00
|
|
|
|
{
|
2014-06-18 13:32:17 +02:00
|
|
|
|
try
|
2014-06-14 18:48:43 +02:00
|
|
|
|
{
|
2014-06-18 13:32:17 +02:00
|
|
|
|
Command cmd = (Command)Activator.CreateInstance(type);
|
|
|
|
|
|
cmds[cmd.CMDName.ToLower()] = cmd;
|
|
|
|
|
|
cmd_names.Add(cmd.CMDName.ToLower());
|
|
|
|
|
|
foreach (string alias in cmd.getCMDAliases())
|
|
|
|
|
|
cmds[alias.ToLower()] = cmd;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleIO.WriteLine(e.Message);
|
2014-06-14 18:48:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-06-18 13:32:17 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-06-14 13:20:15 +02:00
|
|
|
|
|
2014-06-18 13:32:17 +02:00
|
|
|
|
/* Process the provided command */
|
2014-06-14 13:20:15 +02:00
|
|
|
|
|
2014-06-18 13:32:17 +02:00
|
|
|
|
string command_name = command.Split(' ')[0].ToLower();
|
|
|
|
|
|
if (command_name == "help")
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Command.hasArg(command))
|
|
|
|
|
|
{
|
|
|
|
|
|
string help_cmdname = Command.getArgs(command)[0].ToLower();
|
|
|
|
|
|
if (help_cmdname == "help")
|
2014-06-14 18:48:43 +02:00
|
|
|
|
{
|
2014-06-18 13:32:17 +02:00
|
|
|
|
response_msg = "help <cmdname>: show brief help about a command.";
|
2014-06-14 18:48:43 +02:00
|
|
|
|
}
|
2014-06-18 13:32:17 +02:00
|
|
|
|
else if (cmds.ContainsKey(help_cmdname))
|
2014-06-14 18:48:43 +02:00
|
|
|
|
{
|
2014-06-18 13:32:17 +02:00
|
|
|
|
response_msg = cmds[help_cmdname].CMDDesc;
|
2014-06-14 18:48:43 +02:00
|
|
|
|
}
|
2014-06-18 13:32:17 +02:00
|
|
|
|
else response_msg = "Unknown command '" + command_name + "'. Use 'help' for command list.";
|
|
|
|
|
|
}
|
|
|
|
|
|
else response_msg = "help <cmdname>. Available commands: " + String.Join(", ", cmd_names.ToArray());
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (cmds.ContainsKey(command_name))
|
|
|
|
|
|
{
|
|
|
|
|
|
response_msg = cmds[command_name].Run(this, command);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2014-08-18 15:10:15 +02:00
|
|
|
|
response_msg = "Unknown command '" + command_name + "'. Use '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "help' for help.";
|
2014-06-18 13:32:17 +02:00
|
|
|
|
return false;
|
2014-06-14 13:20:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// <summary>
|
2014-05-31 01:59:03 +02:00
|
|
|
|
/// Disconnect the client from the server
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
public void Disconnect()
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-05-31 01:59:03 +02:00
|
|
|
|
foreach (ChatBot bot in bots)
|
|
|
|
|
|
if (bot is ChatBots.Script)
|
|
|
|
|
|
scripts_on_hold.Add((ChatBots.Script)bot);
|
|
|
|
|
|
|
2015-03-02 21:35:45 +01:00
|
|
|
|
if (handler != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
handler.Disconnect();
|
|
|
|
|
|
handler.Dispose();
|
|
|
|
|
|
}
|
2014-06-19 19:24:03 +02:00
|
|
|
|
|
|
|
|
|
|
if (cmdprompt != null)
|
|
|
|
|
|
cmdprompt.Abort();
|
|
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
|
2015-06-20 22:58:18 +02:00
|
|
|
|
if (client != null)
|
|
|
|
|
|
client.Close();
|
2014-05-31 01:59:03 +02:00
|
|
|
|
}
|
2013-07-18 09:27:19 +02:00
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Received some text from the server
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="text">Text received</param>
|
|
|
|
|
|
|
|
|
|
|
|
public void OnTextReceived(string text)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleIO.WriteLineFormatted(text, false);
|
2015-03-23 13:57:31 +01:00
|
|
|
|
for (int i = 0; i < bots.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
bots[i].GetText(text);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!(e is ThreadAbortException))
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleIO.WriteLineFormatted("§8GetText: Got error from " + bots[i].ToString() + ": " + e.ToString());
|
|
|
|
|
|
}
|
|
|
|
|
|
else throw; //ThreadAbortException should not be caught
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-05-31 01:59:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// When connection has been lost
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
|
|
|
|
public void OnConnectionLost(ChatBot.DisconnectReason reason, string message)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool will_restart = false;
|
|
|
|
|
|
|
|
|
|
|
|
switch (reason)
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-05-31 01:59:03 +02:00
|
|
|
|
case ChatBot.DisconnectReason.ConnectionLost:
|
|
|
|
|
|
message = "Connection has been lost.";
|
|
|
|
|
|
ConsoleIO.WriteLine(message);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ChatBot.DisconnectReason.InGameKick:
|
|
|
|
|
|
ConsoleIO.WriteLine("Disconnected by Server :");
|
2014-06-11 20:40:25 +02:00
|
|
|
|
ConsoleIO.WriteLineFormatted(message);
|
2014-05-31 01:59:03 +02:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ChatBot.DisconnectReason.LoginRejected:
|
|
|
|
|
|
ConsoleIO.WriteLine("Login failed :");
|
2014-06-11 20:40:25 +02:00
|
|
|
|
ConsoleIO.WriteLineFormatted(message);
|
2014-05-31 01:59:03 +02:00
|
|
|
|
break;
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
2014-05-31 01:59:03 +02:00
|
|
|
|
|
|
|
|
|
|
foreach (ChatBot bot in bots)
|
|
|
|
|
|
will_restart |= bot.OnDisconnect(reason, message);
|
|
|
|
|
|
|
2015-04-20 17:26:16 +02:00
|
|
|
|
if (!will_restart)
|
2015-04-22 10:27:53 +02:00
|
|
|
|
Program.HandleFailure();
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2014-05-31 01:59:03 +02:00
|
|
|
|
/// Called ~10 times per second by the protocol handler
|
2013-07-18 09:27:19 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
2014-05-31 01:59:03 +02:00
|
|
|
|
public void OnUpdate()
|
2013-07-18 09:27:19 +02:00
|
|
|
|
{
|
2014-05-31 01:59:03 +02:00
|
|
|
|
for (int i = 0; i < bots.Count; i++)
|
2014-06-11 20:40:25 +02:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
bots[i].Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
2014-09-07 15:11:39 +02:00
|
|
|
|
if (!(e is ThreadAbortException))
|
|
|
|
|
|
{
|
2015-03-23 13:57:31 +01:00
|
|
|
|
ConsoleIO.WriteLineFormatted("§8Update: Got error from " + bots[i].ToString() + ": " + e.ToString());
|
2014-09-07 15:11:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
else throw; //ThreadAbortException should not be caught
|
2014-06-11 20:40:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-05-31 01:59:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2014-06-14 13:20:15 +02:00
|
|
|
|
/// Send a chat message or command to the server
|
2014-05-31 01:59:03 +02:00
|
|
|
|
/// </summary>
|
2014-06-14 13:20:15 +02:00
|
|
|
|
/// <param name="text">Text to send to the server</param>
|
|
|
|
|
|
/// <returns>True if the text was sent with no error</returns>
|
2014-05-31 01:59:03 +02:00
|
|
|
|
|
2014-06-19 19:24:03 +02:00
|
|
|
|
public bool SendText(string text)
|
2014-05-31 01:59:03 +02:00
|
|
|
|
{
|
2014-06-14 13:20:15 +02:00
|
|
|
|
if (text.Length > 100) //Message is too long?
|
|
|
|
|
|
{
|
|
|
|
|
|
if (text[0] == '/')
|
|
|
|
|
|
{
|
|
|
|
|
|
//Send the first 100 chars of the command
|
|
|
|
|
|
text = text.Substring(0, 100);
|
|
|
|
|
|
return handler.SendChatMessage(text);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//Send the message splitted into several messages
|
|
|
|
|
|
while (text.Length > 100)
|
|
|
|
|
|
{
|
|
|
|
|
|
handler.SendChatMessage(text.Substring(0, 100));
|
|
|
|
|
|
text = text.Substring(100, text.Length - 100);
|
2015-05-26 19:00:37 +02:00
|
|
|
|
if (Settings.splitMessageDelay.TotalSeconds > 0)
|
|
|
|
|
|
Thread.Sleep(Settings.splitMessageDelay);
|
2014-06-14 13:20:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
return handler.SendChatMessage(text);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else return handler.SendChatMessage(text);
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|
2014-06-18 13:32:17 +02:00
|
|
|
|
|
2014-11-11 00:55:42 +11:00
|
|
|
|
/// <summary>
|
2014-11-10 20:43:00 +01:00
|
|
|
|
/// Allow to respawn after death
|
2014-11-11 00:55:42 +11:00
|
|
|
|
/// </summary>
|
2014-11-10 20:43:00 +01:00
|
|
|
|
/// <returns>True if packet successfully sent</returns>
|
2014-11-11 00:55:42 +11:00
|
|
|
|
|
2014-11-10 20:43:00 +01:00
|
|
|
|
public bool SendRespawnPacket()
|
2014-11-11 00:55:42 +11:00
|
|
|
|
{
|
2014-11-10 20:43:00 +01:00
|
|
|
|
return handler.SendRespawnPacket();
|
2014-11-11 00:55:42 +11:00
|
|
|
|
}
|
2014-11-11 00:32:32 +11:00
|
|
|
|
|
2014-06-18 13:32:17 +02:00
|
|
|
|
/// <summary>
|
2014-11-10 20:43:00 +01:00
|
|
|
|
/// Triggered when a new player joins the game
|
2014-06-18 13:32:17 +02:00
|
|
|
|
/// </summary>
|
2014-11-10 20:43:00 +01:00
|
|
|
|
/// <param name="uuid">UUID of the player</param>
|
|
|
|
|
|
/// <param name="name">Name of the player</param>
|
2014-06-18 13:32:17 +02:00
|
|
|
|
|
2014-11-10 20:43:00 +01:00
|
|
|
|
public void OnPlayerJoin(Guid uuid, string name)
|
2014-11-11 00:55:42 +11:00
|
|
|
|
{
|
2015-04-06 11:42:43 +02:00
|
|
|
|
//Ignore TabListPlus placeholders
|
|
|
|
|
|
if (name.StartsWith("0000tab#"))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2015-03-19 22:08:26 +01:00
|
|
|
|
lock (onlinePlayers)
|
|
|
|
|
|
{
|
|
|
|
|
|
onlinePlayers[uuid] = name;
|
|
|
|
|
|
}
|
2014-11-11 00:55:42 +11:00
|
|
|
|
}
|
2015-05-19 15:36:20 +01:00
|
|
|
|
|
2014-11-10 20:43:00 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Triggered when a player has left the game
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="uuid">UUID of the player</param>
|
2014-11-11 00:55:42 +11:00
|
|
|
|
|
2014-11-10 20:43:00 +01:00
|
|
|
|
public void OnPlayerLeave(Guid uuid)
|
|
|
|
|
|
{
|
2015-03-19 22:08:26 +01:00
|
|
|
|
lock (onlinePlayers)
|
|
|
|
|
|
{
|
|
|
|
|
|
onlinePlayers.Remove(uuid);
|
|
|
|
|
|
}
|
2014-11-11 00:55:42 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-11-10 20:43:00 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get a set of online player names
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>Online player names</returns>
|
|
|
|
|
|
|
2015-06-20 22:58:18 +02:00
|
|
|
|
public string[] GetOnlinePlayers()
|
2014-11-10 20:43:00 +01:00
|
|
|
|
{
|
2015-03-19 22:08:26 +01:00
|
|
|
|
lock (onlinePlayers)
|
|
|
|
|
|
{
|
|
|
|
|
|
return onlinePlayers.Values.Distinct().ToArray();
|
|
|
|
|
|
}
|
2014-11-10 20:43:00 +01:00
|
|
|
|
}
|
2014-11-11 00:55:42 +11:00
|
|
|
|
}
|
2013-07-18 09:27:19 +02:00
|
|
|
|
}
|