private void LoginMethodCallback(IAsyncResult result) { object[] asyncState = result.AsyncState as object[]; LoginProxy proxy = asyncState[0] as LoginProxy; LoginContext context = asyncState[1] as LoginContext; XmlRpcAsyncResult clientResult = result as XmlRpcAsyncResult; LoginMethodResponse reply; IPAddress simIP = IPAddress.Any; // Temporary ushort simPort = 0; uint regionX = 0; uint regionY = 0; bool loginSuccess = false; // Fetch the login response try { reply = proxy.EndLoginToSimulator(clientResult); if (context != CurrentContext) { return; } } catch (Exception ex) { Client.DebugLog(ex.ToString()); UpdateLoginStatus(LoginStatus.Failed, "Error retrieving the login response from the server"); return; } string reason = reply.reason; string message = reply.message; if (reply.login == "true") { loginSuccess = true; // FIXME: No information should be set here, everything can take care of itself // through login reply handlers #region Critical Information try { // Networking Client.Network.CircuitCode = (uint)reply.circuit_code; regionX = (uint)reply.region_x; regionY = (uint)reply.region_y; simPort = (ushort)reply.sim_port; Helpers.TryParse(reply.sim_ip, out simIP); LoginSeedCapability = reply.seed_capability; } catch (Exception) { UpdateLoginStatus(LoginStatus.Failed, "Login server failed to return critical information"); return; } #endregion Critical Information } bool redirect = (reply.login == "indeterminate"); try { if (OnLoginResponse != null) { LoginResponseData data = new LoginResponseData(); if (loginSuccess) { data.Parse(reply); } try { OnLoginResponse(loginSuccess, redirect, message, reason, data); } catch (Exception ex) { Client.Log(ex.ToString(), Helpers.LogLevel.Error); } } } catch (Exception ex) { Client.Log(ex.ToString(), Helpers.LogLevel.Error); } // Make the next network jump, if needed if (redirect) { UpdateLoginStatus(LoginStatus.Redirecting, "Redirecting login..."); // Handle indeterminate logins CurrentContext.Params.URI = reply.next_url; CurrentContext.Params.MethodName = reply.next_method; // Ignore next_options and next_duration for now BeginLogin(); } else if (loginSuccess) { UpdateLoginStatus(LoginStatus.ConnectingToSim, "Connecting to simulator..."); ulong handle = Helpers.UIntsToLong(regionX, regionY); // Connect to the sim given in the login reply if (Connect(simIP, simPort, handle, true, LoginSeedCapability) != null) { // Request the economy data right after login SendPacket(new EconomyDataRequestPacket()); // Update the login message with the MOTD returned from the server UpdateLoginStatus(LoginStatus.Success, message); // Fire an event for connecting to the grid if (OnConnected != null) { try { OnConnected(this.Client); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } } else { UpdateLoginStatus(LoginStatus.Failed, "Unable to connect to simulator"); } } else { // Make sure a usable error key is set if (!String.IsNullOrEmpty(reason)) { InternalErrorKey = reason; } else { InternalErrorKey = "unknown"; } UpdateLoginStatus(LoginStatus.Failed, message); } }