From 328883700a15e4216bf7b251ac099d38f413375e Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 13 May 2013 22:11:28 -0400 Subject: UserProfiles UserProfiles for Robust and Standalone. Includes service and connectors for Robust and standalone opensim plus matching region module. --- .../Avatar/Profile/BasicProfileModule.cs | 176 --- .../Avatar/UserProfiles/UserProfileModule.cs | 1386 ++++++++++++++++++++ .../LocalUserProfilesServiceConnector.cs | 226 ++++ .../Grid/LocalGridServiceConnector.cs | 1 + 4 files changed, 1613 insertions(+), 176 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs create mode 100644 OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs deleted file mode 100644 index bf24030..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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 OpenSimulator 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 System.Globalization; -using System.Reflection; - -using OpenMetaverse; -using log4net; -using Nini.Config; -using Mono.Addins; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; - -namespace OpenSim.Region.CoreModules.Avatar.Profile -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicProfileModule")] - public class BasicProfileModule : IProfileModule, ISharedRegionModule - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - // - // Module vars - // - private List m_Scenes = new List(); - private bool m_Enabled = false; - - #region ISharedRegionModule - - public void Initialise(IConfigSource config) - { - m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); - m_Enabled = true; - } - - public void AddRegion(Scene scene) - { - if (!m_Enabled) - return; - - lock (m_Scenes) - { - if (!m_Scenes.Contains(scene)) - { - m_Scenes.Add(scene); - // Hook up events - scene.EventManager.OnNewClient += OnNewClient; - scene.RegisterModuleInterface(this); - } - } - } - - public void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - } - - public void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - - lock (m_Scenes) - { - m_Scenes.Remove(scene); - } - } - - public void PostInitialise() - { - } - - public void Close() - { - } - - public string Name - { - get { return "BasicProfileModule"; } - } - - public Type ReplaceableInterface - { - get { return typeof(IProfileModule); } - } - - #endregion - - /// New Client Event Handler - private void OnNewClient(IClientAPI client) - { - //Profile - client.OnRequestAvatarProperties += RequestAvatarProperties; - } - - public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) - { - IScene s = remoteClient.Scene; - if (!(s is Scene)) - return; - -// Scene scene = (Scene)s; - - string profileUrl = String.Empty; - string aboutText = String.Empty; - string firstLifeAboutText = String.Empty; - UUID image = UUID.Zero; - UUID firstLifeImage = UUID.Zero; - UUID partner = UUID.Zero; - uint wantMask = 0; - string wantText = String.Empty; - uint skillsMask = 0; - string skillsText = String.Empty; - string languages = String.Empty; - - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, avatarID); - - string name = "Avatar"; - int created = 0; - if (account != null) - { - name = account.FirstName + " " + account.LastName; - created = account.Created; - } - Byte[] charterMember = Utils.StringToBytes(name); - - profileUrl = "No profile data"; - aboutText = string.Empty; - firstLifeAboutText = string.Empty; - image = UUID.Zero; - firstLifeImage = UUID.Zero; - partner = UUID.Zero; - - remoteClient.SendAvatarProperties(avatarID, aboutText, - Util.ToDateTime(created).ToString( - "M/d/yyyy", CultureInfo.InvariantCulture), - charterMember, firstLifeAboutText, - (uint)(0 & 0xff), - firstLifeImage, image, profileUrl, partner); - - //Viewer expects interest data when it asks for properties. - remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText, - skillsMask, skillsText, languages); - } - - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs new file mode 100644 index 0000000..563617d --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -0,0 +1,1386 @@ +/* + * 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 OpenSimulator 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.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Xml; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Mono.Addins; +using OpenSim.Services.Connectors.Hypergrid; + +namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")] + public class UserProfileModule : IProfileModule, INonSharedRegionModule + { + /// + /// Logging + /// + static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // The pair of Dictionaries are used to handle the switching of classified ads + // by maintaining a cache of classified id to creator id mappings and an interest + // count. The entries are removed when the interest count reaches 0. + Dictionary classifiedCache = new Dictionary(); + Dictionary classifiedInterest = new Dictionary(); + + public Scene Scene + { + get; private set; + } + + /// + /// Gets or sets the ConfigSource. + /// + /// + /// The configuration + /// + public IConfigSource Config { + get; + set; + } + + /// + /// Gets or sets the URI to the profile server. + /// + /// + /// The profile server URI. + /// + public string ProfileServerUri { + get; + set; + } + + IProfileModule ProfileModule + { + get; set; + } + + IUserManagement UserManagementModule + { + get; set; + } + + /// + /// Gets or sets a value indicating whether this + /// is enabled. + /// + /// + /// true if enabled; otherwise, false. + /// + public bool Enabled { + get; + set; + } + + #region IRegionModuleBase implementation + /// + /// This is called to initialize the region module. For shared modules, this is called exactly once, after + /// creating the single (shared) instance. For non-shared modules, this is called once on each instance, after + /// the instace for the region has been created. + /// + /// + /// Source. + /// + public void Initialise(IConfigSource source) + { + Config = source; + + IConfig profileConfig = Config.Configs["Profile"]; + + if (profileConfig == null) + { + Enabled = false; + return; + } + + // If we find ProfileURL then we configure for FULL support + // else we setup for BASIC support + ProfileServerUri = profileConfig.GetString("ProfileURL", ""); + if (ProfileServerUri == "") + { + m_log.Info("[PROFILES] UserProfiles module is activated in BASIC mode"); + Enabled = false; + return; + } + else + { + m_log.Info("[PROFILES] UserProfiles module is activated in FULL mode"); + Enabled = true; + } + } + + /// + /// Adds the region. + /// + /// + /// Scene. + /// + public void AddRegion(Scene scene) + { + Scene = scene; + Scene.RegisterModuleInterface(this); + Scene.EventManager.OnNewClient += OnNewClient; + Scene.EventManager.OnMakeRootAgent += HandleOnMakeRootAgent; + + UserManagementModule = Scene.RequestModuleInterface(); + } + + void HandleOnMakeRootAgent (ScenePresence obj) + { + GetImageAssets(((IScenePresence)obj).UUID); + } + + /// + /// Removes the region. + /// + /// + /// Scene. + /// + public void RemoveRegion(Scene scene) + { + } + + /// + /// This will be called once for every scene loaded. In a shared module this will be multiple times in one + /// instance, while a nonshared module instance will only be called once. This method is called after AddRegion + /// has been called in all modules for that scene, providing an opportunity to request another module's + /// interface, or hook an event from another module. + /// + /// + /// Scene. + /// + public void RegionLoaded(Scene scene) + { + } + + /// + /// If this returns non-null, it is the type of an interface that this module intends to register. This will + /// cause the loader to defer loading of this module until all other modules have been loaded. If no other + /// module has registered the interface by then, this module will be activated, else it will remain inactive, + /// letting the other module take over. This should return non-null ONLY in modules that are intended to be + /// easily replaceable, e.g. stub implementations that the developer expects to be replaced by third party + /// provided modules. + /// + /// + /// The replaceable interface. + /// + public Type ReplaceableInterface + { + get { return typeof(IProfileModule); } + } + + /// + /// Called as the instance is closed. + /// + public void Close() + { + } + + /// + /// The name of the module + /// + /// + /// Gets the module name. + /// + public string Name + { + get { return "UserProfileModule"; } + } + #endregion IRegionModuleBase implementation + + #region Region Event Handlers + /// + /// Raises the new client event. + /// + /// + /// Client. + /// + void OnNewClient(IClientAPI client) + { + // Basic or Full module? + if(!Enabled) + { + client.OnRequestAvatarProperties += BasicRequestProperties; + return; + } + + //Profile + client.OnRequestAvatarProperties += RequestAvatarProperties; + client.OnUpdateAvatarProperties += AvatarPropertiesUpdate; + client.OnAvatarInterestUpdate += AvatarInterestsUpdate; + + // Classifieds + client.AddGenericPacketHandler("avatarclassifiedsrequest", ClassifiedsRequest); + client.OnClassifiedInfoUpdate += ClassifiedInfoUpdate; + client.OnClassifiedInfoRequest += ClassifiedInfoRequest; + client.OnClassifiedDelete += ClassifiedDelete; + + // Picks + client.AddGenericPacketHandler("avatarpicksrequest", PicksRequest); + client.AddGenericPacketHandler("pickinforequest", PickInfoRequest); + client.OnPickInfoUpdate += PickInfoUpdate; + client.OnPickDelete += PickDelete; + + // Notes + client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest); + client.OnAvatarNotesUpdate += NotesUpdate; + } + #endregion Region Event Handlers + + #region Classified + /// + /// + /// Handles the avatar classifieds request. + /// + /// + /// Sender. + /// + /// + /// Method. + /// + /// + /// Arguments. + /// + public void ClassifiedsRequest(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + + IClientAPI remoteClient = (IClientAPI)sender; + + UUID targetID; + UUID.TryParse(args[0], out targetID); + + // Can't handle NPC yet... + ScenePresence p = FindPresence(targetID); + + if (null != p) + { + if (p.PresenceType == PresenceType.Npc) + return; + } + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(targetID, out serverURI); + UUID creatorId = UUID.Zero; + + OSDMap parameters= new OSDMap(); + UUID.TryParse(args[0], out creatorId); + parameters.Add("creatorId", OSD.FromUUID(creatorId)); + OSD Params = (OSD)parameters; + if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) + { + // Error Handling here! + // if(parameters.ContainsKey("message") + } + + parameters = (OSDMap)Params; + + OSDArray list = (OSDArray)parameters["result"]; + + Dictionary classifieds = new Dictionary(); + + foreach(OSD map in list) + { + OSDMap m = (OSDMap)map; + UUID cid = m["classifieduuid"].AsUUID(); + string name = m["name"].AsString(); + + classifieds[cid] = name; + + if(!classifiedCache.ContainsKey(cid)) + { + classifiedCache.Add(cid,creatorId); + classifiedInterest.Add(cid, 0); + } + + classifiedInterest[cid] ++; + } + + remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds); + } + + public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient) + { + UUID target = remoteClient.AgentId; + UserClassifiedAdd ad = new UserClassifiedAdd(); + ad.ClassifiedId = queryClassifiedID; + + if(classifiedCache.ContainsKey(queryClassifiedID)) + { + target = classifiedCache[queryClassifiedID]; + + if(classifiedInterest[queryClassifiedID] -- == 0) + { + lock(classifiedCache) + { + lock(classifiedInterest) + { + classifiedInterest.Remove(queryClassifiedID); + } + classifiedCache.Remove(queryClassifiedID); + } + } + } + + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(target, out serverURI); + + object Ad = (object)ad; + if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error getting classified info", false); + return; + } + ad = (UserClassifiedAdd) Ad; + + if(ad.CreatorId == UUID.Zero) + return; + + Vector3 globalPos = new Vector3(); + Vector3.TryParse(ad.GlobalPos, out globalPos); + + remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate, (uint)ad.ExpirationDate, + (uint)ad.Category, ad.Name, ad.Description, ad.ParcelId, (uint)ad.ParentEstate, + ad.SnapshotId, ad.SimName, globalPos, ad.ParcelName, ad.Flags, ad.Price); + + } + + /// + /// Classifieds info update. + /// + /// + /// Queryclassified I. + /// + /// + /// Query category. + /// + /// + /// Query name. + /// + /// + /// Query description. + /// + /// + /// Query parcel I. + /// + /// + /// Query parent estate. + /// + /// + /// Query snapshot I. + /// + /// + /// Query global position. + /// + /// + /// Queryclassified flags. + /// + /// + /// Queryclassified price. + /// + /// + /// Remote client. + /// + public void ClassifiedInfoUpdate(UUID queryclassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID, + uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, + int queryclassifiedPrice, IClientAPI remoteClient) + { + UserClassifiedAdd ad = new UserClassifiedAdd(); + + Scene s = (Scene) remoteClient.Scene; + Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; + ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); + ScenePresence p = FindPresence(remoteClient.AgentId); + Vector3 avaPos = p.AbsolutePosition; + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + + if (land == null) + { + ad.ParcelName = string.Empty; + } + else + { + ad.ParcelName = land.LandData.Name; + } + + ad.CreatorId = remoteClient.AgentId; + ad.ClassifiedId = queryclassifiedID; + ad.Category = Convert.ToInt32(queryCategory); + ad.Name = queryName; + ad.Description = queryDescription; + ad.ParentEstate = Convert.ToInt32(queryParentEstate); + ad.SnapshotId = querySnapshotID; + ad.SimName = remoteClient.Scene.RegionInfo.RegionName; + ad.GlobalPos = queryGlobalPos.ToString (); + ad.Flags = queryclassifiedFlags; + ad.Price = queryclassifiedPrice; + ad.ParcelId = p.currentParcelUUID; + + object Ad = ad; + + OSD X = OSD.SerializeMembers(Ad); + + if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error updating classified", false); + } + } + + /// + /// Classifieds delete. + /// + /// + /// Query classified I. + /// + /// + /// Remote client. + /// + public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) + { + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + + UUID classifiedId; + OSDMap parameters= new OSDMap(); + UUID.TryParse(queryClassifiedID.ToString(), out classifiedId); + parameters.Add("classifiedId", OSD.FromUUID(classifiedId)); + OSD Params = (OSD)parameters; + if(!JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error classified delete", false); + } + + parameters = (OSDMap)Params; + } + #endregion Classified + + #region Picks + /// + /// Handles the avatar picks request. + /// + /// + /// Sender. + /// + /// + /// Method. + /// + /// + /// Arguments. + /// + public void PicksRequest(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + + IClientAPI remoteClient = (IClientAPI)sender; + + UUID targetId; + UUID.TryParse(args[0], out targetId); + + // Can't handle NPC yet... + ScenePresence p = FindPresence(targetId); + + if (null != p) + { + if (p.PresenceType == PresenceType.Npc) + return; + } + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(targetId, out serverURI); + + OSDMap parameters= new OSDMap(); + parameters.Add("creatorId", OSD.FromUUID(targetId)); + OSD Params = (OSD)parameters; + if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error requesting picks", false); + return; + } + + parameters = (OSDMap)Params; + + OSDArray list = (OSDArray)parameters["result"]; + + Dictionary picks = new Dictionary(); + + foreach(OSD map in list) + { + OSDMap m = (OSDMap)map; + UUID cid = m["pickuuid"].AsUUID(); + string name = m["name"].AsString(); + + m_log.DebugFormat("[PROFILES]: PicksRequest {0}", name); + + picks[cid] = name; + } + remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks); + } + + /// + /// Handles the pick info request. + /// + /// + /// Sender. + /// + /// + /// Method. + /// + /// + /// Arguments. + /// + public void PickInfoRequest(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + + UUID targetID; + UUID.TryParse(args[0], out targetID); + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(targetID, out serverURI); + IClientAPI remoteClient = (IClientAPI)sender; + + UserProfilePick pick = new UserProfilePick(); + UUID.TryParse(args[0], out pick.CreatorId); + UUID.TryParse(args[1], out pick.PickId); + + + object Pick = (object)pick; + if(!JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error selecting pick", false); + } + pick = (UserProfilePick) Pick; + if(pick.SnapshotId == UUID.Zero) + { + // In case of a new UserPick, the data may not be ready and we would send wrong data, skip it... + m_log.DebugFormat("[PROFILES]: PickInfoRequest: SnapshotID is {0}", UUID.Zero.ToString()); + return; + } + + Vector3 globalPos; + Vector3.TryParse(pick.GlobalPos,out globalPos); + + m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString()); + + remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, + pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName, + globalPos,pick.SortOrder,pick.Enabled); + } + + /// + /// Updates the userpicks + /// + /// + /// Remote client. + /// + /// + /// Pick I. + /// + /// + /// the creator of the pick + /// + /// + /// Top pick. + /// + /// + /// Name. + /// + /// + /// Desc. + /// + /// + /// Snapshot I. + /// + /// + /// Sort order. + /// + /// + /// Enabled. + /// + public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled) + { + + m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); + UserProfilePick pick = new UserProfilePick(); + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + ScenePresence p = FindPresence(remoteClient.AgentId); + + Vector3 avaPos = p.AbsolutePosition; + // Getting the global position for the Avatar + Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X, + remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y, + avaPos.Z); + + string landOwnerName = string.Empty; + ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y); + if(land.LandData.IsGroupOwned) + { + IGroupsModule groupMod = p.Scene.RequestModuleInterface(); + UUID groupId = land.LandData.GroupID; + GroupRecord groupRecord = groupMod.GetGroupRecord(groupId); + landOwnerName = groupRecord.GroupName; + } + else + { + IUserAccountService accounts = p.Scene.RequestModuleInterface(); + UserAccount user = accounts.GetUserAccount(p.Scene.RegionInfo.ScopeID, land.LandData.OwnerID); + landOwnerName = user.Name; + } + + pick.PickId = pickID; + pick.CreatorId = creatorID; + pick.TopPick = topPick; + pick.Name = name; + pick.Desc = desc; + pick.ParcelId = p.currentParcelUUID; + pick.SnapshotId = snapshotID; + pick.User = landOwnerName; + pick.SimName = remoteClient.Scene.RegionInfo.RegionName; + pick.GlobalPos = posGlobal.ToString(); + pick.SortOrder = sortOrder; + pick.Enabled = enabled; + + object Pick = (object)pick; + if(!JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error updating pick", false); + } + + m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString()); + } + + /// + /// Delete a Pick + /// + /// + /// Remote client. + /// + /// + /// Query pick I. + /// + public void PickDelete(IClientAPI remoteClient, UUID queryPickID) + { + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + + OSDMap parameters= new OSDMap(); + parameters.Add("pickId", OSD.FromUUID(queryPickID)); + OSD Params = (OSD)parameters; + if(!JsonRpcRequest(ref Params, "picks_delete", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error picks delete", false); + } + } + #endregion Picks + + #region Notes + /// + /// Handles the avatar notes request. + /// + /// + /// Sender. + /// + /// + /// Method. + /// + /// + /// Arguments. + /// + public void NotesRequest(Object sender, string method, List args) + { + UserProfileNotes note = new UserProfileNotes(); + + if (!(sender is IClientAPI)) + return; + + IClientAPI remoteClient = (IClientAPI)sender; + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + note.TargetId = remoteClient.AgentId; + UUID.TryParse(args[0], out note.UserId); + + object Note = (object)note; + if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error requesting note", false); + } + note = (UserProfileNotes) Note; + + remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes); + } + + /// + /// Avatars the notes update. + /// + /// + /// Remote client. + /// + /// + /// Query target I. + /// + /// + /// Query notes. + /// + public void NotesUpdate(IClientAPI remoteClient, UUID queryTargetID, string queryNotes) + { + UserProfileNotes note = new UserProfileNotes(); + + note.UserId = remoteClient.AgentId; + note.TargetId = queryTargetID; + note.Notes = queryNotes; + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + + object Note = note; + if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error updating note", false); + } + } + #endregion Notes + + #region Avatar Properties + /// + /// Update the avatars interests . + /// + /// + /// Remote client. + /// + /// + /// Wantmask. + /// + /// + /// Wanttext. + /// + /// + /// Skillsmask. + /// + /// + /// Skillstext. + /// + /// + /// Languages. + /// + public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) + { + UserProfileProperties prop = new UserProfileProperties(); + + prop.UserId = remoteClient.AgentId; + prop.WantToMask = (int)wantmask; + prop.WantToText = wanttext; + prop.SkillsMask = (int)skillsmask; + prop.SkillsText = skillstext; + prop.Language = languages; + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + + object Param = prop; + if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error updating interests", false); + } + } + + public void BasicRequestProperties(IClientAPI remoteClient, UUID avatarID) + { + IScene s = remoteClient.Scene; + if (!(s is Scene)) + return; + + string profileUrl = String.Empty; + string aboutText = String.Empty; + string firstLifeAboutText = String.Empty; + UUID image = UUID.Zero; + UUID firstLifeImage = UUID.Zero; + UUID partner = UUID.Zero; + uint wantMask = 0; + string wantText = String.Empty; + uint skillsMask = 0; + string skillsText = String.Empty; + string languages = String.Empty; + + UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID); + + string name = "Avatar"; + int created = 0; + if (account != null) + { + name = account.FirstName + " " + account.LastName; + created = account.Created; + } + Byte[] charterMember = Utils.StringToBytes(name); + + profileUrl = "No profile data"; + aboutText = string.Empty; + firstLifeAboutText = string.Empty; + image = UUID.Zero; + firstLifeImage = UUID.Zero; + partner = UUID.Zero; + + remoteClient.SendAvatarProperties(avatarID, aboutText, + Util.ToDateTime(created).ToString( + "M/d/yyyy", CultureInfo.InvariantCulture), + charterMember, firstLifeAboutText, + (uint)(0 & 0xff), + firstLifeImage, image, profileUrl, partner); + + //Viewer expects interest data when it asks for properties. + remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText, + skillsMask, skillsText, languages); + } + + /// + /// Requests the avatar properties. + /// + /// + /// Remote client. + /// + /// + /// Avatar I. + /// + public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) + { + if ( String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString())) + { + // Looking for a reason that some viewers are sending null Id's + m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID); + return; + } + + // Can't handle NPC yet... + ScenePresence p = FindPresence(avatarID); + + if (null != p) + { + if (p.PresenceType == PresenceType.Npc) + return; + } + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(avatarID, out serverURI); + + UserAccount account = null; + Dictionary userInfo; + + if (!foreign) + { + account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID); + } + else + { + userInfo = new Dictionary(); + } + + Byte[] charterMember = new Byte[1]; + string born = String.Empty; + uint flags = 0x00; + + if (null != account) + { + if (account.UserTitle == "") + { + charterMember[0] = (Byte)((account.UserFlags & 0xf00) >> 8); + } + else + { + charterMember = Utils.StringToBytes(account.UserTitle); + } + + born = Util.ToDateTime(account.Created).ToString( + "M/d/yyyy", CultureInfo.InvariantCulture); + flags = (uint)(account.UserFlags & 0xff); + } + else + { + if (GetUserAccountData(avatarID, out userInfo) == true) + { + if ((string)userInfo["user_title"] == "") + { + charterMember[0] = (Byte)(((Byte)userInfo["user_flags"] & 0xf00) >> 8); + } + else + { + charterMember = Utils.StringToBytes((string)userInfo["user_title"]); + } + + int val_born = (int)userInfo["user_created"]; + born = Util.ToDateTime(val_born).ToString( + "M/d/yyyy", CultureInfo.InvariantCulture); + + // picky, picky + int val_flags = (int)userInfo["user_flags"]; + flags = (uint)(val_flags & 0xff); + } + } + + UserProfileProperties props = new UserProfileProperties(); + string result = string.Empty; + + props.UserId = avatarID; + GetProfileData(ref props, out result); + + remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags, + props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); + + + remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, + props.SkillsText, props.Language); + } + + /// + /// Updates the avatar properties. + /// + /// + /// Remote client. + /// + /// + /// New profile. + /// + public void AvatarPropertiesUpdate(IClientAPI remoteClient, UserProfileData newProfile) + { + if (remoteClient.AgentId == newProfile.ID) + { + UserProfileProperties prop = new UserProfileProperties(); + + prop.UserId = remoteClient.AgentId; + prop.WebUrl = newProfile.ProfileUrl; + prop.ImageId = newProfile.Image; + prop.AboutText = newProfile.AboutText; + prop.FirstLifeImageId = newProfile.FirstLifeImage; + prop.FirstLifeText = newProfile.FirstLifeAboutText; + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + + object Prop = prop; + + if(!JsonRpcRequest(ref Prop, "avatar_properties_update", serverURI, UUID.Random().ToString())) + { + remoteClient.SendAgentAlertMessage( + "Error updating properties", false); + } + + RequestAvatarProperties(remoteClient, newProfile.ID); + } + } + + + /// + /// Gets the profile data. + /// + /// + /// The profile data. + /// + /// + /// User I. + /// + bool GetProfileData(ref UserProfileProperties properties, out string message) + { + // Can't handle NPC yet... + ScenePresence p = FindPresence(properties.UserId); + + if (null != p) + { + if (p.PresenceType == PresenceType.Npc) + { + message = "Id points to NPC"; + return false; + } + } + + string serverURI = string.Empty; + bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); + + // This is checking a friend on the home grid + // Not HG friend + if ( String.IsNullOrEmpty(serverURI)) + { + message = "No Presence - foreign friend"; + return false; + } + + object Prop = (object)properties; + JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString()); + properties = (UserProfileProperties)Prop; + + message = "Success"; + return true; + } + #endregion Avatar Properties + + #region Utils + bool GetImageAssets(UUID avatarId) + { + string profileServerURI = string.Empty; + string assetServerURI = string.Empty; + + bool foreign = GetUserProfileServerURI(avatarId, out profileServerURI); + + if(!foreign) + return true; + + assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI"); + + OSDMap parameters= new OSDMap(); + parameters.Add("avatarId", OSD.FromUUID(avatarId)); + OSD Params = (OSD)parameters; + if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString())) + { + // Error Handling here! + // if(parameters.ContainsKey("message") + return false; + } + + parameters = (OSDMap)Params; + + OSDArray list = (OSDArray)parameters["result"]; + + foreach(OSD asset in list) + { + OSDString assetId = (OSDString)asset; + + Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString()), this, + delegate (string assetID, Object s, AssetBase a) + { + // m_log.DebugFormat("[PROFILES]: Getting Image Assets {0}", assetID); + return; + }); + } + return true; + } + + /// + /// Gets the user account data. + /// + /// + /// The user profile data. + /// + /// + /// If set to true user I. + /// + /// + /// If set to true user info. + /// + bool GetUserAccountData(UUID userID, out Dictionary userInfo) + { + Dictionary info = new Dictionary(); + + if (UserManagementModule.IsLocalGridUser(userID)) + { + // Is local + IUserAccountService uas = Scene.UserAccountService; + UserAccount account = uas.GetUserAccount(Scene.RegionInfo.ScopeID, userID); + + info["user_flags"] = account.UserFlags; + info["user_created"] = account.Created; + + if (!String.IsNullOrEmpty(account.UserTitle)) + info["user_title"] = account.UserTitle; + else + info["user_title"] = ""; + + userInfo = info; + + return false; + } + else + { + // Is Foreign + string home_url = UserManagementModule.GetUserServerURL(userID, "HomeURI"); + + if (String.IsNullOrEmpty(home_url)) + { + info["user_flags"] = 0; + info["user_created"] = 0; + info["user_title"] = "Unavailable"; + + userInfo = info; + return true; + } + + UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); + + Dictionary account = uConn.GetUserInfo(userID); + + if (account.Count > 0) + { + if (account.ContainsKey("user_flags")) + info["user_flags"] = account["user_flags"]; + else + info["user_flags"] = ""; + + if (account.ContainsKey("user_created")) + info["user_created"] = account["user_created"]; + else + info["user_created"] = ""; + + info["user_title"] = "HG Visitor"; + } + else + { + info["user_flags"] = 0; + info["user_created"] = 0; + info["user_title"] = "HG Visitor"; + } + userInfo = info; + return true; + } + } + + /// + /// Gets the user profile server UR. + /// + /// + /// The user profile server UR. + /// + /// + /// If set to true user I. + /// + /// + /// If set to true server UR. + /// + bool GetUserProfileServerURI(UUID userID, out string serverURI) + { + bool local; + local = UserManagementModule.IsLocalGridUser(userID); + + if (!local) + { + serverURI = UserManagementModule.GetUserServerURL(userID, "ProfileServerURI"); + // Is Foreign + return true; + } + else + { + serverURI = ProfileServerUri; + // Is local + return false; + } + } + + /// + /// Finds the presence. + /// + /// + /// The presence. + /// + /// + /// Client I. + /// + ScenePresence FindPresence(UUID clientID) + { + ScenePresence p; + + p = Scene.GetScenePresence(clientID); + if (p != null && !p.IsChildAgent) + return p; + + return null; + } + #endregion Util + + #region Web Util + /// + /// Sends json-rpc request with a serializable type. + /// + /// + /// OSD Map. + /// + /// + /// Serializable type . + /// + /// + /// Json-rpc method to call. + /// + /// + /// URI of json-rpc service. + /// + /// + /// Id for our call. + /// + bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId) + { + if (jsonId == null) + throw new ArgumentNullException ("jsonId"); + if (uri == null) + throw new ArgumentNullException ("uri"); + if (method == null) + throw new ArgumentNullException ("method"); + if (parameters == null) + throw new ArgumentNullException ("parameters"); + + // Prep our payload + OSDMap json = new OSDMap(); + + json.Add("jsonrpc", OSD.FromString("2.0")); + json.Add("id", OSD.FromString(jsonId)); + json.Add("method", OSD.FromString(method)); + // Experiment + json.Add("params", OSD.SerializeMembers(parameters)); + + string jsonRequestData = OSDParser.SerializeJsonString(json); + byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); + + HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); + // webRequest.Credentials = new NetworkCredential(rpcUser, rpcPass); + webRequest.ContentType = "application/json-rpc"; + webRequest.Method = "POST"; + + Stream dataStream = webRequest.GetRequestStream(); + dataStream.Write(content, 0, content.Length); + dataStream.Close(); + + WebResponse webResponse = null; + try + { + webResponse = webRequest.GetResponse(); + } + catch (WebException e) + { + Console.WriteLine("Web Error" + e.Message); + Console.WriteLine ("Please check input"); + return false; + } + + byte[] buf = new byte[8192]; + Stream rstream = webResponse.GetResponseStream(); + OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); + + if(mret.ContainsKey("error")) + return false; + + // get params... + OSD.DeserializeMembers(ref parameters, (OSDMap) mret["result"]); + return true; + } + + /// + /// Sends json-rpc request with OSD parameter. + /// + /// + /// The rpc request. + /// + /// + /// data - incoming as parameters, outgong as result/error + /// + /// + /// Json-rpc method to call. + /// + /// + /// URI of json-rpc service. + /// + /// + /// If set to true json identifier. + /// + bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId) + { + OSDMap map = new OSDMap(); + + map["jsonrpc"] = "2.0"; + if(string.IsNullOrEmpty(jsonId)) + map["id"] = UUID.Random().ToString(); + else + map["id"] = jsonId; + + map["method"] = method; + map["params"] = data; + + string jsonRequestData = OSDParser.SerializeJsonString(map); + byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); + + HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); + webRequest.ContentType = "application/json-rpc"; + webRequest.Method = "POST"; + + Stream dataStream = webRequest.GetRequestStream(); + dataStream.Write(content, 0, content.Length); + dataStream.Close(); + + WebResponse webResponse = null; + try + { + webResponse = webRequest.GetResponse(); + } + catch (WebException e) + { + Console.WriteLine("Web Error" + e.Message); + Console.WriteLine ("Please check input"); + return false; + } + + byte[] buf = new byte[8192]; + Stream rstream = webResponse.GetResponseStream(); + + OSDMap response = new OSDMap(); + response = (OSDMap)OSDParser.DeserializeJson(rstream); + if(response.ContainsKey("error")) + { + data = response["error"]; + return false; + } + + data = response; + + return true; + } + #endregion Web Util + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs new file mode 100644 index 0000000..323535a --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs @@ -0,0 +1,226 @@ + +/* + * 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 OpenSimulator 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 log4net; +using Mono.Addins; +using Nini.Config; +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Server.Base; +using OpenSim.Server.Handlers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalUserProfilesServicesConnector")] + public class LocalUserProfilesServicesConnector : ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private Dictionary regions = new Dictionary(); + + public IUserProfilesService ServiceModule + { + get; private set; + } + + public bool Enabled + { + get; private set; + } + + public string Name + { + get + { + return "LocalUserProfilesServicesConnector"; + } + } + + public string ConfigName + { + get; private set; + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public LocalUserProfilesServicesConnector() + { + m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector no params"); + } + + public LocalUserProfilesServicesConnector(IConfigSource source) + { + m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector instantiated directly."); + InitialiseService(source); + } + + public void InitialiseService(IConfigSource source) + { + ConfigName = "UserProfilesService"; + + // Instantiate the request handler + IHttpServer Server = MainServer.Instance; + + IConfig config = source.Configs[ConfigName]; + if (config == null) + { + m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: UserProfilesService missing from OpenSim.ini"); + return; + } + + if(!config.GetBoolean("Enabled",false)) + { + Enabled = false; + return; + } + + Enabled = true; + + string serviceDll = config.GetString("LocalServiceModule", + String.Empty); + + if (serviceDll == String.Empty) + { + m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: No LocalServiceModule named in section UserProfilesService"); + return; + } + + Object[] args = new Object[] { source, ConfigName }; + ServiceModule = + ServerUtils.LoadPlugin(serviceDll, + args); + + if (ServiceModule == null) + { + m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: Can't load user profiles service"); + return; + } + + Enabled = true; + + JsonRpcProfileHandlers handler = new JsonRpcProfileHandlers(ServiceModule); + + Server.AddJsonRPCHandler("avatarclassifiedsrequest", handler.AvatarClassifiedsRequest); + Server.AddJsonRPCHandler("classified_update", handler.ClassifiedUpdate); + Server.AddJsonRPCHandler("classifieds_info_query", handler.ClassifiedInfoRequest); + Server.AddJsonRPCHandler("classified_delete", handler.ClassifiedDelete); + Server.AddJsonRPCHandler("avatarpicksrequest", handler.AvatarPicksRequest); + Server.AddJsonRPCHandler("pickinforequest", handler.PickInfoRequest); + Server.AddJsonRPCHandler("picks_update", handler.PicksUpdate); + Server.AddJsonRPCHandler("picks_delete", handler.PicksDelete); + Server.AddJsonRPCHandler("avatarnotesrequest", handler.AvatarNotesRequest); + Server.AddJsonRPCHandler("avatar_notes_update", handler.NotesUpdate); + Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest); + Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate); + Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate); + Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest); + Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData); + Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData); + + } + + #region ISharedRegionModule implementation + + void ISharedRegionModule.PostInitialise() + { + if(!Enabled) + return; + } + + #endregion + + #region IRegionModuleBase implementation + + void IRegionModuleBase.Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("UserProfilesServices", ""); + if (name == Name) + { + InitialiseService(source); + m_log.Info("[LOCAL USERPROFILES SERVICE CONNECTOR]: Local user profiles connector enabled"); + } + } + } + + void IRegionModuleBase.Close() + { + return; + } + + void IRegionModuleBase.AddRegion(Scene scene) + { + if (!Enabled) + return; + + lock (regions) + { + if (regions.ContainsKey(scene.RegionInfo.RegionID)) + m_log.ErrorFormat("[LOCAL USERPROFILES SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); + else + regions.Add(scene.RegionInfo.RegionID, scene); + } + } + + void IRegionModuleBase.RemoveRegion(Scene scene) + { + if (!Enabled) + return; + + lock (regions) + { + if (regions.ContainsKey(scene.RegionInfo.RegionID)) + regions.Remove(scene.RegionInfo.RegionID); + } + } + + void IRegionModuleBase.RegionLoaded(Scene scene) + { + if (!Enabled) + return; + } + #endregion + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index c32820e..3849a3f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public LocalGridServicesConnector() { + m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector no parms."); } public LocalGridServicesConnector(IConfigSource source) -- cgit v1.1