/// <summary> /// Populate FriendList <seealso cref="InternalDictionary"/> with data from the login reply /// </summary> /// <param name="loginSuccess">true if login was successful</param> /// <param name="redirect">true if login request is requiring a redirect</param> /// <param name="message">A string containing the response to the login request</param> /// <param name="reason">A string containing the reason for the request</param> /// <param name="replyData">A <seealso cref="LoginResponseData"/> object containing the decoded /// reply from the login server</param> private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { int uuidLength = UUID.Zero.ToString().Length; if (loginSuccess && replyData.BuddyList != null) { foreach (BuddyListEntry buddy in replyData.BuddyList) { UUID bubid; string id = buddy.buddy_id.Length > uuidLength?buddy.buddy_id.Substring(0, uuidLength) : buddy.buddy_id; if (UUID.TryParse(id, out bubid)) { lock (FriendList.Dictionary) { if (!FriendList.ContainsKey(bubid)) { FriendList[bubid] = new FriendInfo(bubid, (FriendRights)buddy.buddy_rights_given, (FriendRights)buddy.buddy_rights_has); } } } } } }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess && replyData.BuddyList != null) { lock (FriendList) { for (int i = 0; i < replyData.BuddyList.Length; i++) { FriendInfo friend = replyData.BuddyList[i]; FriendList[friend.UUID] = friend; } } } }
/// <summary> /// Populate FriendList <seealso cref="InternalDictionary"/> with data from the login reply /// </summary> /// <param name="loginSuccess">true if login was successful</param> /// <param name="redirect">true if login request is requiring a redirect</param> /// <param name="message">A string containing the response to the login request</param> /// <param name="reason">A string containing the reason for the request</param> /// <param name="replyData">A <seealso cref="LoginResponseData"/> object containing the decoded /// reply from the login server</param> private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess && replyData.BuddyList != null) { if (replyData.BuddyList != null) { foreach (BuddyListEntry buddy in replyData.BuddyList) { UUID bubid = UUID.Parse(buddy.buddy_id); lock (FriendList.Dictionary) { if (!FriendList.ContainsKey(bubid)) { FriendList.Add(bubid, new FriendInfo(UUID.Parse(buddy.buddy_id), (FriendRights)buddy.buddy_rights_given, (FriendRights)buddy.buddy_rights_has)); } } } } } }
/// <summary> /// Handle response from LLSD login replies /// </summary> /// <param name="client"></param> /// <param name="result"></param> /// <param name="error"></param> private void LoginReplyLLSDHandler(CapsClient client, OSD result, Exception error) { if (error == null) { if (result != null && result.Type == OSDType.Map) { OSDMap map = (OSDMap)result; OSD osd; LoginResponseData data = new LoginResponseData(); data.Parse(map); if (map.TryGetValue("login", out osd)) { bool loginSuccess = osd.AsBoolean(); bool redirect = (osd.AsString() == "indeterminate"); if (redirect) { // Login redirected // Make the next login URL jump UpdateLoginStatus(LoginStatus.Redirecting, data.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 // Fire the login callback if (OnLoginResponse != null) { try { OnLoginResponse(loginSuccess, redirect, data.Message, data.Reason, data); } catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } } // These parameters are stored in NetworkManager, so instead of registering // another callback for them we just set the values here CircuitCode = (uint)data.CircuitCode; LoginSeedCapability = data.SeedCapability; UpdateLoginStatus(LoginStatus.ConnectingToSim, "Connecting to simulator..."); ulong handle = Utils.UIntsToLong((uint)data.RegionX, (uint)data.RegionY); if (data.SimIP != null && data.SimPort != 0) { // Connect to the sim given in the login reply if (Connect(data.SimIP, (ushort)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, data.Message); } 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 (data.Reason != String.Empty) InternalErrorKey = data.Reason; else InternalErrorKey = "unknown"; UpdateLoginStatus(LoginStatus.Failed, data.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); } }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData reply) { id = reply.AgentID; sessionID = reply.SessionID; secureSessionID = reply.SecureSessionID; firstName = reply.FirstName; lastName = reply.LastName; startLocation = reply.StartLocation; agentAccess = reply.AgentAccess; Movement.Camera.LookDirection(reply.LookAt); homePosition = reply.HomePosition; homeLookAt = reply.HomeLookAt; }
/// <summary> /// Handles response from XML-RPC login replies /// </summary> private void LoginReplyXmlRpcHandler(XmlRpcResponse response, LoginParams context) { LoginResponseData reply = new LoginResponseData(); ushort simPort = 0; uint regionX = 0; uint regionY = 0; // Fetch the login response if (response == null || !(response.Value is Hashtable)) { UpdateLoginStatus(LoginStatus.Failed, "Invalid or missing login response from the server"); Logger.Log("Invalid or missing login response from the server", Helpers.LogLevel.Warning); return; } try { reply.Parse((Hashtable)response.Value); if (context.LoginID != CurrentContext.Value.LoginID) { Logger.Log("Login response does not match login request. Only one login can be attempted at a time", Helpers.LogLevel.Error); return; } } catch (Exception e) { UpdateLoginStatus(LoginStatus.Failed, "Error retrieving the login response from the server: " + e.Message); Logger.Log("Login response failure: " + e.Message + " " + e.StackTrace, Helpers.LogLevel.Warning); return; } string reason = reply.Reason; string message = reply.Message; if (reply.Login == "true") { // Remove the quotes around our first name. if (reply.FirstName[0] == '"') reply.FirstName = reply.FirstName.Remove(0, 1); if (reply.FirstName[reply.FirstName.Length - 1] == '"') reply.FirstName = reply.FirstName.Remove(reply.FirstName.Length - 1); #region Critical Information try { // Networking Client.Network.CircuitCode = (uint)reply.CircuitCode; regionX = (uint)reply.RegionX; regionY = (uint)reply.RegionY; simPort = (ushort)reply.SimPort; LoginSeedCapability = reply.SeedCapability; } catch (Exception) { UpdateLoginStatus(LoginStatus.Failed, "Login server failed to return critical information"); return; } #endregion Critical Information /* Add any blacklisted UDP packets to the blacklist * for exclusion from packet processing */ if (reply.UDPBlacklist != null) UDPBlacklist.AddRange(reply.UDPBlacklist.Split(',')); // Misc: //uint timestamp = (uint)reply.seconds_since_epoch; //DateTime time = Helpers.UnixTimeToDateTime(timestamp); // TODO: Do something with this? // Unhandled: // reply.gestures // reply.event_categories // reply.classified_categories // reply.event_notifications // reply.ui_config // reply.login_flags // reply.global_textures // reply.inventory_lib_root // reply.inventory_lib_owner // reply.inventory_skeleton // reply.inventory_skel_lib // reply.initial_outfit } bool redirect = (reply.Login == "indeterminate"); try { if (OnLoginResponse != null) { try { OnLoginResponse(reply.Success, redirect, message, reason, reply); } catch (Exception ex) { Logger.Log(ex.ToString(), Helpers.LogLevel.Error); } } } catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, ex); } // Make the next network jump, if needed if (redirect) { UpdateLoginStatus(LoginStatus.Redirecting, "Redirecting login..."); LoginParams loginParams = CurrentContext.Value; loginParams.URI = reply.NextUrl; loginParams.MethodName = reply.NextMethod; loginParams.Options = reply.NextOptions; // Sleep for some amount of time while the servers work int seconds = reply.NextDuration; Logger.Log("Sleeping for " + seconds + " seconds during a login redirect", Helpers.LogLevel.Info); Thread.Sleep(seconds * 1000); CurrentContext = loginParams; BeginLogin(); } else if (reply.Success) { UpdateLoginStatus(LoginStatus.ConnectingToSim, "Connecting to simulator..."); ulong handle = Utils.UIntsToLong(regionX, regionY); // Connect to the sim given in the login reply if (Connect(reply.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); } 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); } }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess) { // Initialize the store here so we know who owns it: _Store = new Inventory(Client, this, Client.Self.AgentID); Logger.DebugLog("Setting InventoryRoot to " + replyData.InventoryRoot.ToString(), Client); InventoryFolder rootFolder = new InventoryFolder(replyData.InventoryRoot); rootFolder.Name = String.Empty; rootFolder.ParentUUID = UUID.Zero; _Store.RootFolder = rootFolder; for (int i = 0; i < replyData.InventorySkeleton.Length; i++) _Store.UpdateNodeFor(replyData.InventorySkeleton[i]); InventoryFolder libraryRootFolder = new InventoryFolder(replyData.LibraryRoot); libraryRootFolder.Name = String.Empty; libraryRootFolder.ParentUUID = UUID.Zero; _Store.LibraryFolder = libraryRootFolder; for (int i = 0; i < replyData.LibrarySkeleton.Length; i++) _Store.UpdateNodeFor(replyData.LibrarySkeleton[i]); } }
public void RegisterLoginResponseHandler(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (OnRegisterLoginRespons != null) OnRegisterLoginRespons(loginSuccess, redirect, message, reason, replyData); }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess && replyData.BuddyList != null) { lock (FriendList) { for (int i = 0; i < replyData.BuddyList.Length; i++) { FriendInfo friend = replyData.BuddyList[i]; FriendList[friend.UUID] = friend; } } } }
/// <summary> /// Populate FriendList <seealso cref="InternalDictionary"/> with data from the login reply /// </summary> /// <param name="loginSuccess">true if login was successful</param> /// <param name="redirect">true if login request is requiring a redirect</param> /// <param name="message">A string containing the response to the login request</param> /// <param name="reason">A string containing the reason for the request</param> /// <param name="replyData">A <seealso cref="LoginResponseData"/> object containing the decoded /// reply from the login server</param> private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { int uuidLength = UUID.Zero.ToString().Length; if (loginSuccess && replyData.BuddyList != null) { foreach (BuddyListEntry buddy in replyData.BuddyList) { UUID bubid; string id = buddy.buddy_id.Length > uuidLength ? buddy.buddy_id.Substring(0, uuidLength) : buddy.buddy_id; if (UUID.TryParse(id, out bubid)) { lock (FriendList.Dictionary) { if (!FriendList.ContainsKey(bubid)) { FriendList[bubid] = new FriendInfo(bubid, (FriendRights)buddy.buddy_rights_given, (FriendRights)buddy.buddy_rights_has); } } } } } }
private void RegisterLoginResponseHandler(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { Vector3D forward = new Vector3D(1, 0, 0); Vector3D target = new Vector3D(replyData.LookAt.X, replyData.LookAt.Z, replyData.LookAt.Y); float radHeading = forward.DotProduct(target); Reference.Viewer.AvatarManager.RadHeading = radHeading * (float)Math.PI; }
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); // 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); } } // 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; 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); } }
LoginResponseData HandleLogin(string firstName, string lastName, string password, string start, string version, string channel) { LoginResponseData response = new LoginResponseData(); Agent agent; UUID agentID = Authentication.Authenticate(firstName, lastName, password); if (agentID != UUID.Zero) { // Authentication successful, create a login instance of this agent agent = Accounts.CreateInstance(agentID); if (agent != null) { // Assign a circuit code and insert the agent into the unassociatedAgents dictionary agent.CircuitCode = UDP.CreateCircuit(agent); agent.TickLastPacketReceived = Environment.TickCount; agent.LastLoginTime = Utils.DateTimeToUnixTime(DateTime.Now); // Get this machine's IP address IPHostEntry addresses = Dns.GetHostByName(Dns.GetHostName()); IPAddress simIP = addresses.AddressList.Length > 0 ? addresses.AddressList[0] : IPAddress.Loopback; response.AgentID = agent.AgentID; response.SecureSessionID = agent.SecureSessionID; response.SessionID = agent.SessionID; response.CircuitCode = agent.CircuitCode; response.AgentAccess = agent.AccessLevel; response.BuddyList = null; // FIXME: response.FirstName = agent.FirstName; response.HomeLookAt = agent.HomeLookAt; response.HomePosition = agent.HomePosition; response.HomeRegion = agent.HomeRegionHandle; response.InventoryRoot = agent.InventoryRoot; response.InventorySkeleton = null; // FIXME: response.LastName = agent.LastName; response.LibraryOwner = agent.InventoryLibraryOwner; response.LibraryRoot = agent.InventoryLibraryRoot; response.LibrarySkeleton = null; // FIXME: response.LookAt = agent.CurrentLookAt; response.Message = "Welcome to Simian"; response.Reason = String.Empty; uint regionX, regionY; Utils.LongToUInts(agent.CurrentRegionHandle, out regionX, out regionY); response.RegionX = regionX; response.RegionY = regionY; response.SecondsSinceEpoch = DateTime.Now; // FIXME: Actually generate a seed capability response.SeedCapability = String.Format("http://{0}:{1}/seed_caps", simIP, HttpPort); response.SimIP = simIP; response.SimPort = (ushort)UDPPort; response.StartLocation = "last"; // FIXME: response.Success = true; } else { // Something went wrong creating an agent instance, return a fail response response.AgentID = agentID; response.FirstName = firstName; response.LastName = lastName; response.Message = "Failed to create an account instance"; response.Reason = "account"; response.Success = false; } } else { // Authentication failed, return a fail response response.AgentID = agentID; response.FirstName = firstName; response.LastName = lastName; response.Message = "Authentication failed"; response.Reason = "key"; response.Success = false; } return response; }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess) { if (Settings.ENABLE_INVENTORY_STORE) { InventorySkeleton = new InventorySkeleton(replyData.InventoryRoot, replyData.AgentID); InventorySkeleton.Folders = replyData.InventoryFolders; } if (Settings.ENABLE_LIBRARY_STORE) { LibrarySkeleton = new InventorySkeleton(replyData.LibraryRoot, replyData.LibraryOwner); LibrarySkeleton.Folders = replyData.LibraryFolders; } if (OnSkeletonsReceived != null) { try { OnSkeletonsReceived(this); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } } }
/// <summary> /// Handles response from XML-RPC login replies /// </summary> private void LoginReplyXmlRpcHandler(XmlRpcResponse response, LoginParams context) { LoginResponseData reply = new LoginResponseData(); // Fetch the login response if (response == null || !(response.Value is Hashtable)) { UpdateLoginStatus(LoginStatus.Failed, "Invalid or missing login response from the server"); Logger.Log("Invalid or missing login response from the server", Helpers.LogLevel.Warning); return; } try { reply.Parse((Hashtable)response.Value); if (context.LoginID != CurrentContext.LoginID) { Logger.Log("Login response does not match login request. Only one login can be attempted at a time", Helpers.LogLevel.Error); return; } } catch (Exception e) { UpdateLoginStatus(LoginStatus.Failed, "Error retrieving the login response from the server: " + e.Message); Logger.Log("Login response failure: " + e.Message + " " + e.StackTrace, Helpers.LogLevel.Warning); return; } LoginReplyXmlRpcHandler(reply, context); }
/// <summary> /// LoginParams and the initial login XmlRpcRequest were made on a remote machine. /// This method now initializes libomv with the results. /// </summary> public void RemoteLoginHandler(LoginResponseData response, LoginParams newContext) { CurrentContext = newContext; LoginReplyXmlRpcHandler(response, newContext); }
/// <summary> /// Populate FriendList <seealso cref="InternalDictionary"/> with data from the login reply /// </summary> /// <param name="loginSuccess">true if login was successful</param> /// <param name="redirect">true if login request is requiring a redirect</param> /// <param name="message">A string containing the response to the login request</param> /// <param name="reason">A string containing the reason for the request</param> /// <param name="replyData">A <seealso cref="LoginResponseData"/> object containing the decoded /// reply from the login server</param> private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess && replyData.BuddyList != null) { if (replyData.BuddyList != null) { foreach (BuddyListEntry buddy in replyData.BuddyList) { FriendList.Add(UUID.Parse(buddy.buddy_id), new FriendInfo(UUID.Parse(buddy.buddy_id), (FriendRights)buddy.buddy_rights_given, (FriendRights)buddy.buddy_rights_has)); } } } }