PageRenderTime 68ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/VirtualReality/async-sim-testing
C# | 1306 lines | 990 code | 164 blank | 152 comment | 239 complexity | a44b79b4172db8beeceb589123767eb5 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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 Aurora.Framework.ClientInterfaces;
  28. using Aurora.Framework.DatabaseInterfaces;
  29. using Aurora.Framework.Modules;
  30. using Aurora.Framework.PresenceInfo;
  31. using Aurora.Framework.SceneInfo;
  32. using Aurora.Framework.Services;
  33. using Aurora.Framework.Services.ClassHelpers.Profile;
  34. using Aurora.Framework.Utilities;
  35. using Nini.Config;
  36. using OpenMetaverse;
  37. using OpenMetaverse.StructuredData;
  38. using System;
  39. using System.Collections.Generic;
  40. using System.Globalization;
  41. using System.Linq;
  42. using EventFlags = OpenMetaverse.DirectoryManager.EventFlags;
  43. using GridRegion = Aurora.Framework.Services.GridRegion;
  44. namespace Aurora.Services.DataService
  45. {
  46. public class LocalDirectoryServiceConnector : ConnectorBase, IDirectoryServiceConnector
  47. {
  48. private IGenericData GD;
  49. #region IDirectoryServiceConnector Members
  50. public void Initialize(IGenericData GenericData, IConfigSource source, IRegistryCore simBase,
  51. string defaultConnectionString)
  52. {
  53. GD = GenericData;
  54. m_registry = simBase;
  55. if (source.Configs[Name] != null)
  56. defaultConnectionString = source.Configs[Name].GetString("ConnectionString", defaultConnectionString);
  57. if (GD != null)
  58. GD.ConnectToDatabase(defaultConnectionString, "Directory",
  59. source.Configs["AuroraConnectors"].GetBoolean("ValidateTables", true));
  60. Framework.Utilities.DataManager.RegisterPlugin(Name + "Local", this);
  61. if (source.Configs["AuroraConnectors"].GetString("DirectoryServiceConnector", "LocalConnector") ==
  62. "LocalConnector")
  63. {
  64. Framework.Utilities.DataManager.RegisterPlugin(this);
  65. }
  66. Init(simBase, Name);
  67. }
  68. public string Name
  69. {
  70. get { return "IDirectoryServiceConnector"; }
  71. }
  72. public void Dispose()
  73. {
  74. }
  75. #region Region
  76. /// <summary>
  77. /// This also updates the parcel, not for just adding a new one
  78. /// </summary>
  79. /// <param name="parcels"></param>
  80. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  81. public void AddRegion(List<LandData> parcels)
  82. {
  83. object remoteValue = DoRemote(parcels);
  84. if (remoteValue != null || m_doRemoteOnly)
  85. return;
  86. if (parcels.Count == 0)
  87. return;
  88. ClearRegion(parcels[0].RegionID);
  89. foreach (var parcel in parcels)
  90. {
  91. var OrFilters = new Dictionary<string, object>();
  92. OrFilters.Add("ParcelID", parcel.GlobalID);
  93. OrFilters.Add("InfoUUID", parcel.InfoUUID);
  94. GD.Delete("searchparcel", new QueryFilter {orFilters = OrFilters});
  95. }
  96. List<object[]> insertValues = parcels.Select(args => new List<object>
  97. {
  98. args.RegionID,
  99. args.GlobalID,
  100. args.LocalID,
  101. args.UserLocation.X,
  102. args.UserLocation.Y,
  103. args.UserLocation.Z,
  104. args.Name,
  105. args.Description,
  106. args.Flags,
  107. args.Dwell,
  108. args.InfoUUID,
  109. ((args.Flags & (uint) ParcelFlags.ForSale) ==
  110. (uint) ParcelFlags.ForSale)
  111. ? 1
  112. : 0,
  113. args.SalePrice,
  114. args.AuctionID,
  115. args.Area,
  116. 0,
  117. args.Maturity,
  118. args.OwnerID,
  119. args.GroupID,
  120. ((args.Flags & (uint) ParcelFlags.ShowDirectory) ==
  121. (uint) ParcelFlags.ShowDirectory)
  122. ? 1
  123. : 0,
  124. args.SnapshotID,
  125. OSDParser.SerializeLLSDXmlString(args.Bitmap),
  126. (int) args.Category,
  127. args.ScopeID
  128. }).Select(Values => Values.ToArray()).ToList();
  129. GD.InsertMultiple("searchparcel", insertValues);
  130. }
  131. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  132. public void ClearRegion(UUID regionID)
  133. {
  134. object remoteValue = DoRemote(regionID);
  135. if (remoteValue != null || m_doRemoteOnly)
  136. return;
  137. QueryFilter filter = new QueryFilter();
  138. filter.andFilters["RegionID"] = regionID;
  139. GD.Delete("searchparcel", filter);
  140. }
  141. #endregion
  142. #region Parcels
  143. private static List<LandData> Query2LandData(List<string> Query)
  144. {
  145. List<LandData> Lands = new List<LandData>();
  146. for (int i = 0; i < Query.Count; i += 24)
  147. {
  148. LandData LandData = new LandData
  149. {
  150. RegionID = UUID.Parse(Query[i]),
  151. GlobalID = UUID.Parse(Query[i + 1]),
  152. LocalID = int.Parse(Query[i + 2]),
  153. UserLocation =
  154. new Vector3(float.Parse(Query[i + 3]), float.Parse(Query[i + 4]),
  155. float.Parse(Query[i + 5])),
  156. Name = Query[i + 6],
  157. Description = Query[i + 7],
  158. Flags = uint.Parse(Query[i + 8]),
  159. Dwell = int.Parse(Query[i + 9]),
  160. InfoUUID = UUID.Parse(Query[i + 10]),
  161. AuctionID = uint.Parse(Query[i + 13]),
  162. Area = int.Parse(Query[i + 14]),
  163. Maturity = int.Parse(Query[i + 16]),
  164. OwnerID = UUID.Parse(Query[i + 17]),
  165. GroupID = UUID.Parse(Query[i + 18]),
  166. SnapshotID = UUID.Parse(Query[i + 20])
  167. };
  168. try
  169. {
  170. LandData.Bitmap = OSDParser.DeserializeLLSDXml(Query[i + 21]);
  171. }
  172. catch
  173. {
  174. }
  175. LandData.Category = (string.IsNullOrEmpty(Query[i + 22]))
  176. ? ParcelCategory.None
  177. : (ParcelCategory) int.Parse(Query[i + 22]);
  178. LandData.ScopeID = UUID.Parse(Query[i + 23]);
  179. Lands.Add(LandData);
  180. }
  181. return Lands;
  182. }
  183. /// <summary>
  184. /// Gets a parcel from the search database by Info UUID (the true cross instance parcel ID)
  185. /// </summary>
  186. /// <param name="InfoUUID"></param>
  187. /// <returns></returns>
  188. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  189. public LandData GetParcelInfo(UUID InfoUUID)
  190. {
  191. object remoteValue = DoRemote(InfoUUID);
  192. if (remoteValue != null || m_doRemoteOnly)
  193. return (LandData) remoteValue;
  194. //Split the InfoUUID so that we get the regions, we'll check for positions in a bit
  195. int RegionX, RegionY;
  196. uint X, Y;
  197. ulong RegionHandle;
  198. Util.ParseFakeParcelID(InfoUUID, out RegionHandle, out X, out Y);
  199. Util.UlongToInts(RegionHandle, out RegionX, out RegionY);
  200. GridRegion r = m_registry.RequestModuleInterface<IGridService>().GetRegionByPosition(null, RegionX,
  201. RegionY);
  202. if (r == null)
  203. {
  204. // m_log.Warn("[DirectoryService]: Could not find region for ParcelID: " + InfoUUID);
  205. return null;
  206. }
  207. //Get info about a specific parcel somewhere in the metaverse
  208. QueryFilter filter = new QueryFilter();
  209. filter.andFilters["RegionID"] = r.RegionID;
  210. List<string> Query = GD.Query(new[] {"*"}, "searchparcel", filter, null, null, null);
  211. //Cant find it, return
  212. if (Query.Count == 0)
  213. {
  214. return null;
  215. }
  216. List<LandData> Lands = Query2LandData(Query);
  217. LandData LandData = null;
  218. bool[,] tempConvertMap = new bool[r.RegionSizeX/4,r.RegionSizeX/4];
  219. tempConvertMap.Initialize();
  220. foreach (LandData land in Lands.Where(land => land.Bitmap != null))
  221. {
  222. ConvertBytesToLandBitmap(ref tempConvertMap, land.Bitmap, r.RegionSizeX);
  223. if (tempConvertMap[X/64, Y/64])
  224. {
  225. LandData = land;
  226. break;
  227. }
  228. }
  229. if (LandData == null && Lands.Count != 0)
  230. LandData = Lands[0];
  231. return LandData;
  232. }
  233. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  234. public LandData GetParcelInfo(UUID RegionID, string ParcelName)
  235. {
  236. object remoteValue = DoRemote(RegionID, ParcelName);
  237. if (remoteValue != null || m_doRemoteOnly)
  238. return (LandData) remoteValue;
  239. IRegionData regiondata = Framework.Utilities.DataManager.RequestPlugin<IRegionData>();
  240. if (regiondata != null)
  241. {
  242. GridRegion region = regiondata.Get(RegionID, null);
  243. if (region != null)
  244. {
  245. UUID parcelInfoID = UUID.Zero;
  246. QueryFilter filter = new QueryFilter();
  247. filter.andFilters["RegionID"] = RegionID;
  248. filter.andFilters["Name"] = ParcelName;
  249. List<string> query = GD.Query(new[] {"InfoUUID"}, "searchparcel", filter, null, 0, 1);
  250. if (query.Count >= 1 && UUID.TryParse(query[0], out parcelInfoID))
  251. {
  252. return GetParcelInfo(parcelInfoID);
  253. }
  254. }
  255. }
  256. return null;
  257. }
  258. /// <summary>
  259. /// Gets all parcels owned by the given user
  260. /// </summary>
  261. /// <param name="OwnerID"></param>
  262. /// <returns></returns>
  263. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  264. public List<ExtendedLandData> GetParcelByOwner(UUID OwnerID)
  265. {
  266. //NOTE: this does check for group deeded land as well, so this can check for that as well
  267. object remoteValue = DoRemote(OwnerID);
  268. if (remoteValue != null || m_doRemoteOnly)
  269. return (List<ExtendedLandData>) remoteValue;
  270. QueryFilter filter = new QueryFilter();
  271. filter.andFilters["OwnerID"] = OwnerID;
  272. List<string> Query = GD.Query(new[] {"*"}, "searchparcel", filter, null, null, null);
  273. return (Query.Count == 0) ? new List<ExtendedLandData>() : LandDataToExtendedLandData(Query2LandData(Query));
  274. }
  275. public List<ExtendedLandData> LandDataToExtendedLandData(List<LandData> data)
  276. {
  277. return (from land in data
  278. let region = m_registry.RequestModuleInterface<IGridService>().GetRegionByUUID(null, land.RegionID)
  279. where region != null
  280. select new ExtendedLandData
  281. {
  282. LandData = land,
  283. RegionType = region.RegionType,
  284. RegionName = region.RegionName,
  285. GlobalPosX = region.RegionLocX + land.UserLocation.X,
  286. GlobalPosY = region.RegionLocY + land.UserLocation.Y
  287. }).ToList();
  288. }
  289. private static QueryFilter GetParcelsByRegionWhereClause(UUID RegionID, UUID owner, ParcelFlags flags,
  290. ParcelCategory category)
  291. {
  292. QueryFilter filter = new QueryFilter();
  293. filter.andFilters["RegionID"] = RegionID;
  294. if (owner != UUID.Zero)
  295. {
  296. filter.andFilters["OwnerID"] = owner;
  297. }
  298. if (flags != ParcelFlags.None)
  299. {
  300. filter.andBitfieldAndFilters["Flags"] = (uint) flags;
  301. }
  302. if (category != ParcelCategory.Any)
  303. {
  304. filter.andFilters["Category"] = (int) category;
  305. }
  306. return filter;
  307. }
  308. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  309. public List<LandData> GetParcelsByRegion(uint start, uint count, UUID RegionID, UUID owner, ParcelFlags flags,
  310. ParcelCategory category)
  311. {
  312. object remoteValue = DoRemote(start, count, RegionID, owner, flags, category);
  313. if (remoteValue != null || m_doRemoteOnly)
  314. return (List<LandData>) remoteValue;
  315. List<LandData> resp = new List<LandData>(0);
  316. if (count == 0)
  317. {
  318. return resp;
  319. }
  320. IRegionData regiondata = Framework.Utilities.DataManager.RequestPlugin<IRegionData>();
  321. if (regiondata != null)
  322. {
  323. GridRegion region = regiondata.Get(RegionID, null);
  324. if (region != null)
  325. {
  326. QueryFilter filter = GetParcelsByRegionWhereClause(RegionID, owner, flags, category);
  327. Dictionary<string, bool> sort = new Dictionary<string, bool>(1);
  328. sort["OwnerID"] = false;
  329. return Query2LandData(GD.Query(new[] {"*"}, "searchparcel", filter, sort, start, count));
  330. }
  331. }
  332. return resp;
  333. }
  334. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  335. public uint GetNumberOfParcelsByRegion(UUID RegionID, UUID owner, ParcelFlags flags, ParcelCategory category)
  336. {
  337. object remoteValue = DoRemote(RegionID, owner, flags, category);
  338. if (remoteValue != null || m_doRemoteOnly)
  339. return (uint) remoteValue;
  340. IRegionData regiondata = Framework.Utilities.DataManager.RequestPlugin<IRegionData>();
  341. if (regiondata != null)
  342. {
  343. GridRegion region = regiondata.Get(RegionID, null);
  344. if (region != null)
  345. {
  346. QueryFilter filter = GetParcelsByRegionWhereClause(RegionID, owner, flags, category);
  347. return uint.Parse(GD.Query(new[] {"COUNT(ParcelID)"}, "searchparcel", filter, null, null, null)[0]);
  348. }
  349. }
  350. return 0;
  351. }
  352. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  353. public List<LandData> GetParcelsWithNameByRegion(uint start, uint count, UUID RegionID, string name)
  354. {
  355. object remoteValue = DoRemote(start, count, RegionID, name);
  356. if (remoteValue != null || m_doRemoteOnly)
  357. return (List<LandData>) remoteValue;
  358. List<LandData> resp = new List<LandData>(0);
  359. if (count == 0)
  360. {
  361. return resp;
  362. }
  363. IRegionData regiondata = Framework.Utilities.DataManager.RequestPlugin<IRegionData>();
  364. if (regiondata != null)
  365. {
  366. GridRegion region = regiondata.Get(RegionID, null);
  367. if (region != null)
  368. {
  369. QueryFilter filter = new QueryFilter();
  370. filter.andFilters["RegionID"] = RegionID;
  371. filter.andFilters["Name"] = name;
  372. Dictionary<string, bool> sort = new Dictionary<string, bool>(1);
  373. sort["OwnerID"] = false;
  374. return Query2LandData(GD.Query(new[] {"*"}, "searchparcel", filter, sort, start, count));
  375. }
  376. }
  377. return resp;
  378. }
  379. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  380. public uint GetNumberOfParcelsWithNameByRegion(UUID RegionID, string name)
  381. {
  382. object remoteValue = DoRemote(RegionID, name);
  383. if (remoteValue != null || m_doRemoteOnly)
  384. return (uint) remoteValue;
  385. IRegionData regiondata = Framework.Utilities.DataManager.RequestPlugin<IRegionData>();
  386. if (regiondata != null)
  387. {
  388. GridRegion region = regiondata.Get(RegionID, null);
  389. if (region != null)
  390. {
  391. QueryFilter filter = new QueryFilter();
  392. filter.andFilters["RegionID"] = RegionID;
  393. filter.andFilters["Name"] = name;
  394. return uint.Parse(GD.Query(new[] {"COUNT(ParcelID)"}, "searchparcel", filter, null, null, null)[0]);
  395. }
  396. }
  397. return 0;
  398. }
  399. /// <summary>
  400. /// Searches for parcels around the grid
  401. /// </summary>
  402. /// <param name="queryText"></param>
  403. /// <param name="category"></param>
  404. /// <param name="StartQuery"></param>
  405. /// <param name="Flags"> </param>
  406. /// <param name="scopeID"> </param>
  407. /// <returns></returns>
  408. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  409. public List<DirPlacesReplyData> FindLand(string queryText, string category, int StartQuery, uint Flags,
  410. UUID scopeID)
  411. {
  412. object remoteValue = DoRemote(queryText, category, StartQuery, Flags, scopeID);
  413. if (remoteValue != null || m_doRemoteOnly)
  414. return (List<DirPlacesReplyData>) remoteValue;
  415. QueryFilter filter = new QueryFilter();
  416. Dictionary<string, bool> sort = new Dictionary<string, bool>();
  417. //If they dwell sort flag is there, sort by dwell going down
  418. if ((Flags & (uint) DirectoryManager.DirFindFlags.DwellSort) ==
  419. (uint) DirectoryManager.DirFindFlags.DwellSort)
  420. {
  421. sort["Dwell"] = false;
  422. }
  423. if (scopeID != UUID.Zero)
  424. filter.andFilters["ScopeID"] = scopeID;
  425. filter.orLikeFilters["Name"] = "%" + queryText + "%";
  426. filter.orLikeFilters["Description"] = "%" + queryText + "%";
  427. filter.andFilters["ShowInSearch"] = 1;
  428. if (category != "-1")
  429. filter.andFilters["Category"] = category;
  430. if ((Flags & (uint) DirectoryManager.DirFindFlags.AreaSort) == (uint) DirectoryManager.DirFindFlags.AreaSort)
  431. sort["Area"] = false;
  432. if ((Flags & (uint) DirectoryManager.DirFindFlags.NameSort) == (uint) DirectoryManager.DirFindFlags.NameSort)
  433. sort["Name"] = false;
  434. List<string> retVal = GD.Query(new[]
  435. {
  436. "InfoUUID",
  437. "Name",
  438. "ForSale",
  439. "Auction",
  440. "Dwell",
  441. "Flags"
  442. }, "searchparcel", filter, sort, (uint) StartQuery, 50);
  443. if (retVal.Count == 0)
  444. {
  445. return new List<DirPlacesReplyData>();
  446. }
  447. List<DirPlacesReplyData> Data = new List<DirPlacesReplyData>();
  448. for (int i = 0; i < retVal.Count; i += 6)
  449. {
  450. //Check to make sure we are sending the requested maturity levels
  451. if (
  452. !((int.Parse(retVal[i + 5]) & (int) ParcelFlags.MaturePublish) == (int) ParcelFlags.MaturePublish &&
  453. ((Flags & (uint) DirectoryManager.DirFindFlags.IncludeMature)) == 0))
  454. {
  455. Data.Add(new DirPlacesReplyData
  456. {
  457. parcelID = new UUID(retVal[i]),
  458. name = retVal[i + 1],
  459. forSale = int.Parse(retVal[i + 2]) == 1,
  460. auction = retVal[i + 3] == "0", //Auction is stored as a 0 if there is no auction
  461. dwell = float.Parse(retVal[i + 4])
  462. });
  463. }
  464. }
  465. return Data;
  466. }
  467. /// <summary>
  468. /// Searches for parcels for sale around the grid
  469. /// </summary>
  470. /// <param name="searchType">2 = Auction only, 8 = For Sale - Mainland, 16 = For Sale - Estate, 4294967295 = All</param>
  471. /// <param name="price"></param>
  472. /// <param name="area"></param>
  473. /// <param name="StartQuery"></param>
  474. /// <param name="Flags"> </param>
  475. /// <param name="scopeID"> </param>
  476. /// <returns></returns>
  477. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  478. public List<DirLandReplyData> FindLandForSale(string searchType, uint price, uint area, int StartQuery,
  479. uint Flags, UUID scopeID)
  480. {
  481. object remoteValue = DoRemote(searchType, price, area, StartQuery, Flags, scopeID);
  482. if (remoteValue != null || m_doRemoteOnly)
  483. return (List<DirLandReplyData>) remoteValue;
  484. QueryFilter filter = new QueryFilter();
  485. //Only parcels set for sale will be checked
  486. filter.andFilters["ForSale"] = "1";
  487. if (scopeID != UUID.Zero)
  488. filter.andFilters["ScopeID"] = scopeID;
  489. //They requested a sale price check
  490. if ((Flags & (uint) DirectoryManager.DirFindFlags.LimitByPrice) ==
  491. (uint) DirectoryManager.DirFindFlags.LimitByPrice)
  492. {
  493. filter.andLessThanEqFilters["SalePrice"] = (int) price;
  494. }
  495. //They requested a
  496. if ((Flags & (uint) DirectoryManager.DirFindFlags.LimitByArea) ==
  497. (uint) DirectoryManager.DirFindFlags.LimitByArea)
  498. {
  499. filter.andGreaterThanEqFilters["Area"] = (int) area;
  500. }
  501. Dictionary<string, bool> sort = new Dictionary<string, bool>();
  502. if ((Flags & (uint) DirectoryManager.DirFindFlags.AreaSort) == (uint) DirectoryManager.DirFindFlags.AreaSort)
  503. sort["Area"] = false;
  504. if ((Flags & (uint) DirectoryManager.DirFindFlags.NameSort) == (uint) DirectoryManager.DirFindFlags.NameSort)
  505. sort["Name"] = false;
  506. List<string> retVal = GD.Query(new[]
  507. {
  508. "InfoUUID",
  509. "Name",
  510. "Auction",
  511. "SalePrice",
  512. "Area",
  513. "Flags"
  514. }, "searchparcel", filter, sort, (uint) StartQuery, 50);
  515. //if there are none, return
  516. if (retVal.Count == 0)
  517. return new List<DirLandReplyData>();
  518. List<DirLandReplyData> Data = new List<DirLandReplyData>();
  519. for (int i = 0; i < retVal.Count; i += 6)
  520. {
  521. DirLandReplyData replyData = new DirLandReplyData
  522. {
  523. forSale = true,
  524. parcelID = new UUID(retVal[i]),
  525. name = retVal[i + 1],
  526. auction = (retVal[i + 2] != "0")
  527. };
  528. //If its an auction and we didn't request to see auctions, skip to the next and continue
  529. if ((Flags & (uint) DirectoryManager.SearchTypeFlags.Auction) ==
  530. (uint) DirectoryManager.SearchTypeFlags.Auction && !replyData.auction)
  531. {
  532. continue;
  533. }
  534. replyData.salePrice = Convert.ToInt32(retVal[i + 3]);
  535. replyData.actualArea = Convert.ToInt32(retVal[i + 4]);
  536. //Check maturity levels depending on what flags the user has set
  537. //0 flag is an override so that we can get all lands for sale, regardless of maturity
  538. if (Flags == 0 ||
  539. !((int.Parse(retVal[i + 5]) & (int) ParcelFlags.MaturePublish) == (int) ParcelFlags.MaturePublish &&
  540. ((Flags & (uint) DirectoryManager.DirFindFlags.IncludeMature)) == 0))
  541. {
  542. Data.Add(replyData);
  543. }
  544. }
  545. return Data;
  546. }
  547. /// <summary>
  548. /// Searches for parcels for sale around the grid
  549. /// </summary>
  550. /// <param name="searchType">2 = Auction only, 8 = For Sale - Mainland, 16 = For Sale - Estate, 4294967295 = All</param>
  551. /// <param name="price"></param>
  552. /// <param name="area"></param>
  553. /// <param name="StartQuery"></param>
  554. /// <param name="Flags"> </param>
  555. /// <param name="regionID"> </param>
  556. /// <returns></returns>
  557. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  558. public List<DirLandReplyData> FindLandForSaleInRegion(string searchType, uint price, uint area, int StartQuery,
  559. uint Flags, UUID regionID)
  560. {
  561. object remoteValue = DoRemote(searchType, price, area, StartQuery, Flags, regionID);
  562. if (remoteValue != null || m_doRemoteOnly)
  563. return (List<DirLandReplyData>) remoteValue;
  564. QueryFilter filter = new QueryFilter();
  565. //Only parcels set for sale will be checked
  566. filter.andFilters["ForSale"] = "1";
  567. filter.andFilters["RegionID"] = regionID;
  568. //They requested a sale price check
  569. if ((Flags & (uint) DirectoryManager.DirFindFlags.LimitByPrice) ==
  570. (uint) DirectoryManager.DirFindFlags.LimitByPrice)
  571. {
  572. filter.andLessThanEqFilters["SalePrice"] = (int) price;
  573. }
  574. //They requested a
  575. if ((Flags & (uint) DirectoryManager.DirFindFlags.LimitByArea) ==
  576. (uint) DirectoryManager.DirFindFlags.LimitByArea)
  577. {
  578. filter.andGreaterThanEqFilters["Area"] = (int) area;
  579. }
  580. Dictionary<string, bool> sort = new Dictionary<string, bool>();
  581. if ((Flags & (uint) DirectoryManager.DirFindFlags.AreaSort) == (uint) DirectoryManager.DirFindFlags.AreaSort)
  582. sort["Area"] = false;
  583. if ((Flags & (uint) DirectoryManager.DirFindFlags.NameSort) == (uint) DirectoryManager.DirFindFlags.NameSort)
  584. sort["Name"] = false;
  585. //if ((queryFlags & (uint)DirectoryManager.DirFindFlags.PerMeterSort) == (uint)DirectoryManager.DirFindFlags.PerMeterSort)
  586. // sort["Area"] = (queryFlags & (uint)DirectoryManager.DirFindFlags.SortAsc) == (uint)DirectoryManager.DirFindFlags.SortAsc);
  587. if ((Flags & (uint) DirectoryManager.DirFindFlags.PricesSort) ==
  588. (uint) DirectoryManager.DirFindFlags.PricesSort)
  589. sort["SalePrice"] = (Flags & (uint) DirectoryManager.DirFindFlags.SortAsc) ==
  590. (uint) DirectoryManager.DirFindFlags.SortAsc;
  591. List<string> retVal = GD.Query(new[]
  592. {
  593. "InfoUUID",
  594. "Name",
  595. "Auction",
  596. "SalePrice",
  597. "Area",
  598. "Flags"
  599. }, "searchparcel", filter, sort, (uint) StartQuery, 50);
  600. //if there are none, return
  601. if (retVal.Count == 0)
  602. return new List<DirLandReplyData>();
  603. List<DirLandReplyData> Data = new List<DirLandReplyData>();
  604. for (int i = 0; i < retVal.Count; i += 6)
  605. {
  606. DirLandReplyData replyData = new DirLandReplyData
  607. {
  608. forSale = true,
  609. parcelID = new UUID(retVal[i]),
  610. name = retVal[i + 1],
  611. auction = (retVal[i + 2] != "0")
  612. };
  613. //If its an auction and we didn't request to see auctions, skip to the next and continue
  614. if ((Flags & (uint) DirectoryManager.SearchTypeFlags.Auction) ==
  615. (uint) DirectoryManager.SearchTypeFlags.Auction && !replyData.auction)
  616. {
  617. continue;
  618. }
  619. replyData.salePrice = Convert.ToInt32(retVal[i + 3]);
  620. replyData.actualArea = Convert.ToInt32(retVal[i + 4]);
  621. //Check maturity levels depending on what flags the user has set
  622. //0 flag is an override so that we can get all lands for sale, regardless of maturity
  623. if (Flags == 0 ||
  624. !((int.Parse(retVal[i + 5]) & (int) ParcelFlags.MaturePublish) == (int) ParcelFlags.MaturePublish &&
  625. ((Flags & (uint) DirectoryManager.DirFindFlags.IncludeMature)) == 0))
  626. {
  627. Data.Add(replyData);
  628. }
  629. }
  630. return Data;
  631. }
  632. /// <summary>
  633. /// Searches for the most popular places around the grid
  634. /// </summary>
  635. /// <param name="queryFlags"></param>
  636. /// <param name="scopeID"></param>
  637. /// <returns></returns>
  638. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  639. public List<DirPopularReplyData> FindPopularPlaces(uint queryFlags, UUID scopeID)
  640. {
  641. object remoteValue = DoRemote(queryFlags, scopeID);
  642. if (remoteValue != null || m_doRemoteOnly)
  643. return (List<DirPopularReplyData>) remoteValue;
  644. QueryFilter filter = new QueryFilter();
  645. Dictionary<string, bool> sort = new Dictionary<string, bool>();
  646. if ((queryFlags & (uint) DirectoryManager.DirFindFlags.AreaSort) ==
  647. (uint) DirectoryManager.DirFindFlags.AreaSort)
  648. sort["Area"] = false;
  649. else if ((queryFlags & (uint) DirectoryManager.DirFindFlags.NameSort) ==
  650. (uint) DirectoryManager.DirFindFlags.NameSort)
  651. sort["Name"] = false;
  652. //else if ((queryFlags & (uint)DirectoryManager.DirFindFlags.PerMeterSort) == (uint)DirectoryManager.DirFindFlags.PerMeterSort)
  653. // sort["Area"] = (queryFlags & (uint)DirectoryManager.DirFindFlags.SortAsc) == (uint)DirectoryManager.DirFindFlags.SortAsc);
  654. //else if ((queryFlags & (uint)DirectoryManager.DirFindFlags.PricesSort) == (uint)DirectoryManager.DirFindFlags.PricesSort)
  655. // sort["SalePrice"] = (queryFlags & (uint)DirectoryManager.DirFindFlags.SortAsc) == (uint)DirectoryManager.DirFindFlags.SortAsc;
  656. else
  657. sort["Dwell"] = false;
  658. if (scopeID != UUID.Zero)
  659. filter.andFilters["ScopeID"] = scopeID;
  660. List<string> retVal = GD.Query(new[]
  661. {
  662. "InfoUUID",
  663. "Name",
  664. "Dwell",
  665. "Flags"
  666. }, "searchparcel", filter, null, 0, 25);
  667. //if there are none, return
  668. if (retVal.Count == 0)
  669. return new List<DirPopularReplyData>();
  670. List<DirPopularReplyData> Data = new List<DirPopularReplyData>();
  671. for (int i = 0; i < retVal.Count; i += 4)
  672. {
  673. //Check maturity levels depending on what flags the user has set
  674. //0 flag is an override so that we can get all lands for sale, regardless of maturity
  675. if (queryFlags == 0 ||
  676. !((int.Parse(retVal[i + 3]) & (int) ParcelFlags.MaturePublish) == (int) ParcelFlags.MaturePublish &&
  677. ((queryFlags & (uint) DirectoryManager.DirFindFlags.IncludeMature)) == 0))
  678. Data.Add(new DirPopularReplyData
  679. {
  680. ParcelID = new UUID(retVal[i]),
  681. Name = retVal[i + 1],
  682. Dwell = int.Parse(retVal[i + 2])
  683. });
  684. }
  685. return Data;
  686. }
  687. private void ConvertBytesToLandBitmap(ref bool[,] tempConvertMap, byte[] Bitmap, int sizeX)
  688. {
  689. try
  690. {
  691. int x = 0, y = 0, i = 0;
  692. int avg = (sizeX*sizeX/128);
  693. for (i = 0; i < avg; i++)
  694. {
  695. byte tempByte = Bitmap[i];
  696. int bitNum = 0;
  697. for (bitNum = 0; bitNum < 8; bitNum++)
  698. {
  699. bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & 1);
  700. tempConvertMap[x, y] = bit;
  701. x++;
  702. if (x > (sizeX/4) - 1)
  703. {
  704. x = 0;
  705. y++;
  706. }
  707. }
  708. }
  709. }
  710. catch
  711. {
  712. }
  713. }
  714. #endregion
  715. #region Classifieds
  716. /// <summary>
  717. /// Searches for classifieds
  718. /// </summary>
  719. /// <param name="queryText"></param>
  720. /// <param name="category"></param>
  721. /// <param name="queryFlags"></param>
  722. /// <param name="StartQuery"></param>
  723. /// <param name="scopeID"> </param>
  724. /// <returns></returns>
  725. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  726. public List<DirClassifiedReplyData> FindClassifieds(string queryText, string category, uint queryFlags,
  727. int StartQuery, UUID scopeID)
  728. {
  729. object remoteValue = DoRemote(queryText, category, queryFlags, StartQuery, scopeID);
  730. if (remoteValue != null || m_doRemoteOnly)
  731. return (List<DirClassifiedReplyData>) remoteValue;
  732. QueryFilter filter = new QueryFilter();
  733. filter.andLikeFilters["Name"] = "%" + queryText + "%";
  734. if (int.Parse(category) != (int) DirectoryManager.ClassifiedCategories.Any) //Check the category
  735. filter.andFilters["Category"] = category;
  736. if (scopeID != UUID.Zero)
  737. filter.andFilters["ScopeID"] = scopeID;
  738. List<string> retVal = GD.Query(new[] {"*"}, "userclassifieds", filter, null, (uint) StartQuery, 50);
  739. if (retVal.Count == 0)
  740. return new List<DirClassifiedReplyData>();
  741. List<DirClassifiedReplyData> Data = new List<DirClassifiedReplyData>();
  742. for (int i = 0; i < retVal.Count; i += 9)
  743. {
  744. //Pull the classified out of OSD
  745. Classified classified = new Classified();
  746. classified.FromOSD((OSDMap) OSDParser.DeserializeJson(retVal[i + 5]));
  747. DirClassifiedReplyData replyData = new DirClassifiedReplyData
  748. {
  749. classifiedFlags = classified.ClassifiedFlags,
  750. classifiedID = classified.ClassifiedUUID,
  751. creationDate = classified.CreationDate,
  752. expirationDate = classified.ExpirationDate,
  753. price = classified.PriceForListing,
  754. name = classified.Name
  755. };
  756. //Check maturity levels
  757. if ((replyData.classifiedFlags & (uint) DirectoryManager.ClassifiedFlags.Mature) !=
  758. (uint) DirectoryManager.ClassifiedFlags.Mature)
  759. {
  760. if ((queryFlags & (uint) DirectoryManager.ClassifiedQueryFlags.Mature) ==
  761. (uint) DirectoryManager.ClassifiedQueryFlags.Mature)
  762. Data.Add(replyData);
  763. }
  764. else
  765. //Its Mature, add all
  766. Data.Add(replyData);
  767. }
  768. return Data;
  769. }
  770. /// <summary>
  771. /// Gets all classifieds in the given region
  772. /// </summary>
  773. /// <param name="regionName"></param>
  774. /// <returns></returns>
  775. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  776. public List<Classified> GetClassifiedsInRegion(string regionName)
  777. {
  778. object remoteValue = DoRemote(regionName);
  779. if (remoteValue != null || m_doRemoteOnly)
  780. return (List<Classified>) remoteValue;
  781. QueryFilter filter = new QueryFilter();
  782. filter.andFilters["SimName"] = regionName;
  783. List<string> retVal = GD.Query(new[] {"*"}, "userclassifieds", filter, null, null, null);
  784. if (retVal.Count == 0)
  785. {
  786. return new List<Classified>();
  787. }
  788. List<Classified> Classifieds = new List<Classified>();
  789. for (int i = 0; i < retVal.Count; i += 9)
  790. {
  791. Classified classified = new Classified();
  792. //Pull the classified out of OSD
  793. classified.FromOSD((OSDMap) OSDParser.DeserializeJson(retVal[i + 6]));
  794. Classifieds.Add(classified);
  795. }
  796. return Classifieds;
  797. }
  798. /// <summary>
  799. /// Get a classified by its UUID
  800. /// </summary>
  801. /// <param name="id"></param>
  802. /// <returns></returns>
  803. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  804. public Classified GetClassifiedByID(UUID id)
  805. {
  806. object remoteValue = DoRemote(id);
  807. if (remoteValue != null || m_doRemoteOnly)
  808. return (Classified) remoteValue;
  809. QueryFilter filter = new QueryFilter();
  810. Dictionary<string, object> where = new Dictionary<string, object>(1);
  811. where.Add("ClassifiedUUID", id);
  812. filter.andFilters = where;
  813. List<string> retVal = GD.Query(new[] {"*"}, "userclassifieds", filter, null, null, null);
  814. if ((retVal == null) || (retVal.Count == 0)) return null;
  815. Classified classified = new Classified();
  816. classified.FromOSD((OSDMap) OSDParser.DeserializeJson(retVal[6]));
  817. return classified;
  818. }
  819. #endregion
  820. #region Events
  821. /// <summary>
  822. /// Searches for events with the given parameters
  823. /// </summary>
  824. /// <param name="queryText"></param>
  825. /// <param name="eventFlags"></param>
  826. /// <param name="StartQuery"></param>
  827. /// <param name="scopeID"> </param>
  828. /// <returns></returns>
  829. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  830. public List<DirEventsReplyData> FindEvents(string queryText, uint eventFlags, int StartQuery, UUID scopeID)
  831. {
  832. object remoteValue = DoRemote(queryText, eventFlags, StartQuery, scopeID);
  833. if (remoteValue != null || m_doRemoteOnly)
  834. return (List<DirEventsReplyData>) remoteValue;
  835. List<DirEventsReplyData> Data = new List<DirEventsReplyData>();
  836. QueryFilter filter = new QueryFilter();
  837. //|0| means search between some days
  838. if (queryText.Contains("|0|"))
  839. {
  840. string StringDay = queryText.Split('|')[0];
  841. if (StringDay == "u") //"u" means search for events that are going on today
  842. {
  843. filter.andGreaterThanEqFilters["UNIX_TIMESTAMP(date)"] = Util.ToUnixTime(DateTime.Today);
  844. }
  845. else
  846. {
  847. //Pull the day out then and search for that many days in the future/past
  848. int Day = int.Parse(StringDay);
  849. DateTime SearchedDay = DateTime.Today.AddDays(Day);
  850. //We only look at one day at a time
  851. DateTime NextDay = SearchedDay.AddDays(1);
  852. filter.andGreaterThanEqFilters["UNIX_TIMESTAMP(date)"] = Util.ToUnixTime(SearchedDay);
  853. filter.andLessThanEqFilters["UNIX_TIMESTAMP(date)"] = Util.ToUnixTime(NextDay);
  854. filter.andLessThanEqFilters["flags"] = (int) eventFlags;
  855. }
  856. }
  857. else
  858. {
  859. filter.andLikeFilters["name"] = "%" + queryText + "%";
  860. }
  861. if (scopeID != UUID.Zero)
  862. filter.andFilters["scopeID"] = scopeID;
  863. List<string> retVal = GD.Query(new[]
  864. {
  865. "EID",
  866. "creator",
  867. "date",
  868. "maturity",
  869. "flags",
  870. "name"
  871. }, "asevents", filter, null, (uint) StartQuery, 50);
  872. if (retVal.Count > 0)
  873. {
  874. for (int i = 0; i < retVal.Count; i += 6)
  875. {
  876. DirEventsReplyData replyData = new DirEventsReplyData
  877. {
  878. eventID = Convert.ToUInt32(retVal[i]),
  879. ownerID = new UUID(retVal[i + 1]),
  880. name = retVal[i + 5],
  881. };
  882. DateTime date = DateTime.Parse(retVal[i + 2]);
  883. replyData.date = date.ToString(new DateTimeFormatInfo());
  884. replyData.unixTime = (uint) Util.ToUnixTime(date);
  885. replyData.eventFlags = Convert.ToUInt32(retVal[i + 4]);
  886. //Check the maturity levels
  887. uint maturity = Convert.ToUInt32(retVal[i + 3]);
  888. if (
  889. (maturity == 0 && (eventFlags & (uint) EventFlags.PG) == (uint) EventFlags.PG) ||
  890. (maturity == 1 && (eventFlags & (uint) EventFlags.Mature) == (uint) EventFlags.Mature) ||
  891. (maturity == 2 && (eventFlags & (uint) EventFlags.Adult) == (uint) EventFlags.Adult)
  892. )
  893. {
  894. Data.Add(replyData);
  895. }
  896. }
  897. }
  898. return Data;
  899. }
  900. /// <summary>
  901. /// Retrives all events in the given region by their maturity level
  902. /// </summary>
  903. /// <param name="regionName"></param>
  904. /// <param name="maturity">Uses DirectoryManager.EventFlags to determine the maturity requested</param>
  905. /// <returns></returns>
  906. [CanBeReflected(ThreatLevel = ThreatLevel.Low)]
  907. public List<DirEventsReplyData> FindAllEventsInRegion(string regionName, int maturity)
  908. {
  909. object remoteValue = DoRemote(regionName, maturity);
  910. if (remoteValue != null || m_doRemoteOnly)
  911. return (List<DirEventsReplyData>) remoteValue;
  912. List<DirEventsReplyData> Data = new List<DirEventsReplyData>();
  913. IRegionData regiondata = Framework.Utilities.DataManager.RequestPlugin<IRegionData>();
  914. if (regiondata != null)
  915. {
  916. List<GridRegion> regions = regiondata.Get(regionName, null, null, null);
  917. if (regions.Co

Large files files are truncated, but you can click here to view the full file