private void LoginReplyHandler(CapsClient client, OSD result, Exception error)
{
if (error == null)
{
if (result != null && result.Type == OSDType.Map)
{
OSDMap map = (OSDMap)result;
OSD osd;
string reason, message;
if (map.TryGetValue("reason", out osd))
reason = osd.AsString();
else
reason = String.Empty;
if (map.TryGetValue("message", out osd))
message = osd.AsString();
else
message = String.Empty;
if (map.TryGetValue("login", out osd))
{
bool loginSuccess = osd.AsBoolean();
bool redirect = (osd.AsString() == "indeterminate");
LoginResponseData data = new LoginResponseData();
data.Reason = reason;
data.Message = message;
if (redirect)
{
// Login redirected
// Make the next login URL jump
UpdateLoginStatus(LoginStatus.Redirecting, message);
LoginParams loginParams = CurrentContext.Value;
loginParams.URI = LoginResponseData.ParseString("next_url", map);
//CurrentContext.Params.MethodName = LoginResponseData.ParseString("next_method", map);
// Sleep for some amount of time while the servers work
int seconds = (int)LoginResponseData.ParseUInt("next_duration", map);
Logger.Log("Sleeping for " + seconds + " seconds during a login redirect",
Helpers.LogLevel.Info);
Thread.Sleep(seconds * 1000);
// Ignore next_options for now
CurrentContext = loginParams;
BeginLogin();
}
else if (loginSuccess)
{
// Login succeeded
// Parse successful login replies into LoginResponseData structs
data.Parse(map);
// These parameters are stored in NetworkManager, so instead of registering
// another callback for them we just set the values here
CircuitCode = data.CircuitCode;
LoginSeedCapability = data.SeedCapability;
SecureSessionID = data.SecureSessionID;
AssetServerUri = data.AssetServerUri;
Console.WriteLine("libomv secure session id: " + data.SecureSessionID);
Console.WriteLine("libomv assetserveruri: " + data.AssetServerUri);
// Fire the login callback
if (OnLoginResponse != null)
{
try { OnLoginResponse(loginSuccess, redirect, message, reason, data); }
catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); }
}
UpdateLoginStatus(LoginStatus.ConnectingToSim, "Connecting to simulator...");
ulong handle = Utils.UIntsToLong(data.RegionX, data.RegionY);
if (data.SimIP != null && data.SimPort != 0)
{
// Connect to the sim given in the login reply
if (Connect(data.SimIP, data.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) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
}
}
else
{
UpdateLoginStatus(LoginStatus.Failed,
"Unable to establish a UDP connection to the simulator");
}
}
else
{
UpdateLoginStatus(LoginStatus.Failed,
"Login server did not return a simulator address");
}
}
else
{
// Login failed
// Make sure a usable error key is set
if (reason != String.Empty)
InternalErrorKey = reason;
else
InternalErrorKey = "unknown";
UpdateLoginStatus(LoginStatus.Failed, message);
}
}
else
{
// Got an LLSD map but no login value
UpdateLoginStatus(LoginStatus.Failed, "login parameter missing in the response");
}
}
else
{
// No LLSD response
InternalErrorKey = "bad response";
UpdateLoginStatus(LoginStatus.Failed, "Empty or unparseable login response");
}
}
else
{
// Connection error
InternalErrorKey = "no connection";
UpdateLoginStatus(LoginStatus.Failed, error.Message);
}
}