/// <summary> /// Manual HTTPS request since we must directly use a TcpClient because of the proxy. /// This method connects to the server, enables SSL, do the request and read the response. /// </summary> /// <param name="headers">Request headers and optional body (POST)</param> /// <param name="host">Host to connect to</param> /// <param name="result">Request result</param> /// <returns>HTTP Status code</returns> private static int doHTTPSRequest(List <string> headers, string host, ref string result) { string postResult = null; int statusCode = 520; AutoTimeout.Perform(() => { TcpClient client = ProxyHandler.newTcpClient(host, 443, true); SslStream stream = new SslStream(client.GetStream()); stream.AuthenticateAsClient(host); stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", headers.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 } }, TimeSpan.FromSeconds(30)); result = postResult; return(statusCode); }
/// <summary> /// Send a http request to the server. Proxy is handled automatically /// </summary> /// <param name="method">Method in string representation</param> /// <param name="body">Optional request body</param> /// <returns></returns> private Response Send(string method, string body = "") { List <string> requestMessage = new List <string>() { string.Format("{0} {1} {2}", method.ToUpper(), path, httpVersion) // Request line }; foreach (string key in Headers) // Headers { var value = Headers[key]; requestMessage.Add(string.Format("{0}: {1}", key, value)); } requestMessage.Add(""); // <CR><LF> if (body != "") { requestMessage.Add(body); } else { requestMessage.Add(""); // <CR><LF> } if (Settings.DebugMessages) { foreach (string l in requestMessage) { ConsoleIO.WriteLine("< " + l); } } Response response = Response.Empty(); AutoTimeout.Perform(() => { TcpClient client = ProxyHandler.newTcpClient(host, port, true); Stream stream; if (isSecure) { stream = new SslStream(client.GetStream()); ((SslStream)stream).AuthenticateAsClient(host); } else { stream = client.GetStream(); } string h = string.Join("\r\n", requestMessage.ToArray()); byte[] data = Encoding.ASCII.GetBytes(h); stream.Write(data, 0, data.Length); stream.Flush(); StreamReader sr = new StreamReader(stream); string rawResult = sr.ReadToEnd(); response = ParseResponse(rawResult); try { sr.Close(); stream.Close(); client.Close(); } catch { } }, TimeSpan.FromSeconds(30)); return(response); }
/// <summary> /// Manual HTTPS request since we must directly use a TcpClient because of the proxy. /// This method connects to the server, enables SSL, do the request and read the response. /// </summary> /// <param name="host">Host to connect to</param> /// <param name="endpoint">Endpoint for making the request</param> /// <param name="request">Request payload</param> /// <param name="result">Request result</param> /// <returns>HTTP Status code</returns> 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 <String> http_request = new List <string>(); 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")) { 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 } }
/// <summary> /// Ping a Minecraft server to get information about the server /// </summary> /// <returns>True if ping was successful</returns> 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); }
/// <summary> /// Ping a Minecraft server to get information about the server /// </summary> /// <returns>True if ping was successful</returns> 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); Protocol17Handler ComTmp = new Protocol17Handler(tcp); if (ComTmp.readNextVarInt() > 0) //Read Response length { if (ComTmp.readNextVarInt() == 0x00) //Read Packet ID { string result = ComTmp.readNextString(); //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]); //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 < 47 && version.Split(' ').Contains("1.8")) { protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0"); } ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ")."); return(true); } } } } return(false); }
public static bool doPing(string host, int port, ref int protocolversion) { try { string version = ""; TcpClient tcp = ProxyHandler.newTcpClient(host, port); tcp.ReceiveTimeout = 30000; // 30 seconds tcp.ReceiveTimeout = 5000; //MC 1.7.2+ SpigotMC servers won't respond, so we need a reasonable timeout. byte[] ping = new byte[2] { 0xfe, 0x01 }; tcp.Client.Send(ping, SocketFlags.None); tcp.Client.Receive(ping, 0, 1, SocketFlags.None); if (ping[0] == 0xff) { Protocol16Handler ComTmp = new Protocol16Handler(tcp); string result = ComTmp.readNextString(); if (Settings.DebugMessages) { // May contain formatting codes, cannot use WriteLineFormatted Console.ForegroundColor = ConsoleColor.DarkGray; ConsoleIO.WriteLine(result); Console.ForegroundColor = ConsoleColor.Gray; } if (result.Length > 2 && result[0] == '§' && result[1] == '1') { string[] tmp = result.Split((char)0x00); protocolversion = (byte)Int16.Parse(tmp[1]); version = tmp[2]; if (protocolversion == 127) //MC 1.7.2+ { return(false); } } else { protocolversion = (byte)39; version = "B1.8.1 - 1.3.2"; } ConsoleIO.WriteLineFormatted(Translations.Get("mcc.use_version", version, protocolversion)); return(true); } else { return(false); } } catch { return(false); } }
public static bool doPing(string host, int port, ref int protocolversion) { try { string version = ""; TcpClient tcp = ProxyHandler.newTcpClient(host, port); tcp.ReceiveTimeout = 5000; //MC 1.7.2+ SpigotMC servers won't respond, so we need a reasonable timeout. byte[] ping = new byte[2] { 0xfe, 0x01 }; tcp.Client.Send(ping, SocketFlags.None); tcp.Client.Receive(ping, 0, 1, SocketFlags.None); if (ping[0] == 0xff) { Protocol16Handler ComTmp = new Protocol16Handler(tcp); string result = ComTmp.readNextString(); if (result.Length > 2 && result[0] == '§' && result[1] == '1') { string[] tmp = result.Split((char)0x00); protocolversion = (byte)Int16.Parse(tmp[1]); version = tmp[2]; if (protocolversion == 127) //MC 1.7.2+ { return(false); } } else { protocolversion = (byte)39; version = "B1.8.1 - 1.3.2"; } ConsoleIO.WriteLineFormatted("§8Server version : MC " + version + " (protocol v" + protocolversion + ")."); return(true); } else { return(false); } } catch { return(false); } }
/// <summary> /// Manual HTTPS request since we must directly use a TcpClient because of the proxy. /// This method connects to the server, enables SSL, do the request and read the response. /// </summary> /// <param name="headers">Request headers and optional body (POST)</param> /// <param name="host">Host to connect to</param> /// <param name="result">Request result</param> /// <returns>HTTP Status code</returns> private static int DoHTTPSRequest(List <string> headers, string host, ref string result) { string postResult = null; int statusCode = 520; Exception exception = null; AutoTimeout.Perform(() => { try { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Performing request to " + host); } TcpClient client = ProxyHandler.newTcpClient(host, 443, true); SslStream stream = new SslStream(client.GetStream()); stream.AuthenticateAsClient(host); if (Settings.DebugMessages) { foreach (string line in headers) { ConsoleIO.WriteLineFormatted("§8> " + line); } } stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", headers.ToArray()))); System.IO.StreamReader sr = new System.IO.StreamReader(stream); string raw_result = sr.ReadToEnd(); if (Settings.DebugMessages) { ConsoleIO.WriteLine(""); foreach (string line in raw_result.Split('\n')) { ConsoleIO.WriteLineFormatted("§8< " + line); } } 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 } } catch (Exception e) { if (!(e is System.Threading.ThreadAbortException)) { exception = e; } } }, TimeSpan.FromSeconds(30)); result = postResult; if (exception != null) { throw exception; } return(statusCode); }
/// <summary> /// Starts the main chat client, wich will login to the server using the MinecraftCom class. /// </summary> /// <param name="user">The chosen username of a premium Minecraft Account</param> /// <param name="sessionID">A valid sessionID obtained with MinecraftCom.GetLogin()</param> /// <param name="server_ip">The server IP</param> /// <param name="port">The server port to use</param> /// <param name="protocolversion">Minecraft protocol version to use</param> /// <param name="uuid">The player's UUID for online-mode authentication</param> /// <param name="singlecommand">If set to true, the client will send a single command and then disconnect from the server</param> /// <param name="command">The text or command to send. Will only be sent if singlecommand is set to true.</param> private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, bool singlecommand, string command) { terrainAndMovementsEnabled = Settings.TerrainAndMovements; bool retry = false; this.sessionid = sessionID; this.uuid = uuid; this.username = user; this.host = server_ip; this.port = port; if (!singlecommand) { if (botsOnHold.Count == 0) { if (Settings.AntiAFK_Enabled) { BotLoad(new ChatBots.AntiAFK(Settings.AntiAFK_Delay)); } if (Settings.Hangman_Enabled) { BotLoad(new ChatBots.HangmanGame(Settings.Hangman_English)); } if (Settings.Alerts_Enabled) { BotLoad(new ChatBots.Alerts()); } if (Settings.ChatLog_Enabled) { BotLoad(new ChatBots.ChatLog(Settings.ExpandVars(Settings.ChatLog_File), Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); } if (Settings.PlayerLog_Enabled) { BotLoad(new ChatBots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.ExpandVars(Settings.PlayerLog_File))); } if (Settings.AutoRelog_Enabled) { BotLoad(new ChatBots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); } if (Settings.ScriptScheduler_Enabled) { BotLoad(new ChatBots.ScriptScheduler(Settings.ExpandVars(Settings.ScriptScheduler_TasksFile))); } if (Settings.RemoteCtrl_Enabled) { BotLoad(new ChatBots.RemoteControl()); } if (Settings.AutoRespond_Enabled) { BotLoad(new ChatBots.AutoRespond(Settings.AutoRespond_Matches)); } //Add your ChatBot here by uncommenting and adapting //BotLoad(new ChatBots.YourBot()); } } try { client = ProxyHandler.newTcpClient(host, port); client.ReceiveBufferSize = 1024 * 1024; handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, forgeInfo, this); Console.WriteLine("Version is supported.\nLogging in..."); try { if (handler.Login()) { if (singlecommand) { handler.SendChatMessage(command); ConsoleIO.WriteLineFormatted("§7Command §8" + command + "§7 sent."); Thread.Sleep(5000); handler.Disconnect(); Thread.Sleep(1000); } else { foreach (ChatBot bot in botsOnHold) { BotLoad(bot, false); } botsOnHold.Clear(); Console.WriteLine("Server was successfully joined.\nType '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "quit' to leave the server."); cmdprompt = new Thread(new ThreadStart(CommandPrompt)); cmdprompt.Name = "MCC Command prompt"; cmdprompt.Start(); } } } catch (Exception e) { ConsoleIO.WriteLineFormatted("§8" + e.Message); Console.WriteLine("Failed to join this server."); retry = true; } } catch (SocketException e) { ConsoleIO.WriteLineFormatted("§8" + e.Message); Console.WriteLine("Failed to connect to this IP."); retry = true; } if (retry) { if (ReconnectionAttemptsLeft > 0) { ConsoleIO.WriteLogLine("Waiting 5 seconds (" + ReconnectionAttemptsLeft + " attempts left)..."); Thread.Sleep(5000); ReconnectionAttemptsLeft--; Program.Restart(); } else if (!singlecommand && Settings.interactiveMode) { Program.HandleFailure(); } } }
/// <summary> /// Ping a Minecraft server to get information about the server /// </summary> /// <returns>True if ping was successful</returns> public static bool doPing(string host, int port, ref int protocolversion, ref ForgeInfo forgeInfo) { string version = ""; TcpClient tcp = ProxyHandler.newTcpClient(host, port); tcp.ReceiveBufferSize = 1024 * 1024; SocketWrapper socketWrapper = new SocketWrapper(tcp); DataTypes dataTypes = new DataTypes(MC18Version); byte[] packet_id = dataTypes.GetVarInt(0); byte[] protocol_version = dataTypes.GetVarInt(-1); byte[] server_port = BitConverter.GetBytes((ushort)port); Array.Reverse(server_port); byte[] next_state = dataTypes.GetVarInt(1); byte[] packet = dataTypes.ConcatBytes(packet_id, protocol_version, dataTypes.GetString(host), server_port, next_state); byte[] tosend = dataTypes.ConcatBytes(dataTypes.GetVarInt(packet.Length), packet); socketWrapper.SendDataRAW(tosend); byte[] status_request = dataTypes.GetVarInt(0); byte[] request_packet = dataTypes.ConcatBytes(dataTypes.GetVarInt(status_request.Length), status_request); socketWrapper.SendDataRAW(request_packet); int packetLength = dataTypes.ReadNextVarIntRAW(socketWrapper); if (packetLength > 0) //Read Response length { List <byte> packetData = new List <byte>(socketWrapper.ReadDataRAW(packetLength)); if (dataTypes.ReadNextVarInt(packetData) == 0x00) //Read Packet ID { string result = dataTypes.ReadNextString(packetData); //Get the Json data if (!String.IsNullOrEmpty(result) && result.StartsWith("{") && result.EndsWith("}")) { Json.JSONData jsonData = Json.ParseJson(result); if (jsonData.Type == Json.JSONData.DataType.Object && jsonData.Properties.ContainsKey("version")) { Json.JSONData versionData = jsonData.Properties["version"]; //Retrieve display name of the Minecraft version if (versionData.Properties.ContainsKey("name")) { version = versionData.Properties["name"].StringValue; } //Retrieve protocol version number for handling this server if (versionData.Properties.ContainsKey("protocol")) { protocolversion = dataTypes.Atoi(versionData.Properties["protocol"].StringValue); } // Check for forge on the server. Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo); ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + (forgeInfo != null ? ", with Forge)." : ").")); return(true); } } } } return(false); }
/// <summary> /// Starts the main chat client, wich will login to the server using the MinecraftCom class. /// </summary> /// <param name="user">The chosen username of a premium Minecraft Account</param> /// <param name="sessionID">A valid sessionID obtained with MinecraftCom.GetLogin()</param> /// <param name="server_ip">The server IP</param> /// <param name="port">The server port to use</param> /// <param name="protocolversion">Minecraft protocol version to use</param> /// <param name="uuid">The player's UUID for online-mode authentication</param> /// <param name="singlecommand">If set to true, the client will send a single command and then disconnect from the server</param> /// <param name="command">The text or command to send. Will only be sent if singlecommand is set to true.</param> private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, bool singlecommand, string command) { this.sessionid = sessionID; this.uuid = uuid; this.username = user; this.host = server_ip; this.port = port; if (!singlecommand) { if (Settings.AntiAFK_Enabled) { BotLoad(new ChatBots.AntiAFK(Settings.AntiAFK_Delay)); } if (Settings.Hangman_Enabled) { BotLoad(new ChatBots.HangmanGame(Settings.Hangman_English)); } if (Settings.Alerts_Enabled) { BotLoad(new ChatBots.Alerts()); } if (Settings.ChatLog_Enabled) { BotLoad(new ChatBots.ChatLog(Settings.expandVars(Settings.ChatLog_File), Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); } if (Settings.PlayerLog_Enabled) { BotLoad(new ChatBots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.expandVars(Settings.PlayerLog_File))); } if (Settings.AutoRelog_Enabled) { BotLoad(new ChatBots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); } if (Settings.ScriptScheduler_Enabled) { BotLoad(new ChatBots.ScriptScheduler(Settings.expandVars(Settings.ScriptScheduler_TasksFile))); } if (Settings.RemoteCtrl_Enabled) { BotLoad(new ChatBots.RemoteControl()); } } try { client = ProxyHandler.newTcpClient(host, port); client.ReceiveBufferSize = 1024 * 1024; handler = Protocol.ProtocolHandler.getProtocolHandler(client, protocolversion, this); Console.WriteLine("Version is supported.\nLogging in..."); if (handler.Login()) { if (singlecommand) { handler.SendChatMessage(command); ConsoleIO.WriteLineFormatted("§7Command §8" + command + "§7 sent."); Thread.Sleep(5000); handler.Disconnect(); Thread.Sleep(1000); } else { foreach (ChatBot bot in scripts_on_hold) { bot.SetHandler(this); } bots.AddRange(scripts_on_hold); scripts_on_hold.Clear(); Console.WriteLine("Server was successfully joined.\nType '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "quit' to leave the server."); cmdprompt = new Thread(new ThreadStart(CommandPrompt)); cmdprompt.Name = "MCC Command prompt"; cmdprompt.Start(); } } } catch (SocketException) { Console.WriteLine("Failed to connect to this IP."); if (AttemptsLeft > 0) { ChatBot.LogToConsole("Waiting 5 seconds (" + AttemptsLeft + " attempts left)..."); Thread.Sleep(5000); AttemptsLeft--; Program.Restart(); } else if (!singlecommand) { Console.ReadLine(); } } }