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 diff --git a/MinecraftClient/AutoTimeout.cs b/MinecraftClient/AutoTimeout.cs new file mode 100644 index 00000000..c0fe5368 --- /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/ChatBot.cs b/MinecraftClient/ChatBot.cs index 4d94ad03..d591c419 100644 --- a/MinecraftClient/ChatBot.cs +++ b/MinecraftClient/ChatBot.cs @@ -204,6 +204,26 @@ namespace MinecraftClient return isValidName(sender); } + //Detect HeroChat PMsend + //From Someone: message + else if (text.StartsWith("From ")) + { + sender = text.Substring(5).Split(':')[0]; + message = text.Substring(text.IndexOf(':') + 2); + return isValidName(sender); + } + + //Detect HeroChat Messages + //[Channel] [Rank] User: Message + else if (text.StartsWith("[") && text.Contains(':') && tmp.Length > 2) + { + int name_end = text.IndexOf(':'); + int name_start = text.Substring(0, name_end).LastIndexOf(']') + 2; + sender = text.Substring(name_start, name_end - name_start); + message = text.Substring(name_end + 2); + return isValidName(sender); + } + else return false; } catch (IndexOutOfRangeException) { return false; } 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'); } } } diff --git a/MinecraftClient/ChatBots/ChatLog.cs b/MinecraftClient/ChatBots/ChatLog.cs index c20d6d4d..7d4acc07 100644 --- a/MinecraftClient/ChatBots/ChatLog.cs +++ b/MinecraftClient/ChatBots/ChatLog.cs @@ -92,7 +92,9 @@ namespace MinecraftClient.ChatBots if (dateandtime) tosave = getTimestamp() + ' ' + tosave; - Directory.CreateDirectory(Path.GetDirectoryName(logfile)); + string directory = Path.GetDirectoryName(logfile); + if (!String.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + Directory.CreateDirectory(directory); FileStream stream = new FileStream(logfile, FileMode.OpenOrCreate); StreamWriter writer = new StreamWriter(stream); stream.Seek(0, SeekOrigin.End); diff --git a/MinecraftClient/ChatBots/RemoteControl.cs b/MinecraftClient/ChatBots/RemoteControl.cs index 818bab6f..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())) + if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Trim())) { string response = ""; performInternalCommand(command, ref response); @@ -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().Trim()))) { SendText("/tpaccept"); } diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs new file mode 100644 index 00000000..116085d0 --- /dev/null +++ b/MinecraftClient/Commands/List.cs @@ -0,0 +1,19 @@ +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) + { + return "PlayerList: " + String.Join(", ", handler.getOnlinePlayers()); + } + } +} + diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index ceaedfb9..2ba5c7d5 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)); } @@ -53,7 +54,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 +70,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 +87,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; @@ -125,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 '" @@ -280,8 +283,11 @@ namespace MinecraftClient if (bot is ChatBots.Script) scripts_on_hold.Add((ChatBots.Script)bot); - handler.Disconnect(); - handler.Dispose(); + if (handler != null) + { + handler.Disconnect(); + handler.Dispose(); + } if (cmdprompt != null) cmdprompt.Abort(); @@ -397,5 +403,36 @@ namespace MinecraftClient { return handler.SendRespawnPacket(); } + + /// + /// 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; + } + + /// + /// Triggered when a player has left the game + /// + /// UUID of the player + + public void OnPlayerLeave(Guid uuid) + { + onlinePlayers.Remove(uuid); + } + + /// + /// Get a set of online player names + /// + /// Online player names + + public string[] getOnlinePlayers() + { + return onlinePlayers.Values.Distinct().ToArray(); + } } } diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 4bbb262f..c174cb1e 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -71,6 +71,7 @@ + @@ -131,6 +132,7 @@ + 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; diff --git a/MinecraftClient/Protocol/Handlers/Protocol17.cs b/MinecraftClient/Protocol/Handlers/Protocol17.cs index 387c8bfc..a514ffc5 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 /// @@ -545,14 +595,13 @@ 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]; - if (result.Contains("modinfo\":")) - { - //Server is running Forge (which is not supported) - version = "Forge " + version; - protocolversion = 0; - } + + //Automatic fix for BungeeCord 1.8 not properly reporting protocol version + if (protocolversion < 47 && version.Split(' ').Contains("1.8")) + protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0"); + ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ")."); return true; } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index d7cc91bc..a1eb60f3 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -137,13 +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 0x3A: + 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: //Player Leave + handler.OnPlayerLeave(uuid); + break; + default: + //Unknown player list item type + break; + } + break; + case 0x3A: //Tab-Complete Result int autocomplete_count = readNextVarInt(ref packetData); string tab_list = ""; for (int i = 0; i < autocomplete_count; i++) @@ -157,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: @@ -256,6 +274,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 + + private Guid readNextUUID(ref byte[] cache) + { + return new Guid(readData(16, ref cache)); + } + /// /// Read a byte array from a cache of bytes and remove it from the cache /// @@ -624,65 +653,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) - { - 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; - } } } diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index cc2b6055..f74d22a4 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -21,6 +21,7 @@ namespace MinecraftClient.Protocol string getUsername(); string getUserUUID(); string getSessionID(); + string[] getOnlinePlayers(); /// /// This method is called when the protocol handler receives a chat message @@ -28,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 /// diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index ce3a704b..08b309f3 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 { @@ -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; @@ -229,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; } /// diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 6ccbe85e..09e508f1 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 ushort ServerPort = 25565; public static string ServerVersion = ""; public static string SingleCommand = ""; public static string ConsoleTitle = ""; @@ -86,11 +86,12 @@ 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(); 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 }; @@ -154,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": @@ -186,7 +187,7 @@ namespace MinecraftClient { //Backup current server info string server_host_temp = ServerIP; - short server_port_temp = ServerPort; + ushort server_port_temp = ServerPort; foreach (string server_line in File.ReadAllLines(argValue)) { @@ -198,7 +199,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 @@ -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; } } @@ -432,13 +435,13 @@ namespace MinecraftClient server = server.ToLower(); string[] sip = server.Split(':'); string host = sip[0]; - short port = 25565; + ushort port = 25565; if (sip.Length > 1) { try { - port = Convert.ToInt16(sip[1]); + port = Convert.ToUInt16(sip[1]); } catch (FormatException) { return false; } } diff --git a/MinecraftClient/config/README.txt b/MinecraftClient/config/README.txt index 2a07bdd2..a6a705e3 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