aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ThirdParty/3Di/LoadBalancer
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs305
-rw-r--r--ThirdParty/3Di/LoadBalancer/TcpClient.cs139
-rw-r--r--ThirdParty/3Di/LoadBalancer/TcpServer.cs98
3 files changed, 297 insertions, 245 deletions
diff --git a/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs b/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs
index 532720d..bceb9af 100644
--- a/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs
+++ b/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs
@@ -42,9 +42,9 @@ using OpenSim.Framework.Servers;
42using OpenSim.Region.ClientStack; 42using OpenSim.Region.ClientStack;
43using OpenSim.Region.Environment.Scenes; 43using OpenSim.Region.Environment.Scenes;
44 44
45[assembly:Addin] 45[assembly : Addin]
46[assembly:AddinDependency ("OpenSim", "0.5")] 46[assembly : AddinDependency("OpenSim", "0.5")]
47[assembly:AddinDependency ("RegionProxy", "0.1")] 47[assembly : AddinDependency("RegionProxy", "0.1")]
48 48
49namespace OpenSim.ApplicationPlugins.LoadBalancer 49namespace OpenSim.ApplicationPlugins.LoadBalancer
50{ 50{
@@ -53,35 +53,41 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private OpenSimMain simMain;
57 private BaseHttpServer commandServer; 56 private BaseHttpServer commandServer;
58 57 private bool[] isLocalNeighbour;
59 private List<UDPServer> udpServers; 58 private bool isSplit = false;
60 private List<RegionInfo> regionData; 59 private TcpServer mTcpServer;
60 private object padlock = new object();
61 61
62 private int proxyOffset; 62 private int proxyOffset;
63 private string proxyURL; 63 private string proxyURL;
64 private List<RegionInfo> regionData;
65 private int[] regionPortList;
64 private SceneManager sceneManager; 66 private SceneManager sceneManager;
67 private string[] sceneURL;
65 private string serializeDir; 68 private string serializeDir;
69 private OpenSimMain simMain;
70 private TcpClient[] tcpClientList;
71 private List<UDPServer> udpServers;
66 72
67 private TcpServer mTcpServer; 73 #region IApplicationPlugin Members
68 74
69 public void Initialise(OpenSimMain openSim) 75 public void Initialise(OpenSimMain openSim)
70 { 76 {
71 m_log.Info("[BALANCER] "+"Entering Initialize()"); 77 m_log.Info("[BALANCER] " + "Entering Initialize()");
72 78
73 proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", ""); 79 proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", "");
74 if(proxyURL.Length==0) return; 80 if (proxyURL.Length == 0) return;
75 81
76 StartTcpServer(); 82 StartTcpServer();
77 ClientView.SynchronizeClient = new ClientView.SynchronizeClientHandler(SynchronizePackets); 83 ClientView.SynchronizeClient = new ClientView.SynchronizeClientHandler(SynchronizePackets);
78 AsynchronousSocketListener.PacketHandler = new AsynchronousSocketListener.PacketRecieveHandler(SynchronizePacketRecieve); 84 AsynchronousSocketListener.PacketHandler = new AsynchronousSocketListener.PacketRecieveHandler(SynchronizePacketRecieve);
79 85
80 this.sceneManager = openSim.SceneManager; 86 sceneManager = openSim.SceneManager;
81 this.udpServers = openSim.UdpServers; 87 udpServers = openSim.UdpServers;
82 this.regionData = openSim.RegionData; 88 regionData = openSim.RegionData;
83 this.simMain = openSim; 89 simMain = openSim;
84 this.commandServer = openSim.HttpServer; 90 commandServer = openSim.HttpServer;
85 91
86 proxyOffset = Int32.Parse(openSim.ConfigSource.Configs["Network"].GetString("proxy_offset", "0")); 92 proxyOffset = Int32.Parse(openSim.ConfigSource.Configs["Network"].GetString("proxy_offset", "0"));
87 serializeDir = openSim.ConfigSource.Configs["Network"].GetString("serialize_dir", "/tmp/"); 93 serializeDir = openSim.ConfigSource.Configs["Network"].GetString("serialize_dir", "/tmp/");
@@ -96,21 +102,24 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
96 commandServer.AddXmlRPCHandler("UpdatePhysics", UpdatePhysics); 102 commandServer.AddXmlRPCHandler("UpdatePhysics", UpdatePhysics);
97 commandServer.AddXmlRPCHandler("GetStatus", GetStatus); 103 commandServer.AddXmlRPCHandler("GetStatus", GetStatus);
98 104
99 m_log.Info("[BALANCER] "+"Exiting Initialize()"); 105 m_log.Info("[BALANCER] " + "Exiting Initialize()");
100 } 106 }
101 107
102 private void StartTcpServer() 108 public void Close()
103 { 109 {
104 Thread server_thread = new Thread(new ThreadStart(
105 delegate {
106 mTcpServer = new TcpServer(10001);
107 mTcpServer.start();
108 }));
109 server_thread.Start();
110 } 110 }
111 111
112 public void Close() 112 #endregion
113
114 private void StartTcpServer()
113 { 115 {
116 Thread server_thread = new Thread(new ThreadStart(
117 delegate
118 {
119 mTcpServer = new TcpServer(10001);
120 mTcpServer.start();
121 }));
122 server_thread.Start();
114 } 123 }
115 124
116 private XmlRpcResponse GetStatus(XmlRpcRequest request) 125 private XmlRpcResponse GetStatus(XmlRpcRequest request)
@@ -118,15 +127,15 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
118 XmlRpcResponse response = new XmlRpcResponse(); 127 XmlRpcResponse response = new XmlRpcResponse();
119 try 128 try
120 { 129 {
121 m_log.Info("[BALANCER] "+"Entering RegionStatus()"); 130 m_log.Info("[BALANCER] " + "Entering RegionStatus()");
122 131
123 int src_port = (int)request.Params[0]; 132 int src_port = (int) request.Params[0];
124 Scene scene = null; 133 Scene scene = null;
125 // try to get the scene object 134 // try to get the scene object
126 RegionInfo src_region = SearchRegionFromPortNum(src_port); 135 RegionInfo src_region = SearchRegionFromPortNum(src_port);
127 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false) 136 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
128 { 137 {
129 m_log.Error("[BALANCER] "+"The Scene is not found"); 138 m_log.Error("[BALANCER] " + "The Scene is not found");
130 return response; 139 return response;
131 } 140 }
132 // serialization of client's informations 141 // serialization of client's informations
@@ -137,7 +146,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
137 { 146 {
138 ClientView client = (ClientView) pre.ControllingClient; 147 ClientView client = (ClientView) pre.ControllingClient;
139 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) { 148 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) {
140 if(client.PacketProcessingEnabled==true) { 149 if (client.PacketProcessingEnabled == true)
150 {
141 get_scene_presence_filter++; 151 get_scene_presence_filter++;
142 } 152 }
143 } 153 }
@@ -149,12 +159,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
149 { 159 {
150 ClientView client = (ClientView) pre.ControllingClient; 160 ClientView client = (ClientView) pre.ControllingClient;
151 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) { 161 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) {
152 if(client.PacketProcessingEnabled==true) { 162 if (client.PacketProcessingEnabled == true)
163 {
153 get_avatar_filter++; 164 get_avatar_filter++;
154 avatar_names += pre.Firstname + " " + pre.Lastname + "; "; 165 avatar_names += pre.Firstname + " " + pre.Lastname + "; ";
155 } 166 }
156 } 167 }
157 168
158 Hashtable responseData = new Hashtable(); 169 Hashtable responseData = new Hashtable();
159 responseData["get_scene_presence_filter"] = get_scene_presence_filter; 170 responseData["get_scene_presence_filter"] = get_scene_presence_filter;
160 responseData["get_scene_presence"] = get_scene_presence; 171 responseData["get_scene_presence"] = get_scene_presence;
@@ -163,12 +174,12 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
163 responseData["avatar_names"] = avatar_names; 174 responseData["avatar_names"] = avatar_names;
164 response.Value = responseData; 175 response.Value = responseData;
165 176
166 m_log.Info("[BALANCER] "+"Exiting RegionStatus()"); 177 m_log.Info("[BALANCER] " + "Exiting RegionStatus()");
167 } 178 }
168 catch (Exception e) 179 catch (Exception e)
169 { 180 {
170 m_log.Error("[BALANCER] "+e.ToString()); 181 m_log.Error("[BALANCER] " + e.ToString());
171 m_log.Error("[BALANCER] "+e.StackTrace); 182 m_log.Error("[BALANCER] " + e.StackTrace);
172 } 183 }
173 return response; 184 return response;
174 } 185 }
@@ -177,19 +188,19 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
177 { 188 {
178 try 189 try
179 { 190 {
180 m_log.Info("[BALANCER] "+"Entering SerializeRegion()"); 191 m_log.Info("[BALANCER] " + "Entering SerializeRegion()");
181 192
182 string src_url = (string)request.Params[0]; 193 string src_url = (string) request.Params[0];
183 int src_port = (int)request.Params[1]; 194 int src_port = (int) request.Params[1];
184 195
185 SerializeRegion(src_url, src_port); 196 SerializeRegion(src_url, src_port);
186 197
187 m_log.Info("[BALANCER] "+"Exiting SerializeRegion()"); 198 m_log.Info("[BALANCER] " + "Exiting SerializeRegion()");
188 } 199 }
189 catch (Exception e) 200 catch (Exception e)
190 { 201 {
191 m_log.Error("[BALANCER] "+e.ToString()); 202 m_log.Error("[BALANCER] " + e.ToString());
192 m_log.Error("[BALANCER] "+e.StackTrace); 203 m_log.Error("[BALANCER] " + e.StackTrace);
193 } 204 }
194 205
195 return new XmlRpcResponse(); 206 return new XmlRpcResponse();
@@ -199,21 +210,21 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
199 { 210 {
200 try 211 try
201 { 212 {
202 m_log.Info("[BALANCER] "+"Entering DeserializeRegion_Move()"); 213 m_log.Info("[BALANCER] " + "Entering DeserializeRegion_Move()");
203 214
204 string src_url = (string)request.Params[0]; 215 string src_url = (string) request.Params[0];
205 int src_port = (int)request.Params[1]; 216 int src_port = (int) request.Params[1];
206 string dst_url = (string)request.Params[2]; 217 string dst_url = (string) request.Params[2];
207 int dst_port = (int)request.Params[3]; 218 int dst_port = (int) request.Params[3];
208 219
209 DeserializeRegion_Move(src_port, dst_port, src_url, dst_url); 220 DeserializeRegion_Move(src_port, dst_port, src_url, dst_url);
210 221
211 m_log.Info("[BALANCER] "+"Exiting DeserializeRegion_Move()"); 222 m_log.Info("[BALANCER] " + "Exiting DeserializeRegion_Move()");
212 } 223 }
213 catch (Exception e) 224 catch (Exception e)
214 { 225 {
215 m_log.Error("[BALANCER] "+e.ToString()); 226 m_log.Error("[BALANCER] " + e.ToString());
216 m_log.Error("[BALANCER] "+e.StackTrace); 227 m_log.Error("[BALANCER] " + e.StackTrace);
217 } 228 }
218 229
219 return new XmlRpcResponse(); 230 return new XmlRpcResponse();
@@ -223,21 +234,21 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
223 { 234 {
224 try 235 try
225 { 236 {
226 m_log.Info("[BALANCER] "+"Entering DeserializeRegion_Clone()"); 237 m_log.Info("[BALANCER] " + "Entering DeserializeRegion_Clone()");
227 238
228 string src_url = (string)request.Params[0]; 239 string src_url = (string) request.Params[0];
229 int src_port = (int)request.Params[1]; 240 int src_port = (int) request.Params[1];
230 string dst_url = (string)request.Params[2]; 241 string dst_url = (string) request.Params[2];
231 int dst_port = (int)request.Params[3]; 242 int dst_port = (int) request.Params[3];
232 243
233 DeserializeRegion_Clone(src_port, dst_port, src_url, dst_url); 244 DeserializeRegion_Clone(src_port, dst_port, src_url, dst_url);
234 245
235 m_log.Info("[BALANCER] "+"Exiting DeserializeRegion_Clone()"); 246 m_log.Info("[BALANCER] " + "Exiting DeserializeRegion_Clone()");
236 } 247 }
237 catch (Exception e) 248 catch (Exception e)
238 { 249 {
239 m_log.Error("[BALANCER] "+e.ToString()); 250 m_log.Error("[BALANCER] " + e.ToString());
240 m_log.Error("[BALANCER] "+e.StackTrace); 251 m_log.Error("[BALANCER] " + e.StackTrace);
241 throw e; 252 throw e;
242 } 253 }
243 254
@@ -248,20 +259,20 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
248 { 259 {
249 try 260 try
250 { 261 {
251 m_log.Info("[BALANCER] "+"Entering TerminateRegion()"); 262 m_log.Info("[BALANCER] " + "Entering TerminateRegion()");
252 263
253 int src_port = (int)request.Params[0]; 264 int src_port = (int) request.Params[0];
254 265
255 // backgroud 266 // backgroud
256 WaitCallback callback = new WaitCallback(TerminateRegion); 267 WaitCallback callback = new WaitCallback(TerminateRegion);
257 ThreadPool.QueueUserWorkItem(callback, src_port); 268 ThreadPool.QueueUserWorkItem(callback, src_port);
258 269
259 m_log.Info("[BALANCER] "+"Exiting TerminateRegion()"); 270 m_log.Info("[BALANCER] " + "Exiting TerminateRegion()");
260 } 271 }
261 catch (Exception e) 272 catch (Exception e)
262 { 273 {
263 m_log.Error("[BALANCER] "+e.ToString()); 274 m_log.Error("[BALANCER] " + e.ToString());
264 m_log.Error("[BALANCER] "+e.StackTrace); 275 m_log.Error("[BALANCER] " + e.StackTrace);
265 } 276 }
266 277
267 return new XmlRpcResponse(); 278 return new XmlRpcResponse();
@@ -282,7 +293,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
282 293
283 if (src_region == null) 294 if (src_region == null)
284 { 295 {
285 m_log.Error("[BALANCER] "+"Region not found"); 296 m_log.Error("[BALANCER] " + "Region not found");
286 return; 297 return;
287 } 298 }
288 299
@@ -303,8 +314,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
303 // import the source region's data 314 // import the source region's data
304 dst_region = DeserializeRegion(dst_port, true, serializeDir); 315 dst_region = DeserializeRegion(dst_port, true, serializeDir);
305 316
306 Util.XmlRpcCommand(dst_region.proxyUrl, "ChangeRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url); 317 Util.XmlRpcCommand(dst_region.proxyUrl, "ChangeRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url);
307 Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset); 318 Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset);
308 } 319 }
309 320
310 private void DeserializeRegion_Clone(int src_port, int dst_port, string src_url, string dst_url) 321 private void DeserializeRegion_Clone(int src_port, int dst_port, string src_url, string dst_url)
@@ -319,19 +330,19 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
319 dst_region = DeserializeRegion(dst_port, false, serializeDir); 330 dst_region = DeserializeRegion(dst_port, false, serializeDir);
320 331
321 // Decide who is in charge for each section 332 // Decide who is in charge for each section
322 int[] port = new int[] { src_port, dst_port }; 333 int[] port = new int[] {src_port, dst_port};
323 string[] url = new string[] { "http://" + src_url + ":" + commandServer.Port, "http://" + dst_url + ":" + commandServer.Port }; 334 string[] url = new string[] {"http://" + src_url + ":" + commandServer.Port, "http://" + dst_url + ":" + commandServer.Port};
324 for(int i=0; i<2; i++) Util.XmlRpcCommand(url[i], "SplitRegion", i, 2, port[0], port[1], url[0], url[1]); 335 for (int i = 0; i < 2; i++) Util.XmlRpcCommand(url[i], "SplitRegion", i, 2, port[0], port[1], url[0], url[1]);
325 336
326 // Enable the proxy 337 // Enable the proxy
327 Util.XmlRpcCommand(dst_region.proxyUrl, "AddRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url); 338 Util.XmlRpcCommand(dst_region.proxyUrl, "AddRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url);
328 Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset); 339 Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset);
329 } 340 }
330 341
331 private void TerminateRegion(object param) 342 private void TerminateRegion(object param)
332 { 343 {
333 RegionInfo src_region = null; 344 RegionInfo src_region = null;
334 int src_port = (int)param; 345 int src_port = (int) param;
335 346
336 //------------------------------------------ 347 //------------------------------------------
337 // Processing of remove region 348 // Processing of remove region
@@ -342,7 +353,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
342 353
343 if (src_region == null) 354 if (src_region == null)
344 { 355 {
345 m_log.Error("[BALANCER] "+"Region not found"); 356 m_log.Error("[BALANCER] " + "Region not found");
346 return; 357 return;
347 } 358 }
348 359
@@ -353,7 +364,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
353 // remove old region 364 // remove old region
354 RemoveRegion(src_region.RegionID, src_region.InternalEndPoint.Port); 365 RemoveRegion(src_region.RegionID, src_region.InternalEndPoint.Port);
355 366
356 m_log.Info("[BALANCER] "+"Region terminated"); 367 m_log.Info("[BALANCER] " + "Region terminated");
357 } 368 }
358 369
359 private RegionInfo SearchRegionFromPortNum(int portnum) 370 private RegionInfo SearchRegionFromPortNum(int portnum)
@@ -377,7 +388,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
377 388
378 private UDPServer SearchUDPServerFromPortNum(int portnum) 389 private UDPServer SearchUDPServerFromPortNum(int portnum)
379 { 390 {
380 return udpServers.Find( delegate(UDPServer server) { return (portnum + proxyOffset == ((IPEndPoint) server.Server.LocalEndPoint).Port); }); 391 return udpServers.Find(delegate(UDPServer server) { return (portnum + proxyOffset == ((IPEndPoint) server.Server.LocalEndPoint).Port); });
381 } 392 }
382 393
383 private void SerializeRegion(RegionInfo src_region, string export_dir) 394 private void SerializeRegion(RegionInfo src_region, string export_dir)
@@ -390,7 +401,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
390 // try to get the scene object 401 // try to get the scene object
391 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false) 402 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
392 { 403 {
393 m_log.Error("[BALANCER] "+"The Scene is not found"); 404 m_log.Error("[BALANCER] " + "The Scene is not found");
394 return; 405 return;
395 } 406 }
396 407
@@ -419,7 +430,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
419 // backup current scene's entities 430 // backup current scene's entities
420 //scene.Backup(); 431 //scene.Backup();
421 432
422 m_log.InfoFormat("[BALANCER] "+"region serialization completed [{0}]", 433 m_log.InfoFormat("[BALANCER] " + "region serialization completed [{0}]",
423 src_region.RegionID.ToString()); 434 src_region.RegionID.ToString());
424 } 435 }
425 436
@@ -428,13 +439,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
428 string filename; 439 string filename;
429 IClientAPI controller = null; 440 IClientAPI controller = null;
430 441
431 m_log.InfoFormat("[BALANCER] "+"agent id : {0}", pre.UUID); 442 m_log.InfoFormat("[BALANCER] " + "agent id : {0}", pre.UUID);
432 443
433 uint[] circuits = scene.ClientManager.GetAllCircuits(pre.UUID); 444 uint[] circuits = scene.ClientManager.GetAllCircuits(pre.UUID);
434 445
435 foreach (uint code in circuits) 446 foreach (uint code in circuits)
436 { 447 {
437 m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code); 448 m_log.InfoFormat("[BALANCER] " + "circuit code : {0}", code);
438 449
439 if (scene.ClientManager.TryGetClient(code, out controller)) 450 if (scene.ClientManager.TryGetClient(code, out controller))
440 { 451 {
@@ -444,7 +455,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
444 455
445 Util.SerializeToFile(filename, info); 456 Util.SerializeToFile(filename, info);
446 457
447 m_log.InfoFormat("[BALANCER] "+"client info serialized [filename={0}]", filename); 458 m_log.InfoFormat("[BALANCER] " + "client info serialized [filename={0}]", filename);
448 } 459 }
449 } 460 }
450 461
@@ -453,7 +464,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
453 464
454 Util.SerializeToFile(filename, pre); 465 Util.SerializeToFile(filename, pre);
455 466
456 m_log.InfoFormat("[BALANCER] "+"scene presence serialized [filename={0}]", filename); 467 m_log.InfoFormat("[BALANCER] " + "scene presence serialized [filename={0}]", filename);
457 } 468 }
458 469
459 private RegionInfo DeserializeRegion(int dst_port, bool move_flag, string import_dir) 470 private RegionInfo DeserializeRegion(int dst_port, bool move_flag, string import_dir)
@@ -470,30 +481,30 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
470 { 481 {
471 m_log.InfoFormat("[BALANCER] RegionInfo filename = [{0}]", filename); 482 m_log.InfoFormat("[BALANCER] RegionInfo filename = [{0}]", filename);
472 483
473 dst_region = new RegionInfo((SearializableRegionInfo)Util.DeserializeFromFile(filename)); 484 dst_region = new RegionInfo((SearializableRegionInfo) Util.DeserializeFromFile(filename));
474 485
475 m_log.InfoFormat("[BALANCER] "+"RegionID = [{0}]", dst_region.RegionID.ToString()); 486 m_log.InfoFormat("[BALANCER] " + "RegionID = [{0}]", dst_region.RegionID.ToString());
476 m_log.InfoFormat("[BALANCER] "+"RegionHandle = [{0}]", dst_region.RegionHandle); 487 m_log.InfoFormat("[BALANCER] " + "RegionHandle = [{0}]", dst_region.RegionHandle);
477 m_log.InfoFormat("[BALANCER] "+"ProxyUrl = [{0}]", dst_region.proxyUrl); 488 m_log.InfoFormat("[BALANCER] " + "ProxyUrl = [{0}]", dst_region.proxyUrl);
478 m_log.InfoFormat("[BALANCER] "+"OriginRegionID = [{0}]", dst_region.originRegionID.ToString()); 489 m_log.InfoFormat("[BALANCER] " + "OriginRegionID = [{0}]", dst_region.originRegionID.ToString());
479 490
480 CreateCloneRegion(dst_region, dst_port, true); 491 CreateCloneRegion(dst_region, dst_port, true);
481 492
482 File.Delete(filename); 493 File.Delete(filename);
483 494
484 m_log.InfoFormat("[BALANCER] "+"region deserialized [{0}]", dst_region.RegionID); 495 m_log.InfoFormat("[BALANCER] " + "region deserialized [{0}]", dst_region.RegionID);
485 } 496 }
486 497
487 // deserialization of client data 498 // deserialization of client data
488 DeserializeClient(dst_region, import_dir); 499 DeserializeClient(dst_region, import_dir);
489 500
490 m_log.InfoFormat("[BALANCER] "+"region deserialization completed [{0}]", 501 m_log.InfoFormat("[BALANCER] " + "region deserialization completed [{0}]",
491 dst_region.ToString()); 502 dst_region.ToString());
492 } 503 }
493 catch (Exception e) 504 catch (Exception e)
494 { 505 {
495 m_log.Error("[BALANCER] "+e.ToString()); 506 m_log.Error("[BALANCER] " + e.ToString());
496 m_log.Error("[BALANCER] "+e.StackTrace); 507 m_log.Error("[BALANCER] " + e.StackTrace);
497 throw e; 508 throw e;
498 } 509 }
499 510
@@ -515,7 +526,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
515 udpserv = SearchUDPServerFromPortNum(scene.RegionInfo.InternalEndPoint.Port); 526 udpserv = SearchUDPServerFromPortNum(scene.RegionInfo.InternalEndPoint.Port);
516 527
517 // restore the scene presence 528 // restore the scene presence
518 for (int i = 0; ; i++) 529 for (int i = 0;; i++)
519 { 530 {
520 string filename = import_dir + "Presence_" + String.Format("{0:0000}", i) + ".bin"; 531 string filename = import_dir + "Presence_" + String.Format("{0:0000}", i) + ".bin";
521 532
@@ -524,7 +535,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
524 break; 535 break;
525 } 536 }
526 537
527 sp = (ScenePresence)Util.DeserializeFromFile(filename); 538 sp = (ScenePresence) Util.DeserializeFromFile(filename);
528 Console.WriteLine("agent id = {0}", sp.UUID); 539 Console.WriteLine("agent id = {0}", sp.UUID);
529 540
530 scene.m_restorePresences.Add(sp.UUID, sp); 541 scene.m_restorePresences.Add(sp.UUID, sp);
@@ -543,7 +554,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
543 uint circuit_code = uint.Parse(fname.Substring(start + 1, end - start - 1)); 554 uint circuit_code = uint.Parse(fname.Substring(start + 1, end - start - 1));
544 m_log.InfoFormat("[BALANCER] " + "client circuit code = {0}", circuit_code); 555 m_log.InfoFormat("[BALANCER] " + "client circuit code = {0}", circuit_code);
545 556
546 data = (ClientInfo)Util.DeserializeFromFile(fname); 557 data = (ClientInfo) Util.DeserializeFromFile(fname);
547 558
548 AgentCircuitData agentdata = new AgentCircuitData(data.agentcircuit); 559 AgentCircuitData agentdata = new AgentCircuitData(data.agentcircuit);
549 scene.AuthenticateHandler.AddNewCircuit(circuit_code, agentdata); 560 scene.AuthenticateHandler.AddNewCircuit(circuit_code, agentdata);
@@ -582,7 +593,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
582 593
583 // change RegionInfo (memory only) 594 // change RegionInfo (memory only)
584 dst_region.InternalEndPoint.Port = dst_port; 595 dst_region.InternalEndPoint.Port = dst_port;
585 dst_region.ExternalHostName = proxyURL.Split(new char[] { '/', ':' })[3]; 596 dst_region.ExternalHostName = proxyURL.Split(new char[] {'/', ':'})[3];
586 597
587 // Create new region 598 // Create new region
588 simMain.CreateRegion(dst_region, false); 599 simMain.CreateRegion(dst_region, false);
@@ -595,7 +606,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
595 { 606 {
596 Console.WriteLine("scene found."); 607 Console.WriteLine("scene found.");
597 608
598 if ((sceneManager.CurrentScene != null) 609 if ((sceneManager.CurrentScene != null)
599 && (sceneManager.CurrentScene.RegionInfo.RegionID == killScene.RegionInfo.RegionID)) 610 && (sceneManager.CurrentScene.RegionInfo.RegionID == killScene.RegionInfo.RegionID))
600 { 611 {
601 sceneManager.TrySetCurrentScene(".."); 612 sceneManager.TrySetCurrentScene("..");
@@ -614,7 +625,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
614 udpsvr.Server.Close(); 625 udpsvr.Server.Close();
615 udpServers.Remove(udpsvr); 626 udpServers.Remove(udpsvr);
616 } 627 }
617 } 628 }
618 629
619 private void RemoveAllClientResource(RegionInfo src_region) 630 private void RemoveAllClientResource(RegionInfo src_region)
620 { 631 {
@@ -625,7 +636,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
625 // try to get the scene object 636 // try to get the scene object
626 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false) 637 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
627 { 638 {
628 m_log.Error("[BALANCER] "+"The Scene is not found"); 639 m_log.Error("[BALANCER] " + "The Scene is not found");
629 return; 640 return;
630 } 641 }
631 642
@@ -639,19 +650,19 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
639 650
640 foreach (uint code in circuits) 651 foreach (uint code in circuits)
641 { 652 {
642 m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code); 653 m_log.InfoFormat("[BALANCER] " + "circuit code : {0}", code);
643 654
644 if (scene.ClientManager.TryGetClient(code, out controller)) 655 if (scene.ClientManager.TryGetClient(code, out controller))
645 { 656 {
646 // stopping clientview thread 657 // stopping clientview thread
647 if (((ClientView)controller).PacketProcessingEnabled) 658 if (((ClientView) controller).PacketProcessingEnabled)
648 { 659 {
649 controller.Stop(); 660 controller.Stop();
650 ((ClientView)controller).PacketProcessingEnabled = false; 661 ((ClientView) controller).PacketProcessingEnabled = false;
651 } 662 }
652 // teminateing clientview thread 663 // teminateing clientview thread
653 controller.Terminate(); 664 controller.Terminate();
654 m_log.Info("[BALANCER] "+"client thread stopped"); 665 m_log.Info("[BALANCER] " + "client thread stopped");
655 } 666 }
656 } 667 }
657 668
@@ -664,12 +675,6 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
664 * This section implements scene splitting and synchronization 675 * This section implements scene splitting and synchronization
665 */ 676 */
666 677
667 private bool[] isLocalNeighbour;
668 private string[] sceneURL;
669 private int[] regionPortList;
670 private TcpClient[] tcpClientList;
671 private bool isSplit = false;
672
673 private XmlRpcResponse SplitRegion(XmlRpcRequest request) 678 private XmlRpcResponse SplitRegion(XmlRpcRequest request)
674 { 679 {
675 try 680 try
@@ -680,25 +685,25 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
680 sceneURL = new string[numRegions]; 685 sceneURL = new string[numRegions];
681 tcpClientList = new TcpClient[numRegions]; 686 tcpClientList = new TcpClient[numRegions];
682 687
683 for(int i=0; i<numRegions; i++) 688 for (int i = 0; i < numRegions; i++)
684 { 689 {
685 regionPortList[i]=(int) request.Params[i+2]; 690 regionPortList[i] = (int) request.Params[i + 2];
686 sceneURL[i]=(string) request.Params[i+2+numRegions]; 691 sceneURL[i] = (string) request.Params[i + 2 + numRegions];
687 } 692 }
688 693
689 string hostname; 694 string hostname;
690 695
691 for(int i=0; i<numRegions; i++) 696 for (int i = 0; i < numRegions; i++)
692 { 697 {
693 hostname = sceneURL[i].Split(new char[] { '/', ':' })[3]; 698 hostname = sceneURL[i].Split(new char[] {'/', ':'})[3];
694 m_log.InfoFormat("[SPLITSCENE] "+"creating tcp client host:{0}", hostname); 699 m_log.InfoFormat("[SPLITSCENE] " + "creating tcp client host:{0}", hostname);
695 tcpClientList[i] = new TcpClient(hostname, 10001); 700 tcpClientList[i] = new TcpClient(hostname, 10001);
696 } 701 }
697 702
698 bool isMaster = (myID == 0); 703 bool isMaster = (myID == 0);
699 704
700 isLocalNeighbour = new bool[numRegions]; 705 isLocalNeighbour = new bool[numRegions];
701 for(int i=0; i<numRegions; i++) isLocalNeighbour[i] = (sceneURL[i] == sceneURL[myID]); 706 for (int i = 0; i < numRegions; i++) isLocalNeighbour[i] = (sceneURL[i] == sceneURL[myID]);
702 707
703 RegionInfo region = SearchRegionFromPortNum(regionPortList[myID]); 708 RegionInfo region = SearchRegionFromPortNum(regionPortList[myID]);
704 709
@@ -708,10 +713,11 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
708 if (sceneManager.TryGetScene(region.RegionID, out scene)) 713 if (sceneManager.TryGetScene(region.RegionID, out scene))
709 { 714 {
710 // Disable event updates, backups etc in the slave(s) 715 // Disable event updates, backups etc in the slave(s)
711 if (isMaster) { 716 if (isMaster)
717 {
712 scene.Region_Status = RegionStatus.Up; 718 scene.Region_Status = RegionStatus.Up;
713 } 719 }
714 else 720 else
715 { 721 {
716 scene.Region_Status = RegionStatus.SlaveScene; 722 scene.Region_Status = RegionStatus.SlaveScene;
717 } 723 }
@@ -729,13 +735,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
729 735
730 foreach (uint code in circuits) 736 foreach (uint code in circuits)
731 { 737 {
732 m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code); 738 m_log.InfoFormat("[BALANCER] " + "circuit code : {0}", code);
733 739
734 if (scene.ClientManager.TryGetClient(code, out controller)) 740 if (scene.ClientManager.TryGetClient(code, out controller))
735 { 741 {
736 // Divide the presences evenly over the set of subscenes 742 // Divide the presences evenly over the set of subscenes
737 ClientView client = (ClientView) controller; 743 ClientView client = (ClientView) controller;
738 client.PacketProcessingEnabled = (( (i + myID) % sceneURL.Length) == 0); 744 client.PacketProcessingEnabled = (((i + myID) % sceneURL.Length) == 0);
739 745
740 m_log.InfoFormat("[SPLITSCENE] === SplitRegion {0}: SP.PacketEnabled {1}", region.RegionID, client.PacketProcessingEnabled); 746 m_log.InfoFormat("[SPLITSCENE] === SplitRegion {0}: SP.PacketEnabled {1}", region.RegionID, client.PacketProcessingEnabled);
741 747
@@ -748,20 +754,20 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
748 ++i; 754 ++i;
749 } 755 }
750 } 756 }
751 757
752 scene.splitID = myID; 758 scene.splitID = myID;
753 scene.SynchronizeScene = new Scene.SynchronizeSceneHandler(SynchronizeScenes); 759 scene.SynchronizeScene = new Scene.SynchronizeSceneHandler(SynchronizeScenes);
754 isSplit = true; 760 isSplit = true;
755 } 761 }
756 else 762 else
757 { 763 {
758 m_log.Error("[SPLITSCENE] "+String.Format("Scene not found {0}", region.RegionID)); 764 m_log.Error("[SPLITSCENE] " + String.Format("Scene not found {0}", region.RegionID));
759 } 765 }
760 } 766 }
761 catch (Exception e) 767 catch (Exception e)
762 { 768 {
763 m_log.Error("[SPLITSCENE] "+e.ToString()); 769 m_log.Error("[SPLITSCENE] " + e.ToString());
764 m_log.Error("[SPLITSCENE] "+e.StackTrace); 770 m_log.Error("[SPLITSCENE] " + e.StackTrace);
765 } 771 }
766 772
767 return new XmlRpcResponse(); 773 return new XmlRpcResponse();
@@ -772,14 +778,14 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
772 // This should only be called for the master scene 778 // This should only be called for the master scene
773 try 779 try
774 { 780 {
775 m_log.Info("[BALANCER] "+"Entering MergeRegions()"); 781 m_log.Info("[BALANCER] " + "Entering MergeRegions()");
776 782
777 string src_url = (string) request.Params[0]; 783 string src_url = (string) request.Params[0];
778 int src_port = (int) request.Params[1]; 784 int src_port = (int) request.Params[1];
779 785
780 RegionInfo region = SearchRegionFromPortNum(src_port); 786 RegionInfo region = SearchRegionFromPortNum(src_port);
781 787
782 Util.XmlRpcCommand(region.proxyUrl, "BlockClientMessages", src_url, src_port + proxyOffset); 788 Util.XmlRpcCommand(region.proxyUrl, "BlockClientMessages", src_url, src_port + proxyOffset);
783 789
784 Scene scene; 790 Scene scene;
785 if (sceneManager.TryGetScene(region.RegionID, out scene)) 791 if (sceneManager.TryGetScene(region.RegionID, out scene))
@@ -802,20 +808,20 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
802 } 808 }
803 809
804 // Delete the slave scenes 810 // Delete the slave scenes
805 for(int i=1; i<sceneURL.Length; i++) 811 for (int i = 1; i < sceneURL.Length; i++)
806 { 812 {
807 string url = (sceneURL[i].Split('/')[2]).Split(':')[0]; // get URL part from EP 813 string url = (sceneURL[i].Split('/')[2]).Split(':')[0]; // get URL part from EP
808 Util.XmlRpcCommand(region.proxyUrl, "DeleteRegion", regionPortList[i] + proxyOffset, url); 814 Util.XmlRpcCommand(region.proxyUrl, "DeleteRegion", regionPortList[i] + proxyOffset, url);
809 Thread.Sleep(1000); 815 Thread.Sleep(1000);
810 Util.XmlRpcCommand(sceneURL[i], "TerminateRegion", regionPortList[i]); // TODO: need + proxyOffset? 816 Util.XmlRpcCommand(sceneURL[i], "TerminateRegion", regionPortList[i]); // TODO: need + proxyOffset?
811 } 817 }
812 818
813 Util.XmlRpcCommand(region.proxyUrl, "UnblockClientMessages", src_url, src_port + proxyOffset); 819 Util.XmlRpcCommand(region.proxyUrl, "UnblockClientMessages", src_url, src_port + proxyOffset);
814 } 820 }
815 catch (Exception e) 821 catch (Exception e)
816 { 822 {
817 m_log.Error("[BALANCER] "+e.ToString()); 823 m_log.Error("[BALANCER] " + e.ToString());
818 m_log.Error("[BALANCER] "+e.StackTrace); 824 m_log.Error("[BALANCER] " + e.StackTrace);
819 throw e; 825 throw e;
820 } 826 }
821 827
@@ -851,7 +857,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
851 Scene scene; 857 Scene scene;
852 if (sceneManager.TryGetScene(region.RegionID, out scene)) 858 if (sceneManager.TryGetScene(region.RegionID, out scene))
853 { 859 {
854 ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == scenePresenceID; }); 860 ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == scenePresenceID; });
855 861
856 if (pre == null) 862 if (pre == null)
857 { 863 {
@@ -862,13 +868,12 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
862// m_log.Info("[SPLITSCENE] "+"LocalUpdatePhysics [region:{0}, client:{1}]", 868// m_log.Info("[SPLITSCENE] "+"LocalUpdatePhysics [region:{0}, client:{1}]",
863// regionID.ToString(), pre.UUID.ToString()); 869// regionID.ToString(), pre.UUID.ToString());
864 870
865 pre.AbsolutePosition = position;// will set PhysicsActor.Position 871 pre.AbsolutePosition = position; // will set PhysicsActor.Position
866 pre.Velocity = velocity; // will set PhysicsActor.Velocity 872 pre.Velocity = velocity; // will set PhysicsActor.Velocity
867 pre.PhysicsActor.Flying = flying; 873 pre.PhysicsActor.Flying = flying;
868 } 874 }
869 } 875 }
870 876
871 object padlock=new object();
872 private void SynchronizeScenes(Scene scene) 877 private void SynchronizeScenes(Scene scene)
873 { 878 {
874 if (!isSplit) 879 if (!isSplit)
@@ -876,7 +881,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
876 return; 881 return;
877 } 882 }
878 883
879 lock(padlock) 884 lock (padlock)
880 { 885 {
881 // Callback activated after a physics scene update 886 // Callback activated after a physics scene update
882// int i = 0; 887// int i = 0;
@@ -888,7 +893,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
888 // Because data changes by the physics simulation when the client doesn't move, 893 // Because data changes by the physics simulation when the client doesn't move,
889 // if MovementFlag is false, It is necessary to synchronize. 894 // if MovementFlag is false, It is necessary to synchronize.
890 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) 895 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true)
891 if(client.PacketProcessingEnabled==true) 896 if (client.PacketProcessingEnabled == true)
892 { 897 {
893 //m_log.Info("[SPLITSCENE] "+String.Format("Client moving in {0} {1}", scene.RegionInfo.RegionID, pre.AbsolutePosition)); 898 //m_log.Info("[SPLITSCENE] "+String.Format("Client moving in {0} {1}", scene.RegionInfo.RegionID, pre.AbsolutePosition));
894 899
@@ -898,8 +903,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
898 { 903 {
899 continue; 904 continue;
900 } 905 }
901 906
902 if(isLocalNeighbour[i]) 907 if (isLocalNeighbour[i])
903 { 908 {
904 //m_log.Info("[SPLITSCENE] "+"Synchronize ScenePresence (Local) [region:{0}=>{1}, client:{2}]", 909 //m_log.Info("[SPLITSCENE] "+"Synchronize ScenePresence (Local) [region:{0}=>{1}, client:{2}]",
905 // scene.RegionInfo.RegionID, regionPortList[i], pre.UUID.ToString()); 910 // scene.RegionInfo.RegionID, regionPortList[i], pre.UUID.ToString());
@@ -912,7 +917,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
912 // pre.Velocity.ToString(), pre.PhysicsActor.Flying); 917 // pre.Velocity.ToString(), pre.PhysicsActor.Flying);
913 918
914 919
915 Util.XmlRpcCommand(sceneURL[i], "UpdatePhysics", 920 Util.XmlRpcCommand(sceneURL[i], "UpdatePhysics",
916 regionPortList[i], pre.UUID.GetBytes(), 921 regionPortList[i], pre.UUID.GetBytes(),
917 pre.AbsolutePosition.GetBytes(), pre.Velocity.GetBytes(), 922 pre.AbsolutePosition.GetBytes(), pre.Velocity.GetBytes(),
918 pre.PhysicsActor.Flying); 923 pre.PhysicsActor.Flying);
@@ -951,7 +956,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
951 return false; 956 return false;
952 } 957 }
953 958
954 Scene localScene = (Scene)scene; 959 Scene localScene = (Scene) scene;
955 960
956 for (int i = 0; i < sceneURL.Length; i++) 961 for (int i = 0; i < sceneURL.Length; i++)
957 { 962 {
@@ -959,8 +964,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
959 { 964 {
960 continue; 965 continue;
961 } 966 }
962 967
963 if(isLocalNeighbour[i]) 968 if (isLocalNeighbour[i])
964 { 969 {
965 //m_log.Info("[SPLITSCENE] "+"Synchronize Packet (Local) [type:{0}, client:{1}]", 970 //m_log.Info("[SPLITSCENE] "+"Synchronize Packet (Local) [type:{0}, client:{1}]",
966 // packet.Type.ToString(), agentID.ToString()); 971 // packet.Type.ToString(), agentID.ToString());
@@ -977,7 +982,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
977 InternalPacketHeader header = new InternalPacketHeader(); 982 InternalPacketHeader header = new InternalPacketHeader();
978 983
979 header.type = 0; 984 header.type = 0;
980 header.throttlePacketType = (int)throttlePacketType; 985 header.throttlePacketType = (int) throttlePacketType;
981 header.numbytes = buff.Length; 986 header.numbytes = buff.Length;
982 header.agent_id = agentID.UUID; 987 header.agent_id = agentID.UUID;
983 header.region_port = regionPortList[i]; 988 header.region_port = regionPortList[i];
@@ -1003,7 +1008,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
1003 1008
1004 if (sceneManager.TryGetScene(region.RegionID, out scene)) 1009 if (sceneManager.TryGetScene(region.RegionID, out scene))
1005 { 1010 {
1006 ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == agentID; }); 1011 ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == agentID; });
1007 1012
1008 if (pre == null) 1013 if (pre == null)
1009 { 1014 {
@@ -1011,7 +1016,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
1011 return; 1016 return;
1012 } 1017 }
1013 1018
1014 if (((ClientView)pre.ControllingClient).PacketProcessingEnabled==true) 1019 if (((ClientView) pre.ControllingClient).PacketProcessingEnabled == true)
1015 { 1020 {
1016 pre.ControllingClient.OutPacket(packet, throttlePacketType); 1021 pre.ControllingClient.OutPacket(packet, throttlePacketType);
1017 } 1022 }
@@ -1050,13 +1055,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
1050 1055
1051 packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero); 1056 packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero);
1052 1057
1053 LocalUpdatePacket(header.region_port, new LLUUID(header.agent_id), 1058 LocalUpdatePacket(header.region_port, new LLUUID(header.agent_id),
1054 packet, (ThrottleOutPacketType)header.throttlePacketType); 1059 packet, (ThrottleOutPacketType) header.throttlePacketType);
1055 } 1060 }
1056 catch (Exception e) 1061 catch (Exception e)
1057 { 1062 {
1058 m_log.Error("[SPLITSCENE] "+e.ToString()); 1063 m_log.Error("[SPLITSCENE] " + e.ToString());
1059 m_log.Error("[SPLITSCENE] "+e.StackTrace); 1064 m_log.Error("[SPLITSCENE] " + e.StackTrace);
1060 } 1065 }
1061 1066
1062 break; 1067 break;
@@ -1067,18 +1072,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
1067 LLUUID scenePresenceID = new LLUUID(header.agent_id); 1072 LLUUID scenePresenceID = new LLUUID(header.agent_id);
1068 LLVector3 position = new LLVector3(buff, 0); 1073 LLVector3 position = new LLVector3(buff, 0);
1069 LLVector3 velocity = new LLVector3(buff, 12); 1074 LLVector3 velocity = new LLVector3(buff, 12);
1070 bool flying = ((buff[24] == (byte)1)?true:false); 1075 bool flying = ((buff[24] == (byte) 1) ? true : false);
1071 1076
1072 LocalUpdatePhysics(regionPort, scenePresenceID, position, velocity, flying); 1077 LocalUpdatePhysics(regionPort, scenePresenceID, position, velocity, flying);
1073 1078
1074 break; 1079 break;
1075 1080
1076 default: 1081 default:
1077 m_log.Info("[SPLITSCENE] "+"Invalid type"); 1082 m_log.Info("[SPLITSCENE] " + "Invalid type");
1078 break; 1083 break;
1079 } 1084 }
1080 1085
1081// m_log.Info("[SPLITSCENE] "+"exiting SynchronizePacketRecieve"); 1086// m_log.Info("[SPLITSCENE] "+"exiting SynchronizePacketRecieve");
1082 } 1087 }
1083 } 1088 }
1084} 1089} \ No newline at end of file
diff --git a/ThirdParty/3Di/LoadBalancer/TcpClient.cs b/ThirdParty/3Di/LoadBalancer/TcpClient.cs
index 7b5bc79..af678a0 100644
--- a/ThirdParty/3Di/LoadBalancer/TcpClient.cs
+++ b/ThirdParty/3Di/LoadBalancer/TcpClient.cs
@@ -30,19 +30,23 @@ using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32 32
33namespace OpenSim.ApplicationPlugins.LoadBalancer { 33namespace OpenSim.ApplicationPlugins.LoadBalancer
34 public class AsynchronousClient { 34{
35 public class AsynchronousClient
36 {
35 private static ManualResetEvent connectDone = new ManualResetEvent(false); 37 private static ManualResetEvent connectDone = new ManualResetEvent(false);
36 private static ManualResetEvent sendDone = new ManualResetEvent(false); 38 private static ManualResetEvent sendDone = new ManualResetEvent(false);
37 39
38 public static Socket StartClient(string hostname, int port) { 40 public static Socket StartClient(string hostname, int port)
39 try { 41 {
42 try
43 {
40 IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname); 44 IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname);
41 IPAddress ipAddress = ipHostInfo.AddressList[0]; 45 IPAddress ipAddress = ipHostInfo.AddressList[0];
42 IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); 46 IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
43 47
44 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 48 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
45 client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), client); 49 client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
46 connectDone.WaitOne(); 50 connectDone.WaitOne();
47 /* 51 /*
48 Send(client,"This is a test<EOF>"); 52 Send(client,"This is a test<EOF>");
@@ -53,19 +57,25 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
53 client.Close(); 57 client.Close();
54 */ 58 */
55 return client; 59 return client;
56 } catch (Exception e) { 60 }
61 catch (Exception e)
62 {
57 Console.WriteLine(e.ToString()); 63 Console.WriteLine(e.ToString());
58 throw new Exception("socket error !!"); 64 throw new Exception("socket error !!");
59 } 65 }
60 } 66 }
61 67
62 private static void ConnectCallback(IAsyncResult ar) { 68 private static void ConnectCallback(IAsyncResult ar)
63 try { 69 {
70 try
71 {
64 Socket client = (Socket) ar.AsyncState; 72 Socket client = (Socket) ar.AsyncState;
65 client.EndConnect(ar); 73 client.EndConnect(ar);
66 Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()); 74 Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
67 connectDone.Set(); 75 connectDone.Set();
68 } catch (Exception e) { 76 }
77 catch (Exception e)
78 {
69 Console.WriteLine(e.ToString()); 79 Console.WriteLine(e.ToString());
70 } 80 }
71 } 81 }
@@ -101,20 +111,26 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
101 } 111 }
102 } 112 }
103*/ 113*/
104 public static void Send(Socket client, byte[] byteData) { 114
115 public static void Send(Socket client, byte[] byteData)
116 {
105 client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); 117 client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
106 } 118 }
107 119
108 private static void SendCallback(IAsyncResult ar) { 120 private static void SendCallback(IAsyncResult ar)
109 try { 121 {
122 try
123 {
110 Socket client = (Socket) ar.AsyncState; 124 Socket client = (Socket) ar.AsyncState;
111 int bytesSent = client.EndSend(ar); 125 int bytesSent = client.EndSend(ar);
112 if(bytesSent > 0) 126 if (bytesSent > 0)
113 { 127 {
114 //Console.WriteLine("Sent {0} bytes to server.", bytesSent); 128 //Console.WriteLine("Sent {0} bytes to server.", bytesSent);
115 } 129 }
116 sendDone.Set(); 130 sendDone.Set();
117 } catch (Exception e) { 131 }
132 catch (Exception e)
133 {
118 Console.WriteLine(e.ToString()); 134 Console.WriteLine(e.ToString());
119 } 135 }
120 } 136 }
@@ -122,28 +138,28 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
122 138
123 public class InternalPacketHeader 139 public class InternalPacketHeader
124 { 140 {
141 public Guid agent_id;
125 private byte[] buffer = new byte[32]; 142 private byte[] buffer = new byte[32];
126 public int type;
127 public int throttlePacketType;
128 public int numbytes; 143 public int numbytes;
129 public Guid agent_id;
130 public int region_port; 144 public int region_port;
145 public int throttlePacketType;
146 public int type;
131 147
132 public void FromBytes(byte[] bytes) 148 public void FromBytes(byte[] bytes)
133 { 149 {
134 int i = 0; // offset 150 int i = 0; // offset
135 try 151 try
136 { 152 {
137 this.type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); 153 type = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
138 this.throttlePacketType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); 154 throttlePacketType = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
139 this.numbytes = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); 155 numbytes = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
140 this.agent_id = new Guid( 156 agent_id = new Guid(
141 bytes[i++] | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24, 157 bytes[i++] | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24,
142 (short)(bytes[i++] | (bytes[i++] << 8)), 158 (short) (bytes[i++] | (bytes[i++] << 8)),
143 (short)(bytes[i++] | (bytes[i++] << 8)), 159 (short) (bytes[i++] | (bytes[i++] << 8)),
144 bytes[i++], bytes[i++], bytes[i++], bytes[i++], 160 bytes[i++], bytes[i++], bytes[i++], bytes[i++],
145 bytes[i++], bytes[i++], bytes[i++], bytes[i++]); 161 bytes[i++], bytes[i++], bytes[i++], bytes[i++]);
146 this.region_port = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); 162 region_port = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
147 } 163 }
148 catch (Exception) 164 catch (Exception)
149 { 165 {
@@ -154,48 +170,54 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
154 public byte[] ToBytes() 170 public byte[] ToBytes()
155 { 171 {
156 int i = 0; 172 int i = 0;
157 this.buffer[i++] = (byte)(this.type % 256); 173 buffer[i++] = (byte) (type % 256);
158 this.buffer[i++] = (byte)((this.type >> 8) % 256); 174 buffer[i++] = (byte) ((type >> 8) % 256);
159 this.buffer[i++] = (byte)((this.type >> 16) % 256); 175 buffer[i++] = (byte) ((type >> 16) % 256);
160 this.buffer[i++] = (byte)((this.type >> 24) % 256); 176 buffer[i++] = (byte) ((type >> 24) % 256);
161 177
162 this.buffer[i++] = (byte)(this.throttlePacketType % 256); 178 buffer[i++] = (byte) (throttlePacketType % 256);
163 this.buffer[i++] = (byte)((this.throttlePacketType >> 8) % 256); 179 buffer[i++] = (byte) ((throttlePacketType >> 8) % 256);
164 this.buffer[i++] = (byte)((this.throttlePacketType >> 16) % 256); 180 buffer[i++] = (byte) ((throttlePacketType >> 16) % 256);
165 this.buffer[i++] = (byte)((this.throttlePacketType >> 24) % 256); 181 buffer[i++] = (byte) ((throttlePacketType >> 24) % 256);
166 182
167 this.buffer[i++] = (byte)(this.numbytes % 256); 183 buffer[i++] = (byte) (numbytes % 256);
168 this.buffer[i++] = (byte)((this.numbytes >> 8) % 256); 184 buffer[i++] = (byte) ((numbytes >> 8) % 256);
169 this.buffer[i++] = (byte)((this.numbytes >> 16) % 256); 185 buffer[i++] = (byte) ((numbytes >> 16) % 256);
170 this.buffer[i++] = (byte)((this.numbytes >> 24) % 256); 186 buffer[i++] = (byte) ((numbytes >> 24) % 256);
171 187
172 // no endian care 188 // no endian care
173 Buffer.BlockCopy(agent_id.ToByteArray(), 0, this.buffer, i, 16); i += 16; 189 Buffer.BlockCopy(agent_id.ToByteArray(), 0, buffer, i, 16);
190 i += 16;
174 191
175 this.buffer[i++] = (byte)(this.region_port % 256); 192 buffer[i++] = (byte) (region_port % 256);
176 this.buffer[i++] = (byte)((this.region_port >> 8) % 256); 193 buffer[i++] = (byte) ((region_port >> 8) % 256);
177 this.buffer[i++] = (byte)((this.region_port >> 16) % 256); 194 buffer[i++] = (byte) ((region_port >> 16) % 256);
178 this.buffer[i++] = (byte)((this.region_port >> 24) % 256); 195 buffer[i++] = (byte) ((region_port >> 24) % 256);
179 196
180 return this.buffer; 197 return buffer;
181 } 198 }
182 } 199 }
183 200
184 public class TcpClient { 201 public class TcpClient
185 202 {
186 public static int internalPacketHeaderSize = 4*4 + 16*1; 203 public static int internalPacketHeaderSize = 4 * 4 + 16 * 1;
204 private Socket mConnection;
187 205
188 private string mHostname; 206 private string mHostname;
189 private int mPort; 207 private int mPort;
190 private Socket mConnection; 208
191 public TcpClient(string hostname, int port) { 209 public TcpClient(string hostname, int port)
192 this.mHostname = hostname; 210 {
193 this.mPort = port; 211 mHostname = hostname;
194 this.mConnection = null; 212 mPort = port;
213 mConnection = null;
195 } 214 }
196 public void connect() { 215
197 this.mConnection = AsynchronousClient.StartClient(mHostname, mPort); 216 public void connect()
217 {
218 mConnection = AsynchronousClient.StartClient(mHostname, mPort);
198 } 219 }
220
199/* 221/*
200 public void recevie() { 222 public void recevie() {
201 if (mConnection == null) { 223 if (mConnection == null) {
@@ -212,17 +234,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
212 } 234 }
213 } 235 }
214*/ 236*/
215 public void send(InternalPacketHeader header, byte[] packet) {
216 237
238 public void send(InternalPacketHeader header, byte[] packet)
239 {
217 lock (this) 240 lock (this)
218 { 241 {
219 242 if (mConnection == null)
220 if (mConnection == null) { 243 {
221// throw new Exception("client not initialized"); 244// throw new Exception("client not initialized");
222 connect(); 245 connect();
223 } 246 }
224 247
225 AsynchronousClient.Send(this.mConnection, header.ToBytes()); 248 AsynchronousClient.Send(mConnection, header.ToBytes());
226 249
227/* 250/*
228for (int i = 0; i < 10; i++) 251for (int i = 0; i < 10; i++)
@@ -231,8 +254,8 @@ for (int i = 0; i < 10; i++)
231} 254}
232Console.WriteLine(""); 255Console.WriteLine("");
233*/ 256*/
234 AsynchronousClient.Send(this.mConnection, packet); 257 AsynchronousClient.Send(mConnection, packet);
235 } 258 }
236 } 259 }
237 } 260 }
238} 261} \ No newline at end of file
diff --git a/ThirdParty/3Di/LoadBalancer/TcpServer.cs b/ThirdParty/3Di/LoadBalancer/TcpServer.cs
index 6d45304..9722a1b 100644
--- a/ThirdParty/3Di/LoadBalancer/TcpServer.cs
+++ b/ThirdParty/3Di/LoadBalancer/TcpServer.cs
@@ -31,42 +31,58 @@ using System.Net;
31using System.Net.Sockets; 31using System.Net.Sockets;
32using System.Threading; 32using System.Threading;
33 33
34namespace OpenSim.ApplicationPlugins.LoadBalancer { 34namespace OpenSim.ApplicationPlugins.LoadBalancer
35 35{
36 public class StateObject { 36 public class StateObject
37 public Socket workSocket = null; 37 {
38 public const int BufferSize = 2048; 38 public const int BufferSize = 2048;
39 public byte[] buffer = new byte[BufferSize]; 39 public byte[] buffer = new byte[BufferSize];
40 public MemoryStream ms_ptr = new MemoryStream();
41 public InternalPacketHeader header = null; 40 public InternalPacketHeader header = null;
41 public MemoryStream ms_ptr = new MemoryStream();
42 public Socket workSocket = null;
42 } 43 }
43 44
44 public class AsynchronousSocketListener { 45 public class AsynchronousSocketListener
45 public static string data = null; 46 {
46 public static ManualResetEvent allDone = new ManualResetEvent(false); 47 public static ManualResetEvent allDone = new ManualResetEvent(false);
48 public static string data = null;
49
50 #region KIRYU
51
52 #region Delegates
47 53
48#region KIRYU
49 public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff); 54 public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff);
55
56 #endregion
57
50 public static PacketRecieveHandler PacketHandler = null; 58 public static PacketRecieveHandler PacketHandler = null;
51#endregion
52 59
53 public AsynchronousSocketListener() { } 60 #endregion
61
62 public AsynchronousSocketListener()
63 {
64 }
54 65
55 public static void StartListening(int port) { 66 public static void StartListening(int port)
67 {
56 IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); 68 IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
57 IPAddress ipAddress = ipHostInfo.AddressList[0]; 69 IPAddress ipAddress = ipHostInfo.AddressList[0];
58 IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); 70 IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
59 71
60 Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); 72 Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
61 try { 73 try
74 {
62 listener.Bind(localEndPoint); 75 listener.Bind(localEndPoint);
63 listener.Listen(100); 76 listener.Listen(100);
64 while (true) { 77 while (true)
78 {
65 allDone.Reset(); 79 allDone.Reset();
66 listener.BeginAccept( new AsyncCallback(AcceptCallback), listener ); 80 listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
67 allDone.WaitOne(); 81 allDone.WaitOne();
68 } 82 }
69 } catch (Exception e) { 83 }
84 catch (Exception e)
85 {
70 Console.WriteLine(e.ToString()); 86 Console.WriteLine(e.ToString());
71 } 87 }
72 /* 88 /*
@@ -75,38 +91,41 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
75 */ 91 */
76 } 92 }
77 93
78 public static void AcceptCallback(IAsyncResult ar) { 94 public static void AcceptCallback(IAsyncResult ar)
95 {
79 allDone.Set(); 96 allDone.Set();
80 Socket listener = (Socket) ar.AsyncState; 97 Socket listener = (Socket) ar.AsyncState;
81 Socket handler = listener.EndAccept(ar); 98 Socket handler = listener.EndAccept(ar);
82 StateObject state = new StateObject(); 99 StateObject state = new StateObject();
83 state.workSocket = handler; 100 state.workSocket = handler;
84 handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 101 handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
85 } 102 }
86 103
87 public static void ReadCallback(IAsyncResult ar) { 104 public static void ReadCallback(IAsyncResult ar)
105 {
88 StateObject state = (StateObject) ar.AsyncState; 106 StateObject state = (StateObject) ar.AsyncState;
89 Socket handler = state.workSocket; 107 Socket handler = state.workSocket;
90 108
91 try 109 try
92 { 110 {
93 int bytesRead = handler.EndReceive(ar); 111 int bytesRead = handler.EndReceive(ar);
94 112
95 //MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead); 113 //MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead);
96 114
97 if (bytesRead > 0) { 115 if (bytesRead > 0)
116 {
98 state.ms_ptr.Write(state.buffer, 0, bytesRead); 117 state.ms_ptr.Write(state.buffer, 0, bytesRead);
99 } 118 }
100 else 119 else
101 { 120 {
102 //MainLog.Instance.Verbose("TCPSERVER", "Connection terminated"); 121 //MainLog.Instance.Verbose("TCPSERVER", "Connection terminated");
103 return; 122 return;
104 } 123 }
105 124
106 long rest_size = state.ms_ptr.Length; 125 long rest_size = state.ms_ptr.Length;
107 long current_pos = 0; 126 long current_pos = 0;
108 while (rest_size > TcpClient.internalPacketHeaderSize) { 127 while (rest_size > TcpClient.internalPacketHeaderSize)
109 128 {
110 if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize)) 129 if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize))
111 { 130 {
112 //MainLog.Instance.Verbose("TCPSERVER", "Processing header"); 131 //MainLog.Instance.Verbose("TCPSERVER", "Processing header");
@@ -136,7 +155,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
136 } 155 }
137 System.Console.WriteLine(); 156 System.Console.WriteLine();
138*/ 157*/
139 158
140 state.ms_ptr.Seek(0, SeekOrigin.End); 159 state.ms_ptr.Seek(0, SeekOrigin.End);
141 // call loadbarancer function 160 // call loadbarancer function
142 if (PacketHandler != null) 161 if (PacketHandler != null)
@@ -155,20 +174,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
155 rest_size -= read_size; 174 rest_size -= read_size;
156 current_pos += read_size; 175 current_pos += read_size;
157 176
158 if (rest_size < TcpClient.internalPacketHeaderSize) { 177 if (rest_size < TcpClient.internalPacketHeaderSize)
159 178 {
160 byte[] rest_bytes = new byte[rest_size]; 179 byte[] rest_bytes = new byte[rest_size];
161 state.ms_ptr.Position = read_size; 180 state.ms_ptr.Position = read_size;
162 state.ms_ptr.Read(rest_bytes, 0, (int)rest_size); 181 state.ms_ptr.Read(rest_bytes, 0, (int) rest_size);
163 state.ms_ptr.Close(); 182 state.ms_ptr.Close();
164 state.ms_ptr = new MemoryStream(); 183 state.ms_ptr = new MemoryStream();
165 state.ms_ptr.Write(rest_bytes, 0, (int)rest_size); 184 state.ms_ptr.Write(rest_bytes, 0, (int) rest_size);
166 break; 185 break;
167 } 186 }
168 } 187 }
169
170 } // while (true) 188 } // while (true)
171
172 } 189 }
173 catch (Exception) 190 catch (Exception)
174 { 191 {
@@ -176,19 +193,26 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
176 //MainLog.Instance.Verbose("TCPSERVER", e.StackTrace); 193 //MainLog.Instance.Verbose("TCPSERVER", e.StackTrace);
177 } 194 }
178 195
179 handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 196 handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
180 } 197 }
181 } 198 }
182 199
183 public class TcpServer { 200 public class TcpServer
201 {
184 private int mPort = 11000; 202 private int mPort = 11000;
185 public TcpServer() { 203
204 public TcpServer()
205 {
186 } 206 }
187 public TcpServer(int port) { 207
208 public TcpServer(int port)
209 {
188 mPort = port; 210 mPort = port;
189 } 211 }
190 public void start() { 212
213 public void start()
214 {
191 AsynchronousSocketListener.StartListening(mPort); 215 AsynchronousSocketListener.StartListening(mPort);
192 } 216 }
193 } 217 }
194} 218} \ No newline at end of file