예제 #1
0
        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;
        }