diff options
Some work on restructuring the namespaces / project names. Note this doesn't compile yet as not all the code has been changed to use the new namespaces. Am committing it now for feedback on the namespaces.
Diffstat (limited to 'OpenSim/Framework/Communications.OGS1/OGS1GridServices.cs')
-rw-r--r-- | OpenSim/Framework/Communications.OGS1/OGS1GridServices.cs | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/OpenSim/Framework/Communications.OGS1/OGS1GridServices.cs b/OpenSim/Framework/Communications.OGS1/OGS1GridServices.cs new file mode 100644 index 0000000..408643f --- /dev/null +++ b/OpenSim/Framework/Communications.OGS1/OGS1GridServices.cs | |||
@@ -0,0 +1,248 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Collections; | ||
4 | using System.Text; | ||
5 | using System.Runtime.Remoting; | ||
6 | using System.Runtime.Remoting.Channels; | ||
7 | using System.Runtime.Remoting.Channels.Tcp; | ||
8 | |||
9 | using OpenSim.Servers; | ||
10 | using OpenSim.Framework; | ||
11 | using OpenSim.Framework.Types; | ||
12 | using OpenSim.Framework.Communications; | ||
13 | |||
14 | using Nwc.XmlRpc; | ||
15 | using libsecondlife; | ||
16 | |||
17 | namespace OpenSim.Framework.Communications.OGS1 | ||
18 | { | ||
19 | public class OGS1GridServices : IGridServices, IInterRegionCommunications | ||
20 | { | ||
21 | public Dictionary<ulong, RegionCommsListener> listeners = new Dictionary<ulong, RegionCommsListener>(); | ||
22 | public GridInfo grid; | ||
23 | public BaseHttpServer httpListener; | ||
24 | private bool initialised = false; | ||
25 | |||
26 | public RegionCommsListener RegisterRegion(RegionInfo regionInfo, GridInfo gridInfo) | ||
27 | { | ||
28 | Hashtable GridParams = new Hashtable(); | ||
29 | |||
30 | grid = gridInfo; | ||
31 | |||
32 | // Login / Authentication | ||
33 | GridParams["authkey"] = gridInfo.GridServerSendKey; | ||
34 | GridParams["UUID"] = regionInfo.SimUUID.ToStringHyphenated(); | ||
35 | GridParams["sim_ip"] = regionInfo.CommsExternalAddress; | ||
36 | GridParams["sim_port"] = regionInfo.CommsIPListenPort.ToString(); | ||
37 | |||
38 | // Package into an XMLRPC Request | ||
39 | ArrayList SendParams = new ArrayList(); | ||
40 | SendParams.Add(GridParams); | ||
41 | |||
42 | // Send Request | ||
43 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams); | ||
44 | XmlRpcResponse GridResp = GridReq.Send(gridInfo.GridServerURI, 3000); | ||
45 | Hashtable GridRespData = (Hashtable)GridResp.Value; | ||
46 | Hashtable griddatahash = GridRespData; | ||
47 | |||
48 | // Process Response | ||
49 | if (GridRespData.ContainsKey("error")) | ||
50 | { | ||
51 | string errorstring = (string)GridRespData["error"]; | ||
52 | OpenSim.Framework.Console.MainLog.Instance.Error("Unable to connect to grid: " + errorstring); | ||
53 | return null; | ||
54 | } | ||
55 | |||
56 | if (!this.listeners.ContainsKey(regionInfo.RegionHandle)) | ||
57 | { | ||
58 | // initialised = true; | ||
59 | httpListener = new BaseHttpServer(regionInfo.CommsIPListenPort); | ||
60 | httpListener.AddXmlRPCHandler("expect_user", this.ExpectUser); | ||
61 | httpListener.Start(); | ||
62 | } | ||
63 | |||
64 | // Initialise the background listeners | ||
65 | listeners[regionInfo.RegionHandle] = new RegionCommsListener(); | ||
66 | |||
67 | return listeners[regionInfo.RegionHandle]; | ||
68 | } | ||
69 | |||
70 | public List<RegionInfo> RequestNeighbours(RegionInfo regionInfo) | ||
71 | { | ||
72 | Hashtable respData = MapBlockQuery((int)regionInfo.RegionLocX - 1, (int)regionInfo.RegionLocY - 1, (int)regionInfo.RegionLocX + 1, (int)regionInfo.RegionLocY + 1); | ||
73 | |||
74 | List<RegionInfo> neighbours = new List<RegionInfo>(); | ||
75 | |||
76 | foreach (Hashtable n in (Hashtable)respData.Values) | ||
77 | { | ||
78 | RegionInfo neighbour = new RegionInfo(); | ||
79 | |||
80 | //OGS1 | ||
81 | neighbour.RegionHandle = (ulong)n["regionhandle"]; | ||
82 | neighbour.RegionLocX = (uint)n["x"]; | ||
83 | neighbour.RegionLocY = (uint)n["y"]; | ||
84 | neighbour.RegionName = (string)n["name"]; | ||
85 | |||
86 | //OGS1+ | ||
87 | neighbour.CommsIPListenAddr = (string)n["sim_ip"]; | ||
88 | neighbour.CommsIPListenPort = (int)n["sim_port"]; | ||
89 | neighbour.CommsExternalAddress = (string)n["sim_uri"]; | ||
90 | neighbour.SimUUID = (string)n["uuid"]; | ||
91 | |||
92 | neighbours.Add(neighbour); | ||
93 | } | ||
94 | |||
95 | return neighbours; | ||
96 | } | ||
97 | |||
98 | public RegionInfo RequestNeighbourInfo(ulong regionHandle) | ||
99 | { | ||
100 | OpenSim.Framework.Console.MainLog.Instance.Warn("Unimplemented - RequestNeighbourInfo()"); | ||
101 | return null; | ||
102 | } | ||
103 | |||
104 | public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) | ||
105 | { | ||
106 | Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY); | ||
107 | |||
108 | List<MapBlockData> neighbours = new List<MapBlockData>(); | ||
109 | |||
110 | foreach (Hashtable n in (Hashtable)respData.Values) | ||
111 | { | ||
112 | MapBlockData neighbour = new MapBlockData(); | ||
113 | |||
114 | neighbour.X = (ushort)n["x"]; | ||
115 | neighbour.Y = (ushort)n["y"]; | ||
116 | |||
117 | neighbour.Name = (string)n["name"]; | ||
118 | neighbour.Access = (byte)n["access"]; | ||
119 | neighbour.RegionFlags = (uint)n["region-flags"]; | ||
120 | neighbour.WaterHeight = (byte)n["water-height"]; | ||
121 | neighbour.MapImageId = (string)n["map-image-id"]; | ||
122 | |||
123 | neighbours.Add(neighbour); | ||
124 | } | ||
125 | |||
126 | return neighbours; | ||
127 | } | ||
128 | |||
129 | /// <summary> | ||
130 | /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates | ||
131 | /// </summary> | ||
132 | /// <remarks>REDUNDANT - OGS1 is to be phased out in favour of OGS2</remarks> | ||
133 | /// <param name="minX">Minimum X value</param> | ||
134 | /// <param name="minY">Minimum Y value</param> | ||
135 | /// <param name="maxX">Maximum X value</param> | ||
136 | /// <param name="maxY">Maximum Y value</param> | ||
137 | /// <returns>Hashtable of hashtables containing map data elements</returns> | ||
138 | private Hashtable MapBlockQuery(int minX, int minY, int maxX, int maxY) | ||
139 | { | ||
140 | Hashtable param = new Hashtable(); | ||
141 | param["xmin"] = minX; | ||
142 | param["ymin"] = minY; | ||
143 | param["xmax"] = maxX; | ||
144 | param["ymax"] = maxY; | ||
145 | IList parameters = new ArrayList(); | ||
146 | parameters.Add(param); | ||
147 | XmlRpcRequest req = new XmlRpcRequest("map_block", parameters); | ||
148 | XmlRpcResponse resp = req.Send(grid.GridServerURI, 3000); | ||
149 | Hashtable respData = (Hashtable)resp.Value; | ||
150 | return respData; | ||
151 | } | ||
152 | |||
153 | // Grid Request Processing | ||
154 | public XmlRpcResponse ExpectUser(XmlRpcRequest request) | ||
155 | { | ||
156 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
157 | AgentCircuitData agentData = new AgentCircuitData(); | ||
158 | agentData.SessionID = new LLUUID((string)requestData["session_id"]); | ||
159 | agentData.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]); | ||
160 | agentData.firstname = (string)requestData["firstname"]; | ||
161 | agentData.lastname = (string)requestData["lastname"]; | ||
162 | agentData.AgentID = new LLUUID((string)requestData["agent_id"]); | ||
163 | agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); | ||
164 | if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1")) | ||
165 | { | ||
166 | agentData.child = true; | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | agentData.startpos = new LLVector3(Convert.ToUInt32(requestData["startpos_x"]), Convert.ToUInt32(requestData["startpos_y"]), Convert.ToUInt32(requestData["startpos_z"])); | ||
171 | agentData.child = false; | ||
172 | |||
173 | } | ||
174 | |||
175 | if (listeners.ContainsKey((ulong)requestData["regionhandle"])) | ||
176 | { | ||
177 | this.listeners[(ulong)requestData["regionhandle"]].TriggerExpectUser((ulong)requestData["regionhandle"], agentData); | ||
178 | } | ||
179 | else | ||
180 | { | ||
181 | OpenSim.Framework.Console.MainLog.Instance.Error("ExpectUser() - Unknown region " + ((ulong)requestData["regionhandle"]).ToString()); | ||
182 | } | ||
183 | |||
184 | return new XmlRpcResponse(); | ||
185 | } | ||
186 | |||
187 | #region InterRegion Comms | ||
188 | private void StartRemoting() | ||
189 | { | ||
190 | TcpChannel ch = new TcpChannel(8895); | ||
191 | ChannelServices.RegisterChannel(ch); | ||
192 | |||
193 | WellKnownServiceTypeEntry wellType = new WellKnownServiceTypeEntry( Type.GetType("OGS1InterRegionRemoting"), "InterRegions", WellKnownObjectMode.Singleton); | ||
194 | RemotingConfiguration.RegisterWellKnownServiceType(wellType); | ||
195 | InterRegionSingleton.Instance.OnArrival += this.IncomingArrival; | ||
196 | InterRegionSingleton.Instance.OnChildAgent += this.IncomingChildAgent; | ||
197 | } | ||
198 | |||
199 | #region Methods called by regions in this instance | ||
200 | public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) | ||
201 | { | ||
202 | if (this.listeners.ContainsKey(regionHandle)) | ||
203 | { | ||
204 | this.listeners[regionHandle].TriggerExpectUser(regionHandle, agentData); | ||
205 | return true; | ||
206 | } | ||
207 | //TODO need to see if we know about where this region is and use .net remoting | ||
208 | // to inform it. | ||
209 | return false; | ||
210 | } | ||
211 | |||
212 | public bool ExpectAvatarCrossing(ulong regionHandle, libsecondlife.LLUUID agentID, libsecondlife.LLVector3 position) | ||
213 | { | ||
214 | if (this.listeners.ContainsKey(regionHandle)) | ||
215 | { | ||
216 | this.listeners[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position); | ||
217 | return true; | ||
218 | } | ||
219 | //TODO need to see if we know about where this region is and use .net remoting | ||
220 | // to inform it. | ||
221 | return false; | ||
222 | } | ||
223 | #endregion | ||
224 | |||
225 | #region Methods triggered by calls from external instances | ||
226 | public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData) | ||
227 | { | ||
228 | if (this.listeners.ContainsKey(regionHandle)) | ||
229 | { | ||
230 | this.listeners[regionHandle].TriggerExpectUser(regionHandle, agentData); | ||
231 | return true; | ||
232 | } | ||
233 | return false; | ||
234 | } | ||
235 | |||
236 | public bool IncomingArrival(ulong regionHandle, libsecondlife.LLUUID agentID, libsecondlife.LLVector3 position) | ||
237 | { | ||
238 | if (this.listeners.ContainsKey(regionHandle)) | ||
239 | { | ||
240 | this.listeners[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position); | ||
241 | return true; | ||
242 | } | ||
243 | return false; | ||
244 | } | ||
245 | #endregion | ||
246 | #endregion | ||
247 | } | ||
248 | } | ||