public Protocol18Handler(TcpClient Client, int ProtocolVersion, IMinecraftComHandler Handler, ForgeInfo ForgeInfo) { ConsoleIO.SetAutoCompleteEngine(this); ChatParser.InitTranslations(); this.c = Client; this.protocolversion = ProtocolVersion; this.handler = Handler; this.forgeInfo = ForgeInfo; if (Settings.TerrainAndMovements && protocolversion > MC18Version) { ConsoleIO.WriteLineFormatted("§8Terrain & Movements currently not handled for that MC version."); Settings.TerrainAndMovements = 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, ref ForgeInfo forgeInfo) { 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); Protocol18Handler ComTmp = new Protocol18Handler(tcp); int packetLength = ComTmp.readNextVarIntRAW(); if (packetLength > 0) //Read Response length { List<byte> packetData = new List<byte>(ComTmp.readDataRAW(packetLength)); if (readNextVarInt(packetData) == 0x00) //Read Packet ID { string result = 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 = atoi(versionData.Properties["protocol"].StringValue); //Automatic fix for BungeeCord 1.8 reporting itself as 1.7... if (protocolversion < 47 && version.Split(' ', '/').Contains("1.8")) protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0"); // Check for forge on the server. if (jsonData.Properties.ContainsKey("modinfo") && jsonData.Properties["modinfo"].Type == Json.JSONData.DataType.Object) { Json.JSONData modData = jsonData.Properties["modinfo"]; if (modData.Properties.ContainsKey("type") && modData.Properties["type"].StringValue == "FML") { forgeInfo = new ForgeInfo(modData); if (forgeInfo.Mods.Any()) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Server is running Forge. Mod list:"); foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods) { ConsoleIO.WriteLineFormatted("§8 " + mod.ToString()); } } else ConsoleIO.WriteLineFormatted("§8Server is running Forge."); } else forgeInfo = null; } } ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + (forgeInfo != null ? ", with Forge)." : ").")); return true; } } } } return false; }
/// <summary> /// Retrieve information about a Minecraft server /// </summary> /// <param name="serverIP">Server IP to ping</param> /// <param name="serverPort">Server Port to ping</param> /// <param name="protocolversion">Will contain protocol version, if ping successful</param> /// <returns>TRUE if ping was successful</returns> public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion, ref ForgeInfo forgeInfo) { bool success = false; int protocolversionTmp = 0; ForgeInfo forgeInfoTmp = null; if (AutoTimeout.Perform(() => { try { if (Protocol16Handler.doPing(serverIP, serverPort, ref protocolversionTmp) || Protocol18Handler.doPing(serverIP, serverPort, ref protocolversionTmp, ref forgeInfoTmp)) { success = true; } else ConsoleIO.WriteLineFormatted("§8Unexpected response from the server (is that a Minecraft server?)"); } catch (Exception e) { ConsoleIO.WriteLineFormatted(String.Format("§8{0}: {1}", e.GetType().FullName, e.Message)); } }, TimeSpan.FromSeconds(30))) { protocolversion = protocolversionTmp; forgeInfo = forgeInfoTmp; return success; } else { ConsoleIO.WriteLineFormatted("§8A timeout occured while attempting to connect to this IP."); return false; } }
/// <summary> /// Get a protocol handler for the specified Minecraft version /// </summary> /// <param name="Client">Tcp Client connected to the server</param> /// <param name="ProtocolVersion">Protocol version to handle</param> /// <param name="Handler">Handler with the appropriate callbacks</param> /// <returns></returns> public static IMinecraftCom getProtocolHandler(TcpClient Client, int ProtocolVersion, ForgeInfo forgeInfo, IMinecraftComHandler Handler) { int[] supportedVersions_Protocol16 = { 51, 60, 61, 72, 73, 74, 78 }; if (Array.IndexOf(supportedVersions_Protocol16, ProtocolVersion) > -1) return new Protocol16Handler(Client, ProtocolVersion, Handler); int[] supportedVersions_Protocol18 = { 4, 5, 47, 107 }; if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1) return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo); throw new NotSupportedException("The protocol version no." + ProtocolVersion + " is not supported."); }
/// <summary> /// Starts the main chat client in single command sending mode /// </summary> /// <param name="username">The chosen username of a premium Minecraft Account</param> /// <param name="uuid">The player's UUID for online-mode authentication</param> /// <param name="sessionID">A valid sessionID obtained after logging in</param> /// <param name="server_ip">The server IP</param> /// <param name="port">The server port to use</param> /// <param name="protocolversion">Minecraft protocol version to use</param> /// <param name="command">The text or command to send.</param> public McTcpClient(string username, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, string command) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, forgeInfo, true, command); }
/// <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) { bool retry = false; 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()); } if (Settings.AutoRespond_Enabled) { BotLoad(new ChatBots.AutoRespond(Settings.AutoRespond_Matches)); } } 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 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 (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> /// Starts the main chat client /// </summary> /// <param name="username">The chosen username of a premium Minecraft Account</param> /// <param name="uuid">The player's UUID for online-mode authentication</param> /// <param name="sessionID">A valid sessionID obtained after logging in</param> /// <param name="server_ip">The server IP</param> /// <param name="port">The server port to use</param> /// <param name="protocolversion">Minecraft protocol version to use</param> public McTcpClient(string username, string uuid, string sessionID, int protocolversion, ForgeInfo forgeInfo, string server_ip, ushort port) { StartClient(username, uuid, sessionID, server_ip, port, protocolversion, forgeInfo, false, ""); }