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 ceaedfb9..8fa06680 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -53,7 +53,7 @@ namespace MinecraftClient /// 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 @@ namespace MinecraftClient /// 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 @@ namespace MinecraftClient /// 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 ce3a704b..56beca83 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -23,7 +23,7 @@ namespace MinecraftClient.Protocol /// 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 6ccbe85e..facdaf68 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -20,7 +20,7 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient //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 @@ namespace MinecraftClient { //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 @@ namespace MinecraftClient && !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 d7cc91bc..d4d8d1a1 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -632,57 +632,7 @@ namespace MinecraftClient.Protocol.Handlers 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 d4d8d1a1..270809dc 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -624,15 +624,5 @@ namespace MinecraftClient.Protocol.Handlers 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 6ccbe85e..03f14f9c 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -20,7 +20,7 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient //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 @@ namespace MinecraftClient { //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 @@ namespace MinecraftClient && !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 @@ namespace MinecraftClient 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 03f14f9c..5b22bc90 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -20,7 +20,7 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient //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 @@ namespace MinecraftClient { //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 @@ namespace MinecraftClient && !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 @@ namespace MinecraftClient 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 ceaedfb9..4e59d1b3 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -53,7 +53,7 @@ namespace MinecraftClient /// 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 @@ namespace MinecraftClient /// 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 @@ namespace MinecraftClient /// 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 ce3a704b..bc8aaf8b 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -23,7 +23,7 @@ namespace MinecraftClient.Protocol /// 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 00000000..b6791f9c --- /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 4e59d1b3..8a72a7de 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -33,6 +33,8 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient 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 4bbb262f..52dba333 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 270809dc..ce65540e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -141,8 +141,28 @@ namespace MinecraftClient.Protocol.Handlers 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 @@ namespace MinecraftClient.Protocol.Handlers 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 cc2b6055..1fddceeb 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -22,6 +22,10 @@ namespace MinecraftClient.Protocol 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 f911c9a3..307f491a 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 | 49 +++++++-------- .../Protocol/Handlers/Protocol18.cs | 60 +++++++++---------- .../Protocol/IMinecraftComHandler.cs | 6 +- 4 files changed, 68 insertions(+), 67 deletions(-) diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs index b6791f9c..b1a653d6 100644 --- a/MinecraftClient/Commands/List.cs +++ b/MinecraftClient/Commands/List.cs @@ -5,16 +5,16 @@ 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 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 8a72a7de..47954ad5 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -33,7 +33,7 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient /// 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 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); } - } + public HashSet getPlayers() { return new HashSet(players.Values); } + } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ce65540e..edac89b1 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -141,28 +141,28 @@ namespace MinecraftClient.Protocol.Handlers 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 @@ namespace MinecraftClient.Protocol.Handlers 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 1fddceeb..79b4fe39 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -22,9 +22,9 @@ namespace MinecraftClient.Protocol 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 | 51 +++++++++++-------- .../Protocol/Handlers/Protocol18.cs | 42 ++++++++------- .../Protocol/IMinecraftComHandler.cs | 20 ++++++-- 4 files changed, 72 insertions(+), 49 deletions(-) diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs index b1a653d6..c322a9f6 100644 --- a/MinecraftClient/Commands/List.cs +++ b/MinecraftClient/Commands/List.cs @@ -12,8 +12,14 @@ namespace MinecraftClient.Commands 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 47954ad5..6f734eb8 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -20,6 +20,7 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient 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 @@ namespace MinecraftClient 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(); } /// @@ -391,19 +389,6 @@ namespace MinecraftClient 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 /// @@ -411,16 +396,38 @@ namespace MinecraftClient public bool SendRespawnPacket() { - return handler.SendRespawnPacket (); + return handler.SendRespawnPacket(); } - public void addPlayer(string uuid, string name) { - players[uuid] = name; + /// + /// Triggered when a new player joins the game + /// + /// UUID of the player + /// Name of the player + + public void OnPlayerJoin(Guid uuid, string name) + { + onlinePlayers[uuid] = name; } - public void removePlayer(string uuid){ - players.Remove (uuid); + + /// + /// Triggered when a player has left the game + /// + /// UUID of the player + + 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 edac89b1..a1eb60f3 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -137,33 +137,31 @@ namespace MinecraftClient.Protocol.Handlers { 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 @@ namespace MinecraftClient.Protocol.Handlers 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 @@ namespace MinecraftClient.Protocol.Handlers /// 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 79b4fe39..f74d22a4 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -21,10 +21,7 @@ namespace MinecraftClient.Protocol 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 @@ namespace MinecraftClient.Protocol 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 387c8bfc..2ab483b7 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol17.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol17.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using System.Threading; using MinecraftClient.Crypto; using MinecraftClient.Proxy; +using System.Security.Cryptography; namespace MinecraftClient.Protocol.Handlers { @@ -96,6 +97,17 @@ namespace MinecraftClient.Protocol.Handlers 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 @@ namespace MinecraftClient.Protocol.Handlers 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 c322a9f6..116085d0 100644 --- a/MinecraftClient/Commands/List.cs +++ b/MinecraftClient/Commands/List.cs @@ -12,14 +12,7 @@ namespace MinecraftClient.Commands 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 54733664..740342f5 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using System.Threading; using MinecraftClient.Crypto; using MinecraftClient.Proxy; +using System.Security.Cryptography; namespace MinecraftClient.Protocol.Handlers { @@ -157,7 +158,11 @@ namespace MinecraftClient.Protocol.Handlers 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 bc8aaf8b..076420d2 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -108,6 +108,7 @@ namespace MinecraftClient.Protocol 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 2ab483b7..844d4102 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol17.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol17.cs @@ -595,14 +595,20 @@ namespace MinecraftClient.Protocol.Handlers { 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 | 137 ++++++++++++----------------- 1 file changed, 54 insertions(+), 83 deletions(-) diff --git a/MinecraftClient/ChatBots/Alerts.cs b/MinecraftClient/ChatBots/Alerts.cs index 4be3b16c..b60a39ee 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 (ConsoleIO.basicIO) //Using a GUI? Pass text as is. + ConsoleIO.WriteLine(text.Replace(alert, "§c" + alert + "§r")); + + else //Using Consome Prompt : Print text with alert highlighted { - if (comp.Contains(exclusion)) + string[] splitted = text.Split(new string[] { alert }, StringSplitOptions.None); + + if (splitted.Length > 0) { - ok = false; - break; - } - } - - if (ok) - { - if (Settings.Alerts_Beep_Enabled) { Console.Beep(); } //Text found ! - - if (ConsoleIO.basicIO) { ConsoleIO.WriteLine(comp.Replace(alert, "§c" + alert + "§r")); } - else - { - - #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 818bab6f..9f12742c 100644 --- a/MinecraftClient/ChatBots/RemoteControl.cs +++ b/MinecraftClient/ChatBots/RemoteControl.cs @@ -24,7 +24,9 @@ namespace MinecraftClient.ChatBots 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 5b22bc90..d97d531a 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -86,6 +86,7 @@ namespace MinecraftClient //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 @@ namespace MinecraftClient { 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 @@ namespace MinecraftClient + "\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 2a07bdd2..34d56d80 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 9f12742c..92d8d308 100644 --- a/MinecraftClient/ChatBots/RemoteControl.cs +++ b/MinecraftClient/ChatBots/RemoteControl.cs @@ -15,7 +15,7 @@ namespace MinecraftClient.ChatBots { 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 @@ namespace MinecraftClient.ChatBots } 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 6f734eb8..29dc1ab6 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -126,7 +126,9 @@ namespace MinecraftClient } 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 92d8d308..dfdf5d2a 100644 --- a/MinecraftClient/ChatBots/RemoteControl.cs +++ b/MinecraftClient/ChatBots/RemoteControl.cs @@ -15,7 +15,7 @@ namespace MinecraftClient.ChatBots { 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 @@ namespace MinecraftClient.ChatBots } 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 d97d531a..09e508f1 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -155,8 +155,8 @@ namespace MinecraftClient 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 | 53 ++++++++++++--------- 3 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 MinecraftClient/AutoTimeout.cs diff --git a/MinecraftClient/AutoTimeout.cs b/MinecraftClient/AutoTimeout.cs new file mode 100644 index 00000000..abc263de --- /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 52dba333..c174cb1e 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 076420d2..08b309f3 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -230,30 +230,37 @@ namespace MinecraftClient.Protocol 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); - - 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(); - - if (raw_result.StartsWith("HTTP/1.1")) + string postResult = null; + int statusCode = 520; + AutoTimeout.Perform(() => { - 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 + 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); + + 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")) + { + 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 abc263de..c0fe5368 100644 --- a/MinecraftClient/AutoTimeout.cs +++ b/MinecraftClient/AutoTimeout.cs @@ -15,7 +15,7 @@ namespace MinecraftClient /// 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 @@ namespace MinecraftClient /// 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 844d4102..a514ffc5 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol17.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol17.cs @@ -599,16 +599,9 @@ namespace MinecraftClient.Protocol.Handlers 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 34d56d80..f679f977 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