PageRenderTime 59ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

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

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