aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Communications/OGS1/OGS1GridServices.cs')
-rw-r--r--OpenSim/Region/Communications/OGS1/OGS1GridServices.cs378
1 files changed, 378 insertions, 0 deletions
diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
new file mode 100644
index 0000000..66c1739
--- /dev/null
+++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
@@ -0,0 +1,378 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Net;
5using System.Runtime.Remoting;
6using System.Runtime.Remoting.Channels;
7using System.Runtime.Remoting.Channels.Tcp;
8using libsecondlife;
9using Nwc.XmlRpc;
10using OpenSim.Framework;
11using OpenSim.Framework.Communications;
12using OpenSim.Framework.Console;
13using OpenSim.Framework.Servers;
14using OpenSim.Framework.Types;
15
16namespace OpenSim.Region.Communications.OGS1
17{
18 public class OGS1GridServices : IGridServices, IInterRegionCommunications
19 {
20 public Dictionary<ulong, RegionCommsListener> listeners = new Dictionary<ulong, RegionCommsListener>();
21 protected Dictionary<ulong, RegionInfo> regions = new Dictionary<ulong, RegionInfo>();
22
23 public BaseHttpServer httpListener;
24 public NetworkServersInfo serversInfo;
25 public BaseHttpServer httpServer;
26
27 public OGS1GridServices(NetworkServersInfo servers_info, BaseHttpServer httpServe)
28 {
29 serversInfo = servers_info;
30 httpServer = httpServe;
31 httpServer.AddXmlRPCHandler("expect_user", this.ExpectUser);
32 this.StartRemoting();
33 }
34
35 public RegionCommsListener RegisterRegion(RegionInfo regionInfo)
36 {
37 if (!this.regions.ContainsKey((uint)regionInfo.RegionHandle))
38 {
39 this.regions.Add(regionInfo.RegionHandle, regionInfo);
40 }
41
42 Hashtable GridParams = new Hashtable();
43
44
45 // Login / Authentication
46
47 GridParams["authkey"] = serversInfo.GridSendKey;
48 GridParams["UUID"] = regionInfo.SimUUID.ToStringHyphenated();
49 GridParams["sim_ip"] = regionInfo.ExternalHostName;
50 GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString();
51 GridParams["region_locx"] = regionInfo.RegionLocX.ToString();
52 GridParams["region_locy"] = regionInfo.RegionLocY.ToString();
53 GridParams["sim_name"] = regionInfo.RegionName;
54 GridParams["http_port"] = serversInfo.HttpListenerPort.ToString();
55 GridParams["remoting_port"] = serversInfo.RemotingListenerPort.ToString();
56 GridParams["map-image-id"] = regionInfo.estateSettings.terrainImageID.ToStringHyphenated();
57
58 // Package into an XMLRPC Request
59 ArrayList SendParams = new ArrayList();
60 SendParams.Add(GridParams);
61
62 // Send Request
63 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams);
64 XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000);
65 Hashtable GridRespData = (Hashtable)GridResp.Value;
66
67 Hashtable griddatahash = GridRespData;
68
69 // Process Response
70 if (GridRespData.ContainsKey("error"))
71 {
72 string errorstring = (string)GridRespData["error"];
73 MainLog.Instance.Error("Unable to connect to grid: " + errorstring);
74 return null;
75 }
76
77 /* if (!this.listeners.ContainsKey(regionInfo.RegionHandle))
78 {
79 MainLog.Instance.Verbose("OGS1 - Registering new HTTP listener on port " + regionInfo.InternalEndPoint.Port.ToString());
80 // initialised = true;
81 httpListener = new BaseHttpServer( regionInfo.InternalEndPoint.Port );
82 httpListener.AddXmlRPCHandler("expect_user", this.ExpectUser);
83 httpListener.Start();
84 }*/
85
86 // Initialise the background listeners
87 RegionCommsListener regListener = new RegionCommsListener();
88 if (this.listeners.ContainsKey(regionInfo.RegionHandle))
89 {
90 this.listeners.Add(regionInfo.RegionHandle, regListener);
91 }
92 else
93 {
94 listeners[regionInfo.RegionHandle] = regListener;
95 }
96
97 return regListener;
98 }
99
100 public List<RegionInfo> RequestNeighbours(RegionInfo regionInfo)
101 {
102
103 Hashtable respData = MapBlockQuery((int)regionInfo.RegionLocX - 1, (int)regionInfo.RegionLocY - 1, (int)regionInfo.RegionLocX + 1, (int)regionInfo.RegionLocY + 1);
104
105 List<RegionInfo> neighbours = new List<RegionInfo>();
106
107 foreach (ArrayList a in respData.Values)
108 {
109 foreach (Hashtable n in a)
110 {
111 uint regX = Convert.ToUInt32(n["x"]);
112 uint regY = Convert.ToUInt32(n["y"]);
113 if ((regionInfo.RegionLocX != regX) || (regionInfo.RegionLocY != regY))
114 {
115 string internalIpStr = (string)n["sim_ip"];
116 uint port = Convert.ToUInt32(n["sim_port"]);
117 string externalUri = (string)n["sim_uri"];
118
119 IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int)port);
120 string neighbourExternalUri = externalUri;
121 RegionInfo neighbour = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
122
123 //OGS1
124 //neighbour.RegionHandle = (ulong)n["regionhandle"]; is now calculated locally
125
126 neighbour.RegionName = (string)n["name"];
127
128 //OGS1+
129 neighbour.SimUUID = (string)n["uuid"];
130
131 neighbours.Add(neighbour);
132 }
133 }
134 }
135
136 return neighbours;
137 }
138
139 public RegionInfo RequestNeighbourInfo(ulong regionHandle)
140 {
141 if (this.regions.ContainsKey(regionHandle))
142 {
143 return this.regions[regionHandle];
144 }
145 //TODO not a region in this instance so ask remote grid server
146
147 Hashtable requestData = new Hashtable();
148 requestData["region_handle"] = regionHandle.ToString();
149 requestData["authkey"] = this.serversInfo.GridSendKey;
150 ArrayList SendParams = new ArrayList();
151 SendParams.Add(requestData);
152 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
153 XmlRpcResponse GridResp = GridReq.Send(this.serversInfo.GridURL, 3000);
154
155 Hashtable responseData = (Hashtable)GridResp.Value;
156
157 if (responseData.ContainsKey("error"))
158 {
159 Console.WriteLine("error received from grid server" + responseData["error"]);
160 return null;
161 }
162
163 uint regX = Convert.ToUInt32((string)responseData["region_locx"]);
164 uint regY = Convert.ToUInt32((string)responseData["region_locy"]);
165 string internalIpStr = (string)responseData["sim_ip"];
166 uint port = Convert.ToUInt32(responseData["sim_port"]);
167 string externalUri = (string)responseData["sim_uri"];
168
169 IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int)port);
170 string neighbourExternalUri = externalUri;
171 RegionInfo regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
172
173 regionInfo.RemotingPort = Convert.ToUInt32((string)responseData["remoting_port"]);
174 regionInfo.RemotingAddress = internalIpStr;
175
176 regionInfo.SimUUID = new LLUUID((string)responseData["region_UUID"]);
177 regionInfo.RegionName = (string)responseData["region_name"];
178
179 return regionInfo;
180 }
181
182 public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
183 {
184 Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY);
185
186 List<MapBlockData> neighbours = new List<MapBlockData>();
187
188 foreach (ArrayList a in respData.Values)
189 {
190 foreach (Hashtable n in a)
191 {
192 MapBlockData neighbour = new MapBlockData();
193
194 neighbour.X = Convert.ToUInt16(n["x"]);
195 neighbour.Y = Convert.ToUInt16(n["y"]);
196
197 neighbour.Name = (string)n["name"];
198 neighbour.Access = Convert.ToByte(n["access"]);
199 neighbour.RegionFlags = Convert.ToUInt32(n["region-flags"]);
200 neighbour.WaterHeight = Convert.ToByte(n["water-height"]);
201 neighbour.MapImageId = new LLUUID((string)n["map-image-id"]);
202
203 neighbours.Add(neighbour);
204 }
205 }
206
207 return neighbours;
208 }
209
210 /// <summary>
211 /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates
212 /// </summary>
213 /// <remarks>REDUNDANT - OGS1 is to be phased out in favour of OGS2</remarks>
214 /// <param name="minX">Minimum X value</param>
215 /// <param name="minY">Minimum Y value</param>
216 /// <param name="maxX">Maximum X value</param>
217 /// <param name="maxY">Maximum Y value</param>
218 /// <returns>Hashtable of hashtables containing map data elements</returns>
219 private Hashtable MapBlockQuery(int minX, int minY, int maxX, int maxY)
220 {
221 Hashtable param = new Hashtable();
222 param["xmin"] = minX;
223 param["ymin"] = minY;
224 param["xmax"] = maxX;
225 param["ymax"] = maxY;
226 IList parameters = new ArrayList();
227 parameters.Add(param);
228 XmlRpcRequest req = new XmlRpcRequest("map_block", parameters);
229 XmlRpcResponse resp = req.Send(serversInfo.GridURL, 3000);
230 Hashtable respData = (Hashtable)resp.Value;
231 return respData;
232 }
233
234 // Grid Request Processing
235 public XmlRpcResponse ExpectUser(XmlRpcRequest request)
236 {
237 Console.WriteLine("Expecting User...");
238 Hashtable requestData = (Hashtable)request.Params[0];
239 AgentCircuitData agentData = new AgentCircuitData();
240 agentData.SessionID = new LLUUID((string)requestData["session_id"]);
241 agentData.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]);
242 agentData.firstname = (string)requestData["firstname"];
243 agentData.lastname = (string)requestData["lastname"];
244 agentData.AgentID = new LLUUID((string)requestData["agent_id"]);
245 agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]);
246 if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1"))
247 {
248 agentData.child = true;
249 }
250 else
251 {
252 agentData.startpos = new LLVector3(Convert.ToUInt32(requestData["startpos_x"]), Convert.ToUInt32(requestData["startpos_y"]), Convert.ToUInt32(requestData["startpos_z"]));
253 agentData.child = false;
254
255 }
256
257 if (listeners.ContainsKey(Convert.ToUInt64((string)requestData["regionhandle"])))
258 {
259 this.listeners[Convert.ToUInt64((string)requestData["regionhandle"])].TriggerExpectUser(Convert.ToUInt64((string)requestData["regionhandle"]), agentData);
260 }
261 else
262 {
263 MainLog.Instance.Error("ExpectUser() - Unknown region " + ((ulong)requestData["regionhandle"]).ToString());
264 }
265
266 MainLog.Instance.Verbose("ExpectUser() - Welcoming new user...");
267
268 return new XmlRpcResponse();
269 }
270
271 #region InterRegion Comms
272 private void StartRemoting()
273 {
274 TcpChannel ch = new TcpChannel(this.serversInfo.RemotingListenerPort);
275 ChannelServices.RegisterChannel(ch, true);
276
277 WellKnownServiceTypeEntry wellType = new WellKnownServiceTypeEntry(typeof(OGS1InterRegionRemoting), "InterRegions", WellKnownObjectMode.Singleton);
278 RemotingConfiguration.RegisterWellKnownServiceType(wellType);
279 InterRegionSingleton.Instance.OnArrival += this.IncomingArrival;
280 InterRegionSingleton.Instance.OnChildAgent += this.IncomingChildAgent;
281 }
282
283 #region Methods called by regions in this instance
284 public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
285 {
286 if (this.listeners.ContainsKey(regionHandle))
287 {
288 this.listeners[regionHandle].TriggerExpectUser(regionHandle, agentData);
289 return true;
290 }
291 RegionInfo regInfo = this.RequestNeighbourInfo(regionHandle);
292 if (regInfo != null)
293 {
294 //don't want to be creating a new link to the remote instance every time like we are here
295 bool retValue = false;
296
297
298 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
299 typeof(OGS1InterRegionRemoting),
300 "tcp://"+ regInfo.RemotingAddress+":"+regInfo.RemotingPort+"/InterRegions");
301 if (remObject != null)
302 {
303
304 retValue = remObject.InformRegionOfChildAgent(regionHandle, agentData);
305 }
306 else
307 {
308 Console.WriteLine("remoting object not found");
309 }
310 remObject = null;
311
312
313 return retValue;
314 }
315
316 return false;
317 }
318
319 public bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position)
320 {
321 if (this.listeners.ContainsKey(regionHandle))
322 {
323 this.listeners[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position);
324 return true;
325 }
326 RegionInfo regInfo = this.RequestNeighbourInfo(regionHandle);
327 if (regInfo != null)
328 {
329 bool retValue = false;
330
331
332 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
333 typeof(OGS1InterRegionRemoting),
334 "tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + "/InterRegions");
335 if (remObject != null)
336 {
337
338 retValue = remObject.ExpectAvatarCrossing(regionHandle, agentID, position);
339 }
340 else
341 {
342 Console.WriteLine("remoting object not found");
343 }
344 remObject = null;
345
346
347 return retValue;
348 }
349 //TODO need to see if we know about where this region is and use .net remoting
350 // to inform it.
351 return false;
352 }
353 #endregion
354
355 #region Methods triggered by calls from external instances
356 public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
357 {
358 if (this.listeners.ContainsKey(regionHandle))
359 {
360 this.listeners[regionHandle].TriggerExpectUser(regionHandle, agentData);
361 return true;
362 }
363 return false;
364 }
365
366 public bool IncomingArrival(ulong regionHandle, LLUUID agentID, LLVector3 position)
367 {
368 if (this.listeners.ContainsKey(regionHandle))
369 {
370 this.listeners[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position);
371 return true;
372 }
373 return false;
374 }
375 #endregion
376 #endregion
377 }
378}