diff options
author | Mike Mazur | 2009-01-28 01:56:04 +0000 |
---|---|---|
committer | Mike Mazur | 2009-01-28 01:56:04 +0000 |
commit | fefe0ff3d9ceaaefccb494ef13a5a98cc0131070 (patch) | |
tree | 01c5057fb9f23c55f07ff102906f5f14d6453118 /ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs | |
parent | Slight cleanup of docs, removing trailing whitespace. (diff) | |
download | opensim-SC_OLD-fefe0ff3d9ceaaefccb494ef13a5a98cc0131070.zip opensim-SC_OLD-fefe0ff3d9ceaaefccb494ef13a5a98cc0131070.tar.gz opensim-SC_OLD-fefe0ff3d9ceaaefccb494ef13a5a98cc0131070.tar.bz2 opensim-SC_OLD-fefe0ff3d9ceaaefccb494ef13a5a98cc0131070.tar.xz |
Removing contents of ThirdParty/3Di. The load balancer can now be found
at http://forge.opensimulator.org/gf/project/loadbalancer/
config key: svn.rmdir
Diffstat (limited to 'ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs')
-rw-r--r-- | ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs | 554 |
1 files changed, 0 insertions, 554 deletions
diff --git a/ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs b/ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs deleted file mode 100644 index a1476fa..0000000 --- a/ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs +++ /dev/null | |||
@@ -1,554 +0,0 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Net; | ||
32 | using System.Net.Sockets; | ||
33 | using System.Reflection; | ||
34 | using log4net; | ||
35 | using Mono.Addins; | ||
36 | using Nwc.XmlRpc; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Servers; | ||
39 | |||
40 | namespace OpenSim.ApplicationPlugins.RegionProxy | ||
41 | { | ||
42 | /* This module has an interface to OpenSim clients that is constant, and is responsible for relaying | ||
43 | * messages to and from clients to the region objects. Since the region objects can be duplicated and | ||
44 | * moved dynamically, the proxy provides methods for changing and adding regions. If more than one region | ||
45 | * is associated with a client port, then the message will be broadcasted to all those regions. | ||
46 | * | ||
47 | * The client interface port may be blocked. While being blocked, all messages from the clients will be | ||
48 | * stored in the proxy. Once the interface port is unblocked again, all stored messages will be resent | ||
49 | * to the regions. This functionality is used when moving or cloning an region to make sure that no messages | ||
50 | * are sent to the region while it is being reconfigured. | ||
51 | * | ||
52 | * The proxy opens a XmlRpc interface with these public methods: | ||
53 | * - AddPort | ||
54 | * - AddRegion | ||
55 | * - ChangeRegion | ||
56 | * - BlockClientMessages | ||
57 | * - UnblockClientMessages | ||
58 | */ | ||
59 | |||
60 | public class RegionProxyPlugin : IApplicationPlugin | ||
61 | { | ||
62 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
63 | private BaseHttpServer command_server; | ||
64 | private ProxyServer proxy; | ||
65 | |||
66 | #region IApplicationPlugin Members | ||
67 | // TODO: required by IPlugin, but likely not at all right | ||
68 | string m_name = "RegionProxy"; | ||
69 | string m_version = "0.1"; | ||
70 | |||
71 | public string Version { get { return m_version; } } | ||
72 | public string Name { get { return m_name; } } | ||
73 | |||
74 | public void Initialise() | ||
75 | { | ||
76 | m_log.Info("[PROXY]: " + Name + " cannot be default-initialized!"); | ||
77 | throw new PluginNotInitialisedException (Name); | ||
78 | } | ||
79 | |||
80 | public void Initialise(OpenSimBase openSim) | ||
81 | { | ||
82 | m_log.Info("[PROXY] Starting proxy"); | ||
83 | string proxyURL = openSim.ConfigSource.Source.Configs["Network"].GetString("proxy_url", ""); | ||
84 | if (proxyURL.Length == 0) return; | ||
85 | |||
86 | uint port = (uint) Int32.Parse(proxyURL.Split(new char[] {':'})[2]); | ||
87 | command_server = new BaseHttpServer(port); | ||
88 | command_server.Start(); | ||
89 | command_server.AddXmlRPCHandler("AddPort", AddPort); | ||
90 | command_server.AddXmlRPCHandler("AddRegion", AddRegion); | ||
91 | command_server.AddXmlRPCHandler("DeleteRegion", DeleteRegion); | ||
92 | command_server.AddXmlRPCHandler("ChangeRegion", ChangeRegion); | ||
93 | command_server.AddXmlRPCHandler("BlockClientMessages", BlockClientMessages); | ||
94 | command_server.AddXmlRPCHandler("UnblockClientMessages", UnblockClientMessages); | ||
95 | command_server.AddXmlRPCHandler("Stop", Stop); | ||
96 | |||
97 | proxy = new ProxyServer(m_log); | ||
98 | } | ||
99 | |||
100 | public void Dispose() | ||
101 | { | ||
102 | } | ||
103 | |||
104 | #endregion | ||
105 | |||
106 | private XmlRpcResponse Stop(XmlRpcRequest request) | ||
107 | { | ||
108 | try | ||
109 | { | ||
110 | proxy.Stop(); | ||
111 | } | ||
112 | catch (Exception e) | ||
113 | { | ||
114 | m_log.Error("[PROXY]" + e.Message); | ||
115 | m_log.Error("[PROXY]" + e.StackTrace); | ||
116 | } | ||
117 | return new XmlRpcResponse(); | ||
118 | } | ||
119 | |||
120 | private XmlRpcResponse AddPort(XmlRpcRequest request) | ||
121 | { | ||
122 | try | ||
123 | { | ||
124 | int clientPort = (int) request.Params[0]; | ||
125 | int regionPort = (int) request.Params[1]; | ||
126 | string regionUrl = (string) request.Params[2]; | ||
127 | proxy.AddPort(clientPort, regionPort, regionUrl); | ||
128 | } | ||
129 | catch (Exception e) | ||
130 | { | ||
131 | m_log.Error("[PROXY]" + e.Message); | ||
132 | m_log.Error("[PROXY]" + e.StackTrace); | ||
133 | } | ||
134 | return new XmlRpcResponse(); | ||
135 | } | ||
136 | |||
137 | private XmlRpcResponse AddRegion(XmlRpcRequest request) | ||
138 | { | ||
139 | try | ||
140 | { | ||
141 | int currentRegionPort = (int) request.Params[0]; | ||
142 | string currentRegionUrl = (string) request.Params[1]; | ||
143 | int newRegionPort = (int) request.Params[2]; | ||
144 | string newRegionUrl = (string) request.Params[3]; | ||
145 | proxy.AddRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl); | ||
146 | } | ||
147 | catch (Exception e) | ||
148 | { | ||
149 | m_log.Error("[PROXY]" + e.Message); | ||
150 | m_log.Error("[PROXY]" + e.StackTrace); | ||
151 | } | ||
152 | return new XmlRpcResponse(); | ||
153 | } | ||
154 | |||
155 | private XmlRpcResponse ChangeRegion(XmlRpcRequest request) | ||
156 | { | ||
157 | try | ||
158 | { | ||
159 | int currentRegionPort = (int) request.Params[0]; | ||
160 | string currentRegionUrl = (string) request.Params[1]; | ||
161 | int newRegionPort = (int) request.Params[2]; | ||
162 | string newRegionUrl = (string) request.Params[3]; | ||
163 | proxy.ChangeRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl); | ||
164 | } | ||
165 | catch (Exception e) | ||
166 | { | ||
167 | m_log.Error("[PROXY]" + e.Message); | ||
168 | m_log.Error("[PROXY]" + e.StackTrace); | ||
169 | } | ||
170 | return new XmlRpcResponse(); | ||
171 | } | ||
172 | |||
173 | private XmlRpcResponse DeleteRegion(XmlRpcRequest request) | ||
174 | { | ||
175 | try | ||
176 | { | ||
177 | int currentRegionPort = (int) request.Params[0]; | ||
178 | string currentRegionUrl = (string) request.Params[1]; | ||
179 | proxy.DeleteRegion(currentRegionPort, currentRegionUrl); | ||
180 | } | ||
181 | catch (Exception e) | ||
182 | { | ||
183 | m_log.Error("[PROXY]" + e.Message); | ||
184 | m_log.Error("[PROXY]" + e.StackTrace); | ||
185 | } | ||
186 | return new XmlRpcResponse(); | ||
187 | } | ||
188 | |||
189 | private XmlRpcResponse BlockClientMessages(XmlRpcRequest request) | ||
190 | { | ||
191 | try | ||
192 | { | ||
193 | string regionUrl = (string) request.Params[0]; | ||
194 | int regionPort = (int) request.Params[1]; | ||
195 | proxy.BlockClientMessages(regionUrl, regionPort); | ||
196 | } | ||
197 | catch (Exception e) | ||
198 | { | ||
199 | m_log.Error("[PROXY]" + e.Message); | ||
200 | m_log.Error("[PROXY]" + e.StackTrace); | ||
201 | } | ||
202 | return new XmlRpcResponse(); | ||
203 | } | ||
204 | |||
205 | private XmlRpcResponse UnblockClientMessages(XmlRpcRequest request) | ||
206 | { | ||
207 | try | ||
208 | { | ||
209 | string regionUrl = (string) request.Params[0]; | ||
210 | int regionPort = (int) request.Params[1]; | ||
211 | proxy.UnblockClientMessages(regionUrl, regionPort); | ||
212 | } | ||
213 | catch (Exception e) | ||
214 | { | ||
215 | m_log.Error("[PROXY]" + e.Message); | ||
216 | m_log.Error("[PROXY]" + e.StackTrace); | ||
217 | } | ||
218 | return new XmlRpcResponse(); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | |||
223 | public class ProxyServer | ||
224 | { | ||
225 | protected readonly ILog m_log; | ||
226 | protected ProxyMap proxy_map = new ProxyMap(); | ||
227 | protected AsyncCallback receivedData; | ||
228 | protected bool running; | ||
229 | |||
230 | public ProxyServer(ILog log) | ||
231 | { | ||
232 | m_log = log; | ||
233 | running = false; | ||
234 | receivedData = new AsyncCallback(OnReceivedData); | ||
235 | } | ||
236 | |||
237 | public void BlockClientMessages(string regionUrl, int regionPort) | ||
238 | { | ||
239 | EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(regionUrl), regionPort)); | ||
240 | ProxyMap.RegionData rd = proxy_map.GetRegionData(client); | ||
241 | rd.isBlocked = true; | ||
242 | } | ||
243 | |||
244 | public void UnblockClientMessages(string regionUrl, int regionPort) | ||
245 | { | ||
246 | EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(regionUrl), regionPort)); | ||
247 | ProxyMap.RegionData rd = proxy_map.GetRegionData(client); | ||
248 | |||
249 | rd.isBlocked = false; | ||
250 | while (rd.storedMessages.Count > 0) | ||
251 | { | ||
252 | StoredMessage msg = (StoredMessage) rd.storedMessages.Dequeue(); | ||
253 | //m_log.Verbose("[PROXY]"+"Resending blocked message from {0}", msg.senderEP); | ||
254 | SendMessage(msg.buffer, msg.length, msg.senderEP, msg.sd); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | public void AddRegion(int oldRegionPort, string oldRegionUrl, int newRegionPort, string newRegionUrl) | ||
259 | { | ||
260 | //m_log.Verbose("[PROXY]"+"AddRegion {0} {1}", oldRegionPort, newRegionPort); | ||
261 | EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort)); | ||
262 | ProxyMap.RegionData data = proxy_map.GetRegionData(client); | ||
263 | data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort)); | ||
264 | } | ||
265 | |||
266 | public void ChangeRegion(int oldRegionPort, string oldRegionUrl, int newRegionPort, string newRegionUrl) | ||
267 | { | ||
268 | //m_log.Verbose("[PROXY]"+"ChangeRegion {0} {1}", oldRegionPort, newRegionPort); | ||
269 | EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort)); | ||
270 | ProxyMap.RegionData data = proxy_map.GetRegionData(client); | ||
271 | data.regions.Clear(); | ||
272 | data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort)); | ||
273 | } | ||
274 | |||
275 | public void DeleteRegion(int oldRegionPort, string oldRegionUrl) | ||
276 | { | ||
277 | m_log.InfoFormat("[PROXY]" + "DeleteRegion {0} {1}", oldRegionPort, oldRegionUrl); | ||
278 | EndPoint regionEP = new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort); | ||
279 | EndPoint client = proxy_map.GetClient(regionEP); | ||
280 | ProxyMap.RegionData data = proxy_map.GetRegionData(client); | ||
281 | data.regions.Remove(regionEP); | ||
282 | } | ||
283 | |||
284 | public void AddPort(int clientPort, int regionPort, string regionUrl) | ||
285 | { | ||
286 | running = true; | ||
287 | |||
288 | //m_log.Verbose("[PROXY]"+"AddPort {0} {1}", clientPort, regionPort); | ||
289 | IPEndPoint clientEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), clientPort); | ||
290 | proxy_map.Add(clientEP, new IPEndPoint(IPAddress.Parse(regionUrl), regionPort)); | ||
291 | |||
292 | ServerData sd = new ServerData(); | ||
293 | sd.clientEP = new IPEndPoint(clientEP.Address, clientEP.Port); | ||
294 | |||
295 | OpenPort(sd); | ||
296 | } | ||
297 | |||
298 | protected void OpenPort(ServerData sd) | ||
299 | { | ||
300 | // sd.clientEP must be set before calling this function | ||
301 | |||
302 | ClosePort(sd); | ||
303 | |||
304 | try | ||
305 | { | ||
306 | m_log.InfoFormat("[PROXY] Opening special UDP socket on {0}", sd.clientEP); | ||
307 | sd.serverIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), ((IPEndPoint) sd.clientEP).Port); | ||
308 | sd.server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); | ||
309 | sd.server.Bind(sd.serverIP); | ||
310 | |||
311 | sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||
312 | //receivedData = new AsyncCallback(OnReceivedData); | ||
313 | sd.server.BeginReceiveFrom(sd.recvBuffer, 0, sd.recvBuffer.Length, SocketFlags.None, ref sd.senderEP, receivedData, sd); | ||
314 | } | ||
315 | catch (Exception e) | ||
316 | { | ||
317 | m_log.ErrorFormat("[PROXY] Failed to (re)open socket {0}", sd.clientEP); | ||
318 | m_log.Error("[PROXY]" + e.Message); | ||
319 | m_log.Error("[PROXY]" + e.StackTrace); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | protected static void ClosePort(ServerData sd) | ||
324 | { | ||
325 | // Close the port if it exists and is open | ||
326 | if (sd.server == null) return; | ||
327 | |||
328 | try | ||
329 | { | ||
330 | sd.server.Shutdown(SocketShutdown.Both); | ||
331 | sd.server.Close(); | ||
332 | } | ||
333 | catch (Exception) | ||
334 | { | ||
335 | } | ||
336 | } | ||
337 | |||
338 | public void Stop() | ||
339 | { | ||
340 | running = false; | ||
341 | m_log.InfoFormat("[PROXY] Stopping the proxy server"); | ||
342 | } | ||
343 | |||
344 | |||
345 | protected virtual void OnReceivedData(IAsyncResult result) | ||
346 | { | ||
347 | if (!running) return; | ||
348 | |||
349 | ServerData sd = (ServerData) result.AsyncState; | ||
350 | sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||
351 | |||
352 | try | ||
353 | { | ||
354 | int numBytes = sd.server.EndReceiveFrom(result, ref sd.senderEP); | ||
355 | if (numBytes > 0) | ||
356 | { | ||
357 | SendMessage(sd.recvBuffer, numBytes, sd.senderEP, sd); | ||
358 | } | ||
359 | } | ||
360 | catch (Exception e) | ||
361 | { | ||
362 | // OpenPort(sd); // reopen the port just in case | ||
363 | m_log.ErrorFormat("[PROXY] EndReceiveFrom failed in {0}", sd.clientEP); | ||
364 | m_log.Error("[PROXY]" + e.Message); | ||
365 | m_log.Error("[PROXY]" + e.StackTrace); | ||
366 | } | ||
367 | |||
368 | WaitForNextMessage(sd); | ||
369 | } | ||
370 | |||
371 | protected void WaitForNextMessage(ServerData sd) | ||
372 | { | ||
373 | bool error = true; | ||
374 | while (error) | ||
375 | { | ||
376 | error = false; | ||
377 | try | ||
378 | { | ||
379 | sd.server.BeginReceiveFrom(sd.recvBuffer, 0, sd.recvBuffer.Length, SocketFlags.None, ref sd.senderEP, receivedData, sd); | ||
380 | } | ||
381 | catch (Exception e) | ||
382 | { | ||
383 | error = true; | ||
384 | m_log.ErrorFormat("[PROXY] BeginReceiveFrom failed, retrying... {0}", sd.clientEP); | ||
385 | m_log.Error("[PROXY]" + e.Message); | ||
386 | m_log.Error("[PROXY]" + e.StackTrace); | ||
387 | OpenPort(sd); | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | |||
392 | protected void SendMessage(byte[] buffer, int length, EndPoint senderEP, ServerData sd) | ||
393 | { | ||
394 | int numBytes = length; | ||
395 | |||
396 | //m_log.ErrorFormat("[PROXY] Got message from {0} in thread {1}, size {2}", senderEP, sd.clientEP, numBytes); | ||
397 | EndPoint client = proxy_map.GetClient(senderEP); | ||
398 | |||
399 | if (client == null) | ||
400 | { | ||
401 | // This message comes from a client object, forward it to the the region(s) | ||
402 | ProxyCodec.EncodeProxyMessage(buffer, ref numBytes, senderEP); | ||
403 | ProxyMap.RegionData rd = proxy_map.GetRegionData(sd.clientEP); | ||
404 | foreach (EndPoint region in rd.regions) | ||
405 | { | ||
406 | if (rd.isBlocked) | ||
407 | { | ||
408 | rd.storedMessages.Enqueue(new StoredMessage(buffer, length, numBytes, senderEP, sd)); | ||
409 | } | ||
410 | else | ||
411 | { | ||
412 | try | ||
413 | { | ||
414 | sd.server.SendTo(buffer, numBytes, SocketFlags.None, region); | ||
415 | //m_log.InfoFormat("[PROXY] Sending client message from {0} to {1}", senderEP, region); | ||
416 | } | ||
417 | catch (Exception e) | ||
418 | { | ||
419 | OpenPort(sd); // reopen the port just in case | ||
420 | m_log.ErrorFormat("[PROXY] Failed sending client message from {0} to {1}", senderEP, region); | ||
421 | m_log.Error("[PROXY]" + e.Message); | ||
422 | m_log.Error("[PROXY]" + e.StackTrace); | ||
423 | return; | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | else | ||
429 | { | ||
430 | try | ||
431 | { | ||
432 | client = ProxyCodec.DecodeProxyMessage(buffer, ref numBytes); | ||
433 | try | ||
434 | { | ||
435 | // This message comes from a region object, forward it to the its client | ||
436 | sd.server.SendTo(buffer, numBytes, SocketFlags.None, client); | ||
437 | //m_log.InfoFormat("[PROXY] Sending region message from {0} to {1}, size {2}", senderEP, client, numBytes); | ||
438 | } | ||
439 | catch (Exception e) | ||
440 | { | ||
441 | OpenPort(sd); // reopen the port just in case | ||
442 | m_log.ErrorFormat("[PROXY] Failed sending region message from {0} to {1}", senderEP, client); | ||
443 | m_log.Error("[PROXY]" + e.Message); | ||
444 | m_log.Error("[PROXY]" + e.StackTrace); | ||
445 | return; | ||
446 | } | ||
447 | } | ||
448 | catch (Exception e) | ||
449 | { | ||
450 | OpenPort(sd); // reopen the port just in case | ||
451 | m_log.ErrorFormat("[PROXY] Failed decoding region message from {0}", senderEP); | ||
452 | m_log.Error("[PROXY]" + e.Message); | ||
453 | m_log.Error("[PROXY]" + e.StackTrace); | ||
454 | return; | ||
455 | } | ||
456 | } | ||
457 | } | ||
458 | |||
459 | #region Nested type: ProxyMap | ||
460 | |||
461 | protected class ProxyMap | ||
462 | { | ||
463 | private Dictionary<EndPoint, RegionData> map; | ||
464 | |||
465 | public ProxyMap() | ||
466 | { | ||
467 | map = new Dictionary<EndPoint, RegionData>(); | ||
468 | } | ||
469 | |||
470 | public void Add(EndPoint client, EndPoint region) | ||
471 | { | ||
472 | if (map.ContainsKey(client)) | ||
473 | { | ||
474 | map[client].regions.Add(region); | ||
475 | } | ||
476 | else | ||
477 | { | ||
478 | RegionData regions = new RegionData(); | ||
479 | map.Add(client, regions); | ||
480 | regions.regions.Add(region); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | public RegionData GetRegionData(EndPoint client) | ||
485 | { | ||
486 | return map[client]; | ||
487 | } | ||
488 | |||
489 | public EndPoint GetClient(EndPoint region) | ||
490 | { | ||
491 | foreach (KeyValuePair<EndPoint, RegionData> pair in map) | ||
492 | { | ||
493 | if (pair.Value.regions.Contains(region)) | ||
494 | { | ||
495 | return pair.Key; | ||
496 | } | ||
497 | } | ||
498 | return null; | ||
499 | } | ||
500 | |||
501 | #region Nested type: RegionData | ||
502 | |||
503 | public class RegionData | ||
504 | { | ||
505 | public bool isBlocked = false; | ||
506 | public List<EndPoint> regions = new List<EndPoint>(); | ||
507 | public Queue storedMessages = new Queue(); | ||
508 | } | ||
509 | |||
510 | #endregion | ||
511 | } | ||
512 | |||
513 | #endregion | ||
514 | |||
515 | #region Nested type: ServerData | ||
516 | |||
517 | protected class ServerData | ||
518 | { | ||
519 | public EndPoint clientEP; | ||
520 | public byte[] recvBuffer = new byte[4096]; | ||
521 | public EndPoint senderEP; | ||
522 | public Socket server; | ||
523 | public IPEndPoint serverIP; | ||
524 | |||
525 | public ServerData() | ||
526 | { | ||
527 | server = null; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | #endregion | ||
532 | |||
533 | #region Nested type: StoredMessage | ||
534 | |||
535 | protected class StoredMessage | ||
536 | { | ||
537 | public byte[] buffer; | ||
538 | public int length; | ||
539 | public ServerData sd; | ||
540 | public EndPoint senderEP; | ||
541 | |||
542 | public StoredMessage(byte[] buffer, int length, int maxLength, EndPoint senderEP, ServerData sd) | ||
543 | { | ||
544 | this.buffer = new byte[maxLength]; | ||
545 | this.length = length; | ||
546 | for (int i = 0; i < length; i++) this.buffer[i] = buffer[i]; | ||
547 | this.senderEP = senderEP; | ||
548 | this.sd = sd; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | #endregion | ||
553 | } | ||
554 | } | ||