/// <summary> /// Start a new Client /// </summary> private static void InitializeClient() { SessionToken session = new SessionToken(); ProtocolHandler.LoginResult result = ProtocolHandler.LoginResult.LoginRequired; if (Settings.Password == "-") { Translations.WriteLineFormatted("mcc.offline"); result = ProtocolHandler.LoginResult.Success; session.PlayerID = "0"; session.PlayerName = Settings.Login; } else { // Validate cached session or login new session. if (Settings.SessionCaching != CacheType.None && SessionCache.Contains(Settings.Login.ToLower())) { session = SessionCache.Get(Settings.Login.ToLower()); result = ProtocolHandler.GetTokenValidation(session); if (result != ProtocolHandler.LoginResult.Success) { Translations.WriteLineFormatted("mcc.session_invalid"); if (Settings.Password == "") { RequestPassword(); } } else { ConsoleIO.WriteLineFormatted(Translations.Get("mcc.session_valid", session.PlayerName)); } } if (result != ProtocolHandler.LoginResult.Success) { Translations.WriteLine("mcc.connecting", Settings.AccountType == ProtocolHandler.AccountType.Mojang ? "Minecraft.net" : "Microsoft"); result = ProtocolHandler.GetLogin(Settings.Login, Settings.Password, Settings.AccountType, out session); if (result == ProtocolHandler.LoginResult.Success && Settings.SessionCaching != CacheType.None) { SessionCache.Store(Settings.Login.ToLower(), session); } } } if (result == ProtocolHandler.LoginResult.Success) { Settings.Username = session.PlayerName; bool isRealms = false; if (Settings.ConsoleTitle != "") { Console.Title = Settings.ExpandVars(Settings.ConsoleTitle); } if (Settings.playerHeadAsIcon) { ConsoleIcon.setPlayerIconAsync(Settings.Username); } if (Settings.DebugMessages) { Translations.WriteLine("debug.session_id", session.ID); } List <string> availableWorlds = new List <string>(); if (Settings.MinecraftRealmsEnabled && !String.IsNullOrEmpty(session.ID)) { availableWorlds = ProtocolHandler.RealmsListWorlds(Settings.Username, session.PlayerID, session.ID); } if (Settings.ServerIP == "") { Translations.Write("mcc.ip"); string addressInput = Console.ReadLine(); if (addressInput.StartsWith("realms:")) { if (Settings.MinecraftRealmsEnabled) { if (availableWorlds.Count == 0) { HandleFailure(Translations.Get("error.realms.access_denied"), false, ChatBot.DisconnectReason.LoginRejected); return; } int worldIndex = 0; string worldId = addressInput.Split(':')[1]; if (!availableWorlds.Contains(worldId) && int.TryParse(worldId, out worldIndex) && worldIndex < availableWorlds.Count) { worldId = availableWorlds[worldIndex]; } if (availableWorlds.Contains(worldId)) { string RealmsAddress = ProtocolHandler.GetRealmsWorldServerAddress(worldId, Settings.Username, session.PlayerID, session.ID); if (RealmsAddress != "") { addressInput = RealmsAddress; isRealms = true; Settings.ServerVersion = MCHighestVersion; } else { HandleFailure(Translations.Get("error.realms.server_unavailable"), false, ChatBot.DisconnectReason.LoginRejected); return; } } else { HandleFailure(Translations.Get("error.realms.server_id"), false, ChatBot.DisconnectReason.LoginRejected); return; } } else { HandleFailure(Translations.Get("error.realms.disabled"), false, null); return; } } Settings.SetServerIP(addressInput); } //Get server version int protocolversion = 0; ForgeInfo forgeInfo = null; if (Settings.ServerVersion != "" && Settings.ServerVersion.ToLower() != "auto") { protocolversion = Protocol.ProtocolHandler.MCVer2ProtocolVersion(Settings.ServerVersion); if (protocolversion != 0) { ConsoleIO.WriteLineFormatted(Translations.Get("mcc.use_version", Settings.ServerVersion, protocolversion)); } else { ConsoleIO.WriteLineFormatted(Translations.Get("mcc.unknown_version", Settings.ServerVersion)); } if (useMcVersionOnce) { useMcVersionOnce = false; Settings.ServerVersion = ""; } } //Retrieve server info if version is not manually set OR if need to retrieve Forge information if (!isRealms && (protocolversion == 0 || Settings.ServerAutodetectForge || (Settings.ServerForceForge && !ProtocolHandler.ProtocolMayForceForge(protocolversion)))) { if (protocolversion != 0) { Translations.WriteLine("mcc.forge"); } else { Translations.WriteLine("mcc.retrieve"); } if (!ProtocolHandler.GetServerInfo(Settings.ServerIP, Settings.ServerPort, ref protocolversion, ref forgeInfo)) { HandleFailure(Translations.Get("error.ping"), true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); return; } } //Force-enable Forge support? if (!isRealms && Settings.ServerForceForge && forgeInfo == null) { if (ProtocolHandler.ProtocolMayForceForge(protocolversion)) { Translations.WriteLine("mcc.forgeforce"); forgeInfo = ProtocolHandler.ProtocolForceForge(protocolversion); } else { HandleFailure(Translations.Get("error.forgeforce"), true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); return; } } //Proceed to server login if (protocolversion != 0) { try { //Start the main TCP client if (Settings.SingleCommand != "") { client = new McClient(session.PlayerName, session.PlayerID, session.ID, Settings.ServerIP, Settings.ServerPort, protocolversion, forgeInfo, Settings.SingleCommand); } else { client = new McClient(session.PlayerName, session.PlayerID, session.ID, protocolversion, forgeInfo, Settings.ServerIP, Settings.ServerPort); } //Update console title if (Settings.ConsoleTitle != "") { Console.Title = Settings.ExpandVars(Settings.ConsoleTitle); } } catch (NotSupportedException) { HandleFailure(Translations.Get("error.unsupported"), true); } } else { HandleFailure(Translations.Get("error.determine"), true); } } else { string failureMessage = Translations.Get("error.login"); string failureReason = ""; switch (result) { case ProtocolHandler.LoginResult.AccountMigrated: failureReason = "error.login.migrated"; break; case ProtocolHandler.LoginResult.ServiceUnavailable: failureReason = "error.login.server"; break; case ProtocolHandler.LoginResult.WrongPassword: failureReason = "error.login.blocked"; break; case ProtocolHandler.LoginResult.InvalidResponse: failureReason = "error.login.response"; break; case ProtocolHandler.LoginResult.NotPremium: failureReason = "error.login.premium"; break; case ProtocolHandler.LoginResult.OtherError: failureReason = "error.login.network"; break; case ProtocolHandler.LoginResult.SSLError: failureReason = "error.login.ssl"; break; case ProtocolHandler.LoginResult.UserCancel: failureReason = "error.login.cancel"; break; default: failureReason = "error.login.unknown"; break; } failureMessage += Translations.Get(failureReason); if (result == ProtocolHandler.LoginResult.SSLError && isUsingMono) { Translations.WriteLineFormatted("error.login.ssl_help"); return; } HandleFailure(failureMessage, false, ChatBot.DisconnectReason.LoginRejected); } }
/// <summary> /// Handle fatal errors such as ping failure, login failure, server disconnection, and so on. /// Allows AutoRelog to perform on fatal errors, prompt for server version, and offline commands. /// </summary> /// <param name="errorMessage">Error message to display and optionally pass to AutoRelog bot</param> /// <param name="versionError">Specify if the error is related to an incompatible or unkown server version</param> /// <param name="disconnectReason">If set, the error message will be processed by the AutoRelog bot</param> public static void HandleFailure(string errorMessage = null, bool versionError = false, ChatBots.AutoRelog.DisconnectReason?disconnectReason = null) { if (!String.IsNullOrEmpty(errorMessage)) { ConsoleIO.Reset(); while (Console.KeyAvailable) { Console.ReadKey(true); } Console.WriteLine(errorMessage); if (disconnectReason.HasValue) { if (ChatBots.AutoRelog.OnDisconnectStatic(disconnectReason.Value, errorMessage)) { return; //AutoRelog is triggering a restart of the client } } } if (Settings.interactiveMode) { if (versionError) { Translations.Write("mcc.server_version"); Settings.ServerVersion = Console.ReadLine(); if (Settings.ServerVersion != "") { useMcVersionOnce = true; Restart(); return; } } if (offlinePrompt == null) { offlinePrompt = new Thread(new ThreadStart(delegate { string command = " "; ConsoleIO.WriteLineFormatted(Translations.Get("mcc.disconnected", (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar))); Translations.WriteLineFormatted("mcc.press_exit"); while (command.Length > 0) { if (!ConsoleIO.BasicIO) { ConsoleIO.Write('>'); } command = Console.ReadLine().Trim(); if (command.Length > 0) { string message = ""; if (Settings.internalCmdChar != ' ' && command[0] == Settings.internalCmdChar) { command = command.Substring(1); } if (command.StartsWith("reco")) { message = new Commands.Reco().Run(null, Settings.ExpandVars(command), null); } else if (command.StartsWith("connect")) { message = new Commands.Connect().Run(null, Settings.ExpandVars(command), null); } else if (command.StartsWith("exit") || command.StartsWith("quit")) { message = new Commands.Exit().Run(null, Settings.ExpandVars(command), null); } else if (command.StartsWith("help")) { ConsoleIO.WriteLineFormatted("§8MCC: " + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + new Commands.Reco().GetCmdDescTranslated()); ConsoleIO.WriteLineFormatted("§8MCC: " + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + new Commands.Connect().GetCmdDescTranslated()); } else { ConsoleIO.WriteLineFormatted(Translations.Get("icmd.unknown", command.Split(' ')[0])); } if (message != "") { ConsoleIO.WriteLineFormatted("§8MCC: " + message); } } } })); offlinePrompt.Start(); } } else { // Not in interactive mode, just exit and let the calling script handle the failure if (disconnectReason.HasValue) { // Return distinct exit codes for known failures. if (disconnectReason.Value == ChatBot.DisconnectReason.UserLogout) { Exit(1); } if (disconnectReason.Value == ChatBot.DisconnectReason.InGameKick) { Exit(2); } if (disconnectReason.Value == ChatBot.DisconnectReason.ConnectionLost) { Exit(3); } if (disconnectReason.Value == ChatBot.DisconnectReason.LoginRejected) { Exit(4); } } Exit(); } }
/// <summary> /// Start a new Client /// </summary> private static void InitializeClient() { SessionToken session = new SessionToken(); ProtocolHandler.LoginResult result = ProtocolHandler.LoginResult.LoginRequired; if (Settings.Password == "-") { Translations.WriteLineFormatted("mcc.offline"); result = ProtocolHandler.LoginResult.Success; session.PlayerID = "0"; session.PlayerName = Settings.Login; } else { // Validate cached session or login new session. if (Settings.SessionCaching != CacheType.None && SessionCache.Contains(Settings.Login.ToLower())) { session = SessionCache.Get(Settings.Login.ToLower()); result = ProtocolHandler.GetTokenValidation(session); if (result != ProtocolHandler.LoginResult.Success) { Translations.WriteLineFormatted("mcc.session_invalid"); if (Settings.Password == "") { RequestPassword(); } } else { ConsoleIO.WriteLineFormatted(Translations.Get("mcc.session_valid", session.PlayerName)); } } if (result != ProtocolHandler.LoginResult.Success) { Translations.WriteLine("mcc.connecting"); result = ProtocolHandler.GetLogin(Settings.Login, Settings.Password, out session); if (result == ProtocolHandler.LoginResult.Success && Settings.SessionCaching != CacheType.None) { SessionCache.Store(Settings.Login.ToLower(), session); } } } if (result == ProtocolHandler.LoginResult.Success) { Settings.Username = session.PlayerName; if (Settings.ConsoleTitle != "") { Console.Title = Settings.ExpandVars(Settings.ConsoleTitle); } if (Settings.playerHeadAsIcon) { ConsoleIcon.setPlayerIconAsync(Settings.Username); } if (Settings.DebugMessages) { Translations.WriteLine("debug.session_id", session.ID); } //ProtocolHandler.RealmsListWorlds(Settings.Username, PlayerID, sessionID); //TODO REMOVE if (Settings.ServerIP == "") { Translations.Write("mcc.ip"); Settings.SetServerIP(Console.ReadLine()); } //Get server version int protocolversion = 0; ForgeInfo forgeInfo = null; if (Settings.ServerVersion != "" && Settings.ServerVersion.ToLower() != "auto") { protocolversion = Protocol.ProtocolHandler.MCVer2ProtocolVersion(Settings.ServerVersion); if (protocolversion != 0) { ConsoleIO.WriteLineFormatted(Translations.Get("mcc.use_version", Settings.ServerVersion, protocolversion)); } else { ConsoleIO.WriteLineFormatted(Translations.Get("mcc.unknown_version", Settings.ServerVersion)); } if (useMcVersionOnce) { useMcVersionOnce = false; Settings.ServerVersion = ""; } } if (protocolversion == 0 || Settings.ServerMayHaveForge) { if (protocolversion != 0) { Translations.WriteLine("mcc.forge"); } else { Translations.WriteLine("mcc.retrieve"); } if (!ProtocolHandler.GetServerInfo(Settings.ServerIP, Settings.ServerPort, ref protocolversion, ref forgeInfo)) { HandleFailure(Translations.Get("error.ping"), true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); return; } } if (protocolversion != 0) { try { //Start the main TCP client if (Settings.SingleCommand != "") { client = new McClient(session.PlayerName, session.PlayerID, session.ID, Settings.ServerIP, Settings.ServerPort, protocolversion, forgeInfo, Settings.SingleCommand); } else { client = new McClient(session.PlayerName, session.PlayerID, session.ID, protocolversion, forgeInfo, Settings.ServerIP, Settings.ServerPort); } //Update console title if (Settings.ConsoleTitle != "") { Console.Title = Settings.ExpandVars(Settings.ConsoleTitle); } } catch (NotSupportedException) { HandleFailure(Translations.Get("error.unsupported"), true); } } else { HandleFailure(Translations.Get("error.determine"), true); } } else { string failureMessage = Translations.Get("error.login"); string failureReason = ""; switch (result) { case ProtocolHandler.LoginResult.AccountMigrated: failureReason = "error.login.migrated"; break; case ProtocolHandler.LoginResult.ServiceUnavailable: failureReason = "error.login.server"; break; case ProtocolHandler.LoginResult.WrongPassword: failureReason = "error.login.blocked"; break; case ProtocolHandler.LoginResult.InvalidResponse: failureReason = "error.login.response"; break; case ProtocolHandler.LoginResult.NotPremium: failureReason = "error.login.premium"; break; case ProtocolHandler.LoginResult.OtherError: failureReason = "error.login.network"; break; case ProtocolHandler.LoginResult.SSLError: failureReason = "error.login.ssl"; break; default: failureReason = "error.login.unknown"; break; } failureMessage += Translations.Get(failureReason); if (result == ProtocolHandler.LoginResult.SSLError && isUsingMono) { Translations.WriteLineFormatted("error.login.ssl_help"); return; } HandleFailure(failureMessage, false, ChatBot.DisconnectReason.LoginRejected); } }