protected bool DoWorldConnect() { Monitor.Enter(scene); try { // Set up the mask window, so that they don't see the loading loadWindow.Visible = true; xmlUiWindow.Visible = false; MessageDispatcher.Instance.ClearQueue(); Monitor.Enter(worldManager); string clientVersion = this.Version; try { string worldId = loginSettings.worldId; WorldServerEntry entry; Boolean reconnect = (worldId != networkHelper.connectedWorldId); NetworkHelperStatus status = NetworkHelperStatus.Success; worldManager.ClearWorld(); if (reconnect) { networkHelper.Disconnect(); //if (useLocalWorld) // worldId = "local_world"; if (!networkHelper.HasWorldEntry(loginSettings.worldId)) networkHelper.ResolveWorld(loginSettings); entry = networkHelper.GetWorldEntry(loginSettings.worldId); status = networkHelper.ConnectToLogin(loginSettings.worldId, clientVersion); if (status == NetworkHelperStatus.UnsupportedClientVersion) { // Temporary workaround to handle version with the 1.1 server. // Unfortunately, the 1.1 server does not handle newer client numbers. log.InfoFormat("Attempting to connect as a 1.1 client"); clientVersion = "1.1"; networkHelper.Disconnect(); status = networkHelper.ConnectToLogin(loginSettings.worldId, clientVersion); } if (status == NetworkHelperStatus.WorldTcpConnectFailure) { errorMessage = "Unable to connect to tcp world server"; errorPage = "unable_connect_tcp_world.htm"; return false; } else if (status == NetworkHelperStatus.UnsupportedClientVersion) { errorMessage = "Server does not support this version"; errorPage = "unable_connect_tcp_world.htm"; return false; } } else { entry = networkHelper.GetWorldEntry(loginSettings.worldId); } foreach (Dictionary<string, object> c in networkHelper.CharacterEntries) { log.Info("Character: "); foreach (string attr in c.Keys) log.InfoFormat(" '{0}' => '{1}'", attr, c[attr]); } // We need to hook our message filter, whether or not we are // standalone, so instead of doing it later (right before // RdpWorldConnect), do it here. RequireLoginFilter checkAndHandleLogin = new RequireLoginFilter(worldManager); MessageDispatcher.Instance.SetWorldMessageFilter(checkAndHandleLogin.ShouldQueue); if (entry.StartupScript != null) UiScripting.RunFile(entry.StartupScript, "Standalone"); if (status != NetworkHelperStatus.Success && status != NetworkHelperStatus.Standalone) { log.InfoFormat("World Connect Status: {0}", status); errorMessage = "Unable to connect to server"; return false; } if (status != NetworkHelperStatus.Standalone && !useLocalWorld) { CharacterEntry charEntry; if (loginSettings.characterId > 0) { log.InfoFormat("Selecting character with id: {0}", loginSettings.characterId); charEntry = SelectCharacter(networkHelper.CharacterEntries, loginSettings.characterId); } else { log.Warn("Selecting first character in list of characters (deprecated)"); // just grab the first charEntry = SelectAnyCharacter(networkHelper.CharacterEntries); } string proxyHostname = charEntry.Hostname; int proxyPort = charEntry.Port; if (proxyHostname == null) { NetworkHelperStatus tokenStatus = networkHelper.GetProxyToken(charEntry.CharacterId); proxyHostname = networkHelper.ProxyPluginHost; proxyPort = networkHelper.ProxyPluginPort; } networkHelper.DisconnectFromLogin(); string actualHost = proxyHostname; if (actualHost == ":same") actualHost = NetworkHelper.Instance.LoginPluginHost; status = networkHelper.ConnectToWorld(charEntry.CharacterId, actualHost, proxyPort, clientVersion + ", " + ClientCapabilities); if (status != NetworkHelperStatus.Success) { log.InfoFormat("World Connect Status: {0}", status); return false; } } ClientAPI.OnWorldConnect(); } finally { Monitor.Exit(worldManager); } // We use the null setting to indicate that we haven't logged in, so // we need to reset it back to null before the connect. loginMessage = null; // At this point, the network helper can start handling messages. if (!WaitForStartupMessages()) { if (loginFailed && loginMessage != null) // The server rejected our login errorMessage = loginMessage; else if (loginMessage != null) // our login went ok (and we got something back), but something else (terrain/player) failed errorMessage = "Unable to communicate with server"; else errorMessage = "Unable to connect to server"; return false; } } catch (Exception ex) { LogUtil.ExceptionLog.WarnFormat("Got an exception in world connect: {0}", ex); } finally { Monitor.Exit(scene); } return true; }
/// <summary> /// Overridden to switch to event based keyboard input. /// </summary> /// <returns></returns> protected bool Setup() { #if USE_PERFORMANCE_COUNTERS SetupPerformanceCategories(); CreateCounters(); #endif this.Tick += new TickEvent(OnTick); worldManager = new WorldManager(verifyServer, behaviorParms); NetworkHelper helper = new NetworkHelper(worldManager); if (this.LoopbackWorldServerEntry != null) { string worldId = this.LoopbackWorldServerEntry.WorldName; // Bypass the login and connection to master server loginSettings.worldId = worldId; helper.SetWorldEntry(worldId, this.LoopbackWorldServerEntry); helper.AuthToken = this.LoopbackIdToken; } networkHelper = helper; // Sets up the various things attached to the world manager, // as well as registering the various message handlers. // This also initializes the networkHelper. worldManager.Init(this); // Register our handlers. We must do this before we call // MessageDispatcher.Instance.HandleMessageQueue, so that we will // get the callbacks for the incoming messages. #if NOT // NOTE: Test client isn't advanced enough to handle these. // Register our handler for the Portal messages, so that we // can drop our connection to the world server, and establish a new // connection to the new world. MessageDispatcher.Instance.RegisterHandler(WorldMessageType.Portal, new MessageHandler(this.HandlePortal)); // Register our handler for the UiTheme messages, so that we // can swap out the user interface. MessageDispatcher.Instance.RegisterHandler(WorldMessageType.UiTheme, new MessageHandler(this.HandleUiTheme)); #endif // Register our handler for the LoginResponse messages, so that we // can throw up a dialog if needed. MessageDispatcher.Instance.RegisterHandler(WorldMessageType.LoginResponse, new WorldMessageHandler(this.HandleLoginResponse)); if (!networkHelper.HasWorldEntry(loginSettings.worldId)) networkHelper.ResolveWorld(loginSettings); WorldServerEntry entry = networkHelper.GetWorldEntry(loginSettings.worldId); NetworkHelperStatus status = networkHelper.ConnectToLogin(loginSettings.worldId); // We need to hook our message filter, whether or not we are // standalone, so instead of doing it later (right before // RdpWorldConnect), do it here. RequireLoginFilter checkAndHandleLogin = new RequireLoginFilter(worldManager); MessageDispatcher.Instance.SetWorldMessageFilter(checkAndHandleLogin.ShouldQueue); if (status != NetworkHelperStatus.Success && status != NetworkHelperStatus.Standalone) { Trace.TraceInformation("World Connect Status: " + status); return false; } networkHelper.DisconnectFromLogin(); CharacterEntry charEntry = SelectCharacter(networkHelper.CharacterEntries, -1); status = networkHelper.ConnectToWorld(charEntry.CharacterId, charEntry.Hostname, charEntry.Port, this.Version); if (status != NetworkHelperStatus.Success) { Trace.TraceInformation("World Connect Status: " + status); return false; } // At this point, the network helper can start handling messages. if (!WaitForStartupMessages()) { if (loginFailed && loginMessage != null) // The server rejected our login throw new ClientException(loginMessage); else if (loginMessage != null) // our login went ok (and we got something back), but something else (terrain/player) failed throw new ClientException("Unable to communicate with server"); else throw new ClientException("Unable to connect to server"); } // At this point, I can have a camera // networkHelper.WorldManager = worldManager; // inputHandler.InitViewpoint(worldManager.Player); Logger.Log(4, "Client setup complete: " + DateTime.Now); // At this point, you can create timer events. return true; }