PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/Aurora/Services/DataService/Connectors/Local/LocalProfileConnector.cs

https://bitbucket.org/VirtualReality/aurora-sim
C# | 359 lines | 249 code | 59 blank | 51 comment | 70 complexity | 55f11057c26b4e29b8e90cec08ae1025 MD5 | raw file
  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Aurora-Sim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System.Collections.Generic;
  28. using Aurora.Framework;
  29. using Nini.Config;
  30. using OpenMetaverse;
  31. using OpenMetaverse.StructuredData;
  32. namespace Aurora.Services.DataService
  33. {
  34. public class LocalProfileConnector : ConnectorBase, IProfileConnector
  35. {
  36. //We can use a cache because we are the only place that profiles will be served from
  37. private readonly Dictionary<UUID, IUserProfileInfo> UserProfilesCache = new Dictionary<UUID, IUserProfileInfo>();
  38. private IGenericData GD;
  39. #region IProfileConnector Members
  40. public void Initialize(IGenericData GenericData, IConfigSource source, IRegistryCore simBase,
  41. string defaultConnectionString)
  42. {
  43. GD = GenericData;
  44. if (source.Configs[Name] != null)
  45. defaultConnectionString = source.Configs[Name].GetString("ConnectionString", defaultConnectionString);
  46. GD.ConnectToDatabase(defaultConnectionString, "Agent",
  47. source.Configs["AuroraConnectors"].GetBoolean("ValidateTables", true));
  48. DataManager.DataManager.RegisterPlugin(Name + "Local", this);
  49. if (source.Configs["AuroraConnectors"].GetString("ProfileConnector", "LocalConnector") == "LocalConnector")
  50. {
  51. DataManager.DataManager.RegisterPlugin(this);
  52. }
  53. Init(simBase, Name);
  54. }
  55. public string Name
  56. {
  57. get { return "IProfileConnector"; }
  58. }
  59. /// <summary>
  60. /// Get a user's profile
  61. /// </summary>
  62. /// <param name = "agentID"></param>
  63. /// <returns></returns>
  64. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  65. public IUserProfileInfo GetUserProfile(UUID agentID)
  66. {
  67. object remoteValue = DoRemote(agentID);
  68. if (remoteValue != null || m_doRemoteOnly)
  69. return (IUserProfileInfo)remoteValue;
  70. IUserProfileInfo UserProfile = new IUserProfileInfo();
  71. //Try from the user profile first before getting from the DB
  72. if (UserProfilesCache.TryGetValue(agentID, out UserProfile))
  73. return UserProfile;
  74. var connector = GetWhetherUserIsForeign(agentID);
  75. if (connector != null)
  76. return connector.GetUserProfile(agentID);
  77. QueryFilter filter = new QueryFilter();
  78. filter.andFilters["ID"] = agentID;
  79. filter.andFilters["`Key`"] = "LLProfile";
  80. List<string> query = null;
  81. //Grab it from the almost generic interface
  82. query = GD.Query(new[] { "Value" }, "userdata", filter, null, null, null);
  83. if (query == null || query.Count == 0)
  84. return null;
  85. //Pull out the OSDmap
  86. OSDMap profile = (OSDMap) OSDParser.DeserializeLLSDXml(query[0]);
  87. UserProfile = new IUserProfileInfo();
  88. UserProfile.FromOSD(profile);
  89. //Add to the cache
  90. UserProfilesCache[agentID] = UserProfile;
  91. return UserProfile;
  92. }
  93. private IRemoteProfileConnector GetWhetherUserIsForeign(UUID agentID)
  94. {
  95. OpenSim.Services.Interfaces.IUserFinder userFinder = m_registry.RequestModuleInterface<OpenSim.Services.Interfaces.IUserFinder>();
  96. if (userFinder != null && !userFinder.IsLocalGridUser(agentID))
  97. {
  98. string url = userFinder.GetUserServerURL(agentID, "ProfileServerURI");
  99. IRemoteProfileConnector connector = Aurora.DataManager.DataManager.RequestPlugin<IRemoteProfileConnector>();
  100. if (connector != null)
  101. connector.Init(url, m_registry);
  102. return connector;
  103. }
  104. return null;
  105. }
  106. /// <summary>
  107. /// Update a user's profile (Note: this does not work if the user does not have a profile)
  108. /// </summary>
  109. /// <param name = "Profile"></param>
  110. /// <returns></returns>
  111. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  112. public bool UpdateUserProfile(IUserProfileInfo Profile)
  113. {
  114. object remoteValue = DoRemote(Profile);
  115. if (remoteValue != null || m_doRemoteOnly)
  116. return remoteValue != null && (bool)remoteValue;
  117. IUserProfileInfo previousProfile = GetUserProfile(Profile.PrincipalID);
  118. //Make sure the previous one exists
  119. if (previousProfile == null)
  120. return false;
  121. //Now fix values that the sim cannot change
  122. Profile.Partner = previousProfile.Partner;
  123. Profile.CustomType = previousProfile.CustomType;
  124. Profile.MembershipGroup = previousProfile.MembershipGroup;
  125. Profile.Created = previousProfile.Created;
  126. Dictionary<string, object> values = new Dictionary<string, object>(1);
  127. values["Value"] = OSDParser.SerializeLLSDXmlString(Profile.ToOSD());
  128. QueryFilter filter = new QueryFilter();
  129. filter.andFilters["ID"] = Profile.PrincipalID.ToString();
  130. filter.andFilters["`Key`"] = "LLProfile";
  131. //Update cache
  132. UserProfilesCache[Profile.PrincipalID] = Profile;
  133. return GD.Update("userdata", values, null, filter, null, null);
  134. }
  135. /// <summary>
  136. /// Create a new profile for a user
  137. /// </summary>
  138. /// <param name = "AgentID"></param>
  139. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Full)]
  140. public void CreateNewProfile(UUID AgentID)
  141. {
  142. object remoteValue = DoRemote(AgentID);
  143. if (remoteValue != null || m_doRemoteOnly)
  144. return;
  145. List<object> values = new List<object> {AgentID.ToString(), "LLProfile"};
  146. //Create a new basic profile for them
  147. IUserProfileInfo profile = new IUserProfileInfo {PrincipalID = AgentID};
  148. values.Add(OSDParser.SerializeLLSDXmlString(profile.ToOSD())); //Value which is a default Profile
  149. GD.Insert("userdata", values.ToArray());
  150. }
  151. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  152. public bool AddClassified(Classified classified)
  153. {
  154. object remoteValue = DoRemote(classified);
  155. if (remoteValue != null || m_doRemoteOnly)
  156. return remoteValue != null && (bool)remoteValue;
  157. if (GetUserProfile(classified.CreatorUUID) == null)
  158. return false;
  159. string keywords = classified.Description;
  160. if (keywords.Length > 512)
  161. keywords = keywords.Substring(keywords.Length - 512, 512);
  162. //It might be updating, delete the old
  163. QueryFilter filter = new QueryFilter();
  164. filter.andFilters["ClassifiedUUID"] = classified.ClassifiedUUID;
  165. GD.Delete("userclassifieds", filter);
  166. List<object> values = new List<object>{
  167. classified.Name,
  168. classified.Category,
  169. classified.SimName,
  170. classified.CreatorUUID,
  171. classified.ScopeID,
  172. classified.ClassifiedUUID,
  173. OSDParser.SerializeJsonString(classified.ToOSD()),
  174. classified.PriceForListing,
  175. keywords
  176. };
  177. return GD.Insert("userclassifieds", values.ToArray());
  178. }
  179. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  180. public List<Classified> GetClassifieds(UUID ownerID)
  181. {
  182. object remoteValue = DoRemote(ownerID);
  183. if (remoteValue != null || m_doRemoteOnly)
  184. return (List<Classified>)remoteValue;
  185. var connector = GetWhetherUserIsForeign(ownerID);
  186. if (connector != null)
  187. return connector.GetClassifieds(ownerID);
  188. QueryFilter filter = new QueryFilter();
  189. filter.andFilters["OwnerUUID"] = ownerID;
  190. List<string> query = GD.Query(new[] { "*" }, "userclassifieds", filter, null, null, null);
  191. List<Classified> classifieds = new List<Classified>();
  192. for (int i = 0; i < query.Count; i += 9)
  193. {
  194. Classified classified = new Classified();
  195. classified.FromOSD((OSDMap) OSDParser.DeserializeJson(query[i + 6]));
  196. classifieds.Add(classified);
  197. }
  198. return classifieds;
  199. }
  200. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  201. public Classified GetClassified(UUID queryClassifiedID)
  202. {
  203. object remoteValue = DoRemote(queryClassifiedID);
  204. if (remoteValue != null || m_doRemoteOnly)
  205. return (Classified)remoteValue;
  206. QueryFilter filter = new QueryFilter();
  207. filter.andFilters["ClassifiedUUID"] = queryClassifiedID;
  208. List<string> query = GD.Query(new[] { "*" }, "userclassifieds", filter, null, null, null);
  209. if (query.Count < 9)
  210. {
  211. return null;
  212. }
  213. Classified classified = new Classified();
  214. classified.FromOSD((OSDMap) OSDParser.DeserializeJson(query[6]));
  215. return classified;
  216. }
  217. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  218. public void RemoveClassified(UUID queryClassifiedID)
  219. {
  220. object remoteValue = DoRemote(queryClassifiedID);
  221. if (remoteValue != null || m_doRemoteOnly)
  222. return;
  223. QueryFilter filter = new QueryFilter();
  224. filter.andFilters["ClassifiedUUID"] = queryClassifiedID;
  225. GD.Delete("userclassifieds", filter);
  226. }
  227. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  228. public bool AddPick(ProfilePickInfo pick)
  229. {
  230. object remoteValue = DoRemote(pick);
  231. if (remoteValue != null || m_doRemoteOnly)
  232. return remoteValue != null && (bool)remoteValue;
  233. if (GetUserProfile(pick.CreatorUUID) == null)
  234. return false;
  235. //It might be updating, delete the old
  236. QueryFilter filter = new QueryFilter();
  237. filter.andFilters["PickUUID"] = pick.PickUUID;
  238. GD.Delete("userpicks", filter);
  239. List<object> values = new List<object>
  240. {
  241. pick.Name,
  242. pick.SimName,
  243. pick.CreatorUUID,
  244. pick.PickUUID,
  245. OSDParser.SerializeJsonString(pick.ToOSD())
  246. };
  247. return GD.Insert("userpicks", values.ToArray());
  248. }
  249. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  250. public ProfilePickInfo GetPick(UUID queryPickID)
  251. {
  252. object remoteValue = DoRemote(queryPickID);
  253. if (remoteValue != null || m_doRemoteOnly)
  254. return (ProfilePickInfo)remoteValue;
  255. QueryFilter filter = new QueryFilter();
  256. filter.andFilters["PickUUID"] = queryPickID;
  257. List<string> query = GD.Query(new[] { "*" }, "userpicks", filter, null, null, null);
  258. if (query.Count < 5)
  259. return null;
  260. ProfilePickInfo pick = new ProfilePickInfo();
  261. pick.FromOSD((OSDMap) OSDParser.DeserializeJson(query[4]));
  262. return pick;
  263. }
  264. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  265. public List<ProfilePickInfo> GetPicks(UUID ownerID)
  266. {
  267. object remoteValue = DoRemote(ownerID);
  268. if (remoteValue != null || m_doRemoteOnly)
  269. return (List<ProfilePickInfo>)remoteValue;
  270. var connector = GetWhetherUserIsForeign(ownerID);
  271. if (connector != null)
  272. return connector.GetPicks(ownerID);
  273. QueryFilter filter = new QueryFilter();
  274. filter.andFilters["OwnerUUID"] = ownerID;
  275. List<string> query = GD.Query(new[] { "*" }, "userpicks", filter, null, null, null);
  276. List<ProfilePickInfo> picks = new List<ProfilePickInfo>();
  277. for (int i = 0; i < query.Count; i += 5)
  278. {
  279. ProfilePickInfo pick = new ProfilePickInfo();
  280. pick.FromOSD((OSDMap) OSDParser.DeserializeJson(query[i + 4]));
  281. picks.Add(pick);
  282. }
  283. return picks;
  284. }
  285. [CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
  286. public void RemovePick(UUID queryPickID)
  287. {
  288. object remoteValue = DoRemote(queryPickID);
  289. if (remoteValue != null || m_doRemoteOnly)
  290. return;
  291. QueryFilter filter = new QueryFilter();
  292. filter.andFilters["PickUUID"] = queryPickID;
  293. GD.Delete("userpicks", filter);
  294. }
  295. #endregion
  296. public void Dispose()
  297. {
  298. }
  299. }
  300. }