OGS1GridServices.cs 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885
  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 OpenSim 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;
  29. using System.Collections.Generic;
  30. using System.IO;
  31. using System.Net;
  32. using System.Net.Sockets;
  33. using System.Reflection;
  34. using System.Runtime.Remoting;
  35. using System.Runtime.Remoting.Channels;
  36. using System.Runtime.Remoting.Channels.Tcp;
  37. using System.Security.Authentication;
  38. using System.Threading;
  39. using OpenMetaverse;
  40. using log4net;
  41. using Nwc.XmlRpc;
  42. using OpenSim.Framework;
  43. using OpenSim.Framework.Communications;
  44. using OpenSim.Framework.Servers;
  45. using OpenSim.Region.Communications.Local;
  46. namespace OpenSim.Region.Communications.OGS1
  47. {
  48. public class OGS1GridServices : IGridServices, IInterRegionCommunications
  49. {
  50. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  51. /// <summary>
  52. /// Encapsulate local backend services for manipulation of local regions
  53. /// </summary>
  54. private LocalBackEndServices m_localBackend = new LocalBackEndServices();
  55. private Dictionary<ulong, RegionInfo> m_remoteRegionInfoCache = new Dictionary<ulong, RegionInfo>();
  56. // private List<SimpleRegionInfo> m_knownRegions = new List<SimpleRegionInfo>();
  57. private Dictionary<ulong, int> m_deadRegionCache = new Dictionary<ulong, int>();
  58. private Dictionary<string, string> m_queuedGridSettings = new Dictionary<string, string>();
  59. private List<RegionInfo> m_regionsOnInstance = new List<RegionInfo>();
  60. public BaseHttpServer httpListener;
  61. public NetworkServersInfo serversInfo;
  62. public BaseHttpServer httpServer;
  63. public string gdebugRegionName
  64. {
  65. get { return m_localBackend.gdebugRegionName; }
  66. set { m_localBackend.gdebugRegionName = value; }
  67. }
  68. public string rdebugRegionName
  69. {
  70. get { return _rdebugRegionName; }
  71. set { _rdebugRegionName = value; }
  72. }
  73. private string _rdebugRegionName = String.Empty;
  74. public bool RegionLoginsEnabled
  75. {
  76. get { return m_localBackend.RegionLoginsEnabled; }
  77. set { m_localBackend.RegionLoginsEnabled = value; }
  78. }
  79. /// <summary>
  80. /// Contructor. Adds "expect_user" and "check" xmlrpc method handlers
  81. /// </summary>
  82. /// <param name="servers_info"></param>
  83. /// <param name="httpServe"></param>
  84. public OGS1GridServices(NetworkServersInfo servers_info, BaseHttpServer httpServe)
  85. {
  86. serversInfo = servers_info;
  87. httpServer = httpServe;
  88. //Respond to Grid Services requests
  89. httpServer.AddXmlRPCHandler("expect_user", ExpectUser);
  90. httpServer.AddXmlRPCHandler("logoff_user", LogOffUser);
  91. httpServer.AddXmlRPCHandler("check", PingCheckReply);
  92. httpServer.AddXmlRPCHandler("land_data", LandData);
  93. StartRemoting();
  94. }
  95. // see IGridServices
  96. public RegionCommsListener RegisterRegion(RegionInfo regionInfo)
  97. {
  98. m_regionsOnInstance.Add(regionInfo);
  99. m_log.InfoFormat(
  100. "[OGS1 GRID SERVICES]: Attempting to register region {0} with grid at {1}",
  101. regionInfo.RegionName, serversInfo.GridURL);
  102. Hashtable GridParams = new Hashtable();
  103. // Login / Authentication
  104. GridParams["authkey"] = serversInfo.GridSendKey;
  105. GridParams["recvkey"] = serversInfo.GridRecvKey;
  106. GridParams["UUID"] = regionInfo.RegionID.ToString();
  107. GridParams["sim_ip"] = regionInfo.ExternalHostName;
  108. GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString();
  109. GridParams["region_locx"] = regionInfo.RegionLocX.ToString();
  110. GridParams["region_locy"] = regionInfo.RegionLocY.ToString();
  111. GridParams["sim_name"] = regionInfo.RegionName;
  112. GridParams["http_port"] = serversInfo.HttpListenerPort.ToString();
  113. GridParams["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString();
  114. GridParams["map-image-id"] = regionInfo.RegionSettings.TerrainImageID.ToString();
  115. GridParams["originUUID"] = regionInfo.originRegionID.ToString();
  116. GridParams["server_uri"] = regionInfo.ServerURI;
  117. GridParams["region_secret"] = regionInfo.regionSecret;
  118. GridParams["major_interface_version"] = VersionInfo.MajorInterfaceVersion.ToString();
  119. if (regionInfo.MasterAvatarAssignedUUID != UUID.Zero)
  120. GridParams["master_avatar_uuid"] = regionInfo.MasterAvatarAssignedUUID.ToString();
  121. else
  122. GridParams["master_avatar_uuid"] = regionInfo.EstateSettings.EstateOwner.ToString();
  123. // Package into an XMLRPC Request
  124. ArrayList SendParams = new ArrayList();
  125. SendParams.Add(GridParams);
  126. // Send Request
  127. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams);
  128. XmlRpcResponse GridResp;
  129. try
  130. {
  131. // The timeout should always be significantly larger than the timeout for the grid server to request
  132. // the initial status of the region before confirming registration.
  133. GridResp = GridReq.Send(serversInfo.GridURL, 90000);
  134. }
  135. catch (Exception e)
  136. {
  137. Exception e2
  138. = new Exception(
  139. String.Format(
  140. "Unable to register region with grid at {0}. Grid service not running?",
  141. serversInfo.GridURL),
  142. e);
  143. throw e2;
  144. }
  145. Hashtable GridRespData = (Hashtable)GridResp.Value;
  146. // Hashtable griddatahash = GridRespData;
  147. // Process Response
  148. if (GridRespData.ContainsKey("error"))
  149. {
  150. string errorstring = (string) GridRespData["error"];
  151. Exception e = new Exception(
  152. String.Format("Unable to connect to grid at {0}: {1}", serversInfo.GridURL, errorstring));
  153. throw e;
  154. }
  155. else
  156. {
  157. // m_knownRegions = RequestNeighbours(regionInfo.RegionLocX, regionInfo.RegionLocY);
  158. if (GridRespData.ContainsKey("allow_forceful_banlines"))
  159. {
  160. if ((string) GridRespData["allow_forceful_banlines"] != "TRUE")
  161. {
  162. //m_localBackend.SetForcefulBanlistsDisallowed(regionInfo.RegionHandle);
  163. m_queuedGridSettings.Add("allow_forceful_banlines", "FALSE");
  164. }
  165. }
  166. m_log.InfoFormat(
  167. "[OGS1 GRID SERVICES]: Region {0} successfully registered with grid at {1}",
  168. regionInfo.RegionName, serversInfo.GridURL);
  169. }
  170. return m_localBackend.RegisterRegion(regionInfo);
  171. }
  172. // see IGridServices
  173. public bool DeregisterRegion(RegionInfo regionInfo)
  174. {
  175. Hashtable GridParams = new Hashtable();
  176. GridParams["UUID"] = regionInfo.RegionID.ToString();
  177. // Package into an XMLRPC Request
  178. ArrayList SendParams = new ArrayList();
  179. SendParams.Add(GridParams);
  180. // Send Request
  181. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_after_region_moved", SendParams);
  182. XmlRpcResponse GridResp = null;
  183. try
  184. {
  185. GridResp = GridReq.Send(serversInfo.GridURL, 10000);
  186. }
  187. catch (Exception e)
  188. {
  189. Exception e2
  190. = new Exception(
  191. String.Format(
  192. "Unable to deregister region with grid at {0}. Grid service not running?",
  193. serversInfo.GridURL),
  194. e);
  195. throw e2;
  196. }
  197. Hashtable GridRespData = (Hashtable) GridResp.Value;
  198. // Hashtable griddatahash = GridRespData;
  199. // Process Response
  200. if (GridRespData != null && GridRespData.ContainsKey("error"))
  201. {
  202. string errorstring = (string)GridRespData["error"];
  203. m_log.Error("Unable to connect to grid: " + errorstring);
  204. return false;
  205. }
  206. return m_localBackend.DeregisterRegion(regionInfo);
  207. }
  208. public virtual Dictionary<string, string> GetGridSettings()
  209. {
  210. Dictionary<string, string> returnGridSettings = new Dictionary<string, string>();
  211. lock (m_queuedGridSettings)
  212. {
  213. foreach (string Dictkey in m_queuedGridSettings.Keys)
  214. {
  215. returnGridSettings.Add(Dictkey, m_queuedGridSettings[Dictkey]);
  216. }
  217. m_queuedGridSettings.Clear();
  218. }
  219. return returnGridSettings;
  220. }
  221. // see IGridServices
  222. public List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
  223. {
  224. Hashtable respData = MapBlockQuery((int) x - 1, (int) y - 1, (int) x + 1, (int) y + 1);
  225. List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
  226. foreach (ArrayList neighboursList in respData.Values)
  227. {
  228. foreach (Hashtable neighbourData in neighboursList)
  229. {
  230. uint regX = Convert.ToUInt32(neighbourData["x"]);
  231. uint regY = Convert.ToUInt32(neighbourData["y"]);
  232. if ((x != regX) || (y != regY))
  233. {
  234. string simIp = (string) neighbourData["sim_ip"];
  235. uint port = Convert.ToUInt32(neighbourData["sim_port"]);
  236. // string externalUri = (string) neighbourData["sim_uri"];
  237. // string externalIpStr = String.Empty;
  238. try
  239. {
  240. // externalIpStr = Util.GetHostFromDNS(simIp).ToString();
  241. Util.GetHostFromDNS(simIp).ToString();
  242. }
  243. catch (SocketException e)
  244. {
  245. m_log.WarnFormat(
  246. "[OGS1 GRID SERVICES]: RequestNeighbours(): Lookup of neighbour {0} failed! Not including in neighbours list. {1}",
  247. simIp, e);
  248. continue;
  249. }
  250. SimpleRegionInfo sri = new SimpleRegionInfo(regX, regY, simIp, port);
  251. sri.RemotingPort = Convert.ToUInt32(neighbourData["remoting_port"]);
  252. if (neighbourData.ContainsKey("http_port"))
  253. {
  254. sri.HttpPort = Convert.ToUInt32(neighbourData["http_port"]);
  255. }
  256. else
  257. {
  258. m_log.Error("[OGS1 GRID SERVICES]: Couldn't find httpPort, using default 9000; please upgrade your grid-server to r7621 or later");
  259. sri.HttpPort = 9000; // that's the default and will probably be wrong
  260. }
  261. sri.RegionID = new UUID((string) neighbourData["uuid"]);
  262. neighbours.Add(sri);
  263. }
  264. }
  265. }
  266. return neighbours;
  267. }
  268. /// <summary>
  269. /// Request information about a region.
  270. /// </summary>
  271. /// <param name="regionHandle"></param>
  272. /// <returns>
  273. /// null on a failure to contact or get a response from the grid server
  274. /// FIXME: Might be nicer to return a proper exception here since we could inform the client more about the
  275. /// nature of the faiulre.
  276. /// </returns>
  277. public RegionInfo RequestNeighbourInfo(UUID Region_UUID)
  278. {
  279. // don't ask the gridserver about regions on this instance...
  280. foreach (RegionInfo info in m_regionsOnInstance)
  281. {
  282. if (info.RegionID == Region_UUID) return info;
  283. }
  284. // didn't find it so far, we have to go the long way
  285. RegionInfo regionInfo;
  286. Hashtable requestData = new Hashtable();
  287. requestData["region_UUID"] = Region_UUID.ToString();
  288. requestData["authkey"] = serversInfo.GridSendKey;
  289. ArrayList SendParams = new ArrayList();
  290. SendParams.Add(requestData);
  291. XmlRpcRequest gridReq = new XmlRpcRequest("simulator_data_request", SendParams);
  292. XmlRpcResponse gridResp = null;
  293. try
  294. {
  295. gridResp = gridReq.Send(serversInfo.GridURL, 3000);
  296. }
  297. catch (Exception e)
  298. {
  299. m_log.ErrorFormat(
  300. "[OGS1 GRID SERVICES]: Communication with the grid server at {0} failed, {1}",
  301. serversInfo.GridURL, e);
  302. return null;
  303. }
  304. Hashtable responseData = (Hashtable)gridResp.Value;
  305. if (responseData.ContainsKey("error"))
  306. {
  307. m_log.WarnFormat("[OGS1 GRID SERVICES]: Error received from grid server: {0}", responseData["error"]);
  308. return null;
  309. }
  310. regionInfo = buildRegionInfo(responseData, String.Empty);
  311. if (requestData.ContainsKey("regionHandle"))
  312. {
  313. m_remoteRegionInfoCache.Add(Convert.ToUInt64((string) requestData["regionHandle"]), regionInfo);
  314. }
  315. return regionInfo;
  316. }
  317. /// <summary>
  318. /// Request information about a region.
  319. /// </summary>
  320. /// <param name="regionHandle"></param>
  321. /// <returns></returns>
  322. public RegionInfo RequestNeighbourInfo(ulong regionHandle)
  323. {
  324. RegionInfo regionInfo = m_localBackend.RequestNeighbourInfo(regionHandle);
  325. if (regionInfo != null)
  326. {
  327. return regionInfo;
  328. }
  329. if (!m_remoteRegionInfoCache.TryGetValue(regionHandle, out regionInfo))
  330. {
  331. try
  332. {
  333. Hashtable requestData = new Hashtable();
  334. requestData["region_handle"] = regionHandle.ToString();
  335. requestData["authkey"] = serversInfo.GridSendKey;
  336. ArrayList SendParams = new ArrayList();
  337. SendParams.Add(requestData);
  338. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
  339. XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000);
  340. Hashtable responseData = (Hashtable) GridResp.Value;
  341. if (responseData.ContainsKey("error"))
  342. {
  343. m_log.Error("[OGS1 GRID SERVICES]: Error received from grid server: " + responseData["error"]);
  344. return null;
  345. }
  346. uint regX = Convert.ToUInt32((string) responseData["region_locx"]);
  347. uint regY = Convert.ToUInt32((string) responseData["region_locy"]);
  348. string externalHostName = (string) responseData["sim_ip"];
  349. uint port = Convert.ToUInt32(responseData["sim_port"]);
  350. // string externalUri = (string) responseData["sim_uri"];
  351. //IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port);
  352. IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(externalHostName), (int)port);
  353. regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalHostName);
  354. regionInfo.RemotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
  355. regionInfo.RemotingAddress = externalHostName;
  356. if (responseData.ContainsKey("http_port"))
  357. {
  358. regionInfo.HttpPort = Convert.ToUInt32((string) responseData["http_port"]);
  359. }
  360. regionInfo.RegionID = new UUID((string) responseData["region_UUID"]);
  361. regionInfo.RegionName = (string) responseData["region_name"];
  362. lock (m_remoteRegionInfoCache)
  363. {
  364. if (!m_remoteRegionInfoCache.ContainsKey(regionHandle))
  365. {
  366. m_remoteRegionInfoCache.Add(regionHandle, regionInfo);
  367. }
  368. }
  369. }
  370. catch (Exception e)
  371. {
  372. m_log.Error("[OGS1 GRID SERVICES]: " +
  373. "Region lookup failed for: " + regionHandle.ToString() +
  374. " - Is the GridServer down?" + e.ToString());
  375. return null;
  376. }
  377. }
  378. return regionInfo;
  379. }
  380. public RegionInfo RequestClosestRegion(string regionName)
  381. {
  382. foreach (RegionInfo ri in m_remoteRegionInfoCache.Values)
  383. {
  384. if (ri.RegionName == regionName)
  385. return ri;
  386. }
  387. RegionInfo regionInfo = null;
  388. try
  389. {
  390. Hashtable requestData = new Hashtable();
  391. requestData["region_name_search"] = regionName;
  392. requestData["authkey"] = serversInfo.GridSendKey;
  393. ArrayList SendParams = new ArrayList();
  394. SendParams.Add(requestData);
  395. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
  396. XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000);
  397. Hashtable responseData = (Hashtable) GridResp.Value;
  398. if (responseData.ContainsKey("error"))
  399. {
  400. m_log.ErrorFormat("[OGS1 GRID SERVICES]: Error received from grid server: ", responseData["error"]);
  401. return null;
  402. }
  403. regionInfo = buildRegionInfo(responseData, "");
  404. if (!m_remoteRegionInfoCache.ContainsKey(regionInfo.RegionHandle))
  405. m_remoteRegionInfoCache.Add(regionInfo.RegionHandle, regionInfo);
  406. }
  407. catch
  408. {
  409. m_log.Error("[OGS1 GRID SERVICES]: " +
  410. "Region lookup failed for: " + regionName +
  411. " - Is the GridServer down?");
  412. }
  413. return regionInfo;
  414. }
  415. /// <summary>
  416. ///
  417. /// </summary>
  418. /// <param name="minX"></param>
  419. /// <param name="minY"></param>
  420. /// <param name="maxX"></param>
  421. /// <param name="maxY"></param>
  422. /// <returns></returns>
  423. public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
  424. {
  425. int temp = 0;
  426. if (minX > maxX)
  427. {
  428. temp = minX;
  429. minX = maxX;
  430. maxX = temp;
  431. }
  432. if (minY > maxY)
  433. {
  434. temp = minY;
  435. minY = maxY;
  436. maxY = temp;
  437. }
  438. Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY);
  439. List<MapBlockData> neighbours = new List<MapBlockData>();
  440. foreach (ArrayList a in respData.Values)
  441. {
  442. foreach (Hashtable n in a)
  443. {
  444. MapBlockData neighbour = new MapBlockData();
  445. neighbour.X = Convert.ToUInt16(n["x"]);
  446. neighbour.Y = Convert.ToUInt16(n["y"]);
  447. neighbour.Name = (string) n["name"];
  448. neighbour.Access = Convert.ToByte(n["access"]);
  449. neighbour.RegionFlags = Convert.ToUInt32(n["region-flags"]);
  450. neighbour.WaterHeight = Convert.ToByte(n["water-height"]);
  451. neighbour.MapImageId = new UUID((string) n["map-image-id"]);
  452. neighbours.Add(neighbour);
  453. }
  454. }
  455. return neighbours;
  456. }
  457. /// <summary>
  458. /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates
  459. /// </summary>
  460. /// <remarks>REDUNDANT - OGS1 is to be phased out in favour of OGS2</remarks>
  461. /// <param name="minX">Minimum X value</param>
  462. /// <param name="minY">Minimum Y value</param>
  463. /// <param name="maxX">Maximum X value</param>
  464. /// <param name="maxY">Maximum Y value</param>
  465. /// <returns>Hashtable of hashtables containing map data elements</returns>
  466. private Hashtable MapBlockQuery(int minX, int minY, int maxX, int maxY)
  467. {
  468. Hashtable param = new Hashtable();
  469. param["xmin"] = minX;
  470. param["ymin"] = minY;
  471. param["xmax"] = maxX;
  472. param["ymax"] = maxY;
  473. IList parameters = new ArrayList();
  474. parameters.Add(param);
  475. try
  476. {
  477. XmlRpcRequest req = new XmlRpcRequest("map_block", parameters);
  478. XmlRpcResponse resp = req.Send(serversInfo.GridURL, 10000);
  479. Hashtable respData = (Hashtable) resp.Value;
  480. return respData;
  481. }
  482. catch (Exception e)
  483. {
  484. m_log.Error("MapBlockQuery XMLRPC failure: " + e);
  485. return new Hashtable();
  486. }
  487. }
  488. /// <summary>
  489. /// A ping / version check
  490. /// </summary>
  491. /// <param name="request"></param>
  492. /// <returns></returns>
  493. public XmlRpcResponse PingCheckReply(XmlRpcRequest request)
  494. {
  495. XmlRpcResponse response = new XmlRpcResponse();
  496. Hashtable respData = new Hashtable();
  497. respData["online"] = "true";
  498. m_localBackend.PingCheckReply(respData);
  499. response.Value = respData;
  500. return response;
  501. }
  502. /// <summary>
  503. /// Received from the user server when a user starts logging in. This call allows
  504. /// the region to prepare for direct communication from the client. Sends back an empty
  505. /// xmlrpc response on completion.
  506. /// </summary>
  507. /// <param name="request"></param>
  508. /// <returns></returns>
  509. public XmlRpcResponse ExpectUser(XmlRpcRequest request)
  510. {
  511. Hashtable requestData = (Hashtable) request.Params[0];
  512. AgentCircuitData agentData = new AgentCircuitData();
  513. agentData.SessionID = new UUID((string) requestData["session_id"]);
  514. agentData.SecureSessionID = new UUID((string) requestData["secure_session_id"]);
  515. agentData.firstname = (string) requestData["firstname"];
  516. agentData.lastname = (string) requestData["lastname"];
  517. agentData.AgentID = new UUID((string) requestData["agent_id"]);
  518. agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]);
  519. agentData.CapsPath = (string) requestData["caps_path"];
  520. ulong regionHandle = Convert.ToUInt64((string) requestData["regionhandle"]);
  521. m_log.DebugFormat(
  522. "[CLIENT]: Told by user service to prepare for a connection from {0} {1} {2}, circuit {3}",
  523. agentData.firstname, agentData.lastname, agentData.AgentID, agentData.circuitcode);
  524. if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1"))
  525. {
  526. m_log.Debug("[CLIENT]: Child agent detected");
  527. agentData.child = true;
  528. }
  529. else
  530. {
  531. m_log.Debug("[CLIENT]: Main agent detected");
  532. agentData.startpos =
  533. new Vector3((float)Convert.ToDecimal((string)requestData["startpos_x"]),
  534. (float)Convert.ToDecimal((string)requestData["startpos_y"]),
  535. (float)Convert.ToDecimal((string)requestData["startpos_z"]));
  536. agentData.child = false;
  537. }
  538. XmlRpcResponse resp = new XmlRpcResponse();
  539. if (!RegionLoginsEnabled)
  540. {
  541. m_log.InfoFormat(
  542. "[CLIENT]: Denying access for user {0} {1} because region login is currently disabled",
  543. agentData.firstname, agentData.lastname);
  544. Hashtable respdata = new Hashtable();
  545. respdata["success"] = "FALSE";
  546. respdata["reason"] = "region login currently disabled";
  547. resp.Value = respdata;
  548. }
  549. else
  550. {
  551. RegionInfo[] regions = m_regionsOnInstance.ToArray();
  552. bool banned = false;
  553. for (int i = 0; i < regions.Length; i++)
  554. {
  555. if (regions[i] != null)
  556. {
  557. if (regions[i].RegionHandle == regionHandle)
  558. {
  559. if (regions[i].EstateSettings.IsBanned(agentData.AgentID))
  560. {
  561. banned = true;
  562. break;
  563. }
  564. }
  565. }
  566. }
  567. if (banned)
  568. {
  569. m_log.InfoFormat(
  570. "[CLIENT]: Denying access for user {0} {1} because user is banned",
  571. agentData.firstname, agentData.lastname);
  572. Hashtable respdata = new Hashtable();
  573. respdata["success"] = "FALSE";
  574. respdata["reason"] = "banned";
  575. resp.Value = respdata;
  576. }
  577. else
  578. {
  579. m_localBackend.TriggerExpectUser(regionHandle, agentData);
  580. Hashtable respdata = new Hashtable();
  581. respdata["success"] = "TRUE";
  582. resp.Value = respdata;
  583. }
  584. }
  585. return resp;
  586. }
  587. // Grid Request Processing
  588. /// <summary>
  589. /// Ooops, our Agent must be dead if we're getting this request!
  590. /// </summary>
  591. /// <param name="request"></param>
  592. /// <returns></returns>
  593. public XmlRpcResponse LogOffUser(XmlRpcRequest request)
  594. {
  595. m_log.Debug("[CONNECTION DEBUGGING]: LogOff User Called");
  596. Hashtable requestData = (Hashtable)request.Params[0];
  597. string message = (string)requestData["message"];
  598. UUID agentID = UUID.Zero;
  599. UUID RegionSecret = UUID.Zero;
  600. UUID.TryParse((string)requestData["agent_id"], out agentID);
  601. UUID.TryParse((string)requestData["region_secret"], out RegionSecret);
  602. ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]);
  603. m_localBackend.TriggerLogOffUser(regionHandle, agentID, RegionSecret,message);
  604. return new XmlRpcResponse();
  605. }
  606. #region m_interRegion Comms
  607. /// <summary>
  608. /// Start listening for .net remoting calls from other regions.
  609. /// </summary>
  610. private void StartRemoting()
  611. {
  612. TcpChannel ch;
  613. try
  614. {
  615. ch = new TcpChannel((int)NetworkServersInfo.RemotingListenerPort);
  616. ChannelServices.RegisterChannel(ch, false); // Disabled security as Mono doesn't support this.
  617. }
  618. catch (Exception ex)
  619. {
  620. m_log.Error("[OGS1 GRID SERVICES]: Exception while attempting to listen on TCP port " + (int)NetworkServersInfo.RemotingListenerPort + ".");
  621. throw (ex);
  622. }
  623. WellKnownServiceTypeEntry wellType =
  624. new WellKnownServiceTypeEntry(typeof (OGS1InterRegionRemoting), "InterRegions",
  625. WellKnownObjectMode.Singleton);
  626. RemotingConfiguration.RegisterWellKnownServiceType(wellType);
  627. InterRegionSingleton.Instance.OnArrival += TriggerExpectAvatarCrossing;
  628. InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent;
  629. InterRegionSingleton.Instance.OnPrimGroupArrival += IncomingPrim;
  630. InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing;
  631. InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp;
  632. InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate;
  633. InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection;
  634. }
  635. #region Methods called by regions in this instance
  636. public bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  637. {
  638. int failures = 0;
  639. lock (m_deadRegionCache)
  640. {
  641. if (m_deadRegionCache.ContainsKey(regionHandle))
  642. {
  643. failures = m_deadRegionCache[regionHandle];
  644. }
  645. }
  646. if (failures <= 3)
  647. {
  648. RegionInfo regInfo = null;
  649. try
  650. {
  651. if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData))
  652. {
  653. return true;
  654. }
  655. regInfo = RequestNeighbourInfo(regionHandle);
  656. if (regInfo != null)
  657. {
  658. //don't want to be creating a new link to the remote instance every time like we are here
  659. bool retValue = false;
  660. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  661. typeof(OGS1InterRegionRemoting),
  662. "tcp://" + regInfo.RemotingAddress +
  663. ":" + regInfo.RemotingPort +
  664. "/InterRegions");
  665. if (remObject != null)
  666. {
  667. retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData);
  668. }
  669. else
  670. {
  671. m_log.Warn("[OGS1 GRID SERVICES]: remoting object not found");
  672. }
  673. remObject = null;
  674. // m_log.Info("[INTER]: " +
  675. // gdebugRegionName +
  676. // ": OGS1 tried to Update Child Agent data on outside region and got " +
  677. // retValue.ToString());
  678. return retValue;
  679. }
  680. NoteDeadRegion(regionHandle);
  681. return false;
  682. }
  683. catch (RemotingException e)
  684. {
  685. NoteDeadRegion(regionHandle);
  686. m_log.WarnFormat(
  687. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  688. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  689. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  690. return false;
  691. }
  692. catch (SocketException e)
  693. {
  694. NoteDeadRegion(regionHandle);
  695. m_log.WarnFormat(
  696. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  697. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  698. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  699. return false;
  700. }
  701. catch (InvalidCredentialException e)
  702. {
  703. NoteDeadRegion(regionHandle);
  704. m_log.WarnFormat(
  705. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  706. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  707. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  708. return false;
  709. }
  710. catch (AuthenticationException e)
  711. {
  712. NoteDeadRegion(regionHandle);
  713. m_log.WarnFormat(
  714. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  715. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  716. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  717. return false;
  718. }
  719. catch (Exception e)
  720. {
  721. NoteDeadRegion(regionHandle);
  722. m_log.WarnFormat("[OGS1 GRID SERVICES]: Unable to connect to adjacent region: {0} {1},{2}",
  723. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  724. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  725. return false;
  726. }
  727. }
  728. else
  729. {
  730. //m_log.Info("[INTERREGION]: Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString());
  731. return false;
  732. }
  733. }
  734. /// <summary>
  735. /// Inform a region that a child agent will be on the way from a client.
  736. /// </summary>
  737. /// <param name="regionHandle"></param>
  738. /// <param name="agentData"></param>
  739. /// <returns></returns>
  740. public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
  741. {
  742. RegionInfo regInfo = null;
  743. try
  744. {
  745. if (m_localBackend.InformRegionOfChildAgent(regionHandle, agentData))
  746. {
  747. return true;
  748. }
  749. regInfo = RequestNeighbourInfo(regionHandle);
  750. if (regInfo != null)
  751. {
  752. //don't want to be creating a new link to the remote instance every time like we are here
  753. bool retValue = false;
  754. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  755. typeof(OGS1InterRegionRemoting),
  756. "tcp://" + regInfo.RemotingAddress +
  757. ":" + regInfo.RemotingPort +
  758. "/InterRegions");
  759. if (remObject != null)
  760. {
  761. retValue = remObject.InformRegionOfChildAgent(regionHandle, new sAgentCircuitData(agentData));
  762. }
  763. else
  764. {
  765. m_log.Warn("[OGS1 GRID SERVICES]: remoting object not found");
  766. }
  767. remObject = null;
  768. m_log.Info("[OGS1 GRID SERVICES]: " +
  769. m_localBackend._gdebugRegionName + ": OGS1 tried to InformRegionOfChildAgent for " +
  770. agentData.firstname + " " + agentData.lastname + " and got " +
  771. retValue.ToString());
  772. return retValue;
  773. }
  774. NoteDeadRegion(regionHandle);
  775. return false;
  776. }
  777. catch (RemotingException e)
  778. {
  779. NoteDeadRegion(regionHandle);
  780. m_log.WarnFormat(
  781. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  782. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  783. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  784. return false;
  785. }
  786. catch (SocketException e)
  787. {
  788. NoteDeadRegion(regionHandle);
  789. m_log.WarnFormat(
  790. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  791. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  792. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  793. return false;
  794. }
  795. catch (InvalidCredentialException e)
  796. {
  797. NoteDeadRegion(regionHandle);
  798. m_log.WarnFormat(
  799. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  800. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  801. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  802. return false;
  803. }
  804. catch (AuthenticationException e)
  805. {
  806. NoteDeadRegion(regionHandle);
  807. m_log.WarnFormat(
  808. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  809. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  810. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  811. return false;
  812. }
  813. catch (Exception e)
  814. {
  815. NoteDeadRegion(regionHandle);
  816. if (regInfo != null)
  817. {
  818. m_log.WarnFormat(
  819. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  820. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  821. }
  822. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  823. return false;
  824. }
  825. }
  826. // UGLY!
  827. public bool RegionUp(SerializableRegionInfo region, ulong regionhandle)
  828. {
  829. SerializableRegionInfo regInfo = null;
  830. try
  831. {
  832. // You may ask why this is in here...
  833. // The region asking the grid services about itself..
  834. // And, surprisingly, the reason is.. it doesn't know
  835. // it's own remoting port! How special.
  836. RegionUpData regiondata = new RegionUpData(region.RegionLocX, region.RegionLocY, region.ExternalHostName, region.InternalEndPoint.Port);
  837. region = new SerializableRegionInfo(RequestNeighbourInfo(region.RegionHandle));
  838. region.RemotingAddress = region.ExternalHostName;
  839. region.RemotingPort = NetworkServersInfo.RemotingListenerPort;
  840. region.HttpPort = serversInfo.HttpListenerPort;
  841. if (m_localBackend.RegionUp(region, regionhandle))
  842. {
  843. return true;
  844. }
  845. regInfo = new SerializableRegionInfo(RequestNeighbourInfo(regionhandle));
  846. if (regInfo != null)
  847. {
  848. // If we're not trying to remote to ourselves.
  849. if (regInfo.RemotingAddress != region.RemotingAddress && region.RemotingAddress != null)
  850. {
  851. //don't want to be creating a new link to the remote instance every time like we are here
  852. bool retValue = false;
  853. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
  854. typeof(OGS1InterRegionRemoting),
  855. "tcp://" +
  856. regInfo.RemotingAddress +
  857. ":" + regInfo.RemotingPort +
  858. "/InterRegions");
  859. if (remObject != null)
  860. {
  861. retValue = remObject.RegionUp(regiondata, regionhandle);
  862. }
  863. else
  864. {
  865. m_log.Warn("[OGS1 GRID SERVICES]: remoting object not found");
  866. }
  867. remObject = null;
  868. m_log.Info(
  869. "[INTER]: " + m_localBackend._gdebugRegionName + ": OGS1 tried to inform region I'm up");
  870. return retValue;
  871. }
  872. else
  873. {
  874. // We're trying to inform ourselves via remoting.
  875. // This is here because we're looping over the listeners before we get here.
  876. // Odd but it should work.
  877. return true;
  878. }
  879. }
  880. return false;
  881. }
  882. catch (RemotingException e)
  883. {
  884. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region using tcp://" +
  885. regInfo.RemotingAddress +
  886. ":" + regInfo.RemotingPort +
  887. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  888. " - Is this neighbor up?");
  889. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  890. return false;
  891. }
  892. catch (SocketException e)
  893. {
  894. m_log.Warn("[OGS1 GRID SERVICES]: Socket Error: Unable to connect to adjacent region using tcp://" +
  895. regInfo.RemotingAddress +
  896. ":" + regInfo.RemotingPort +
  897. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  898. " - Is this neighbor up?");
  899. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  900. return false;
  901. }
  902. catch (InvalidCredentialException e)
  903. {
  904. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
  905. regInfo.RemotingAddress +
  906. ":" + regInfo.RemotingPort +
  907. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  908. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  909. return false;
  910. }
  911. catch (AuthenticationException e)
  912. {
  913. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region using tcp://" +
  914. regInfo.RemotingAddress +
  915. ":" + regInfo.RemotingPort +
  916. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  917. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  918. return false;
  919. }
  920. catch (Exception e)
  921. {
  922. // This line errors with a Null Reference Exception.. Why? @.@
  923. //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress +
  924. // ":" + regInfo.RemotingPort +
  925. //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one");
  926. m_log.Debug(e.ToString());
  927. return false;
  928. }
  929. }
  930. /// <summary>
  931. ///
  932. /// </summary>
  933. /// <param name="regionHandle"></param>
  934. /// <param name="agentData"></param>
  935. /// <returns></returns>
  936. public bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod)
  937. {
  938. int failures = 0;
  939. lock (m_deadRegionCache)
  940. {
  941. if (m_deadRegionCache.ContainsKey(regionHandle))
  942. {
  943. failures = m_deadRegionCache[regionHandle];
  944. }
  945. }
  946. if (failures <= 1)
  947. {
  948. RegionInfo regInfo = null;
  949. try
  950. {
  951. if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod))
  952. {
  953. return true;
  954. }
  955. regInfo = RequestNeighbourInfo(regionHandle);
  956. if (regInfo != null)
  957. {
  958. //don't want to be creating a new link to the remote instance every time like we are here
  959. bool retValue = false;
  960. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  961. typeof(OGS1InterRegionRemoting),
  962. "tcp://" + regInfo.RemotingAddress +
  963. ":" + regInfo.RemotingPort +
  964. "/InterRegions");
  965. if (remObject != null)
  966. {
  967. m_log.DebugFormat("[INTERREGION]: Sending prim crossing message for prim {0}", primID.ToString());
  968. retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod);
  969. m_log.DebugFormat("[INTERREGION]: Return from prim crossing message for prim {0}: {1}", primID.ToString(), retValue.ToString());
  970. }
  971. else
  972. {
  973. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  974. }
  975. remObject = null;
  976. return retValue;
  977. }
  978. NoteDeadRegion(regionHandle);
  979. return false;
  980. }
  981. catch (RemotingException e)
  982. {
  983. NoteDeadRegion(regionHandle);
  984. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  985. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  986. return false;
  987. }
  988. catch (SocketException e)
  989. {
  990. NoteDeadRegion(regionHandle);
  991. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  992. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  993. return false;
  994. }
  995. catch (InvalidCredentialException e)
  996. {
  997. NoteDeadRegion(regionHandle);
  998. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
  999. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1000. return false;
  1001. }
  1002. catch (AuthenticationException e)
  1003. {
  1004. NoteDeadRegion(regionHandle);
  1005. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
  1006. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1007. return false;
  1008. }
  1009. catch (Exception e)
  1010. {
  1011. NoteDeadRegion(regionHandle);
  1012. m_log.Warn("[OGS1 GRID SERVICES]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
  1013. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0}", e);
  1014. return false;
  1015. }
  1016. }
  1017. else
  1018. {
  1019. return false;
  1020. }
  1021. }
  1022. /// <summary>
  1023. ///
  1024. /// </summary>
  1025. /// <param name="regionHandle"></param>
  1026. /// <param name="agentID"></param>
  1027. /// <param name="position"></param>
  1028. /// <returns></returns>
  1029. public bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
  1030. {
  1031. RegionInfo[] regions = m_regionsOnInstance.ToArray();
  1032. bool banned = false;
  1033. for (int i = 0; i < regions.Length; i++)
  1034. {
  1035. if (regions[i] != null)
  1036. {
  1037. if (regions[i].RegionHandle == regionHandle)
  1038. {
  1039. if (regions[i].EstateSettings.IsBanned(agentID))
  1040. {
  1041. banned = true;
  1042. break;
  1043. }
  1044. }
  1045. }
  1046. }
  1047. if (banned)
  1048. return false;
  1049. RegionInfo regInfo = null;
  1050. try
  1051. {
  1052. if (m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying))
  1053. {
  1054. return true;
  1055. }
  1056. regInfo = RequestNeighbourInfo(regionHandle);
  1057. if (regInfo != null)
  1058. {
  1059. bool retValue = false;
  1060. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
  1061. typeof (OGS1InterRegionRemoting),
  1062. "tcp://" + regInfo.RemotingAddress +
  1063. ":" + regInfo.RemotingPort +
  1064. "/InterRegions");
  1065. if (remObject != null)
  1066. {
  1067. retValue =
  1068. remObject.ExpectAvatarCrossing(regionHandle, agentID.Guid, new sLLVector3(position),
  1069. isFlying);
  1070. }
  1071. else
  1072. {
  1073. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  1074. }
  1075. remObject = null;
  1076. return retValue;
  1077. }
  1078. //TODO need to see if we know about where this region is and use .net remoting
  1079. // to inform it.
  1080. NoteDeadRegion(regionHandle);
  1081. return false;
  1082. }
  1083. catch (RemotingException e)
  1084. {
  1085. NoteDeadRegion(regionHandle);
  1086. m_log.WarnFormat(
  1087. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  1088. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  1089. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1090. return false;
  1091. }
  1092. catch
  1093. {
  1094. NoteDeadRegion(regionHandle);
  1095. return false;
  1096. }
  1097. }
  1098. public bool ExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical)
  1099. {
  1100. RegionInfo regInfo = null;
  1101. try
  1102. {
  1103. if (m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical))
  1104. {
  1105. return true;
  1106. }
  1107. regInfo = RequestNeighbourInfo(regionHandle);
  1108. if (regInfo != null)
  1109. {
  1110. bool retValue = false;
  1111. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
  1112. typeof (OGS1InterRegionRemoting),
  1113. "tcp://" + regInfo.RemotingAddress +
  1114. ":" + regInfo.RemotingPort +
  1115. "/InterRegions");
  1116. if (remObject != null)
  1117. {
  1118. retValue =
  1119. remObject.ExpectAvatarCrossing(regionHandle, agentID.Guid, new sLLVector3(position),
  1120. isPhysical);
  1121. }
  1122. else
  1123. {
  1124. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  1125. }
  1126. remObject = null;
  1127. return retValue;
  1128. }
  1129. //TODO need to see if we know about where this region is and use .net remoting
  1130. // to inform it.
  1131. NoteDeadRegion(regionHandle);
  1132. return false;
  1133. }
  1134. catch (RemotingException e)
  1135. {
  1136. NoteDeadRegion(regionHandle);
  1137. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  1138. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1139. return false;
  1140. }
  1141. catch (SocketException e)
  1142. {
  1143. NoteDeadRegion(regionHandle);
  1144. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  1145. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1146. return false;
  1147. }
  1148. catch (InvalidCredentialException e)
  1149. {
  1150. NoteDeadRegion(regionHandle);
  1151. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
  1152. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1153. return false;
  1154. }
  1155. catch (AuthenticationException e)
  1156. {
  1157. NoteDeadRegion(regionHandle);
  1158. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
  1159. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1160. return false;
  1161. }
  1162. catch (Exception e)
  1163. {
  1164. NoteDeadRegion(regionHandle);
  1165. m_log.Warn("[OGS1 GRID SERVICES]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
  1166. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0}", e);
  1167. return false;
  1168. }
  1169. }
  1170. public bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
  1171. {
  1172. RegionInfo regInfo = null;
  1173. try
  1174. {
  1175. if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID))
  1176. {
  1177. return true;
  1178. }
  1179. regInfo = RequestNeighbourInfo(regionHandle);
  1180. if (regInfo != null)
  1181. {
  1182. // bool retValue = false;
  1183. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  1184. typeof(OGS1InterRegionRemoting),
  1185. "tcp://" + regInfo.RemotingAddress +
  1186. ":" + regInfo.RemotingPort +
  1187. "/InterRegions");
  1188. if (remObject != null)
  1189. {
  1190. // retValue =
  1191. remObject.TellRegionToCloseChildConnection(regionHandle, agentID.Guid);
  1192. }
  1193. else
  1194. {
  1195. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  1196. }
  1197. remObject = null;
  1198. return true;
  1199. }
  1200. //TODO need to see if we know about where this region is and use .net remoting
  1201. // to inform it.
  1202. NoteDeadRegion(regionHandle);
  1203. return false;
  1204. }
  1205. catch (RemotingException)
  1206. {
  1207. NoteDeadRegion(regionHandle);
  1208. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName +
  1209. " " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1210. //m_log.Debug(e.ToString());
  1211. return false;
  1212. }
  1213. catch (SocketException e)
  1214. {
  1215. NoteDeadRegion(regionHandle);
  1216. m_log.Warn("[OGS1 GRID SERVICES]: Socket Error: Unable to connect to adjacent region using tcp://" +
  1217. regInfo.RemotingAddress +
  1218. ":" + regInfo.RemotingPort +
  1219. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  1220. " - Is this neighbor up?");
  1221. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1222. return false;
  1223. }
  1224. catch (InvalidCredentialException e)
  1225. {
  1226. NoteDeadRegion(regionHandle);
  1227. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
  1228. regInfo.RemotingAddress +
  1229. ":" + regInfo.RemotingPort +
  1230. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1231. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1232. return false;
  1233. }
  1234. catch (AuthenticationException e)
  1235. {
  1236. NoteDeadRegion(regionHandle);
  1237. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region using tcp://" +
  1238. regInfo.RemotingAddress +
  1239. ":" + regInfo.RemotingPort +
  1240. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1241. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1242. return false;
  1243. }
  1244. catch (WebException e)
  1245. {
  1246. NoteDeadRegion(regionHandle);
  1247. m_log.Warn("[OGS1 GRID SERVICES]: WebException exception: Unable to connect to adjacent region using tcp://" +
  1248. regInfo.RemotingAddress +
  1249. ":" + regInfo.RemotingPort +
  1250. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1251. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1252. return false;
  1253. }
  1254. catch (Exception e)
  1255. {
  1256. NoteDeadRegion(regionHandle);
  1257. // This line errors with a Null Reference Exception.. Why? @.@
  1258. //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress +
  1259. // ":" + regInfo.RemotingPort +
  1260. //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one");
  1261. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0}", e);
  1262. return false;
  1263. }
  1264. }
  1265. public bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId)
  1266. {
  1267. return m_localBackend.AcknowledgeAgentCrossed(regionHandle, agentId);
  1268. }
  1269. public bool AcknowledgePrimCrossed(ulong regionHandle, UUID primId)
  1270. {
  1271. return m_localBackend.AcknowledgePrimCrossed(regionHandle, primId);
  1272. }
  1273. #endregion
  1274. #region Methods triggered by calls from external instances
  1275. /// <summary>
  1276. ///
  1277. /// </summary>
  1278. /// <param name="regionHandle"></param>
  1279. /// <param name="agentData"></param>
  1280. /// <returns></returns>
  1281. public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
  1282. {
  1283. //m_log.Info("[INTER]: " + gdebugRegionName + ": Incoming OGS1 Agent " + agentData.firstname + " " + agentData.lastname);
  1284. return m_localBackend.IncomingChildAgent(regionHandle, agentData);
  1285. }
  1286. public bool TriggerRegionUp(RegionUpData regionData, ulong regionhandle)
  1287. {
  1288. m_log.Info(
  1289. "[OGS1 GRID SERVICES]: " +
  1290. m_localBackend._gdebugRegionName + "Incoming OGS1 RegionUpReport: " + "(" + regionData.X +
  1291. "," + regionData.Y + "). Giving this region a fresh set of 'dead' tries");
  1292. RegionInfo nRegionInfo = new RegionInfo();
  1293. nRegionInfo.SetEndPoint("127.0.0.1", regionData.PORT);
  1294. nRegionInfo.ExternalHostName = regionData.IPADDR;
  1295. nRegionInfo.RegionLocX = regionData.X;
  1296. nRegionInfo.RegionLocY = regionData.Y;
  1297. lock (m_deadRegionCache)
  1298. {
  1299. if (m_deadRegionCache.ContainsKey(nRegionInfo.RegionHandle))
  1300. {
  1301. m_deadRegionCache.Remove(nRegionInfo.RegionHandle);
  1302. }
  1303. }
  1304. return m_localBackend.TriggerRegionUp(nRegionInfo, regionhandle);
  1305. }
  1306. public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  1307. {
  1308. //m_log.Info("[INTER]: Incoming OGS1 Child Agent Data Update");
  1309. return m_localBackend.TriggerChildAgentUpdate(regionHandle, cAgentData);
  1310. }
  1311. /// <summary>
  1312. ///
  1313. /// </summary>
  1314. /// <param name="regionHandle"></param>
  1315. /// <param name="agentData"></param>
  1316. /// <returns></returns>
  1317. public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod)
  1318. {
  1319. m_log.DebugFormat("[INTERREGION]: Got prim crosssing request for {0}", primID);
  1320. m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod);
  1321. return true;
  1322. }
  1323. /// <summary>
  1324. ///
  1325. /// </summary>
  1326. /// <param name="regionHandle"></param>
  1327. /// <param name="agentID"></param>
  1328. /// <param name="position"></param>
  1329. /// <returns></returns>
  1330. public bool TriggerExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
  1331. {
  1332. return m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
  1333. }
  1334. public bool TriggerExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical)
  1335. {
  1336. return m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical);
  1337. }
  1338. public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
  1339. {
  1340. return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
  1341. }
  1342. #endregion
  1343. #endregion
  1344. int timeOut = 10; //10 seconds
  1345. /// <summary>
  1346. /// Check that a region is available for TCP comms. This is necessary for .NET remoting between regions.
  1347. /// </summary>
  1348. /// <param name="address"></param>
  1349. /// <param name="port"></param>
  1350. /// <param name="retry"></param>
  1351. /// <returns></returns>
  1352. public bool CheckRegion(string address, uint port, bool retry)
  1353. {
  1354. bool available = false;
  1355. bool timed_out = true;
  1356. IPAddress ia = Util.GetHostFromDNS(address);
  1357. IPEndPoint m_EndPoint;
  1358. try
  1359. {
  1360. m_EndPoint = new IPEndPoint(ia, (int)port);
  1361. }
  1362. catch (Exception)
  1363. {
  1364. m_log.Debug("[OGS1 GRID SERVICES]: Invalid remoting address: " + address);
  1365. return false;
  1366. }
  1367. AsyncCallback callback = delegate(IAsyncResult iar)
  1368. {
  1369. Socket s = (Socket)iar.AsyncState;
  1370. try
  1371. {
  1372. s.EndConnect(iar);
  1373. available = true;
  1374. timed_out = false;
  1375. }
  1376. catch (Exception e)
  1377. {
  1378. m_log.DebugFormat(
  1379. "[OGS1 GRID SERVICES]: Callback EndConnect exception: {0}:{1}", e.Message, e.StackTrace);
  1380. }
  1381. s.Close();
  1382. };
  1383. try
  1384. {
  1385. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  1386. IAsyncResult ar = socket.BeginConnect(m_EndPoint, callback, socket);
  1387. ar.AsyncWaitHandle.WaitOne(timeOut * 1000, false);
  1388. }
  1389. catch (Exception e)
  1390. {
  1391. m_log.DebugFormat(
  1392. "[OGS1 GRID SERVICES]: CheckRegion Socket Setup exception: {0}:{1}", e.Message, e.StackTrace);
  1393. return false;
  1394. }
  1395. if (timed_out)
  1396. {
  1397. m_log.DebugFormat(
  1398. "[OGS1 GRID SERVICES]: socket [{0}] timed out ({1}) waiting to obtain a connection.",
  1399. m_EndPoint, timeOut * 1000);
  1400. if (retry)
  1401. {
  1402. return CheckRegion(address, port, false);
  1403. }
  1404. }
  1405. return available;
  1406. }
  1407. public bool CheckRegion(string address, uint port)
  1408. {
  1409. return CheckRegion(address, port, true);
  1410. }
  1411. public void NoteDeadRegion(ulong regionhandle)
  1412. {
  1413. lock (m_deadRegionCache)
  1414. {
  1415. if (m_deadRegionCache.ContainsKey(regionhandle))
  1416. {
  1417. m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1;
  1418. }
  1419. else
  1420. {
  1421. m_deadRegionCache.Add(regionhandle, 1);
  1422. }
  1423. }
  1424. }
  1425. public LandData RequestLandData (ulong regionHandle, uint x, uint y)
  1426. {
  1427. m_log.DebugFormat("[OGS1 GRID SERVICES] requests land data in {0}, at {1}, {2}",
  1428. regionHandle, x, y);
  1429. LandData landData = m_localBackend.RequestLandData(regionHandle, x, y);
  1430. if (landData == null)
  1431. {
  1432. Hashtable hash = new Hashtable();
  1433. hash["region_handle"] = regionHandle.ToString();
  1434. hash["x"] = x.ToString();
  1435. hash["y"] = y.ToString();
  1436. IList paramList = new ArrayList();
  1437. paramList.Add(hash);
  1438. try
  1439. {
  1440. // this might be cached, as we probably requested it just a moment ago...
  1441. RegionInfo info = RequestNeighbourInfo(regionHandle);
  1442. if (info != null) // just to be sure
  1443. {
  1444. XmlRpcRequest request = new XmlRpcRequest("land_data", paramList);
  1445. string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
  1446. XmlRpcResponse response = request.Send(uri, 10000);
  1447. if (response.IsFault)
  1448. {
  1449. m_log.ErrorFormat("[OGS1 GRID SERVICES] remote call returned an error: {0}", response.FaultString);
  1450. }
  1451. else
  1452. {
  1453. hash = (Hashtable)response.Value;
  1454. try
  1455. {
  1456. landData = new LandData();
  1457. landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]);
  1458. landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]);
  1459. landData.Area = Convert.ToInt32(hash["Area"]);
  1460. landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]);
  1461. landData.Description = (string)hash["Description"];
  1462. landData.Flags = Convert.ToUInt32(hash["Flags"]);
  1463. landData.GlobalID = new UUID((string)hash["GlobalID"]);
  1464. landData.Name = (string)hash["Name"];
  1465. landData.OwnerID = new UUID((string)hash["OwnerID"]);
  1466. landData.SalePrice = Convert.ToInt32(hash["SalePrice"]);
  1467. landData.SnapshotID = new UUID((string)hash["SnapshotID"]);
  1468. landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]);
  1469. m_log.DebugFormat("[OGS1 GRID SERVICES] Got land data for parcel {0}", landData.Name);
  1470. }
  1471. catch (Exception e)
  1472. {
  1473. m_log.Error("[OGS1 GRID SERVICES] Got exception while parsing land-data:", e);
  1474. }
  1475. }
  1476. }
  1477. else m_log.WarnFormat("[OGS1 GRID SERVICES] Couldn't find region with handle {0}", regionHandle);
  1478. }
  1479. catch (Exception e)
  1480. {
  1481. m_log.ErrorFormat("[OGS1 GRID SERVICES] Couldn't contact region {0}: {1}", regionHandle, e);
  1482. }
  1483. }
  1484. return landData;
  1485. }
  1486. // Grid Request Processing
  1487. /// <summary>
  1488. /// Someone asked us about parcel-information
  1489. /// </summary>
  1490. /// <param name="request"></param>
  1491. /// <returns></returns>
  1492. public XmlRpcResponse LandData(XmlRpcRequest request)
  1493. {
  1494. Hashtable requestData = (Hashtable)request.Params[0];
  1495. ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]);
  1496. uint x = Convert.ToUInt32(requestData["x"]);
  1497. uint y = Convert.ToUInt32(requestData["y"]);
  1498. m_log.DebugFormat("[OGS1 GRID SERVICES]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle);
  1499. LandData landData = m_localBackend.RequestLandData(regionHandle, x, y);
  1500. Hashtable hash = new Hashtable();
  1501. if (landData != null)
  1502. {
  1503. // for now, only push out the data we need for answering a ParcelInfoReqeust
  1504. hash["AABBMax"] = landData.AABBMax.ToString();
  1505. hash["AABBMin"] = landData.AABBMin.ToString();
  1506. hash["Area"] = landData.Area.ToString();
  1507. hash["AuctionID"] = landData.AuctionID.ToString();
  1508. hash["Description"] = landData.Description;
  1509. hash["Flags"] = landData.Flags.ToString();
  1510. hash["GlobalID"] = landData.GlobalID.ToString();
  1511. hash["Name"] = landData.Name;
  1512. hash["OwnerID"] = landData.OwnerID.ToString();
  1513. hash["SalePrice"] = landData.SalePrice.ToString();
  1514. hash["SnapshotID"] = landData.SnapshotID.ToString();
  1515. hash["UserLocation"] = landData.UserLocation.ToString();
  1516. }
  1517. XmlRpcResponse response = new XmlRpcResponse();
  1518. response.Value = hash;
  1519. return response;
  1520. }
  1521. public List<RegionInfo> RequestNamedRegions (string name, int maxNumber)
  1522. {
  1523. // no asking of the local backend first, here, as we have to ask the gridserver anyway.
  1524. Hashtable hash = new Hashtable();
  1525. hash["name"] = name;
  1526. hash["maxNumber"] = maxNumber.ToString();
  1527. IList paramList = new ArrayList();
  1528. paramList.Add(hash);
  1529. Hashtable result = XmlRpcSearchForRegionByName(paramList);
  1530. if (result == null) return null;
  1531. uint numberFound = Convert.ToUInt32(result["numFound"]);
  1532. List<RegionInfo> infos = new List<RegionInfo>();
  1533. for (int i = 0; i < numberFound; ++i)
  1534. {
  1535. string prefix = "region" + i + ".";
  1536. RegionInfo info = buildRegionInfo(result, prefix);
  1537. infos.Add(info);
  1538. }
  1539. return infos;
  1540. }
  1541. private RegionInfo buildRegionInfo(Hashtable responseData, string prefix)
  1542. {
  1543. uint regX = Convert.ToUInt32((string) responseData[prefix + "region_locx"]);
  1544. uint regY = Convert.ToUInt32((string) responseData[prefix + "region_locy"]);
  1545. string internalIpStr = (string) responseData[prefix + "sim_ip"];
  1546. uint port = Convert.ToUInt32(responseData[prefix + "sim_port"]);
  1547. IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(internalIpStr), (int) port);
  1548. RegionInfo regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
  1549. regionInfo.RemotingPort = Convert.ToUInt32((string) responseData[prefix + "remoting_port"]);
  1550. regionInfo.RemotingAddress = internalIpStr;
  1551. if (responseData.ContainsKey(prefix + "http_port"))
  1552. {
  1553. regionInfo.HttpPort = Convert.ToUInt32((string) responseData[prefix + "http_port"]);
  1554. }
  1555. regionInfo.RegionID = new UUID((string) responseData[prefix + "region_UUID"]);
  1556. regionInfo.RegionName = (string) responseData[prefix + "region_name"];
  1557. regionInfo.RegionSettings.TerrainImageID = new UUID((string) responseData[prefix + "map_UUID"]);
  1558. return regionInfo;
  1559. }
  1560. private Hashtable XmlRpcSearchForRegionByName(IList parameters)
  1561. {
  1562. try
  1563. {
  1564. XmlRpcRequest request = new XmlRpcRequest("search_for_region_by_name", parameters);
  1565. XmlRpcResponse resp = request.Send(serversInfo.GridURL, 10000);
  1566. Hashtable respData = (Hashtable) resp.Value;
  1567. if (respData != null && respData.Contains("faultCode"))
  1568. {
  1569. m_log.WarnFormat("[OGS1 GRID SERVICES]: Got an error while contacting GridServer: {0}", respData["faultString"]);
  1570. return null;
  1571. }
  1572. return respData;
  1573. }
  1574. catch (Exception e)
  1575. {
  1576. m_log.Error("[OGS1 GRID SERVICES]: MapBlockQuery XMLRPC failure: ", e);
  1577. return null;
  1578. }
  1579. }
  1580. public List<UUID> InformFriendsInOtherRegion(UUID agentId, ulong destRegionHandle, List<UUID> friends, bool online)
  1581. {
  1582. List<UUID> tpdAway = new List<UUID>();
  1583. // destRegionHandle is a region on another server
  1584. RegionInfo info = RequestNeighbourInfo(destRegionHandle);
  1585. if (info != null)
  1586. {
  1587. string httpServer = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/presence_update_bulk";
  1588. Hashtable reqParams = new Hashtable();
  1589. reqParams["agentID"] = agentId.ToString();
  1590. reqParams["agentOnline"] = online;
  1591. int count = 0;
  1592. foreach (UUID uuid in friends)
  1593. {
  1594. reqParams["friendID_" + count++] = uuid.ToString();
  1595. }
  1596. reqParams["friendCount"] = count;
  1597. IList parameters = new ArrayList();
  1598. parameters.Add(reqParams);
  1599. try
  1600. {
  1601. XmlRpcRequest request = new XmlRpcRequest("presence_update_bulk", parameters);
  1602. XmlRpcResponse response = request.Send(httpServer, 5000);
  1603. Hashtable respData = (Hashtable)response.Value;
  1604. count = (int)respData["friendCount"];
  1605. for (int i = 0; i < count; ++i)
  1606. {
  1607. UUID uuid;
  1608. if (UUID.TryParse((string)respData["friendID_" + i], out uuid)) tpdAway.Add(uuid);
  1609. }
  1610. }
  1611. catch (Exception e)
  1612. {
  1613. m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e);
  1614. }
  1615. }
  1616. else m_log.WarnFormat("[OGS1 GRID SERVICES]: Couldn't find region {0}???", destRegionHandle);
  1617. return tpdAway;
  1618. }
  1619. public bool TriggerTerminateFriend(ulong destRegionHandle, UUID agentID, UUID exFriendID)
  1620. {
  1621. // destRegionHandle is a region on another server
  1622. RegionInfo info = RequestNeighbourInfo(destRegionHandle);
  1623. if (info == null)
  1624. {
  1625. m_log.WarnFormat("[OGS1 GRID SERVICES]: Couldn't find region {0}", destRegionHandle);
  1626. return false; // region not found???
  1627. }
  1628. string httpServer = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/presence_update_bulk";
  1629. Hashtable reqParams = new Hashtable();
  1630. reqParams["agentID"] = agentID.ToString();
  1631. reqParams["friendID"] = exFriendID.ToString();
  1632. IList parameters = new ArrayList();
  1633. parameters.Add(reqParams);
  1634. try
  1635. {
  1636. XmlRpcRequest request = new XmlRpcRequest("terminate_friend", parameters);
  1637. XmlRpcResponse response = request.Send(httpServer, 5000);
  1638. Hashtable respData = (Hashtable)response.Value;
  1639. return (bool)respData["success"];
  1640. }
  1641. catch (Exception e)
  1642. {
  1643. m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e);
  1644. return false;
  1645. }
  1646. }
  1647. }
  1648. }