* Rex merges, Messaging server
							parent
							
								
									ce0d1132f8
								
							
						
					
					
						commit
						6f00175d89
					
				|  | @ -1,160 +1,157 @@ | |||
| /* | ||||
| * Copyright (c) Contributors, http://opensimulator.org/ | ||||
| * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions are met: | ||||
| *     * Redistributions of source code must retain the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer. | ||||
| *     * Redistributions in binary form must reproduce the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer in the | ||||
| *       documentation and/or other materials provided with the distribution. | ||||
| *     * Neither the name of the OpenSim Project nor the | ||||
| *       names of its contributors may be used to endorse or promote products | ||||
| *       derived from this software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| *  | ||||
| */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using libsecondlife; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Communications.Cache; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Servers; | ||||
| 
 | ||||
| namespace OpenSim.Grid.MessagingServer | ||||
| { | ||||
|     /// <summary> | ||||
|     /// </summary> | ||||
|     public class OpenMessage_Main : conscmd_callback | ||||
|     { | ||||
|         private MessageServerConfig Cfg; | ||||
| 
 | ||||
|         //public UserManager m_userManager; | ||||
|         //public UserLoginService m_loginService; | ||||
| 
 | ||||
|         private LogBase m_console; | ||||
|         private LLUUID m_lastCreatedUser = LLUUID.Random(); | ||||
| 
 | ||||
|         [STAThread] | ||||
|         public static void Main(string[] args) | ||||
|         { | ||||
|             Console.WriteLine("Launching MessagingServer..."); | ||||
| 
 | ||||
|             OpenMessage_Main messageserver = new OpenMessage_Main(); | ||||
| 
 | ||||
|             messageserver.Startup(); | ||||
|             messageserver.Work(); | ||||
|         } | ||||
| 
 | ||||
|         private OpenMessage_Main() | ||||
|         { | ||||
|             if (!Directory.Exists(Util.logDir())) | ||||
|             { | ||||
|                 Directory.CreateDirectory(Util.logDir()); | ||||
|             } | ||||
|             m_console = | ||||
|                 new LogBase((Path.Combine(Util.logDir(), "opengrid-messagingserver-console.log")), "OpenMessage", this, true); | ||||
|             MainLog.Instance = m_console; | ||||
|         } | ||||
| 
 | ||||
|         private void Work() | ||||
|         { | ||||
|             m_console.Notice("Enter help for a list of commands\n"); | ||||
| 
 | ||||
|             while (true) | ||||
|             { | ||||
|                 m_console.MainLogPrompt(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Startup() | ||||
|         { | ||||
|             Cfg = new MessageServerConfig("MESSAGING SERVER", (Path.Combine(Util.configDir(), "MessagingServer_Config.xml"))); | ||||
| 
 | ||||
|              | ||||
| 
 | ||||
|             MainLog.Instance.Verbose("REGION", "Starting HTTP process"); | ||||
|             BaseHttpServer httpServer = new BaseHttpServer(Cfg.HttpPort); | ||||
| 
 | ||||
|             //httpServer.AddXmlRPCHandler("login_to_simulator", m_loginService.XmlRpcLoginMethod); | ||||
| 
 | ||||
|             //httpServer.AddXmlRPCHandler("get_user_by_name", m_userManager.XmlRPCGetUserMethodName); | ||||
|             //httpServer.AddXmlRPCHandler("get_user_by_uuid", m_userManager.XmlRPCGetUserMethodUUID); | ||||
|             //httpServer.AddXmlRPCHandler("get_avatar_picker_avatar", m_userManager.XmlRPCGetAvatarPickerAvatar); | ||||
|             //httpServer.AddXmlRPCHandler("add_new_user_friend", m_userManager.XmlRpcResponseXmlRPCAddUserFriend); | ||||
|             //httpServer.AddXmlRPCHandler("remove_user_friend", m_userManager.XmlRpcResponseXmlRPCRemoveUserFriend); | ||||
|             //httpServer.AddXmlRPCHandler("update_user_friend_perms", m_userManager.XmlRpcResponseXmlRPCUpdateUserFriendPerms); | ||||
|             //httpServer.AddXmlRPCHandler("get_user_friend_list", m_userManager.XmlRpcResponseXmlRPCGetUserFriendList); | ||||
|              | ||||
| 
 | ||||
|             //httpServer.AddStreamHandler( | ||||
|                 //new RestStreamHandler("DELETE", "/usersessions/", m_userManager.RestDeleteUserSessionMethod)); | ||||
| 
 | ||||
|             httpServer.Start(); | ||||
|             m_console.Status("SERVER", "Messageserver 0.4 - Startup complete"); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public void do_create(string what) | ||||
|         { | ||||
|             switch (what) | ||||
|             { | ||||
|                 case "user": | ||||
|                      | ||||
|                     try | ||||
|                     { | ||||
|                         //userID = | ||||
|                             //m_userManager.AddUserProfile(tempfirstname, templastname, tempMD5Passwd, regX, regY); | ||||
|                     } catch (Exception ex) | ||||
|                     { | ||||
|                         m_console.Error("SERVER", "Error creating user: {0}", ex.ToString()); | ||||
|                     } | ||||
| 
 | ||||
|                     try | ||||
|                     { | ||||
|                         //RestObjectPoster.BeginPostObject<Guid>(m_userManager._config.InventoryUrl + "CreateInventory/", | ||||
|                                                                //userID.UUID); | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         m_console.Error("SERVER", "Error creating inventory for user: {0}", ex.ToString()); | ||||
|                     } | ||||
|                    // m_lastCreatedUser = userID; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void RunCmd(string cmd, string[] cmdparams) | ||||
|         { | ||||
|             switch (cmd) | ||||
|             { | ||||
|                 case "help": | ||||
|                     m_console.Notice("shutdown - shutdown the message server (USE CAUTION!)"); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "shutdown": | ||||
|                     m_console.Close(); | ||||
|                     Environment.Exit(0); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Show(string ShowWhat) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| /* | ||||
| * Copyright (c) Contributors, http://opensimulator.org/ | ||||
| * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions are met: | ||||
| *     * Redistributions of source code must retain the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer. | ||||
| *     * Redistributions in binary form must reproduce the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer in the | ||||
| *       documentation and/or other materials provided with the distribution. | ||||
| *     * Neither the name of the OpenSim Project nor the | ||||
| *       names of its contributors may be used to endorse or promote products | ||||
| *       derived from this software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| *  | ||||
| */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using libsecondlife; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Communications.Cache; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Servers; | ||||
| 
 | ||||
| namespace OpenSim.Grid.MessagingServer | ||||
| { | ||||
|     /// <summary> | ||||
|     /// </summary> | ||||
|     public class OpenMessage_Main : BaseOpenSimServer, conscmd_callback | ||||
|     { | ||||
|         private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private MessageServerConfig Cfg; | ||||
| 
 | ||||
|         //public UserManager m_userManager; | ||||
|         //public UserLoginService m_loginService; | ||||
|          | ||||
|         private LLUUID m_lastCreatedUser = LLUUID.Random(); | ||||
| 
 | ||||
|         [STAThread] | ||||
|         public static void Main(string[] args) | ||||
|         { | ||||
|             log4net.Config.XmlConfigurator.Configure(); | ||||
| 
 | ||||
|             m_log.Info("Launching MessagingServer..."); | ||||
| 
 | ||||
|             OpenMessage_Main messageserver = new OpenMessage_Main(); | ||||
| 
 | ||||
|             messageserver.Startup(); | ||||
|             messageserver.Work(); | ||||
|         } | ||||
| 
 | ||||
|         private OpenMessage_Main() | ||||
|         { | ||||
|             m_console = new ConsoleBase("OpenMessage", this); | ||||
|             MainConsole.Instance = m_console; | ||||
|         } | ||||
| 
 | ||||
|         private void Work() | ||||
|         { | ||||
|             m_console.Notice("Enter help for a list of commands\n"); | ||||
| 
 | ||||
|             while (true) | ||||
|             { | ||||
|                 m_console.Prompt(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Startup() | ||||
|         { | ||||
|             Cfg = new MessageServerConfig("MESSAGING SERVER", (Path.Combine(Util.configDir(), "MessagingServer_Config.xml"))); | ||||
| 
 | ||||
|             m_log.Info("[REGION]: Starting HTTP process"); | ||||
|             BaseHttpServer httpServer = new BaseHttpServer(Cfg.HttpPort); | ||||
| 
 | ||||
|             //httpServer.AddXmlRPCHandler("login_to_simulator", m_loginService.XmlRpcLoginMethod); | ||||
| 
 | ||||
|             //httpServer.AddXmlRPCHandler("get_user_by_name", m_userManager.XmlRPCGetUserMethodName); | ||||
|             //httpServer.AddXmlRPCHandler("get_user_by_uuid", m_userManager.XmlRPCGetUserMethodUUID); | ||||
|             //httpServer.AddXmlRPCHandler("get_avatar_picker_avatar", m_userManager.XmlRPCGetAvatarPickerAvatar); | ||||
|             //httpServer.AddXmlRPCHandler("add_new_user_friend", m_userManager.XmlRpcResponseXmlRPCAddUserFriend); | ||||
|             //httpServer.AddXmlRPCHandler("remove_user_friend", m_userManager.XmlRpcResponseXmlRPCRemoveUserFriend); | ||||
|             //httpServer.AddXmlRPCHandler("update_user_friend_perms", m_userManager.XmlRpcResponseXmlRPCUpdateUserFriendPerms); | ||||
|             //httpServer.AddXmlRPCHandler("get_user_friend_list", m_userManager.XmlRpcResponseXmlRPCGetUserFriendList); | ||||
|              | ||||
| 
 | ||||
|             //httpServer.AddStreamHandler( | ||||
|                 //new RestStreamHandler("DELETE", "/usersessions/", m_userManager.RestDeleteUserSessionMethod)); | ||||
| 
 | ||||
|             httpServer.Start(); | ||||
|             m_log.Info("[SERVER]: Messageserver 0.5 - Startup complete"); | ||||
|         } | ||||
| 
 | ||||
|         public void do_create(string what) | ||||
|         { | ||||
|             switch (what) | ||||
|             { | ||||
|                 case "user": | ||||
|                      | ||||
|                     try | ||||
|                     { | ||||
|                         //userID = | ||||
|                             //m_userManager.AddUserProfile(tempfirstname, templastname, tempMD5Passwd, regX, regY); | ||||
|                     } catch (Exception ex) | ||||
|                     { | ||||
|                         m_console.Error("[SERVER]: Error creating user: {0}", ex.ToString()); | ||||
|                     } | ||||
| 
 | ||||
|                     try | ||||
|                     { | ||||
|                         //RestObjectPoster.BeginPostObject<Guid>(m_userManager._config.InventoryUrl + "CreateInventory/", | ||||
|                                                                //userID.UUID); | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         m_console.Error("[SERVER]: Error creating inventory for user: {0}", ex.ToString()); | ||||
|                     } | ||||
|                     // m_lastCreatedUser = userID; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override void RunCmd(string cmd, string[] cmdparams) | ||||
|         { | ||||
|             base.RunCmd(cmd, cmdparams); | ||||
|              | ||||
|             switch (cmd) | ||||
|             { | ||||
|                 case "help": | ||||
|                     m_console.Notice("shutdown - shutdown the message server (USE CAUTION!)"); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "shutdown": | ||||
|                     m_console.Close(); | ||||
|                     Environment.Exit(0); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Show(string ShowWhat) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,480 +1,478 @@ | |||
| /* | ||||
| * Copyright (c) Contributors, http://opensimulator.org/ | ||||
| * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions are met: | ||||
| *     * Redistributions of source code must retain the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer. | ||||
| *     * Redistributions in binary form must reproduce the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer in the | ||||
| *       documentation and/or other materials provided with the distribution. | ||||
| *     * Neither the name of the OpenSim Project nor the | ||||
| *       names of its contributors may be used to endorse or promote products | ||||
| *       derived from this software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| *  | ||||
| */ | ||||
| using System; | ||||
| using System.Net; | ||||
| using System.Net.Sockets; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| //using System.Xml; | ||||
| using libsecondlife; | ||||
| using Nwc.XmlRpc; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Data; | ||||
| using OpenSim.Framework.Servers; | ||||
| using FriendRights = libsecondlife.FriendRights; | ||||
| 
 | ||||
| namespace OpenSim.Grid.MessagingServer | ||||
| { | ||||
|     public class MessageService | ||||
|     { | ||||
|         private LogBase m_log; | ||||
|         private MessageServerConfig m_cfg; | ||||
| 
 | ||||
|         //A hashtable of all current presences this server knows about | ||||
|         private Hashtable m_presences = new Hashtable(); | ||||
| 
 | ||||
|         //a hashtable of all current regions this server knows about | ||||
|         private Hashtable m_regionInfoCache = new Hashtable(); | ||||
| 
 | ||||
|         //A hashtable containing lists of UUIDs keyed by UUID for fast backreferencing | ||||
|         private Hashtable m_presence_BackReferences = new Hashtable(); | ||||
| 
 | ||||
|         // Hashtable containing work units that need to be processed | ||||
|         private Hashtable m_unProcessedWorkUnits = new Hashtable(); | ||||
| 
 | ||||
| 
 | ||||
|         public MessageService(LogBase log, MessageServerConfig cfg) | ||||
|         { | ||||
|             m_log = log; | ||||
|             m_cfg = cfg; | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         #region RegionComms Methods | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Informs a region about an Agent | ||||
|         /// </summary> | ||||
|         /// <param name="TalkingAbout">User to talk about</param> | ||||
|         /// <param name="UserToUpdate">User we're sending this too (contains the region)</param> | ||||
|         public void SendRegionPresenceUpdate(UserPresenceData TalkingAbout, UserPresenceData UserToUpdate) | ||||
|         { | ||||
|             // TODO: Fill in pertenant Presence Data from 'TalkingAbout' | ||||
| 
 | ||||
|             RegionProfileData whichRegion = UserToUpdate.regionData; | ||||
|             //whichRegion.httpServerURI | ||||
| 
 | ||||
|             Hashtable PresenceParams = new Hashtable(); | ||||
|             ArrayList SendParams = new ArrayList(); | ||||
|             SendParams.Add(PresenceParams); | ||||
| 
 | ||||
|             MainLog.Instance.Verbose("PRESENCE", "Informing " + whichRegion.regionName + " at " + whichRegion.httpServerURI); | ||||
|             // Send | ||||
|             XmlRpcRequest RegionReq = new XmlRpcRequest("presence_update", SendParams); | ||||
|             XmlRpcResponse RegionResp = RegionReq.Send(whichRegion.httpServerURI, 6000); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region FriendList Methods | ||||
| 
 | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Process Friendlist subscriptions for a user | ||||
|         /// The login method calls this for a User | ||||
|         /// </summary> | ||||
|         /// <param name="userpresence">The Agent we're processing the friendlist subscriptions</param> | ||||
|         public void ProcessFriendListSubscriptions(UserPresenceData userpresence) | ||||
|         { | ||||
|             List<FriendListItem> uFriendList = userpresence.friendData; | ||||
|             for (int i = 0; i < uFriendList.Count; i++) | ||||
|             { | ||||
|                 m_presence_BackReferences.Add(userpresence.agentData.AgentID, uFriendList[i].Friend); | ||||
|                 m_presence_BackReferences.Add(uFriendList[i].Friend, userpresence.agentData.AgentID); | ||||
| 
 | ||||
|                 if (m_presences.Contains(uFriendList[i].Friend)) | ||||
|                 { | ||||
|                     UserPresenceData friendup = (UserPresenceData)m_presences[uFriendList[i]]; | ||||
|                     // Add backreference | ||||
|                      | ||||
|                     SubscribeToPresenceUpdates(userpresence, friendup, uFriendList[i],i); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             m_presences.Add(userpresence.agentData.AgentID, userpresence); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Does the necessary work to subscribe one agent to another's presence notifications | ||||
|         /// Gets called by ProcessFriendListSubscriptions.  You shouldn't call this directly  | ||||
|         /// unless you know what you're doing | ||||
|         /// </summary> | ||||
|         /// <param name="userpresence">P1</param> | ||||
|         /// <param name="friendpresence">P2</param> | ||||
|         /// <param name="uFriendListItem"></param> | ||||
|         /// <param name="uFriendListIndex"></param> | ||||
|         public void SubscribeToPresenceUpdates(UserPresenceData userpresence, UserPresenceData friendpresence,  | ||||
|                                                 FriendListItem uFriendListItem, int uFriendListIndex) | ||||
|         { | ||||
|              | ||||
|             if ((uFriendListItem.FriendListOwnerPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||||
|             { | ||||
|                 // Subscribe and Send Out updates | ||||
|                 if (!friendpresence.subscriptionData.Contains(friendpresence.agentData.AgentID)) | ||||
|                 { | ||||
|                     userpresence.subscriptionData.Add(friendpresence.agentData.AgentID); | ||||
|                     //Send Region Notice....    | ||||
|                      | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // we need to send out online status update, but the user is already subscribed | ||||
|                      | ||||
|                 } | ||||
|                 SendRegionPresenceUpdate(friendpresence, userpresence); | ||||
|             } | ||||
|             if ((uFriendListItem.FriendPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||||
|             { | ||||
|                 if (!friendpresence.subscriptionData.Contains(userpresence.agentData.AgentID)) | ||||
|                 { | ||||
|                     friendpresence.subscriptionData.Add(userpresence.agentData.AgentID); | ||||
|                     //Send Region Notice.... | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // we need to send out online status update, but the user is already subscribed | ||||
| 
 | ||||
|                 } | ||||
|                 SendRegionPresenceUpdate(userpresence, friendpresence); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Adds a backreference so presence specific data doesn't have to be  | ||||
|         /// enumerated for each logged in user every time someone logs on or off. | ||||
|         /// </summary> | ||||
|         /// <param name="agentID"></param> | ||||
|         /// <param name="friendID"></param> | ||||
|         public void addBackReference(LLUUID agentID, LLUUID friendID) | ||||
|         { | ||||
|             if (m_presence_BackReferences.Contains(friendID)) | ||||
|             { | ||||
|                 List<LLUUID> presenseBackReferences = (List<LLUUID>)m_presence_BackReferences[friendID]; | ||||
|                 if (!presenseBackReferences.Contains(agentID)) | ||||
|                 { | ||||
|                     presenseBackReferences.Add(agentID); | ||||
|                 } | ||||
|                 m_presence_BackReferences[friendID] = presenseBackReferences; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 List<LLUUID> presenceBackReferences = new List<LLUUID>(); | ||||
|                 presenceBackReferences.Add(agentID); | ||||
|                 m_presence_BackReferences[friendID] = presenceBackReferences; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Removes a backreference to free up some memory | ||||
|         /// </summary> | ||||
|         /// <param name="agentID"></param> | ||||
|         /// <param name="friendID"></param> | ||||
|         public void removeBackReference(LLUUID agentID, LLUUID friendID) | ||||
|         { | ||||
|             if (m_presence_BackReferences.Contains(friendID)) | ||||
|             { | ||||
|                 List<LLUUID> presenseBackReferences = (List<LLUUID>)m_presence_BackReferences[friendID]; | ||||
|                 if (presenseBackReferences.Contains(agentID)) | ||||
|                 { | ||||
|                     presenseBackReferences.Remove(agentID); | ||||
|                 } | ||||
| 
 | ||||
|                 // If there are no more backreferences for this agent,  | ||||
|                 // remove it to free up memory. | ||||
|                 if (presenseBackReferences.Count == 0) | ||||
|                 { | ||||
|                     m_presence_BackReferences.Remove(agentID); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// Logoff Processor.  Call this to clean up agent presence data and send logoff presence notifications | ||||
|         /// </summary> | ||||
|         /// <param name="AgentID"></param> | ||||
|         private void ProcessLogOff(LLUUID AgentID) | ||||
|         { | ||||
|             if (m_presences.Contains(AgentID)) | ||||
|             { | ||||
|                 UserPresenceData AgentData = (UserPresenceData)m_presences[AgentID]; | ||||
| 
 | ||||
|                 if (m_presence_BackReferences.Contains(AgentID)) | ||||
|                 { | ||||
|                     List<LLUUID> AgentsNeedingNotification = (List<LLUUID>)m_presence_BackReferences[AgentID]; | ||||
|                     for (int i = 0; i < AgentsNeedingNotification.Count; i++) | ||||
|                     { | ||||
|                         // TODO: Do Region Notifications | ||||
|                         if (m_presences.Contains(AgentsNeedingNotification[i])) | ||||
|                         { | ||||
|                             UserPresenceData friendd = (UserPresenceData)m_presences[AgentsNeedingNotification[i]]; | ||||
|                              | ||||
|                             // This might need to be enumerated and checked before we try to remove it. | ||||
|                             friendd.subscriptionData.Remove(AgentID); | ||||
|                              | ||||
|                             List<FriendListItem> fl = friendd.friendData; | ||||
|                             for (int j = 0; j < fl.Count; j++) | ||||
|                             { | ||||
|                                 if (fl[j].Friend == AgentID) | ||||
|                                 { | ||||
|                                     fl[j].onlinestatus = false; | ||||
|                                 } | ||||
| 
 | ||||
|                             } | ||||
|                             friendd.friendData = fl; | ||||
| 
 | ||||
|                             SendRegionPresenceUpdate(AgentData, friendd); | ||||
| 
 | ||||
|                         } | ||||
|                         removeBackReference(AgentID, AgentsNeedingNotification[i]); | ||||
| 
 | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region UserServer Comms | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner | ||||
|         /// </summary> | ||||
|         /// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param> | ||||
|         public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner) | ||||
|         { | ||||
|             List<FriendListItem> buddylist = new List<FriendListItem>(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 Hashtable param = new Hashtable(); | ||||
|                 param["ownerID"] = friendlistowner.UUID.ToString(); | ||||
| 
 | ||||
|                 IList parameters = new ArrayList(); | ||||
|                 parameters.Add(param); | ||||
|                 XmlRpcRequest req = new XmlRpcRequest("get_user_friend_list", parameters); | ||||
|                 XmlRpcResponse resp = req.Send(m_cfg.UserServerURL, 3000); | ||||
|                 Hashtable respData = (Hashtable)resp.Value; | ||||
| 
 | ||||
|                 if (respData.Contains("avcount")) | ||||
|                 { | ||||
|                     buddylist = ConvertXMLRPCDataToFriendListItemList(respData); | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             catch (WebException e) | ||||
|             { | ||||
|                 MainLog.Instance.Warn("Error when trying to fetch Avatar's friends list: " + | ||||
|                                       e.Message); | ||||
|                 // Return Empty list (no friends) | ||||
|             } | ||||
|             return buddylist; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Converts XMLRPC Friend List to FriendListItem Object | ||||
|         /// </summary> | ||||
|         /// <param name="data">XMLRPC response data Hashtable</param> | ||||
|         /// <returns></returns> | ||||
|         public List<FriendListItem> ConvertXMLRPCDataToFriendListItemList(Hashtable data) | ||||
|         { | ||||
|             List<FriendListItem> buddylist = new List<FriendListItem>(); | ||||
|             int buddycount = Convert.ToInt32((string)data["avcount"]); | ||||
| 
 | ||||
| 
 | ||||
|             for (int i = 0; i < buddycount; i++) | ||||
|             { | ||||
|                 FriendListItem buddylistitem = new FriendListItem(); | ||||
| 
 | ||||
|                 buddylistitem.FriendListOwner = new LLUUID((string)data["ownerID" + i.ToString()]); | ||||
|                 buddylistitem.Friend = new LLUUID((string)data["friendID" + i.ToString()]); | ||||
|                 buddylistitem.FriendListOwnerPerms = (uint)Convert.ToInt32((string)data["ownerPerms" + i.ToString()]); | ||||
|                 buddylistitem.FriendPerms = (uint)Convert.ToInt32((string)data["friendPerms" + i.ToString()]); | ||||
| 
 | ||||
|                 buddylist.Add(buddylistitem); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             return buddylist; | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// UserServer sends an expect_user method | ||||
|         /// this handles the method and provisions the  | ||||
|         /// necessary info for presence to work | ||||
|         /// </summary> | ||||
|         /// <param name="request">UserServer Data</param> | ||||
|         /// <returns></returns> | ||||
|         public XmlRpcResponse UserLoggedOn(XmlRpcRequest request) | ||||
|         { | ||||
| 
 | ||||
|             Hashtable requestData = (Hashtable)request.Params[0]; | ||||
|             AgentCircuitData agentData = new AgentCircuitData(); | ||||
|             agentData.SessionID = new LLUUID((string)requestData["session_id"]); | ||||
|             agentData.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]); | ||||
|             agentData.firstname = (string)requestData["firstname"]; | ||||
|             agentData.lastname = (string)requestData["lastname"]; | ||||
|             agentData.AgentID = new LLUUID((string)requestData["agent_id"]); | ||||
|             agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); | ||||
|             agentData.CapsPath = (string)requestData["caps_path"]; | ||||
| 
 | ||||
|             if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1")) | ||||
|             { | ||||
|                 agentData.child = true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 agentData.startpos = | ||||
|                     new LLVector3(Convert.ToUInt32(requestData["startpos_x"]), | ||||
|                                   Convert.ToUInt32(requestData["startpos_y"]), | ||||
|                                   Convert.ToUInt32(requestData["startpos_z"])); | ||||
|                 agentData.child = false; | ||||
|             } | ||||
| 
 | ||||
|             ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); | ||||
| 
 | ||||
|             UserPresenceData up = new UserPresenceData(); | ||||
|             up.agentData = agentData; | ||||
|             List<FriendListItem> flData = GetUserFriendList(agentData.AgentID); | ||||
|             up.friendData = flData; | ||||
|             RegionProfileData riData = GetRegionInfo(regionHandle); | ||||
|             up.regionData = riData; | ||||
| 
 | ||||
|             ProcessFriendListSubscriptions(up); | ||||
| 
 | ||||
| 
 | ||||
|             return new XmlRpcResponse(); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// The UserServer got a Logoff message  | ||||
|         /// Cleanup time for that user.  Send out presence notifications | ||||
|         /// </summary> | ||||
|         /// <param name="request"></param> | ||||
|         /// <returns></returns> | ||||
|         public XmlRpcResponse UserLoggedOff(XmlRpcRequest request) | ||||
|         { | ||||
| 
 | ||||
|             Hashtable requestData = (Hashtable)request.Params[0]; | ||||
|              | ||||
|             LLUUID AgentID = new LLUUID((string)requestData["agent_id"]); | ||||
| 
 | ||||
| 
 | ||||
|             ProcessLogOff(AgentID); | ||||
| 
 | ||||
| 
 | ||||
|             return new XmlRpcResponse(); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|         #region regioninfo gathering | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets and caches a RegionInfo object from the gridserver based on regionhandle | ||||
|         /// if the regionhandle is already cached, use the cached values | ||||
|         /// </summary> | ||||
|         /// <param name="regionhandle">handle to the XY of the region we're looking for</param> | ||||
|         /// <returns>A RegionInfo object to stick in the presence info</returns> | ||||
|         public RegionProfileData GetRegionInfo(ulong regionhandle) | ||||
|         { | ||||
|             RegionProfileData regionInfo = null; | ||||
|             if (m_regionInfoCache.Contains(regionhandle)) | ||||
|             { | ||||
|                 regionInfo = (RegionProfileData)m_regionInfoCache[regionhandle]; | ||||
|             } | ||||
|             else  | ||||
|             { | ||||
|                 regionInfo = RequestRegionInfo(regionhandle); | ||||
|             } | ||||
|             return regionInfo; | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// Get RegionProfileData from the GridServer | ||||
|         /// We'll Cache this information and use it for presence updates | ||||
|         /// </summary> | ||||
|         /// <param name="regionHandle"></param> | ||||
|         /// <returns></returns> | ||||
|         public RegionProfileData RequestRegionInfo(ulong regionHandle) | ||||
|         {   RegionProfileData regionProfile = null; | ||||
|             try | ||||
|             { | ||||
|                  | ||||
|                 Hashtable requestData = new Hashtable(); | ||||
|                 requestData["region_handle"] = regionHandle.ToString(); | ||||
|                 requestData["authkey"] = m_cfg.GridSendKey; | ||||
|                 ArrayList SendParams = new ArrayList(); | ||||
|                 SendParams.Add(requestData); | ||||
|                 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); | ||||
|                 XmlRpcResponse GridResp = GridReq.Send(m_cfg.GridServerURL, 3000); | ||||
|                  | ||||
|                 Hashtable responseData = (Hashtable)GridResp.Value; | ||||
| 
 | ||||
|                 if (responseData.ContainsKey("error")) | ||||
|                 { | ||||
|                     m_log.Error("GRID","error received from grid server" + responseData["error"]); | ||||
|                     return null; | ||||
|                 } | ||||
| 
 | ||||
|                 uint regX = Convert.ToUInt32((string)responseData["region_locx"]); | ||||
|                 uint regY = Convert.ToUInt32((string)responseData["region_locy"]); | ||||
|                 string internalIpStr = (string)responseData["sim_ip"]; | ||||
|                 uint port = Convert.ToUInt32(responseData["sim_port"]); | ||||
|                 string externalUri = (string)responseData["sim_uri"]; | ||||
|                 string neighbourExternalUri = externalUri; | ||||
| 
 | ||||
|                 regionProfile = new RegionProfileData(); | ||||
|                 regionProfile.httpPort = (uint)Convert.ToInt32((string)responseData["http_port"]); | ||||
|                 regionProfile.httpServerURI = "http://" + internalIpStr + ":" + regionProfile.httpPort + "/"; | ||||
|                 regionProfile.regionHandle = Helpers.UIntsToLong((regX * 256), (regY * 256)); | ||||
|                 regionProfile.regionLocX = regX; | ||||
|                 regionProfile.regionLocY = regY; | ||||
|                 | ||||
|                 regionProfile.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); | ||||
|                 regionProfile.UUID = new LLUUID((string)responseData["region_UUID"]); | ||||
|                 regionProfile.regionName = (string)responseData["region_name"]; | ||||
| 
 | ||||
|                 m_regionInfoCache.Add(regionHandle, regionProfile); | ||||
|             } | ||||
|             catch (WebException) | ||||
|             { | ||||
|                 MainLog.Instance.Error("GRID", | ||||
|                                        "Region lookup failed for: " + regionHandle.ToString() + | ||||
|                                        " - Is the GridServer down?"); | ||||
|                 return null; | ||||
|             } | ||||
|             | ||||
| 
 | ||||
|             return regionProfile; | ||||
|         } | ||||
|         #endregion | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| /* | ||||
| * Copyright (c) Contributors, http://opensimulator.org/ | ||||
| * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions are met: | ||||
| *     * Redistributions of source code must retain the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer. | ||||
| *     * Redistributions in binary form must reproduce the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer in the | ||||
| *       documentation and/or other materials provided with the distribution. | ||||
| *     * Neither the name of the OpenSim Project nor the | ||||
| *       names of its contributors may be used to endorse or promote products | ||||
| *       derived from this software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| *  | ||||
| */ | ||||
| using System; | ||||
| using System.Net; | ||||
| using System.Net.Sockets; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| //using System.Xml; | ||||
| using libsecondlife; | ||||
| using Nwc.XmlRpc; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Data; | ||||
| using OpenSim.Framework.Servers; | ||||
| using FriendRights = libsecondlife.FriendRights; | ||||
| 
 | ||||
| namespace OpenSim.Grid.MessagingServer | ||||
| { | ||||
|     public class MessageService | ||||
|     { | ||||
|         private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private MessageServerConfig m_cfg; | ||||
| 
 | ||||
|         //A hashtable of all current presences this server knows about | ||||
|         private Hashtable m_presences = new Hashtable(); | ||||
| 
 | ||||
|         //a hashtable of all current regions this server knows about | ||||
|         private Hashtable m_regionInfoCache = new Hashtable(); | ||||
| 
 | ||||
|         //A hashtable containing lists of UUIDs keyed by UUID for fast backreferencing | ||||
|         private Hashtable m_presence_BackReferences = new Hashtable(); | ||||
| 
 | ||||
|         // Hashtable containing work units that need to be processed | ||||
|         private Hashtable m_unProcessedWorkUnits = new Hashtable(); | ||||
| 
 | ||||
|         public MessageService(MessageServerConfig cfg) | ||||
|         { | ||||
|             m_cfg = cfg; | ||||
|         } | ||||
|          | ||||
|         #region RegionComms Methods | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Informs a region about an Agent | ||||
|         /// </summary> | ||||
|         /// <param name="TalkingAbout">User to talk about</param> | ||||
|         /// <param name="UserToUpdate">User we're sending this too (contains the region)</param> | ||||
|         public void SendRegionPresenceUpdate(UserPresenceData TalkingAbout, UserPresenceData UserToUpdate) | ||||
|         { | ||||
|             // TODO: Fill in pertenant Presence Data from 'TalkingAbout' | ||||
| 
 | ||||
|             RegionProfileData whichRegion = UserToUpdate.regionData; | ||||
|             //whichRegion.httpServerURI | ||||
| 
 | ||||
|             Hashtable PresenceParams = new Hashtable(); | ||||
|             ArrayList SendParams = new ArrayList(); | ||||
|             SendParams.Add(PresenceParams); | ||||
| 
 | ||||
|             m_log.Info("[PRESENCE]: Informing " + whichRegion.regionName + " at " + whichRegion.httpServerURI); | ||||
|             // Send | ||||
|             XmlRpcRequest RegionReq = new XmlRpcRequest("presence_update", SendParams); | ||||
|             XmlRpcResponse RegionResp = RegionReq.Send(whichRegion.httpServerURI, 6000); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region FriendList Methods | ||||
| 
 | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Process Friendlist subscriptions for a user | ||||
|         /// The login method calls this for a User | ||||
|         /// </summary> | ||||
|         /// <param name="userpresence">The Agent we're processing the friendlist subscriptions</param> | ||||
|         public void ProcessFriendListSubscriptions(UserPresenceData userpresence) | ||||
|         { | ||||
|             List<FriendListItem> uFriendList = userpresence.friendData; | ||||
|             for (int i = 0; i < uFriendList.Count; i++) | ||||
|             { | ||||
|                 m_presence_BackReferences.Add(userpresence.agentData.AgentID, uFriendList[i].Friend); | ||||
|                 m_presence_BackReferences.Add(uFriendList[i].Friend, userpresence.agentData.AgentID); | ||||
| 
 | ||||
|                 if (m_presences.Contains(uFriendList[i].Friend)) | ||||
|                 { | ||||
|                     UserPresenceData friendup = (UserPresenceData)m_presences[uFriendList[i]]; | ||||
|                     // Add backreference | ||||
|                      | ||||
|                     SubscribeToPresenceUpdates(userpresence, friendup, uFriendList[i],i); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             m_presences.Add(userpresence.agentData.AgentID, userpresence); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Does the necessary work to subscribe one agent to another's presence notifications | ||||
|         /// Gets called by ProcessFriendListSubscriptions.  You shouldn't call this directly  | ||||
|         /// unless you know what you're doing | ||||
|         /// </summary> | ||||
|         /// <param name="userpresence">P1</param> | ||||
|         /// <param name="friendpresence">P2</param> | ||||
|         /// <param name="uFriendListItem"></param> | ||||
|         /// <param name="uFriendListIndex"></param> | ||||
|         public void SubscribeToPresenceUpdates(UserPresenceData userpresence, UserPresenceData friendpresence,  | ||||
|                                                 FriendListItem uFriendListItem, int uFriendListIndex) | ||||
|         { | ||||
|              | ||||
|             if ((uFriendListItem.FriendListOwnerPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||||
|             { | ||||
|                 // Subscribe and Send Out updates | ||||
|                 if (!friendpresence.subscriptionData.Contains(friendpresence.agentData.AgentID)) | ||||
|                 { | ||||
|                     userpresence.subscriptionData.Add(friendpresence.agentData.AgentID); | ||||
|                     //Send Region Notice....    | ||||
|                      | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // we need to send out online status update, but the user is already subscribed | ||||
|                      | ||||
|                 } | ||||
|                 SendRegionPresenceUpdate(friendpresence, userpresence); | ||||
|             } | ||||
|             if ((uFriendListItem.FriendPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||||
|             { | ||||
|                 if (!friendpresence.subscriptionData.Contains(userpresence.agentData.AgentID)) | ||||
|                 { | ||||
|                     friendpresence.subscriptionData.Add(userpresence.agentData.AgentID); | ||||
|                     //Send Region Notice.... | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // we need to send out online status update, but the user is already subscribed | ||||
| 
 | ||||
|                 } | ||||
|                 SendRegionPresenceUpdate(userpresence, friendpresence); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Adds a backreference so presence specific data doesn't have to be  | ||||
|         /// enumerated for each logged in user every time someone logs on or off. | ||||
|         /// </summary> | ||||
|         /// <param name="agentID"></param> | ||||
|         /// <param name="friendID"></param> | ||||
|         public void addBackReference(LLUUID agentID, LLUUID friendID) | ||||
|         { | ||||
|             if (m_presence_BackReferences.Contains(friendID)) | ||||
|             { | ||||
|                 List<LLUUID> presenseBackReferences = (List<LLUUID>)m_presence_BackReferences[friendID]; | ||||
|                 if (!presenseBackReferences.Contains(agentID)) | ||||
|                 { | ||||
|                     presenseBackReferences.Add(agentID); | ||||
|                 } | ||||
|                 m_presence_BackReferences[friendID] = presenseBackReferences; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 List<LLUUID> presenceBackReferences = new List<LLUUID>(); | ||||
|                 presenceBackReferences.Add(agentID); | ||||
|                 m_presence_BackReferences[friendID] = presenceBackReferences; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Removes a backreference to free up some memory | ||||
|         /// </summary> | ||||
|         /// <param name="agentID"></param> | ||||
|         /// <param name="friendID"></param> | ||||
|         public void removeBackReference(LLUUID agentID, LLUUID friendID) | ||||
|         { | ||||
|             if (m_presence_BackReferences.Contains(friendID)) | ||||
|             { | ||||
|                 List<LLUUID> presenseBackReferences = (List<LLUUID>)m_presence_BackReferences[friendID]; | ||||
|                 if (presenseBackReferences.Contains(agentID)) | ||||
|                 { | ||||
|                     presenseBackReferences.Remove(agentID); | ||||
|                 } | ||||
| 
 | ||||
|                 // If there are no more backreferences for this agent,  | ||||
|                 // remove it to free up memory. | ||||
|                 if (presenseBackReferences.Count == 0) | ||||
|                 { | ||||
|                     m_presence_BackReferences.Remove(agentID); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// Logoff Processor.  Call this to clean up agent presence data and send logoff presence notifications | ||||
|         /// </summary> | ||||
|         /// <param name="AgentID"></param> | ||||
|         private void ProcessLogOff(LLUUID AgentID) | ||||
|         { | ||||
|             if (m_presences.Contains(AgentID)) | ||||
|             { | ||||
|                 UserPresenceData AgentData = (UserPresenceData)m_presences[AgentID]; | ||||
| 
 | ||||
|                 if (m_presence_BackReferences.Contains(AgentID)) | ||||
|                 { | ||||
|                     List<LLUUID> AgentsNeedingNotification = (List<LLUUID>)m_presence_BackReferences[AgentID]; | ||||
|                     for (int i = 0; i < AgentsNeedingNotification.Count; i++) | ||||
|                     { | ||||
|                         // TODO: Do Region Notifications | ||||
|                         if (m_presences.Contains(AgentsNeedingNotification[i])) | ||||
|                         { | ||||
|                             UserPresenceData friendd = (UserPresenceData)m_presences[AgentsNeedingNotification[i]]; | ||||
|                              | ||||
|                             // This might need to be enumerated and checked before we try to remove it. | ||||
|                             friendd.subscriptionData.Remove(AgentID); | ||||
|                              | ||||
|                             List<FriendListItem> fl = friendd.friendData; | ||||
|                             for (int j = 0; j < fl.Count; j++) | ||||
|                             { | ||||
|                                 if (fl[j].Friend == AgentID) | ||||
|                                 { | ||||
|                                     fl[j].onlinestatus = false; | ||||
|                                 } | ||||
| 
 | ||||
|                             } | ||||
|                             friendd.friendData = fl; | ||||
| 
 | ||||
|                             SendRegionPresenceUpdate(AgentData, friendd); | ||||
| 
 | ||||
|                         } | ||||
|                         removeBackReference(AgentID, AgentsNeedingNotification[i]); | ||||
| 
 | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region UserServer Comms | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner | ||||
|         /// </summary> | ||||
|         /// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param> | ||||
|         public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner) | ||||
|         { | ||||
|             List<FriendListItem> buddylist = new List<FriendListItem>(); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 Hashtable param = new Hashtable(); | ||||
|                 param["ownerID"] = friendlistowner.UUID.ToString(); | ||||
| 
 | ||||
|                 IList parameters = new ArrayList(); | ||||
|                 parameters.Add(param); | ||||
|                 XmlRpcRequest req = new XmlRpcRequest("get_user_friend_list", parameters); | ||||
|                 XmlRpcResponse resp = req.Send(m_cfg.UserServerURL, 3000); | ||||
|                 Hashtable respData = (Hashtable)resp.Value; | ||||
| 
 | ||||
|                 if (respData.Contains("avcount")) | ||||
|                 { | ||||
|                     buddylist = ConvertXMLRPCDataToFriendListItemList(respData); | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             catch (WebException e) | ||||
|             { | ||||
|                 m_log.Warn("Error when trying to fetch Avatar's friends list: " + | ||||
|                                       e.Message); | ||||
|                 // Return Empty list (no friends) | ||||
|             } | ||||
|             return buddylist; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Converts XMLRPC Friend List to FriendListItem Object | ||||
|         /// </summary> | ||||
|         /// <param name="data">XMLRPC response data Hashtable</param> | ||||
|         /// <returns></returns> | ||||
|         public List<FriendListItem> ConvertXMLRPCDataToFriendListItemList(Hashtable data) | ||||
|         { | ||||
|             List<FriendListItem> buddylist = new List<FriendListItem>(); | ||||
|             int buddycount = Convert.ToInt32((string)data["avcount"]); | ||||
| 
 | ||||
| 
 | ||||
|             for (int i = 0; i < buddycount; i++) | ||||
|             { | ||||
|                 FriendListItem buddylistitem = new FriendListItem(); | ||||
| 
 | ||||
|                 buddylistitem.FriendListOwner = new LLUUID((string)data["ownerID" + i.ToString()]); | ||||
|                 buddylistitem.Friend = new LLUUID((string)data["friendID" + i.ToString()]); | ||||
|                 buddylistitem.FriendListOwnerPerms = (uint)Convert.ToInt32((string)data["ownerPerms" + i.ToString()]); | ||||
|                 buddylistitem.FriendPerms = (uint)Convert.ToInt32((string)data["friendPerms" + i.ToString()]); | ||||
| 
 | ||||
|                 buddylist.Add(buddylistitem); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             return buddylist; | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// UserServer sends an expect_user method | ||||
|         /// this handles the method and provisions the  | ||||
|         /// necessary info for presence to work | ||||
|         /// </summary> | ||||
|         /// <param name="request">UserServer Data</param> | ||||
|         /// <returns></returns> | ||||
|         public XmlRpcResponse UserLoggedOn(XmlRpcRequest request) | ||||
|         { | ||||
| 
 | ||||
|             Hashtable requestData = (Hashtable)request.Params[0]; | ||||
|             AgentCircuitData agentData = new AgentCircuitData(); | ||||
|             agentData.SessionID = new LLUUID((string)requestData["session_id"]); | ||||
|             agentData.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]); | ||||
|             agentData.firstname = (string)requestData["firstname"]; | ||||
|             agentData.lastname = (string)requestData["lastname"]; | ||||
|             agentData.AgentID = new LLUUID((string)requestData["agent_id"]); | ||||
|             agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); | ||||
|             agentData.CapsPath = (string)requestData["caps_path"]; | ||||
| 
 | ||||
|             if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1")) | ||||
|             { | ||||
|                 agentData.child = true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 agentData.startpos = | ||||
|                     new LLVector3(Convert.ToUInt32(requestData["startpos_x"]), | ||||
|                                   Convert.ToUInt32(requestData["startpos_y"]), | ||||
|                                   Convert.ToUInt32(requestData["startpos_z"])); | ||||
|                 agentData.child = false; | ||||
|             } | ||||
| 
 | ||||
|             ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); | ||||
| 
 | ||||
|             UserPresenceData up = new UserPresenceData(); | ||||
|             up.agentData = agentData; | ||||
|             List<FriendListItem> flData = GetUserFriendList(agentData.AgentID); | ||||
|             up.friendData = flData; | ||||
|             RegionProfileData riData = GetRegionInfo(regionHandle); | ||||
|             up.regionData = riData; | ||||
| 
 | ||||
|             ProcessFriendListSubscriptions(up); | ||||
| 
 | ||||
| 
 | ||||
|             return new XmlRpcResponse(); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// The UserServer got a Logoff message  | ||||
|         /// Cleanup time for that user.  Send out presence notifications | ||||
|         /// </summary> | ||||
|         /// <param name="request"></param> | ||||
|         /// <returns></returns> | ||||
|         public XmlRpcResponse UserLoggedOff(XmlRpcRequest request) | ||||
|         { | ||||
| 
 | ||||
|             Hashtable requestData = (Hashtable)request.Params[0]; | ||||
|              | ||||
|             LLUUID AgentID = new LLUUID((string)requestData["agent_id"]); | ||||
| 
 | ||||
| 
 | ||||
|             //ProcessLogOff(AgentID); | ||||
| 
 | ||||
| 
 | ||||
|             return new XmlRpcResponse(); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|         #region regioninfo gathering | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets and caches a RegionInfo object from the gridserver based on regionhandle | ||||
|         /// if the regionhandle is already cached, use the cached values | ||||
|         /// </summary> | ||||
|         /// <param name="regionhandle">handle to the XY of the region we're looking for</param> | ||||
|         /// <returns>A RegionInfo object to stick in the presence info</returns> | ||||
|         public RegionProfileData GetRegionInfo(ulong regionhandle) | ||||
|         { | ||||
|             RegionProfileData regionInfo = null; | ||||
|             if (m_regionInfoCache.Contains(regionhandle)) | ||||
|             { | ||||
|                 regionInfo = (RegionProfileData)m_regionInfoCache[regionhandle]; | ||||
|             } | ||||
|             else  | ||||
|             { | ||||
|                 regionInfo = RequestRegionInfo(regionhandle); | ||||
|             } | ||||
|             return regionInfo; | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// Get RegionProfileData from the GridServer | ||||
|         /// We'll Cache this information and use it for presence updates | ||||
|         /// </summary> | ||||
|         /// <param name="regionHandle"></param> | ||||
|         /// <returns></returns> | ||||
|         public RegionProfileData RequestRegionInfo(ulong regionHandle) | ||||
|         {   RegionProfileData regionProfile = null; | ||||
|             try | ||||
|             { | ||||
|                  | ||||
|                 Hashtable requestData = new Hashtable(); | ||||
|                 requestData["region_handle"] = regionHandle.ToString(); | ||||
|                 requestData["authkey"] = m_cfg.GridSendKey; | ||||
|                 ArrayList SendParams = new ArrayList(); | ||||
|                 SendParams.Add(requestData); | ||||
|                 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); | ||||
|                 XmlRpcResponse GridResp = GridReq.Send(m_cfg.GridServerURL, 3000); | ||||
|                  | ||||
|                 Hashtable responseData = (Hashtable)GridResp.Value; | ||||
| 
 | ||||
|                 if (responseData.ContainsKey("error")) | ||||
|                 { | ||||
|                     m_log.Error("[GRID]: error received from grid server" + responseData["error"]); | ||||
|                     return null; | ||||
|                 } | ||||
| 
 | ||||
|                 uint regX = Convert.ToUInt32((string)responseData["region_locx"]); | ||||
|                 uint regY = Convert.ToUInt32((string)responseData["region_locy"]); | ||||
|                 string internalIpStr = (string)responseData["sim_ip"]; | ||||
|                 uint port = Convert.ToUInt32(responseData["sim_port"]); | ||||
|                 string externalUri = (string)responseData["sim_uri"]; | ||||
|                 string neighbourExternalUri = externalUri; | ||||
| 
 | ||||
|                 regionProfile = new RegionProfileData(); | ||||
|                 regionProfile.httpPort = (uint)Convert.ToInt32((string)responseData["http_port"]); | ||||
|                 regionProfile.httpServerURI = "http://" + internalIpStr + ":" + regionProfile.httpPort + "/"; | ||||
|                 regionProfile.regionHandle = Helpers.UIntsToLong((regX * Constants.RegionSize), (regY * Constants.RegionSize)); | ||||
|                 regionProfile.regionLocX = regX; | ||||
|                 regionProfile.regionLocY = regY; | ||||
|                 | ||||
|                 regionProfile.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); | ||||
|                 regionProfile.UUID = new LLUUID((string)responseData["region_UUID"]); | ||||
|                 regionProfile.regionName = (string)responseData["region_name"]; | ||||
| 
 | ||||
|                 m_regionInfoCache.Add(regionHandle, regionProfile); | ||||
|             } | ||||
|             catch (WebException) | ||||
|             { | ||||
|                 m_log.Error("[GRID]: " + | ||||
|                                        "Region lookup failed for: " + regionHandle.ToString() + | ||||
|                                        " - Is the GridServer down?"); | ||||
|                 return null; | ||||
|             } | ||||
|             | ||||
| 
 | ||||
|             return regionProfile; | ||||
|         } | ||||
|         #endregion | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -1,53 +1,53 @@ | |||
| /* | ||||
| * Copyright (c) Contributors, http://opensimulator.org/ | ||||
| * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions are met: | ||||
| *     * Redistributions of source code must retain the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer. | ||||
| *     * Redistributions in binary form must reproduce the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer in the | ||||
| *       documentation and/or other materials provided with the distribution. | ||||
| *     * Neither the name of the OpenSim Project nor the | ||||
| *       names of its contributors may be used to endorse or promote products | ||||
| *       derived from this software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| *  | ||||
| */ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using libsecondlife; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Data; | ||||
| 
 | ||||
| 
 | ||||
| namespace OpenSim.Grid.MessagingServer | ||||
| { | ||||
|     public class UserPresenceData | ||||
|     { | ||||
|         public AgentCircuitData agentData = new AgentCircuitData(); | ||||
|         public RegionProfileData regionData = new RegionProfileData(); | ||||
|         public string httpURI = ""; | ||||
|         public List<FriendListItem> friendData = new List<FriendListItem> (); | ||||
|         public List<LLUUID> subscriptionData = new List<LLUUID>(); | ||||
| 
 | ||||
|         public UserPresenceData() | ||||
|         { | ||||
|              | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| /* | ||||
| * Copyright (c) Contributors, http://opensimulator.org/ | ||||
| * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions are met: | ||||
| *     * Redistributions of source code must retain the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer. | ||||
| *     * Redistributions in binary form must reproduce the above copyright | ||||
| *       notice, this list of conditions and the following disclaimer in the | ||||
| *       documentation and/or other materials provided with the distribution. | ||||
| *     * Neither the name of the OpenSim Project nor the | ||||
| *       names of its contributors may be used to endorse or promote products | ||||
| *       derived from this software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| *  | ||||
| */ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using libsecondlife; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Data; | ||||
| 
 | ||||
| 
 | ||||
| namespace OpenSim.Grid.MessagingServer | ||||
| { | ||||
|     public class UserPresenceData | ||||
|     { | ||||
|         public AgentCircuitData agentData = new AgentCircuitData(); | ||||
|         public RegionProfileData regionData = new RegionProfileData(); | ||||
|         public string httpURI = String.Empty; | ||||
|         public List<FriendListItem> friendData = new List<FriendListItem> (); | ||||
|         public List<LLUUID> subscriptionData = new List<LLUUID>(); | ||||
| 
 | ||||
|         public UserPresenceData() | ||||
|         { | ||||
|              | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Adam Frisby
						Adam Frisby