RegionGridServiceConnector.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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 log4net;
  28. using Mono.Addins;
  29. using System;
  30. using System.Collections.Generic;
  31. using System.Reflection;
  32. using Nini.Config;
  33. using OpenMetaverse;
  34. using OpenSim.Framework;
  35. using OpenSim.Region.Framework.Interfaces;
  36. using OpenSim.Region.Framework.Scenes;
  37. using OpenSim.Server.Base;
  38. using OpenSim.Services.Interfaces;
  39. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  40. namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
  41. {
  42. [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionGridServicesConnector")]
  43. public class RegionGridServicesConnector : ISharedRegionModule, IGridService
  44. {
  45. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  46. private bool m_Enabled = false;
  47. private GridInfo m_ThisGridInfo;
  48. private IGridService m_LocalGridService;
  49. private IGridService m_RemoteGridService;
  50. private RegionInfoCache m_RegionInfoCache;
  51. public RegionGridServicesConnector()
  52. {
  53. }
  54. public RegionGridServicesConnector(IConfigSource source)
  55. {
  56. InitialiseServices(source);
  57. }
  58. #region ISharedRegionmodule
  59. public Type ReplaceableInterface
  60. {
  61. get { return null; }
  62. }
  63. public string Name
  64. {
  65. get { return "RegionGridServicesConnector"; }
  66. }
  67. public void Initialise(IConfigSource source)
  68. {
  69. IConfig moduleConfig = source.Configs["Modules"];
  70. if (moduleConfig != null)
  71. {
  72. string name = moduleConfig.GetString("GridServices", string.Empty);
  73. if (name == Name)
  74. {
  75. if(InitialiseServices(source))
  76. {
  77. m_Enabled = true;
  78. if(m_RemoteGridService == null)
  79. m_log.Info("[REGION GRID CONNECTOR]: enabled in Standalone mode");
  80. else
  81. m_log.Info("[REGION GRID CONNECTOR]: enabled in Grid mode");
  82. }
  83. }
  84. }
  85. }
  86. private bool InitialiseServices(IConfigSource source)
  87. {
  88. IConfig gridConfig = source.Configs["GridService"];
  89. if (gridConfig == null)
  90. {
  91. m_log.Error("[REGION GRID CONNECTOR]: GridService missing from OpenSim.ini");
  92. return false;
  93. }
  94. string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
  95. if (string.IsNullOrWhiteSpace(serviceDll))
  96. {
  97. m_log.Error("[REGION GRID CONNECTOR]: No LocalServiceModule named in section GridService");
  98. return false;
  99. }
  100. object[] args = new object[] { source };
  101. m_LocalGridService = ServerUtils.LoadPlugin<IGridService>(serviceDll, args);
  102. if (m_LocalGridService == null)
  103. {
  104. m_log.Error("[REGION GRID CONNECTOR]: failed to load LocalServiceModule");
  105. return false;
  106. }
  107. string networkConnector = gridConfig.GetString("NetworkConnector", string.Empty);
  108. if (!string.IsNullOrWhiteSpace(networkConnector))
  109. {
  110. m_RemoteGridService = ServerUtils.LoadPlugin<IGridService>(networkConnector, args);
  111. if (m_RemoteGridService == null)
  112. {
  113. m_log.Error("[REGION GRID CONNECTOR]: failed to load NetworkConnector");
  114. return false;
  115. }
  116. }
  117. m_RegionInfoCache = new RegionInfoCache();
  118. return true;
  119. }
  120. public void PostInitialise()
  121. {
  122. }
  123. public void Close()
  124. {
  125. m_ThisGridInfo = null;
  126. }
  127. public void AddRegion(Scene scene)
  128. {
  129. if (m_Enabled)
  130. {
  131. scene.RegisterModuleInterface<IGridService>(this);
  132. if(m_ThisGridInfo == null)
  133. m_ThisGridInfo = scene.SceneGridInfo;
  134. GridRegion r = new GridRegion(scene.RegionInfo);
  135. m_RegionInfoCache.CacheLocal(r);
  136. scene.EventManager.OnRegionUp += OnRegionUp;
  137. }
  138. }
  139. public void RemoveRegion(Scene scene)
  140. {
  141. if (m_Enabled)
  142. {
  143. m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionHandle);
  144. scene.EventManager.OnRegionUp -= OnRegionUp;
  145. }
  146. }
  147. public void RegionLoaded(Scene scene)
  148. {
  149. }
  150. #endregion
  151. private void OnRegionUp(GridRegion region)
  152. {
  153. // This shouldn't happen
  154. if (region == null || !m_Enabled)
  155. return;
  156. m_RegionInfoCache.CacheNearNeighbour(region.ScopeID, region);
  157. }
  158. #region IGridService
  159. public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
  160. {
  161. string msg = m_LocalGridService.RegisterRegion(scopeID, regionInfo);
  162. if (msg == string.Empty && m_RemoteGridService != null)
  163. return m_RemoteGridService.RegisterRegion(scopeID, regionInfo);
  164. return msg;
  165. }
  166. public bool DeregisterRegion(UUID regionID)
  167. {
  168. if (m_LocalGridService.DeregisterRegion(regionID) && m_RemoteGridService != null)
  169. return m_RemoteGridService.DeregisterRegion(regionID);
  170. return false;
  171. }
  172. public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
  173. {
  174. if(m_RemoteGridService == null)
  175. return m_LocalGridService.GetNeighbours(scopeID, regionID);
  176. return m_RemoteGridService.GetNeighbours(scopeID, regionID);
  177. }
  178. public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
  179. {
  180. bool inCache = false;
  181. GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionID, out inCache);
  182. if (inCache)
  183. return rinfo;
  184. rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
  185. if (rinfo != null)
  186. {
  187. m_RegionInfoCache.Cache(scopeID, rinfo);
  188. return rinfo;
  189. }
  190. if(m_RemoteGridService != null)
  191. {
  192. rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID);
  193. m_RegionInfoCache.Cache(scopeID, rinfo);
  194. }
  195. return rinfo;
  196. }
  197. public GridRegion GetRegionByHandle(UUID scopeID, ulong regionhandle)
  198. {
  199. bool inCache = false;
  200. GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionhandle, out inCache);
  201. if (inCache)
  202. return rinfo;
  203. rinfo = m_LocalGridService.GetRegionByHandle(scopeID, regionhandle);
  204. if (rinfo != null)
  205. {
  206. m_RegionInfoCache.Cache(scopeID, rinfo);
  207. return rinfo;
  208. }
  209. if(m_RemoteGridService != null)
  210. {
  211. rinfo = m_RemoteGridService.GetRegionByHandle(scopeID, regionhandle);
  212. m_RegionInfoCache.Cache(scopeID, rinfo);
  213. }
  214. return rinfo;
  215. }
  216. // Get a region given its base world coordinates (in meters).
  217. // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
  218. // be the base coordinate of the region.
  219. // The coordinates are world coords (meters), NOT region units.
  220. public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
  221. {
  222. bool inCache = false;
  223. GridRegion rinfo = m_RegionInfoCache.Get(scopeID, (uint)x, (uint)y, out inCache);
  224. if (inCache)
  225. return rinfo;
  226. rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
  227. if (rinfo != null)
  228. {
  229. // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Found region {0} on local. Pos=<{1},{2}>, RegionHandle={3}",
  230. // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
  231. m_RegionInfoCache.Cache(scopeID, rinfo);
  232. return rinfo;
  233. }
  234. if(m_RemoteGridService != null)
  235. {
  236. rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y);
  237. if (rinfo == null)
  238. {
  239. // uint regionX = Util.WorldToRegionLoc((uint)x);
  240. // uint regionY = Util.WorldToRegionLoc((uint)y);
  241. // m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY);
  242. }
  243. else
  244. {
  245. m_RegionInfoCache.Cache(scopeID, rinfo);
  246. // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}",
  247. // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
  248. }
  249. }
  250. return rinfo;
  251. }
  252. public GridRegion GetRegionByName(UUID scopeID, string name)
  253. {
  254. bool inCache = false;
  255. GridRegion rinfo = m_RegionInfoCache.Get(scopeID, name, out inCache);
  256. if (inCache)
  257. return rinfo;
  258. rinfo = m_LocalGridService.GetRegionByName(scopeID, name);
  259. if (rinfo != null)
  260. {
  261. m_RegionInfoCache.Cache(scopeID, rinfo);
  262. return rinfo;
  263. }
  264. if(m_RemoteGridService == null)
  265. return null;
  266. // HG urls should not get here, strip them
  267. // side effect is that local regions with same name as HG may also be found
  268. // this mb good or bad
  269. string regionName = name;
  270. if(name.Contains("."))
  271. {
  272. if(!m_ThisGridInfo.HasHGConfig)
  273. return rinfo; // no HG
  274. string regionURI = "";
  275. if (!Util.buildHGRegionURI(name, out regionURI, out regionName))
  276. return rinfo; // invalid
  277. if (m_ThisGridInfo.IsLocalGrid(regionURI) != 1)
  278. return rinfo; // not local grid
  279. }
  280. if (string.IsNullOrEmpty(regionName))
  281. {
  282. rinfo = m_RemoteGridService.GetDefaultRegions(UUID.Zero)[0];
  283. if (rinfo == null)
  284. m_log.Warn("[REMOTE GRID CONNECTOR] returned null default region");
  285. else
  286. m_log.WarnFormat("[REMOTE GRID CONNECTOR] returned default region {0}", rinfo.RegionName);
  287. }
  288. else
  289. rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName);
  290. m_RegionInfoCache.Cache(scopeID, rinfo);
  291. return rinfo;
  292. }
  293. public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
  294. {
  295. List<GridRegion> rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber);
  296. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionsByName {0} found {1} regions", name, rinfo.Count);
  297. if(m_RemoteGridService == null)
  298. return rinfo;
  299. // HG urls should not get here, strip them
  300. // side effect is that local regions with same name as HG may also be found
  301. // this mb good or bad
  302. string regionName = name;
  303. if(name.Contains("."))
  304. {
  305. if(!m_ThisGridInfo.HasHGConfig)
  306. return rinfo; // no HG
  307. string regionURI = "";
  308. if (!Util.buildHGRegionURI(name, out regionURI, out regionName))
  309. return rinfo; // invalid
  310. if (m_ThisGridInfo.IsLocalGrid(regionURI) != 1)
  311. return rinfo; // not local grid
  312. }
  313. List<GridRegion> grinfo = null;
  314. if (string.IsNullOrEmpty(regionName))
  315. {
  316. List<GridRegion> grinfos = m_RemoteGridService.GetDefaultRegions(scopeID);
  317. if (grinfos == null || grinfos.Count == 0)
  318. m_log.Warn("[REMOTE GRID CONNECTOR] returned no default regions");
  319. else
  320. {
  321. m_log.WarnFormat("[REMOTE GRID CONNECTOR] returned default regions {0}, ...", grinfos[0].RegionName);
  322. // only return first
  323. grinfo = new List<GridRegion>(){grinfos[0]};
  324. }
  325. }
  326. else
  327. grinfo = m_RemoteGridService.GetRegionsByName(scopeID, regionName, maxNumber);
  328. if (grinfo != null)
  329. {
  330. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count);
  331. foreach (GridRegion r in grinfo)
  332. {
  333. m_RegionInfoCache.Cache(r);
  334. if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
  335. rinfo.Add(r);
  336. }
  337. }
  338. return rinfo;
  339. }
  340. public virtual List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
  341. {
  342. List<GridRegion> rinfo = m_LocalGridService.GetRegionRange(scopeID, xmin, xmax, ymin, ymax);
  343. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionRange {0} found {1} regions", name, rinfo.Count);
  344. if(m_RemoteGridService != null)
  345. {
  346. List<GridRegion> grinfo = m_RemoteGridService.GetRegionRange(scopeID, xmin, xmax, ymin, ymax);
  347. if (grinfo != null)
  348. {
  349. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count);
  350. foreach (GridRegion r in grinfo)
  351. {
  352. m_RegionInfoCache.Cache(r);
  353. if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
  354. rinfo.Add(r);
  355. }
  356. }
  357. }
  358. return rinfo;
  359. }
  360. public List<GridRegion> GetDefaultRegions(UUID scopeID)
  361. {
  362. List<GridRegion> rinfo = m_LocalGridService.GetDefaultRegions(scopeID);
  363. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetDefaultRegions {0} found {1} regions", name, rinfo.Count);
  364. if(m_RemoteGridService != null)
  365. {
  366. List<GridRegion> grinfo = m_RemoteGridService.GetDefaultRegions(scopeID);
  367. if (grinfo != null)
  368. {
  369. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count);
  370. foreach (GridRegion r in grinfo)
  371. {
  372. m_RegionInfoCache.Cache(r);
  373. if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
  374. rinfo.Add(r);
  375. }
  376. }
  377. }
  378. return rinfo;
  379. }
  380. public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
  381. {
  382. List<GridRegion> rinfo = m_LocalGridService.GetDefaultHypergridRegions(scopeID);
  383. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetDefaultHypergridRegions {0} found {1} regions", name, rinfo.Count);
  384. if(m_RemoteGridService != null)
  385. {
  386. List<GridRegion> grinfo = m_RemoteGridService.GetDefaultHypergridRegions(scopeID);
  387. if (grinfo != null)
  388. {
  389. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultHypergridRegions {0} found {1} regions", name, grinfo.Count);
  390. foreach (GridRegion r in grinfo)
  391. {
  392. m_RegionInfoCache.Cache(r);
  393. if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
  394. rinfo.Add(r);
  395. }
  396. }
  397. }
  398. return rinfo;
  399. }
  400. public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
  401. {
  402. List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y);
  403. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetFallbackRegions {0} found {1} regions", name, rinfo.Count);
  404. if(m_RemoteGridService != null)
  405. {
  406. List<GridRegion> grinfo = m_RemoteGridService.GetFallbackRegions(scopeID, x, y);
  407. if (grinfo != null)
  408. {
  409. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count);
  410. foreach (GridRegion r in grinfo)
  411. {
  412. m_RegionInfoCache.Cache(r);
  413. if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
  414. rinfo.Add(r);
  415. }
  416. }
  417. }
  418. return rinfo;
  419. }
  420. public List<GridRegion> GetHyperlinks(UUID scopeID)
  421. {
  422. List<GridRegion> rinfo = m_LocalGridService.GetHyperlinks(scopeID);
  423. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetHyperlinks {0} found {1} regions", name, rinfo.Count);
  424. if(m_RemoteGridService != null)
  425. {
  426. List<GridRegion> grinfo = m_RemoteGridService.GetHyperlinks(scopeID);
  427. if (grinfo != null)
  428. {
  429. //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count);
  430. foreach (GridRegion r in grinfo)
  431. {
  432. m_RegionInfoCache.Cache(r);
  433. if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
  434. rinfo.Add(r);
  435. }
  436. }
  437. }
  438. return rinfo;
  439. }
  440. public int GetRegionFlags(UUID scopeID, UUID regionID)
  441. {
  442. int flags = m_LocalGridService.GetRegionFlags(scopeID, regionID);
  443. if (flags == -1 && m_RemoteGridService != null)
  444. flags = m_RemoteGridService.GetRegionFlags(scopeID, regionID);
  445. return flags;
  446. }
  447. public Dictionary<string, object> GetExtraFeatures()
  448. {
  449. Dictionary<string, object> extraFeatures;
  450. extraFeatures = m_LocalGridService.GetExtraFeatures();
  451. if (extraFeatures.Count == 0 && m_RemoteGridService != null)
  452. extraFeatures = m_RemoteGridService.GetExtraFeatures();
  453. return extraFeatures;
  454. }
  455. #endregion
  456. }
  457. }