From dc06cef704124f7c636584c58a23c12cc3b40f07 Mon Sep 17 00:00:00 2001 From: ORelio Date: Thu, 9 Oct 2014 08:08:40 +0200 Subject: [PATCH 01/30] Fix OverflowException for server port Change short to int. Bug report by 1092CQ. --- MinecraftClient/McTcpClient.cs | 6 +++--- MinecraftClient/Protocol/ProtocolHandler.cs | 2 +- MinecraftClient/Settings.cs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index ceaedfb908..8fa0668088 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -53,7 +53,7 @@ public class McTcpClient : IMinecraftComHandler /// The server port to use /// Minecraft protocol version to use - public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, short port) + public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, int port) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, ""); } @@ -69,7 +69,7 @@ public McTcpClient(string username, string uuid, string sessionID, int protocolv /// Minecraft protocol version to use /// The text or command to send. - public McTcpClient(string username, string uuid, string sessionID, string server_ip, short port, int protocolversion, string command) + public McTcpClient(string username, string uuid, string sessionID, string server_ip, int port, int protocolversion, string command) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, true, command); } @@ -86,7 +86,7 @@ public McTcpClient(string username, string uuid, string sessionID, string server /// If set to true, the client will send a single command and then disconnect from the server /// The text or command to send. Will only be sent if singlecommand is set to true. - private void StartClient(string user, string uuid, string sessionID, string server_ip, short port, int protocolversion, bool singlecommand, string command) + private void StartClient(string user, string uuid, string sessionID, string server_ip, int port, int protocolversion, bool singlecommand, string command) { this.sessionid = sessionID; this.uuid = uuid; diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index ce3a704b4b..56beca8380 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -23,7 +23,7 @@ public static class ProtocolHandler /// Will contain protocol version, if ping successful /// TRUE if ping was successful - public static bool GetServerInfo(string serverIP, short serverPort, ref int protocolversion) + public static bool GetServerInfo(string serverIP, int serverPort, ref int protocolversion) { try { diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 6ccbe85ec1..facdaf6850 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -20,7 +20,7 @@ public static class Settings public static string Username = ""; public static string Password = ""; public static string ServerIP = ""; - public static short ServerPort = 25565; + public static int ServerPort = 25565; public static string ServerVersion = ""; public static string SingleCommand = ""; public static string ConsoleTitle = ""; @@ -90,7 +90,7 @@ public static class Settings //Custom app variables and Minecraft accounts private static Dictionary AppVars = new Dictionary(); private static Dictionary> Accounts = new Dictionary>(); - private static Dictionary> Servers = new Dictionary>(); + private static Dictionary> Servers = new Dictionary>(); private enum ParseMode { Default, Main, AppVars, Proxy, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl }; @@ -186,7 +186,7 @@ public static void LoadSettings(string settingsfile) { //Backup current server info string server_host_temp = ServerIP; - short server_port_temp = ServerPort; + int server_port_temp = ServerPort; foreach (string server_line in File.ReadAllLines(argValue)) { @@ -198,7 +198,7 @@ public static void LoadSettings(string settingsfile) && !server_data[0].Contains('.') && setServerIP(server_data[1])) Servers[server_data[0]] - = new KeyValuePair(ServerIP, ServerPort); + = new KeyValuePair(ServerIP, ServerPort); } //Restore current server info From 531aede9d5e65d1e80685ee43e516ade2e903701 Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 28 Oct 2014 21:39:21 +0100 Subject: [PATCH 02/30] Protocol18: Redirect ping to Protocol17 Removed duplicate ping code --- .../Protocol/Handlers/Protocol18.cs | 52 +------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index d7cc91bcfc..d4d8d1a188 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -632,57 +632,7 @@ public string AutoComplete(string BehindCursor) public static bool doPing(string host, int port, ref int protocolversion) { - string version = ""; - TcpClient tcp = ProxyHandler.newTcpClient(host, port); - tcp.ReceiveBufferSize = 1024 * 1024; - - byte[] packet_id = getVarInt(0); - byte[] protocol_version = getVarInt(4); - byte[] server_adress_val = Encoding.UTF8.GetBytes(host); - byte[] server_adress_len = getVarInt(server_adress_val.Length); - byte[] server_port = BitConverter.GetBytes((ushort)port); Array.Reverse(server_port); - byte[] next_state = getVarInt(1); - byte[] packet = concatBytes(packet_id, protocol_version, server_adress_len, server_adress_val, server_port, next_state); - byte[] tosend = concatBytes(getVarInt(packet.Length), packet); - - tcp.Client.Send(tosend, SocketFlags.None); - - byte[] status_request = getVarInt(0); - byte[] request_packet = concatBytes(getVarInt(status_request.Length), status_request); - - tcp.Client.Send(request_packet, SocketFlags.None); - - int packetID = -1; - byte[] packetData = new byte[] { }; - Protocol18Handler ComTmp = new Protocol18Handler(tcp); - ComTmp.readNextPacket(ref packetID, ref packetData); - if (packetData.Length > 0) //Verify Response length - { - if (packetID == 0x00) //Read Packet ID - { - string result = ComTmp.readNextString(ref packetData); //Get the Json data - if (result[0] == '{' && result.Contains("protocol\":") && result.Contains("name\":\"")) - { - string[] tmp_ver = result.Split(new string[] { "protocol\":" }, StringSplitOptions.None); - string[] tmp_name = result.Split(new string[] { "name\":\"" }, StringSplitOptions.None); - - if (tmp_ver.Length >= 2 && tmp_name.Length >= 2) - { - protocolversion = atoi(tmp_ver[1]); - version = tmp_name[1].Split('"')[0]; - if (result.Contains("modinfo\":")) - { - //Server is running Forge (which is not supported) - version = "Forge " + version; - protocolversion = 0; - } - ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ")."); - return true; - } - } - } - } - return false; + return Protocol17Handler.doPing(host, port, ref protocolversion); } } } From d6c286bfbf8b4bb492b37a0ab109e9b353be4d11 Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 28 Oct 2014 21:44:40 +0100 Subject: [PATCH 03/30] Remove useless ping method from Protocol18 ping method wasn't part of the interface so it can in fact be removed without any issue. --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index d4d8d1a188..270809dccd 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -624,15 +624,5 @@ public string AutoComplete(string BehindCursor) while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; } return autocomplete_result; } - - /// - /// Ping a Minecraft server to get information about the server - /// - /// True if ping was successful - - public static bool doPing(string host, int port, ref int protocolversion) - { - return Protocol17Handler.doPing(host, port, ref protocolversion); - } } } From b90466447f7efa7f8805e600ef138545fb36e979 Mon Sep 17 00:00:00 2001 From: Lauchlin Date: Wed, 5 Nov 2014 01:59:32 +1100 Subject: [PATCH 04/30] Use usigned short to cover full range of ports Each side of a TCP connection has an associated 16-bit unsigned port number (0-65535). Use an unsigned short rather than a signed short otherwise you'll only get half the ports! --- MinecraftClient/Settings.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 6ccbe85ec1..03f14f9cad 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -20,7 +20,7 @@ public static class Settings public static string Username = ""; public static string Password = ""; public static string ServerIP = ""; - public static short ServerPort = 25565; + public static unsigned short ServerPort = 25565; public static string ServerVersion = ""; public static string SingleCommand = ""; public static string ConsoleTitle = ""; @@ -90,7 +90,7 @@ public static class Settings //Custom app variables and Minecraft accounts private static Dictionary AppVars = new Dictionary(); private static Dictionary> Accounts = new Dictionary>(); - private static Dictionary> Servers = new Dictionary>(); + private static Dictionary> Servers = new Dictionary>(); private enum ParseMode { Default, Main, AppVars, Proxy, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl }; @@ -186,7 +186,7 @@ public static void LoadSettings(string settingsfile) { //Backup current server info string server_host_temp = ServerIP; - short server_port_temp = ServerPort; + unsigned short server_port_temp = ServerPort; foreach (string server_line in File.ReadAllLines(argValue)) { @@ -198,7 +198,7 @@ public static void LoadSettings(string settingsfile) && !server_data[0].Contains('.') && setServerIP(server_data[1])) Servers[server_data[0]] - = new KeyValuePair(ServerIP, ServerPort); + = new KeyValuePair(ServerIP, ServerPort); } //Restore current server info @@ -432,13 +432,13 @@ public static bool setServerIP(string server) server = server.ToLower(); string[] sip = server.Split(':'); string host = sip[0]; - short port = 25565; + unsigned short port = 25565; if (sip.Length > 1) { try { - port = Convert.ToInt16(sip[1]); + port = Convert.ToUInt16(sip[1]); } catch (FormatException) { return false; } } From 466ad07b71271c3091b6d91043ec95f1bb99f827 Mon Sep 17 00:00:00 2001 From: Lauchlin Date: Wed, 5 Nov 2014 02:04:33 +1100 Subject: [PATCH 05/30] Using ushort rather than keyword I'm not so familiar with this syntax. --- MinecraftClient/Settings.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 03f14f9cad..5b22bc905c 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -20,7 +20,7 @@ public static class Settings public static string Username = ""; public static string Password = ""; public static string ServerIP = ""; - public static unsigned short ServerPort = 25565; + public static ushort ServerPort = 25565; public static string ServerVersion = ""; public static string SingleCommand = ""; public static string ConsoleTitle = ""; @@ -90,7 +90,7 @@ public static class Settings //Custom app variables and Minecraft accounts private static Dictionary AppVars = new Dictionary(); private static Dictionary> Accounts = new Dictionary>(); - private static Dictionary> Servers = new Dictionary>(); + private static Dictionary> Servers = new Dictionary>(); private enum ParseMode { Default, Main, AppVars, Proxy, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl }; @@ -186,7 +186,7 @@ public static void LoadSettings(string settingsfile) { //Backup current server info string server_host_temp = ServerIP; - unsigned short server_port_temp = ServerPort; + ushort server_port_temp = ServerPort; foreach (string server_line in File.ReadAllLines(argValue)) { @@ -198,7 +198,7 @@ public static void LoadSettings(string settingsfile) && !server_data[0].Contains('.') && setServerIP(server_data[1])) Servers[server_data[0]] - = new KeyValuePair(ServerIP, ServerPort); + = new KeyValuePair(ServerIP, ServerPort); } //Restore current server info @@ -432,7 +432,7 @@ public static bool setServerIP(string server) server = server.ToLower(); string[] sip = server.Split(':'); string host = sip[0]; - unsigned short port = 25565; + ushort port = 25565; if (sip.Length > 1) { From 284d335b2a4bb8eea2f8946f8c1088edc7af0a18 Mon Sep 17 00:00:00 2001 From: Lauchlin Date: Wed, 5 Nov 2014 02:05:33 +1100 Subject: [PATCH 06/30] Update short to ushort --- MinecraftClient/McTcpClient.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index ceaedfb908..4e59d1b34b 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -53,7 +53,7 @@ public class McTcpClient : IMinecraftComHandler /// The server port to use /// Minecraft protocol version to use - public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, short port) + public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, ushort port) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, ""); } @@ -69,7 +69,7 @@ public McTcpClient(string username, string uuid, string sessionID, int protocolv /// Minecraft protocol version to use /// The text or command to send. - public McTcpClient(string username, string uuid, string sessionID, string server_ip, short port, int protocolversion, string command) + public McTcpClient(string username, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, string command) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, true, command); } @@ -86,7 +86,7 @@ public McTcpClient(string username, string uuid, string sessionID, string server /// If set to true, the client will send a single command and then disconnect from the server /// The text or command to send. Will only be sent if singlecommand is set to true. - private void StartClient(string user, string uuid, string sessionID, string server_ip, short port, int protocolversion, bool singlecommand, string command) + 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; From 006a1a5f4b86aa96a734528ed32a06ccd8c888e9 Mon Sep 17 00:00:00 2001 From: Lauchlin Wilkinson Date: Thu, 6 Nov 2014 17:59:19 +1100 Subject: [PATCH 07/30] Missed ushort in protocol handler --- MinecraftClient/Protocol/ProtocolHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index ce3a704b4b..bc8aaf8b81 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -23,7 +23,7 @@ public static class ProtocolHandler /// Will contain protocol version, if ping successful /// TRUE if ping was successful - public static bool GetServerInfo(string serverIP, short serverPort, ref int protocolversion) + public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion) { try { From 07fed5cd243e10ddab5fbf3c091c5921c8035e79 Mon Sep 17 00:00:00 2001 From: lokulin Date: Tue, 11 Nov 2014 00:32:32 +1100 Subject: [PATCH 08/30] Added a player list command /list --- MinecraftClient/Commands/List.cs | 20 +++++++++++ MinecraftClient/McTcpClient.cs | 32 +++++++++++++++--- MinecraftClient/MinecraftClient.csproj | 1 + .../Protocol/Handlers/Protocol18.cs | 33 ++++++++++++++++++- .../Protocol/IMinecraftComHandler.cs | 4 +++ 5 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 MinecraftClient/Commands/List.cs diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs new file mode 100644 index 0000000000..b6791f9c85 --- /dev/null +++ b/MinecraftClient/Commands/List.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MinecraftClient.Commands +{ + public class List : Command + { + public override string CMDName { get { return "list"; } } + public override string CMDDesc { get { return "list: get the player list."; } } + + public override string Run(McTcpClient handler, string command) + { + handler.ListPlayers(); + return ""; + } + } +} + diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 4e59d1b34b..8a72a7dec9 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -33,6 +33,8 @@ public class McTcpClient : IMinecraftComHandler private string uuid; private string sessionid; + public Dictionary players; + public int getServerPort() { return port; } public string getServerHost() { return host; } public string getUsername() { return username; } @@ -56,6 +58,7 @@ public class McTcpClient : IMinecraftComHandler public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, ushort port) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, ""); + players = new Dictionary(); } /// @@ -388,14 +391,35 @@ public bool SendText(string text) else return handler.SendChatMessage(text); } + /// + /// Display a list of players + /// + /// True if the players can be listed + public bool ListPlayers() + { + ConsoleIO.WriteLine ("Player List"); + foreach (string player in players.Values) + ConsoleIO.WriteLine (player); + return true; + } + /// /// Allow to respawn after death /// /// True if packet successfully sent public bool SendRespawnPacket() - { - return handler.SendRespawnPacket(); - } - } + { + return handler.SendRespawnPacket (); + } + + public void addPlayer(string uuid, string name) { + players[uuid] = name; + } + public void removePlayer(string uuid){ + players.Remove (uuid); + } + + public HashSet getPlayers() { return new HashSet(players.Values); } + } } diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 4bbb262fea..52dba3330b 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -131,6 +131,7 @@ + diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 270809dccd..ce65540ecb 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -141,8 +141,28 @@ private bool handlePacket(int packetID, byte[] packetData) SendPacket(0x00, getVarInt(readNextVarInt(ref packetData))); break; case 0x02: - handler.OnTextReceived(ChatParser.ParseText(readNextString(ref packetData))); + handler.OnTextReceived(ChatParser.ParseText(readNextString(ref packetData))); break; + case 0x0C: //Entity Look and Relative Move + //ConsoleIO.WriteLineFormatted("§8 0x0C entity:" + readNextVarInt(ref packetData) + " has come in to sight"); + break; + case 0x38: // update player list + int action = readNextVarInt (ref packetData); + int numActions = readNextVarInt (ref packetData); + string uuid = readNextUUID (ref packetData); + switch (action) { + case 0x00: + string name = readNextString (ref packetData); + handler.addPlayer (uuid, name); + break; + case 0x04: + handler.removePlayer (uuid); + break; + default: + //do nothing + break; + } + break; case 0x3A: int autocomplete_count = readNextVarInt(ref packetData); string tab_list = ""; @@ -256,6 +276,17 @@ private string readNextString(ref byte[] cache) else return ""; } + /// + /// Read a uuid from a cache of bytes and remove it from the cache + /// + /// Cache of bytes to read from + /// The uuid as a string + + private string readNextUUID(ref byte[] cache) + { + return BitConverter.ToString(readData (16, ref cache)).Replace ("-", string.Empty).ToLower(); + } + /// /// Read a byte array from a cache of bytes and remove it from the cache /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index cc2b6055f3..1fddceeb30 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -22,6 +22,10 @@ public interface IMinecraftComHandler string getUserUUID(); string getSessionID(); + void addPlayer(string uuid, string name); + void removePlayer(string uuid); + HashSet getPlayers(); + /// /// This method is called when the protocol handler receives a chat message /// From b0988a8960b3c815ce253648fb6a990cfa75db2a Mon Sep 17 00:00:00 2001 From: lokulin Date: Tue, 11 Nov 2014 00:34:56 +1100 Subject: [PATCH 09/30] Ignore MonoDevelop userprefs file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f911c9a39e..307f491a00 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /MinecraftClient.suo /MinecraftClientGUI.v11.suo /MinecraftClientGUI.suo +/MinecraftClient.userprefs From 7fa2e0d02e336be7f0e6032f9005a40437174dca Mon Sep 17 00:00:00 2001 From: lokulin Date: Tue, 11 Nov 2014 00:55:42 +1100 Subject: [PATCH 10/30] fixed whitespace to fit with code style --- MinecraftClient/Commands/List.cs | 20 +++---- MinecraftClient/McTcpClient.cs | 53 ++++++++-------- .../Protocol/Handlers/Protocol18.cs | 60 +++++++++---------- .../Protocol/IMinecraftComHandler.cs | 6 +- 4 files changed, 70 insertions(+), 69 deletions(-) diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs index b6791f9c85..b1a653d611 100644 --- a/MinecraftClient/Commands/List.cs +++ b/MinecraftClient/Commands/List.cs @@ -5,16 +5,16 @@ namespace MinecraftClient.Commands { - public class List : Command - { - public override string CMDName { get { return "list"; } } - public override string CMDDesc { get { return "list: get the player list."; } } + public class List : Command + { + public override string CMDName { get { return "list"; } } + public override string CMDDesc { get { return "list: get the player list."; } } - public override string Run(McTcpClient handler, string command) - { - handler.ListPlayers(); - return ""; - } - } + public override string Run(McTcpClient handler, string command) + { + handler.ListPlayers(); + return ""; + } + } } diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 8a72a7dec9..47954ad558 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -33,7 +33,7 @@ public class McTcpClient : IMinecraftComHandler private string uuid; private string sessionid; - public Dictionary players; + public Dictionary players; public int getServerPort() { return port; } public string getServerHost() { return host; } @@ -58,7 +58,7 @@ public class McTcpClient : IMinecraftComHandler public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, ushort port) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, ""); - players = new Dictionary(); + players = new Dictionary(); } /// @@ -391,17 +391,18 @@ public bool SendText(string text) else return handler.SendChatMessage(text); } - /// - /// Display a list of players - /// - /// True if the players can be listed - public bool ListPlayers() - { - ConsoleIO.WriteLine ("Player List"); - foreach (string player in players.Values) - ConsoleIO.WriteLine (player); - return true; - } + /// + /// Display a list of players + /// + /// True if the players can be listed + + public bool ListPlayers() + { + ConsoleIO.WriteLine ("Player List"); + foreach (string player in players.Values) + ConsoleIO.WriteLine (player); + return true; + } /// /// Allow to respawn after death @@ -409,17 +410,17 @@ public bool ListPlayers() /// True if packet successfully sent public bool SendRespawnPacket() - { - return handler.SendRespawnPacket (); - } - - public void addPlayer(string uuid, string name) { - players[uuid] = name; - } - public void removePlayer(string uuid){ - players.Remove (uuid); - } - - public HashSet getPlayers() { return new HashSet(players.Values); } - } + { + return handler.SendRespawnPacket (); + } + + public void addPlayer(string uuid, string name) { + players[uuid] = name; + } + public void removePlayer(string uuid){ + players.Remove (uuid); + } + + public HashSet getPlayers() { return new HashSet(players.Values); } + } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ce65540ecb..edac89b159 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -141,28 +141,28 @@ private bool handlePacket(int packetID, byte[] packetData) SendPacket(0x00, getVarInt(readNextVarInt(ref packetData))); break; case 0x02: - handler.OnTextReceived(ChatParser.ParseText(readNextString(ref packetData))); + handler.OnTextReceived(ChatParser.ParseText(readNextString(ref packetData))); + break; + case 0x0C: //Entity Look and Relative Move + //ConsoleIO.WriteLineFormatted("§8 0x0C entity:" + readNextVarInt(ref packetData) + " has come in to sight"); + break; + case 0x38: // update player list + int action = readNextVarInt (ref packetData); + int numActions = readNextVarInt (ref packetData); + string uuid = readNextUUID (ref packetData); + switch (action) { + case 0x00: + string name = readNextString (ref packetData); + handler.addPlayer (uuid, name); + break; + case 0x04: + handler.removePlayer (uuid); + break; + default: + //do nothing + break; + } break; - case 0x0C: //Entity Look and Relative Move - //ConsoleIO.WriteLineFormatted("§8 0x0C entity:" + readNextVarInt(ref packetData) + " has come in to sight"); - break; - case 0x38: // update player list - int action = readNextVarInt (ref packetData); - int numActions = readNextVarInt (ref packetData); - string uuid = readNextUUID (ref packetData); - switch (action) { - case 0x00: - string name = readNextString (ref packetData); - handler.addPlayer (uuid, name); - break; - case 0x04: - handler.removePlayer (uuid); - break; - default: - //do nothing - break; - } - break; case 0x3A: int autocomplete_count = readNextVarInt(ref packetData); string tab_list = ""; @@ -276,16 +276,16 @@ private string readNextString(ref byte[] cache) else return ""; } - /// - /// Read a uuid from a cache of bytes and remove it from the cache - /// - /// Cache of bytes to read from - /// The uuid as a string + /// + /// Read a uuid from a cache of bytes and remove it from the cache + /// + /// Cache of bytes to read from + /// The uuid as a string - private string readNextUUID(ref byte[] cache) - { - return BitConverter.ToString(readData (16, ref cache)).Replace ("-", string.Empty).ToLower(); - } + private string readNextUUID(ref byte[] cache) + { + return BitConverter.ToString(readData (16, ref cache)).Replace ("-", string.Empty).ToLower(); + } /// /// Read a byte array from a cache of bytes and remove it from the cache diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 1fddceeb30..79b4fe39ee 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -22,9 +22,9 @@ public interface IMinecraftComHandler string getUserUUID(); string getSessionID(); - void addPlayer(string uuid, string name); - void removePlayer(string uuid); - HashSet getPlayers(); + void addPlayer(string uuid, string name); + void removePlayer(string uuid); + HashSet getPlayers(); /// /// This method is called when the protocol handler receives a chat message From f82041288de5bd2bef4121a8a1db76dab9b31c66 Mon Sep 17 00:00:00 2001 From: ORelio Date: Mon, 10 Nov 2014 20:43:00 +0100 Subject: [PATCH 11/30] /list command improvements Coding style, Guid, interface, Fallback Command --- MinecraftClient/Commands/List.cs | 8 +++- MinecraftClient/McTcpClient.cs | 47 +++++++++++-------- .../Protocol/Handlers/Protocol18.cs | 42 ++++++++--------- .../Protocol/IMinecraftComHandler.cs | 20 ++++++-- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs index b1a653d611..c322a9f6cf 100644 --- a/MinecraftClient/Commands/List.cs +++ b/MinecraftClient/Commands/List.cs @@ -12,8 +12,14 @@ public class List : Command public override string Run(McTcpClient handler, string command) { - handler.ListPlayers(); + string[] onlinePlayers = handler.getOnlinePlayers(); + if (onlinePlayers.Length == 0) //Not properly handled by Protocol handler? + { + //Fallback to server /list command + handler.SendText("/list"); return ""; + } + else return "PlayerList: " + String.Join(", ", onlinePlayers); } } } diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 47954ad558..6f734eb828 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -20,6 +20,7 @@ public class McTcpClient : IMinecraftComHandler private static List cmd_names = new List(); private static Dictionary cmds = new Dictionary(); private List bots = new List(); + private Dictionary onlinePlayers = new Dictionary(); private static List scripts_on_hold = new List(); 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)); } @@ -33,8 +34,6 @@ public class McTcpClient : IMinecraftComHandler private string uuid; private string sessionid; - public Dictionary players; - public int getServerPort() { return port; } public string getServerHost() { return host; } public string getUsername() { return username; } @@ -58,7 +57,6 @@ public class McTcpClient : IMinecraftComHandler public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, ushort port) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, ""); - players = new Dictionary(); } /// @@ -392,35 +390,44 @@ public bool SendText(string text) } /// - /// Display a list of players + /// Allow to respawn after death /// - /// True if the players can be listed + /// True if packet successfully sent - public bool ListPlayers() + public bool SendRespawnPacket() { - ConsoleIO.WriteLine ("Player List"); - foreach (string player in players.Values) - ConsoleIO.WriteLine (player); - return true; + return handler.SendRespawnPacket(); } /// - /// Allow to respawn after death + /// Triggered when a new player joins the game /// - /// True if packet successfully sent + /// UUID of the player + /// Name of the player - public bool SendRespawnPacket() + public void OnPlayerJoin(Guid uuid, string name) { - return handler.SendRespawnPacket (); + onlinePlayers[uuid] = name; } + + /// + /// Triggered when a player has left the game + /// + /// UUID of the player - public void addPlayer(string uuid, string name) { - players[uuid] = name; - } - public void removePlayer(string uuid){ - players.Remove (uuid); + public void OnPlayerLeave(Guid uuid) + { + onlinePlayers.Remove(uuid); } - public HashSet getPlayers() { return new HashSet(players.Values); } + /// + /// Get a set of online player names + /// + /// Online player names + + public string[] getOnlinePlayers() + { + return onlinePlayers.Values.Distinct().ToArray(); + } } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index edac89b159..a1eb60f3cf 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -137,33 +137,31 @@ private bool handlePacket(int packetID, byte[] packetData) { switch (packetID) { - case 0x00: + case 0x00: //Keep-Alive SendPacket(0x00, getVarInt(readNextVarInt(ref packetData))); break; - case 0x02: + case 0x02: //Chat message handler.OnTextReceived(ChatParser.ParseText(readNextString(ref packetData))); break; - case 0x0C: //Entity Look and Relative Move - //ConsoleIO.WriteLineFormatted("§8 0x0C entity:" + readNextVarInt(ref packetData) + " has come in to sight"); - break; - case 0x38: // update player list - int action = readNextVarInt (ref packetData); - int numActions = readNextVarInt (ref packetData); - string uuid = readNextUUID (ref packetData); - switch (action) { - case 0x00: - string name = readNextString (ref packetData); - handler.addPlayer (uuid, name); + case 0x38: //Player List update + int action = readNextVarInt(ref packetData); + int numActions = readNextVarInt(ref packetData); + Guid uuid = readNextUUID(ref packetData); + switch (action) + { + case 0x00: //Player Join + string name = readNextString(ref packetData); + handler.OnPlayerJoin(uuid, name); break; - case 0x04: - handler.removePlayer (uuid); + case 0x04: //Player Leave + handler.OnPlayerLeave(uuid); break; default: - //do nothing + //Unknown player list item type break; } break; - case 0x3A: + case 0x3A: //Tab-Complete Result int autocomplete_count = readNextVarInt(ref packetData); string tab_list = ""; for (int i = 0; i < autocomplete_count; i++) @@ -177,10 +175,10 @@ private bool handlePacket(int packetID, byte[] packetData) if (tab_list.Length > 0) ConsoleIO.WriteLineFormatted("§8" + tab_list, false); break; - case 0x40: + case 0x40: //Kick Packet handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, ChatParser.ParseText(readNextString(ref packetData))); return false; - case 0x46: + case 0x46: //Network Compression Treshold Info compression_treshold = readNextVarInt(ref packetData); break; default: @@ -280,11 +278,11 @@ private string readNextString(ref byte[] cache) /// Read a uuid from a cache of bytes and remove it from the cache /// /// Cache of bytes to read from - /// The uuid as a string + /// The uuid - private string readNextUUID(ref byte[] cache) + private Guid readNextUUID(ref byte[] cache) { - return BitConverter.ToString(readData (16, ref cache)).Replace ("-", string.Empty).ToLower(); + return new Guid(readData(16, ref cache)); } /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 79b4fe39ee..f74d22a4b6 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -21,10 +21,7 @@ public interface IMinecraftComHandler string getUsername(); string getUserUUID(); string getSessionID(); - - void addPlayer(string uuid, string name); - void removePlayer(string uuid); - HashSet getPlayers(); + string[] getOnlinePlayers(); /// /// This method is called when the protocol handler receives a chat message @@ -32,6 +29,21 @@ public interface IMinecraftComHandler void OnTextReceived(string text); + /// + /// This method is called when a new player joins the game + /// + /// UUID of the player + /// Name of the player + + void OnPlayerJoin(Guid uuid, string name); + + /// + /// This method is called when a player has left the game + /// + /// UUID of the player + + void OnPlayerLeave(Guid uuid); + /// /// This method is called when the connection has been lost /// From 8d16f1ec89d8bc4182a7e116ece7c002a546b4ea Mon Sep 17 00:00:00 2001 From: ORelio Date: Mon, 10 Nov 2014 20:56:12 +0100 Subject: [PATCH 12/30] Add /list support in Protocol17 Fake UUID using md5(username) since protocol17 does not have UUID in player list item packet --- .../Protocol/Handlers/Protocol17.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/MinecraftClient/Protocol/Handlers/Protocol17.cs b/MinecraftClient/Protocol/Handlers/Protocol17.cs index 387c8bfc41..2ab483b771 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol17.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol17.cs @@ -6,6 +6,7 @@ using System.Threading; using MinecraftClient.Crypto; using MinecraftClient.Proxy; +using System.Security.Cryptography; namespace MinecraftClient.Protocol.Handlers { @@ -96,6 +97,17 @@ private bool Update() case 0x02: handler.OnTextReceived(ChatParser.ParseText(readNextString())); break; + case 0x38: + string name = readNextString(); + bool online = readNextBool(); + short ping = readNextShort(); + Guid FakeUUID = new Guid(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray()); + if (online) + { + handler.OnPlayerJoin(FakeUUID, name); + } + else handler.OnPlayerLeave(FakeUUID); + break; case 0x3A: int autocomplete_count = readNextVarInt(); string tab_list = ""; @@ -186,6 +198,44 @@ private string readNextString() else return ""; } + /// + /// Read a uuid from the network + /// + /// Cache of bytes to read from + /// The uuid + + private Guid readNextUUID() + { + byte[] cache = new byte[16]; + Receive(cache, 0, 16, SocketFlags.None); + return new Guid(cache); + } + + /// + /// Read a short from the network + /// + /// + + private short readNextShort() + { + byte[] tmp = new byte[2]; + Receive(tmp, 0, 2, SocketFlags.None); + Array.Reverse(tmp); + return BitConverter.ToInt16(tmp, 0); + } + + /// + /// Read a boolean from the network + /// + /// + + private bool readNextBool() + { + byte[] tmp = new byte[1]; + Receive(tmp, 0, 1, SocketFlags.None); + return tmp[0] != 0x00; + } + /// /// Read a byte array from the network /// From 8e458f7ab95d6c44ae3651e3f1fc4d2d5de9b5e4 Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 11 Nov 2014 12:35:08 +0100 Subject: [PATCH 13/30] Add /list support in Protocol16 Removed fallback to server /list command --- MinecraftClient/Commands/List.cs | 9 +-------- MinecraftClient/Protocol/Handlers/Protocol16.cs | 7 ++++++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs index c322a9f6cf..116085d037 100644 --- a/MinecraftClient/Commands/List.cs +++ b/MinecraftClient/Commands/List.cs @@ -12,14 +12,7 @@ public class List : Command public override string Run(McTcpClient handler, string command) { - string[] onlinePlayers = handler.getOnlinePlayers(); - if (onlinePlayers.Length == 0) //Not properly handled by Protocol handler? - { - //Fallback to server /list command - handler.SendText("/list"); - return ""; - } - else return "PlayerList: " + String.Join(", ", onlinePlayers); + return "PlayerList: " + String.Join(", ", handler.getOnlinePlayers()); } } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 5473366437..740342f564 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -6,6 +6,7 @@ using System.Threading; using MinecraftClient.Crypto; using MinecraftClient.Proxy; +using System.Security.Cryptography; namespace MinecraftClient.Protocol.Handlers { @@ -157,7 +158,11 @@ private bool processPacket(byte id) if (readNextInt() == 2022) { handler.OnTextReceived("You are dead. Type /reco to respawn & reconnect."); } if (protocolversion >= 72) { readData(4); } else readData(1); break; - case 0xC9: readNextString(); readData(3); break; + case 0xC9: + string name = readNextString(); bool online = readNextByte() != 0x00; readData(2); + Guid FakeUUID = new Guid(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray()); + if (online) { handler.OnPlayerJoin(FakeUUID, name); } else { handler.OnPlayerLeave(FakeUUID); } + break; case 0xCA: if (protocolversion >= 72) { readData(9); } else readData(3); break; case 0xCB: autocomplete_result = readNextString(); autocomplete_received = true; break; case 0xCC: readNextString(); readData(4); break; From 2dec21ddc75d6630c8fd4a5f27ae7b7d8e8877e0 Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 11 Nov 2014 12:36:15 +0100 Subject: [PATCH 14/30] Add Minecraft 1.8.1 in supported version list Allows support for version=1.8.1 in config file --- MinecraftClient/Protocol/ProtocolHandler.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index bc8aaf8b81..076420d278 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -108,6 +108,7 @@ public static int MCVer2ProtocolVersion(string MCVersion) case "1.7.10": return 5; case "1.8.0": + case "1.8.1": return 47; default: return 0; From 4752094f1fd909fed9112c441e1f1ebafeb95342 Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 11 Nov 2014 12:44:37 +0100 Subject: [PATCH 15/30] Fix server version detection for Bungeecord 1.8 --- MinecraftClient/Protocol/Handlers/Protocol17.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol17.cs b/MinecraftClient/Protocol/Handlers/Protocol17.cs index 2ab483b771..844d410249 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol17.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol17.cs @@ -595,14 +595,20 @@ public static bool doPing(string host, int port, ref int protocolversion) { protocolversion = atoi(tmp_ver[1]); - // Handle if "name" exists twice, like when connecting to a server with another user logged in. + //Handle if "name" exists twice, eg when connecting to a server with another user logged in. version = (tmp_name.Length == 2) ? tmp_name[1].Split('"')[0] : tmp_name[2].Split('"')[0]; + + //Automatic fix for BungeeCord 1.8 not properly reporting protocol version + if (protocolversion == 0 && version.Split(' ').Contains("1.8")) + protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0"); + if (result.Contains("modinfo\":")) { //Server is running Forge (which is not supported) version = "Forge " + version; protocolversion = 0; } + ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ")."); return true; } From 1499f8cbfc01d387cabfaa39622765836b746a48 Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 16 Dec 2014 19:17:06 +0100 Subject: [PATCH 16/30] Refactor Alerts Bot + Fix crash More efficient, succint and readable code with less bugs! Fixed crash when displaying alert under certain conditions. --- MinecraftClient/ChatBots/Alerts.cs | 133 +++++++++++------------------ 1 file changed, 52 insertions(+), 81 deletions(-) diff --git a/MinecraftClient/ChatBots/Alerts.cs b/MinecraftClient/ChatBots/Alerts.cs index 4be3b16cc8..b60a39ee80 100644 --- a/MinecraftClient/ChatBots/Alerts.cs +++ b/MinecraftClient/ChatBots/Alerts.cs @@ -2,125 +2,96 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.IO; namespace MinecraftClient.ChatBots { /// /// This bot make the console beep on some specified words. Useful to detect when someone is talking to you, for example. /// - public class Alerts : ChatBot { private string[] dictionary = new string[0]; private string[] excludelist = new string[0]; - public override void Initialize() + /// + /// Import alerts from the specified file + /// + /// + /// + private static string[] FromFile(string file) { - if (System.IO.File.Exists(Settings.Alerts_MatchesFile)) + if (File.Exists(file)) { - List tmp_dictionary = new List(); - string[] file_lines = System.IO.File.ReadAllLines(Settings.Alerts_MatchesFile); - foreach (string line in file_lines) - if (line.Trim().Length > 0 && !tmp_dictionary.Contains(line.ToLower())) - tmp_dictionary.Add(line.ToLower()); - dictionary = tmp_dictionary.ToArray(); + //Read all lines from file, remove lines with no text, convert to lowercase, + //remove duplicate entries, convert to a string array, and return the result. + return File.ReadAllLines(file) + .Where(line => !String.IsNullOrWhiteSpace(line)) + .Select(line => line.ToLower()) + .Distinct().ToArray(); } - else LogToConsole("File not found: " + Settings.Alerts_MatchesFile); - - if (System.IO.File.Exists(Settings.Alerts_ExcludesFile)) + else { - List tmp_excludelist = new List(); - string[] file_lines = System.IO.File.ReadAllLines(Settings.Alerts_ExcludesFile); - foreach (string line in file_lines) - if (line.Trim().Length > 0 && !tmp_excludelist.Contains(line.Trim().ToLower())) - tmp_excludelist.Add(line.ToLower()); - excludelist = tmp_excludelist.ToArray(); + LogToConsole("File not found: " + Settings.Alerts_MatchesFile); + return new string[0]; } - else LogToConsole("File not found : " + Settings.Alerts_ExcludesFile); } + /// + /// Intitialize the Alerts bot + /// + public override void Initialize() + { + dictionary = FromFile(Settings.Alerts_MatchesFile); + excludelist = FromFile(Settings.Alerts_ExcludesFile); + } + + /// + /// Process text received from the server to display alerts + /// + /// Received text public override void GetText(string text) { - text = getVerbatim(text); - string comp = text.ToLower(); - foreach (string alert in dictionary) + //Remove color codes and convert to lowercase + text = getVerbatim(text).ToLower(); + + //Proceed only if no exclusions are found in text + if (!excludelist.Any(exclusion => text.Contains(exclusion))) { - if (comp.Contains(alert)) + //Show an alert for each alert item found in text, if any + foreach (string alert in dictionary.Where(alert => text.Contains(alert))) { - bool ok = true; + if (Settings.Alerts_Beep_Enabled) + Console.Beep(); //Text found ! - foreach (string exclusion in excludelist) - { - if (comp.Contains(exclusion)) - { - ok = false; - break; - } - } + if (ConsoleIO.basicIO) //Using a GUI? Pass text as is. + ConsoleIO.WriteLine(text.Replace(alert, "§c" + alert + "§r")); - if (ok) + else //Using Consome Prompt : Print text with alert highlighted { - if (Settings.Alerts_Beep_Enabled) { Console.Beep(); } //Text found ! + string[] splitted = text.Split(new string[] { alert }, StringSplitOptions.None); - if (ConsoleIO.basicIO) { ConsoleIO.WriteLine(comp.Replace(alert, "§c" + alert + "§r")); } - else + if (splitted.Length > 0) { - - #region Displaying the text with the interesting part highlighted - Console.BackgroundColor = ConsoleColor.DarkGray; Console.ForegroundColor = ConsoleColor.White; + ConsoleIO.Write(splitted[0]); - //Will be used for text displaying - string[] temp = comp.Split(alert.Split(','), StringSplitOptions.None); - int p = 0; - - //Special case : alert in the beginning of the text - string test = ""; - for (int i = 0; i < alert.Length; i++) - { - test += comp[i]; - } - if (test == alert) + for (int i = 1; i < splitted.Length; i++) { Console.BackgroundColor = ConsoleColor.Yellow; Console.ForegroundColor = ConsoleColor.Red; - for (int i = 0; i < alert.Length; i++) - { - ConsoleIO.Write(text[p]); - p++; - } - } + ConsoleIO.Write(alert); - //Displaying the rest of the text - for (int i = 0; i < temp.Length; i++) - { Console.BackgroundColor = ConsoleColor.DarkGray; Console.ForegroundColor = ConsoleColor.White; - for (int j = 0; j < temp[i].Length; j++) - { - ConsoleIO.Write(text[p]); - p++; - } - Console.BackgroundColor = ConsoleColor.Yellow; - Console.ForegroundColor = ConsoleColor.Red; - try - { - for (int j = 0; j < alert.Length; j++) - { - ConsoleIO.Write(text[p]); - p++; - } - } - catch (IndexOutOfRangeException) { } + ConsoleIO.Write(splitted[i]); } - Console.BackgroundColor = ConsoleColor.Black; - Console.ForegroundColor = ConsoleColor.Gray; - ConsoleIO.Write('\n'); - - #endregion - } + + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Gray; + ConsoleIO.Write('\n'); } } } From dd001e35195c67b700474a753d2ef241f59093dc Mon Sep 17 00:00:00 2001 From: ORelio Date: Fri, 2 Jan 2015 22:10:12 +0100 Subject: [PATCH 17/30] Auto-Tpaccept from everyone Disabled by default. Suggested by medxo --- MinecraftClient/ChatBots/RemoteControl.cs | 4 +++- MinecraftClient/Settings.cs | 5 ++++- MinecraftClient/config/README.txt | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/ChatBots/RemoteControl.cs b/MinecraftClient/ChatBots/RemoteControl.cs index 818bab6f45..9f12742c5c 100644 --- a/MinecraftClient/ChatBots/RemoteControl.cs +++ b/MinecraftClient/ChatBots/RemoteControl.cs @@ -24,7 +24,9 @@ public override void GetText(string text) SendPrivateMessage(sender, response); } } - else if (Settings.RemoteCtrl_AutoTpaccept && isTeleportRequest(text, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower())) + else if (Settings.RemoteCtrl_AutoTpaccept + && isTeleportRequest(text, ref sender) + && (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower()))) { SendText("/tpaccept"); } diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 5b22bc905c..d97d531a27 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -86,6 +86,7 @@ public static class Settings //Remote Control public static bool RemoteCtrl_Enabled = false; public static bool RemoteCtrl_AutoTpaccept = true; + public static bool RemoteCtrl_AutoTpaccept_Everyone = false; //Custom app variables and Minecraft accounts private static Dictionary AppVars = new Dictionary(); @@ -271,6 +272,7 @@ public static void LoadSettings(string settingsfile) { case "enabled": RemoteCtrl_Enabled = str2bool(argValue); break; case "autotpaccept": RemoteCtrl_AutoTpaccept = str2bool(argValue); break; + case "tpaccepteveryone": RemoteCtrl_AutoTpaccept_Everyone = str2bool(argValue); break; } break; @@ -399,7 +401,8 @@ public static void WriteDefaultSettings(string settingsfile) + "\r\n" + "[RemoteControl]\r\n" + "enabled=false\r\n" - + "autotpaccept=true\r\n", Encoding.UTF8); + + "autotpaccept=true\r\n" + + "tpaccepteveryone=false\r\n", Encoding.UTF8); } public static int str2int(string str) { try { return Convert.ToInt32(str); } catch { return 0; } } diff --git a/MinecraftClient/config/README.txt b/MinecraftClient/config/README.txt index 2a07bdd2e9..34d56d8006 100644 --- a/MinecraftClient/config/README.txt +++ b/MinecraftClient/config/README.txt @@ -161,7 +161,8 @@ When the remote control bot is enabled, you can send commands to your bot using Don't forget to add your username in botowners INI setting if you want it to obey. To perform a command simply do the following: /tell Where is an internal command as described in "Internal commands" section. -If enabled, remote control will auto-accept /tpa and /tpahere requests from the bot owners. +Remote control system can auto-accept /tpa and /tpahere requests from the bot owners. +Auto-accept can be disabled or extended to requests from anyone in remote control configuration. ========================= Disclaimer & Last words From bdbc408279f6cff1207d1b8094d2d9bbae56e98f Mon Sep 17 00:00:00 2001 From: medxo Date: Thu, 22 Jan 2015 11:20:46 +0000 Subject: [PATCH 18/30] Update RemoteControl.cs --- MinecraftClient/ChatBots/RemoteControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/ChatBots/RemoteControl.cs b/MinecraftClient/ChatBots/RemoteControl.cs index 9f12742c5c..92d8d308ff 100644 --- a/MinecraftClient/ChatBots/RemoteControl.cs +++ b/MinecraftClient/ChatBots/RemoteControl.cs @@ -15,7 +15,7 @@ public override void GetText(string text) { text = getVerbatim(text); string command = "", sender = ""; - if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower())) + if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Replace(" ",""))) { string response = ""; performInternalCommand(command, ref response); @@ -26,7 +26,7 @@ public override void GetText(string text) } else if (Settings.RemoteCtrl_AutoTpaccept && isTeleportRequest(text, ref sender) - && (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower()))) + && (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower().Replace(" ","")))) { SendText("/tpaccept"); } From 24c4344a70efe85460e215bf72cd8370f119e4f6 Mon Sep 17 00:00:00 2001 From: ORelio Date: Fri, 23 Jan 2015 22:07:46 +0100 Subject: [PATCH 19/30] Fix scripts failing to send msg after reco Script was using old disposed handler Fixed by properly updating reference Bug report by 1092CQ (thanks!) --- MinecraftClient/McTcpClient.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 6f734eb828..29dc1ab62c 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -126,7 +126,9 @@ private void StartClient(string user, string uuid, string sessionID, string serv } else { - foreach (ChatBot bot in scripts_on_hold) { bots.Add(bot); } + 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 '" From ee406b233e05c09711b0f6d05d32e077d5ec89cb Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 27 Jan 2015 20:23:59 +0100 Subject: [PATCH 20/30] Use Trim instead of space deletion --- MinecraftClient/ChatBots/RemoteControl.cs | 4 ++-- MinecraftClient/Settings.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MinecraftClient/ChatBots/RemoteControl.cs b/MinecraftClient/ChatBots/RemoteControl.cs index 92d8d308ff..dfdf5d2a35 100644 --- a/MinecraftClient/ChatBots/RemoteControl.cs +++ b/MinecraftClient/ChatBots/RemoteControl.cs @@ -15,7 +15,7 @@ public override void GetText(string text) { text = getVerbatim(text); string command = "", sender = ""; - if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Replace(" ",""))) + if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Trim())) { string response = ""; performInternalCommand(command, ref response); @@ -26,7 +26,7 @@ public override void GetText(string text) } else if (Settings.RemoteCtrl_AutoTpaccept && isTeleportRequest(text, ref sender) - && (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower().Replace(" ","")))) + && (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower().Trim()))) { SendText("/tpaccept"); } diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index d97d531a27..09e508f1fd 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -155,8 +155,8 @@ public static void LoadSettings(string settingsfile) case "botowners": Bots_Owners.Clear(); - foreach (string name in argValue.ToLower().Replace(" ", "").Split(',')) - Bots_Owners.Add(name); + foreach (string name in argValue.ToLower().Split(',')) + Bots_Owners.Add(name.Trim()); break; case "internalcmdchar": From 391eca102c388eb85e78985ed8fe58010be076fb Mon Sep 17 00:00:00 2001 From: ORelio Date: Tue, 27 Jan 2015 20:38:59 +0100 Subject: [PATCH 21/30] Add 15 seconds timeout to session and login Add AutoTimeout class for use on login and session requests. Bug report by GamerCorey7. --- MinecraftClient/AutoTimeout.cs | 41 +++++++++++++++++ MinecraftClient/MinecraftClient.csproj | 1 + MinecraftClient/Protocol/ProtocolHandler.cs | 49 ++++++++++++--------- 3 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 MinecraftClient/AutoTimeout.cs diff --git a/MinecraftClient/AutoTimeout.cs b/MinecraftClient/AutoTimeout.cs new file mode 100644 index 0000000000..abc263de78 --- /dev/null +++ b/MinecraftClient/AutoTimeout.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading; + +namespace MinecraftClient +{ + /// + /// Allow easy timeout on pieces of code + /// + /// + /// By ORelio - (c) 2014 - CDDL 1.0 + /// + public class AutoTimeout + { + /// + /// Perform the specified action with specified timeout + /// + /// Action to run + /// Maximum timeout in milliseconds + /// True if the action finished whithout timing out + public static bool Perform(Action action, int timeout) + { + return Perform(action, TimeSpan.FromMilliseconds(timeout)); + } + + /// + /// Perform the specified action with specified timeout + /// + /// Action to run + /// Maximum timeout + /// True if the action finished whithout timing out + public static bool Perform(Action action, TimeSpan timeout) + { + Thread thread = new Thread(new ThreadStart(action)); + thread.Start(); + bool success = thread.Join(timeout); + if (!success) + thread.Abort(); + return success; + } + } +} \ No newline at end of file diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 52dba3330b..c174cb1ebd 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -71,6 +71,7 @@ + diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 076420d278..08b309f353 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -230,30 +230,37 @@ public static bool SessionCheck(string uuid, string accesstoken, string serverha private static int doHTTPSPost(string host, string endpoint, string request, ref string result) { - TcpClient client = ProxyHandler.newTcpClient(host, 443); - SslStream stream = new SslStream(client.GetStream()); - stream.AuthenticateAsClient(host); + string postResult = null; + int statusCode = 520; + AutoTimeout.Perform(() => + { + TcpClient client = ProxyHandler.newTcpClient(host, 443); + SslStream stream = new SslStream(client.GetStream()); + stream.AuthenticateAsClient(host); - List http_request = new List(); - http_request.Add("POST " + endpoint + " HTTP/1.1"); - http_request.Add("Host: " + host); - http_request.Add("User-Agent: MCC/" + Program.Version); - http_request.Add("Content-Type: application/json"); - http_request.Add("Content-Length: " + Encoding.ASCII.GetBytes(request).Length); - http_request.Add("Connection: close"); - http_request.Add(""); - http_request.Add(request); + List http_request = new List(); + http_request.Add("POST " + endpoint + " HTTP/1.1"); + http_request.Add("Host: " + host); + http_request.Add("User-Agent: MCC/" + Program.Version); + http_request.Add("Content-Type: application/json"); + http_request.Add("Content-Length: " + Encoding.ASCII.GetBytes(request).Length); + http_request.Add("Connection: close"); + http_request.Add(""); + http_request.Add(request); - stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", http_request.ToArray()))); - System.IO.StreamReader sr = new System.IO.StreamReader(stream); - string raw_result = sr.ReadToEnd(); + stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", http_request.ToArray()))); + System.IO.StreamReader sr = new System.IO.StreamReader(stream); + string raw_result = sr.ReadToEnd(); - if (raw_result.StartsWith("HTTP/1.1")) - { - result = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4); - return Settings.str2int(raw_result.Split(' ')[1]); - } - else return 520; //Web server is returning an unknown error + if (raw_result.StartsWith("HTTP/1.1")) + { + postResult = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4); + statusCode = Settings.str2int(raw_result.Split(' ')[1]); + } + else statusCode = 520; //Web server is returning an unknown error + }, 15000); + result = postResult; + return statusCode; } /// From 2408b51d286370f2dde5a6e995e19c710adabe1b Mon Sep 17 00:00:00 2001 From: ORelio Date: Sat, 31 Jan 2015 11:21:06 +0100 Subject: [PATCH 22/30] Fix BungeeCord 1.8 (2nd attempt) --- MinecraftClient/AutoTimeout.cs | 4 ++-- MinecraftClient/Protocol/Handlers/Protocol17.cs | 9 +-------- MinecraftClient/config/README.txt | 6 +++--- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/MinecraftClient/AutoTimeout.cs b/MinecraftClient/AutoTimeout.cs index abc263de78..c0fe53686f 100644 --- a/MinecraftClient/AutoTimeout.cs +++ b/MinecraftClient/AutoTimeout.cs @@ -15,7 +15,7 @@ public class AutoTimeout /// Perform the specified action with specified timeout /// /// Action to run - /// Maximum timeout in milliseconds + /// Maximum timeout in milliseconds /// True if the action finished whithout timing out public static bool Perform(Action action, int timeout) { @@ -26,7 +26,7 @@ public static bool Perform(Action action, int timeout) /// Perform the specified action with specified timeout /// /// Action to run - /// Maximum timeout + /// Maximum timeout /// True if the action finished whithout timing out public static bool Perform(Action action, TimeSpan timeout) { diff --git a/MinecraftClient/Protocol/Handlers/Protocol17.cs b/MinecraftClient/Protocol/Handlers/Protocol17.cs index 844d410249..a514ffc5cb 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol17.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol17.cs @@ -599,16 +599,9 @@ public static bool doPing(string host, int port, ref int protocolversion) version = (tmp_name.Length == 2) ? tmp_name[1].Split('"')[0] : tmp_name[2].Split('"')[0]; //Automatic fix for BungeeCord 1.8 not properly reporting protocol version - if (protocolversion == 0 && version.Split(' ').Contains("1.8")) + if (protocolversion < 47 && version.Split(' ').Contains("1.8")) protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0"); - if (result.Contains("modinfo\":")) - { - //Server is running Forge (which is not supported) - version = "Forge " + version; - protocolversion = 0; - } - ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ")."); return true; } diff --git a/MinecraftClient/config/README.txt b/MinecraftClient/config/README.txt index 34d56d8006..f679f977b8 100644 --- a/MinecraftClient/config/README.txt +++ b/MinecraftClient/config/README.txt @@ -60,7 +60,7 @@ In scripts and remote control, no slash is needed to perform the command. - respawn : Use this to respawn if you are dead (like clicking "respawn" ingame) - log : display some text in the console (useful for scripts) - set varname=value : set a value which can be used as %varname% in further commands - - wait