diff options
author | diva | 2009-01-01 19:42:24 +0000 |
---|---|---|
committer | diva | 2009-01-01 19:42:24 +0000 |
commit | d8ebf2fc9d7d2e50735d50e75f7153f487efe958 (patch) | |
tree | c14d5e80e3d34d0a2f547cb3d0b965dea8e55e90 | |
parent | Minor fix for HG request neighbors. Should not return hyperlink neighbors, on... (diff) | |
download | opensim-SC_OLD-d8ebf2fc9d7d2e50735d50e75f7153f487efe958.zip opensim-SC_OLD-d8ebf2fc9d7d2e50735d50e75f7153f487efe958.tar.gz opensim-SC_OLD-d8ebf2fc9d7d2e50735d50e75f7153f487efe958.tar.bz2 opensim-SC_OLD-d8ebf2fc9d7d2e50735d50e75f7153f487efe958.tar.xz |
Major changes in interregion communications. This breaks compatibility with older versions, and may result is all sorts of weirdnesses when interacting with sims in older versions. Changes:
- Introducing synchronous Teleports. Now the receiving region calls back the sending region after the client has been made a root agent there, that is, after client sends CompleteMovement to the destination.
- SendCloseAgent moved from OGS1 Remoting to RESTComms.
Diffstat (limited to '')
9 files changed, 338 insertions, 75 deletions
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 257f435..f3ac943 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs | |||
@@ -144,6 +144,7 @@ namespace OpenSim.Framework | |||
144 | 144 | ||
145 | byte[] VisualParams; | 145 | byte[] VisualParams; |
146 | 146 | ||
147 | public string CallbackURI; | ||
147 | 148 | ||
148 | public OSDMap PackUpdateMessage() | 149 | public OSDMap PackUpdateMessage() |
149 | { | 150 | { |
@@ -191,6 +192,9 @@ namespace OpenSim.Framework | |||
191 | 192 | ||
192 | // Last few fields are still missing | 193 | // Last few fields are still missing |
193 | 194 | ||
195 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) | ||
196 | args["callback_uri"] = OSD.FromString(CallbackURI); | ||
197 | |||
194 | return args; | 198 | return args; |
195 | } | 199 | } |
196 | 200 | ||
@@ -284,6 +288,9 @@ namespace OpenSim.Framework | |||
284 | 288 | ||
285 | if (args["active_group_id"] != null) | 289 | if (args["active_group_id"] != null) |
286 | ActiveGroupID = args["active_group_id"].AsUUID(); | 290 | ActiveGroupID = args["active_group_id"].AsUUID(); |
291 | |||
292 | if (args["callback_uri"] != null) | ||
293 | CallbackURI = args["callback_uri"].AsString(); | ||
287 | } | 294 | } |
288 | 295 | ||
289 | public AgentData() | 296 | public AgentData() |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index c3b3a01..b3ca651 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -177,7 +177,7 @@ namespace OpenSim | |||
177 | presence.UUID, | 177 | presence.UUID, |
178 | regionInfo.RegionName)); | 178 | regionInfo.RegionName)); |
179 | 179 | ||
180 | presence.Scene.CloseConnection(presence.UUID); | 180 | presence.Scene.IncomingCloseAgent(presence.UUID); |
181 | } | 181 | } |
182 | } | 182 | } |
183 | m_console.Notice(""); | 183 | m_console.Notice(""); |
diff --git a/OpenSim/Region/Environment/Interfaces/IInterregionComms.cs b/OpenSim/Region/Environment/Interfaces/IInterregionComms.cs index b70e885..e197622 100644 --- a/OpenSim/Region/Environment/Interfaces/IInterregionComms.cs +++ b/OpenSim/Region/Environment/Interfaces/IInterregionComms.cs | |||
@@ -36,6 +36,8 @@ namespace OpenSim.Region.Environment.Interfaces | |||
36 | public interface IInterregionCommsOut | 36 | public interface IInterregionCommsOut |
37 | { | 37 | { |
38 | bool SendChildAgentUpdate(ulong regionHandle, AgentData data); | 38 | bool SendChildAgentUpdate(ulong regionHandle, AgentData data); |
39 | bool SendReleaseAgent(ulong regionHandle, UUID id, string uri); | ||
40 | bool SendCloseAgent(ulong regionHandle, UUID id); | ||
39 | } | 41 | } |
40 | 42 | ||
41 | // This may not be needed, but having it here for now. | 43 | // This may not be needed, but having it here for now. |
diff --git a/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs b/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs index 781bf1c..9f547a2 100644 --- a/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs +++ b/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs | |||
@@ -120,23 +120,57 @@ namespace OpenSim.Region.Environment.Modules.Communications.Local | |||
120 | 120 | ||
121 | public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData) | 121 | public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData) |
122 | { | 122 | { |
123 | lock (m_sceneList) | 123 | foreach (Scene s in m_sceneList) |
124 | { | 124 | { |
125 | foreach (Scene s in m_sceneList) | 125 | if (s.RegionInfo.RegionHandle == regionHandle) |
126 | { | 126 | { |
127 | if (s.RegionInfo.RegionHandle == regionHandle) | 127 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); |
128 | { | 128 | s.IncomingChildAgentDataUpdate(cAgentData); |
129 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); | 129 | return true; |
130 | return s.IncomingChildAgentDataUpdate(cAgentData); | ||
131 | //if (OnChildAgentUpdate != null) | ||
132 | // return OnChildAgentUpdate(cAgentData); | ||
133 | } | ||
134 | } | 130 | } |
135 | } | 131 | } |
136 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | 132 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); |
137 | return false; | 133 | return false; |
138 | } | 134 | } |
139 | 135 | ||
136 | public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) | ||
137 | { | ||
138 | //uint x, y; | ||
139 | //Utils.LongToUInts(regionHandle, out x, out y); | ||
140 | //x = x / Constants.RegionSize; | ||
141 | //y = y / Constants.RegionSize; | ||
142 | //Console.WriteLine("\n >>> Local SendReleaseAgent " + x + "-" + y); | ||
143 | foreach (Scene s in m_sceneList) | ||
144 | { | ||
145 | if (s.RegionInfo.RegionHandle == regionHandle) | ||
146 | { | ||
147 | //m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); | ||
148 | return s.IncomingReleaseAgent(id); | ||
149 | } | ||
150 | } | ||
151 | //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent"); | ||
152 | return false; | ||
153 | } | ||
154 | |||
155 | public bool SendCloseAgent(ulong regionHandle, UUID id) | ||
156 | { | ||
157 | //uint x, y; | ||
158 | //Utils.LongToUInts(regionHandle, out x, out y); | ||
159 | //x = x / Constants.RegionSize; | ||
160 | //y = y / Constants.RegionSize; | ||
161 | //Console.WriteLine("\n >>> Local SendCloseAgent " + x + "-" + y); | ||
162 | foreach (Scene s in m_sceneList) | ||
163 | { | ||
164 | if (s.RegionInfo.RegionHandle == regionHandle) | ||
165 | { | ||
166 | //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); | ||
167 | return s.IncomingCloseAgent(id); | ||
168 | } | ||
169 | } | ||
170 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); | ||
171 | return false; | ||
172 | } | ||
173 | |||
140 | #endregion /* IInterregionComms */ | 174 | #endregion /* IInterregionComms */ |
141 | } | 175 | } |
142 | } | 176 | } |
diff --git a/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs index b7c9269..f48e474 100644 --- a/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs +++ b/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs | |||
@@ -146,6 +146,40 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
146 | 146 | ||
147 | } | 147 | } |
148 | 148 | ||
149 | public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) | ||
150 | { | ||
151 | // Try local first | ||
152 | if (m_localBackend.SendReleaseAgent(regionHandle, id, uri)) | ||
153 | return true; | ||
154 | |||
155 | // else do the remote thing | ||
156 | return DoReleaseAgentCall(regionHandle, id, uri); | ||
157 | } | ||
158 | |||
159 | public bool SendCloseAgent(ulong regionHandle, UUID id) | ||
160 | { | ||
161 | // Try local first | ||
162 | if (m_localBackend.SendCloseAgent(regionHandle, id)) | ||
163 | return true; | ||
164 | |||
165 | // else do the remote thing | ||
166 | RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); | ||
167 | if (regInfo != null) | ||
168 | { | ||
169 | return DoCloseAgentCall(regInfo, id); | ||
170 | } | ||
171 | //else | ||
172 | // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); | ||
173 | return false; | ||
174 | } | ||
175 | |||
176 | #endregion /* IInterregionComms */ | ||
177 | |||
178 | #region DoWork functions for the above public interface | ||
179 | //------------------------------------------------------------------- | ||
180 | // Internal functions for the above public interface | ||
181 | //------------------------------------------------------------------- | ||
182 | |||
149 | protected bool DoChildAgentUpdateCall(RegionInfo region, AgentData cAgentData) | 183 | protected bool DoChildAgentUpdateCall(RegionInfo region, AgentData cAgentData) |
150 | { | 184 | { |
151 | // Eventually, we want to use a caps url instead of the agentID | 185 | // Eventually, we want to use a caps url instead of the agentID |
@@ -168,7 +202,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
168 | m_log.Debug("[REST COMMS]: PackUpdateMessage failed with exception: " + e.Message); | 202 | m_log.Debug("[REST COMMS]: PackUpdateMessage failed with exception: " + e.Message); |
169 | } | 203 | } |
170 | // Add the regionhandle of the destination region | 204 | // Add the regionhandle of the destination region |
171 | ulong regionHandle = GetRegionHandle(region); | 205 | ulong regionHandle = GetRegionHandle(region.RegionHandle); |
172 | args["destination_handle"] = OSD.FromString(regionHandle.ToString()); | 206 | args["destination_handle"] = OSD.FromString(regionHandle.ToString()); |
173 | 207 | ||
174 | string strBuffer = ""; | 208 | string strBuffer = ""; |
@@ -231,9 +265,77 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
231 | 265 | ||
232 | } | 266 | } |
233 | 267 | ||
234 | #endregion /* IInterregionComms */ | 268 | protected bool DoReleaseAgentCall(ulong regionHandle, UUID id, string uri) |
269 | { | ||
270 | //Console.WriteLine(" >>> DoReleaseAgentCall <<< " + uri); | ||
271 | |||
272 | WebRequest request = WebRequest.Create(uri); | ||
273 | request.Method = "DELETE"; | ||
274 | request.Timeout = 10000; | ||
275 | |||
276 | try | ||
277 | { | ||
278 | WebResponse webResponse = request.GetResponse(); | ||
279 | if (webResponse == null) | ||
280 | { | ||
281 | m_log.Info("[REST COMMS]: Null reply on agent get "); | ||
282 | } | ||
283 | |||
284 | StreamReader sr = new StreamReader(webResponse.GetResponseStream()); | ||
285 | //reply = sr.ReadToEnd().Trim(); | ||
286 | sr.ReadToEnd().Trim(); | ||
287 | sr.Close(); | ||
288 | //m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply); | ||
289 | |||
290 | } | ||
291 | catch (WebException ex) | ||
292 | { | ||
293 | m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message); | ||
294 | // ignore, really | ||
295 | } | ||
296 | |||
297 | return true; | ||
298 | |||
299 | } | ||
300 | |||
301 | protected bool DoCloseAgentCall(RegionInfo region, UUID id) | ||
302 | { | ||
303 | string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() +"/"; | ||
304 | |||
305 | //Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri); | ||
235 | 306 | ||
236 | #region Called from remote instances on this instance | 307 | WebRequest request = WebRequest.Create(uri); |
308 | request.Method = "DELETE"; | ||
309 | request.Timeout = 10000; | ||
310 | |||
311 | try | ||
312 | { | ||
313 | WebResponse webResponse = request.GetResponse(); | ||
314 | if (webResponse == null) | ||
315 | { | ||
316 | m_log.Info("[REST COMMS]: Null reply on agent get "); | ||
317 | } | ||
318 | |||
319 | StreamReader sr = new StreamReader(webResponse.GetResponseStream()); | ||
320 | //reply = sr.ReadToEnd().Trim(); | ||
321 | sr.ReadToEnd().Trim(); | ||
322 | sr.Close(); | ||
323 | //m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply); | ||
324 | |||
325 | } | ||
326 | catch (WebException ex) | ||
327 | { | ||
328 | m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message); | ||
329 | // ignore, really | ||
330 | } | ||
331 | |||
332 | return true; | ||
333 | |||
334 | } | ||
335 | |||
336 | #endregion /* DoWork */ | ||
337 | |||
338 | #region Incoming calls from remote instances | ||
237 | 339 | ||
238 | public Hashtable AgentHandler(Hashtable request) | 340 | public Hashtable AgentHandler(Hashtable request) |
239 | { | 341 | { |
@@ -250,7 +352,8 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
250 | 352 | ||
251 | UUID agentID; | 353 | UUID agentID; |
252 | string action; | 354 | string action; |
253 | if (!GetParams((string)request["uri"], out agentID, out action)) | 355 | ulong regionHandle; |
356 | if (!GetParams((string)request["uri"], out agentID, out regionHandle, out action)) | ||
254 | { | 357 | { |
255 | m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]); | 358 | m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]); |
256 | responsedata["int_response_code"] = 404; | 359 | responsedata["int_response_code"] = 404; |
@@ -274,11 +377,9 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
274 | 377 | ||
275 | return responsedata; | 378 | return responsedata; |
276 | } | 379 | } |
277 | else if (method.Equals("GET")) | 380 | else if (method.Equals("DELETE")) |
278 | { | 381 | { |
279 | m_log.InfoFormat("[REST COMMS]: method {0} not implemented yet in agent message", method); | 382 | DoDelete(request, responsedata, agentID, action, regionHandle); |
280 | responsedata["int_response_code"] = 404; | ||
281 | responsedata["str_response_string"] = "false"; | ||
282 | 383 | ||
283 | return responsedata; | 384 | return responsedata; |
284 | } | 385 | } |
@@ -293,7 +394,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
293 | 394 | ||
294 | } | 395 | } |
295 | 396 | ||
296 | protected virtual void DoPut(Hashtable request, Hashtable responsedata) | 397 | protected OSDMap GetOSDMap(Hashtable request) |
297 | { | 398 | { |
298 | OSDMap args = null; | 399 | OSDMap args = null; |
299 | try | 400 | try |
@@ -302,20 +403,32 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
302 | // We should pay attention to the content-type, but let's assume we know it's Json | 403 | // We should pay attention to the content-type, but let's assume we know it's Json |
303 | buffer = OSDParser.DeserializeJson((string)request["body"]); | 404 | buffer = OSDParser.DeserializeJson((string)request["body"]); |
304 | if (buffer.Type == OSDType.Map) | 405 | if (buffer.Type == OSDType.Map) |
406 | { | ||
305 | args = (OSDMap)buffer; | 407 | args = (OSDMap)buffer; |
408 | return args; | ||
409 | } | ||
306 | else | 410 | else |
307 | { | 411 | { |
308 | // uh? | 412 | // uh? |
309 | m_log.Debug("[REST COMMS]: Got OSD of type " + buffer.Type.ToString()); | 413 | m_log.Debug("[REST COMMS]: Got OSD of type " + buffer.Type.ToString()); |
414 | return null; | ||
310 | } | 415 | } |
311 | } | 416 | } |
312 | catch (Exception ex) | 417 | catch (Exception ex) |
313 | { | 418 | { |
314 | m_log.InfoFormat("[REST COMMS]: exception on parse of ChildAgentUpdate message {0}", ex.Message); | 419 | m_log.InfoFormat("[REST COMMS]: exception on parse of ChildAgentUpdate message {0}", ex.Message); |
420 | return null; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | protected virtual void DoPut(Hashtable request, Hashtable responsedata) | ||
425 | { | ||
426 | OSDMap args = GetOSDMap(request); | ||
427 | if (args == null) | ||
428 | { | ||
315 | responsedata["int_response_code"] = 400; | 429 | responsedata["int_response_code"] = 400; |
316 | responsedata["str_response_string"] = "false"; | 430 | responsedata["str_response_string"] = "false"; |
317 | 431 | return; | |
318 | return ; | ||
319 | } | 432 | } |
320 | 433 | ||
321 | // retrieve the regionhandle | 434 | // retrieve the regionhandle |
@@ -343,19 +456,34 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
343 | responsedata["str_response_string"] = result.ToString(); | 456 | responsedata["str_response_string"] = result.ToString(); |
344 | } | 457 | } |
345 | 458 | ||
459 | protected virtual void DoDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) | ||
460 | { | ||
461 | //Console.WriteLine(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); | ||
462 | bool result = true; | ||
463 | if (action.Equals("release")) | ||
464 | { | ||
465 | result = m_localBackend.SendReleaseAgent(regionHandle, id, ""); | ||
466 | } | ||
467 | else | ||
468 | result = m_localBackend.SendCloseAgent(regionHandle, id); | ||
469 | |||
470 | responsedata["int_response_code"] = 200; | ||
471 | responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); | ||
472 | } | ||
346 | #endregion | 473 | #endregion |
347 | 474 | ||
348 | #region Misc | 475 | #region Misc |
349 | /// <summary> | 476 | /// <summary> |
350 | /// Extract the param from an uri. | 477 | /// Extract the param from an uri. |
351 | /// </summary> | 478 | /// </summary> |
352 | /// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/release</param> | 479 | /// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/handle/release</param> |
353 | /// <param name="uri">uuid on uuid field</param> | 480 | /// <param name="uri">uuid on uuid field</param> |
354 | /// <param name="action">optional action</param> | 481 | /// <param name="action">optional action</param> |
355 | protected bool GetParams(string uri, out UUID uuid, out string action) | 482 | protected bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action) |
356 | { | 483 | { |
357 | uuid = UUID.Zero; | 484 | uuid = UUID.Zero; |
358 | action = ""; | 485 | action = ""; |
486 | regionHandle = 0; | ||
359 | 487 | ||
360 | uri = uri.Trim(new char[] { '/' }); | 488 | uri = uri.Trim(new char[] { '/' }); |
361 | string[] parts = uri.Split('/'); | 489 | string[] parts = uri.Split('/'); |
@@ -369,20 +497,29 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST | |||
369 | return false; | 497 | return false; |
370 | 498 | ||
371 | if (parts.Length >= 3) | 499 | if (parts.Length >= 3) |
372 | action = parts[2]; | 500 | UInt64.TryParse(parts[2], out regionHandle); |
373 | 501 | if (parts.Length >= 4) | |
502 | action = parts[3]; | ||
503 | |||
374 | return true; | 504 | return true; |
375 | } | 505 | } |
376 | } | 506 | } |
377 | 507 | ||
378 | protected virtual ulong GetRegionHandle(RegionInfo region) | 508 | protected virtual ulong GetRegionHandle(ulong handle) |
379 | { | 509 | { |
380 | if (m_aScene.SceneGridService is HGSceneCommunicationService) | 510 | if (m_aScene.SceneGridService is HGSceneCommunicationService) |
381 | return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(region.RegionHandle); | 511 | return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(handle); |
382 | 512 | ||
383 | return region.RegionHandle; | 513 | return handle; |
384 | } | 514 | } |
385 | 515 | ||
516 | protected virtual bool IsHyperlink(ulong handle) | ||
517 | { | ||
518 | if (m_aScene.SceneGridService is HGSceneCommunicationService) | ||
519 | return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.IsHyperlinkRegion(handle); | ||
520 | |||
521 | return false; | ||
522 | } | ||
386 | #endregion /* Misc */ | 523 | #endregion /* Misc */ |
387 | 524 | ||
388 | } | 525 | } |
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs index bcd378f..abf4065 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs | |||
@@ -256,15 +256,16 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
256 | // return; | 256 | // return; |
257 | //} | 257 | //} |
258 | 258 | ||
259 | SetInTransit(avatar.UUID); | ||
259 | // Let's send a full update of the agent. This is a synchronous call. | 260 | // Let's send a full update of the agent. This is a synchronous call. |
260 | AgentData agent = new AgentData(); | 261 | AgentData agent = new AgentData(); |
261 | avatar.CopyTo(agent); | 262 | avatar.CopyTo(agent); |
262 | agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!! | 263 | agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!! |
264 | agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort + | ||
265 | "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; | ||
263 | 266 | ||
264 | m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); | 267 | m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); |
265 | 268 | ||
266 | avatar.MakeChildAgent(); | ||
267 | |||
268 | m_log.DebugFormat( | 269 | m_log.DebugFormat( |
269 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID); | 270 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID); |
270 | 271 | ||
@@ -288,17 +289,32 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
288 | /// Hypergrid mod stop | 289 | /// Hypergrid mod stop |
289 | /// | 290 | /// |
290 | 291 | ||
292 | |||
293 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | ||
294 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | ||
295 | // that the client contacted the destination before we send the attachments and close things here. | ||
296 | if (!WaitForCallback(avatar.UUID)) | ||
297 | { | ||
298 | // Client never contacted destination. Let's restore everything back | ||
299 | avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | ||
300 | |||
301 | ResetFromTransit(avatar.UUID); | ||
302 | // Yikes! We should just have a ref to scene here. | ||
303 | avatar.Scene.InformClientOfNeighbours(avatar); | ||
304 | |||
305 | // Finally, kill the agent we just created at the destination. | ||
306 | m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID); | ||
307 | |||
308 | return; | ||
309 | } | ||
310 | |||
311 | // Can't go back from here | ||
291 | if (KiPrimitive != null) | 312 | if (KiPrimitive != null) |
292 | { | 313 | { |
293 | KiPrimitive(avatar.LocalId); | 314 | KiPrimitive(avatar.LocalId); |
294 | } | 315 | } |
295 | 316 | ||
296 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 317 | avatar.MakeChildAgent(); |
297 | // trigers a whole shebang of things there, including MakeRoot. So let's wait plenty before | ||
298 | // we send the attachments and close things here. | ||
299 | // It would be nice if the client would tell us when that whole thing is done, so we wouldn't have | ||
300 | // to use this Thread.Sleep voodoo | ||
301 | Thread.Sleep(4000); | ||
302 | 318 | ||
303 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 319 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it |
304 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | 320 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); |
@@ -310,7 +326,7 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
310 | /// | 326 | /// |
311 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) | 327 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) |
312 | { | 328 | { |
313 | Thread.Sleep(8000); | 329 | Thread.Sleep(5000); |
314 | avatar.Close(); | 330 | avatar.Close(); |
315 | CloseConnection(avatar.UUID); | 331 | CloseConnection(avatar.UUID); |
316 | } | 332 | } |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 56b5df6..13b9169 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -2692,7 +2692,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
2692 | { | 2692 | { |
2693 | m_sceneGridService.OnExpectUser += NewUserConnection; | 2693 | m_sceneGridService.OnExpectUser += NewUserConnection; |
2694 | m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing; | 2694 | m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing; |
2695 | m_sceneGridService.OnCloseAgentConnection += CloseConnection; | 2695 | m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent; |
2696 | m_sceneGridService.OnRegionUp += OtherRegionUp; | 2696 | m_sceneGridService.OnRegionUp += OtherRegionUp; |
2697 | //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; | 2697 | //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; |
2698 | m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup; | 2698 | m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup; |
@@ -2724,7 +2724,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
2724 | m_sceneGridService.OnRegionUp -= OtherRegionUp; | 2724 | m_sceneGridService.OnRegionUp -= OtherRegionUp; |
2725 | m_sceneGridService.OnExpectUser -= NewUserConnection; | 2725 | m_sceneGridService.OnExpectUser -= NewUserConnection; |
2726 | m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing; | 2726 | m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing; |
2727 | m_sceneGridService.OnCloseAgentConnection -= CloseConnection; | 2727 | m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent; |
2728 | m_sceneGridService.OnGetLandData -= GetLandData; | 2728 | m_sceneGridService.OnGetLandData -= GetLandData; |
2729 | 2729 | ||
2730 | if (m_interregionCommsIn != null) | 2730 | if (m_interregionCommsIn != null) |
@@ -2979,12 +2979,22 @@ namespace OpenSim.Region.Environment.Scenes | |||
2979 | return false; | 2979 | return false; |
2980 | } | 2980 | } |
2981 | 2981 | ||
2982 | public virtual bool IncomingReleaseAgent(UUID id) | ||
2983 | { | ||
2984 | return m_sceneGridService.ReleaseAgent(id); | ||
2985 | } | ||
2986 | |||
2987 | public void SendReleaseAgent(ulong regionHandle, UUID id, string uri) | ||
2988 | { | ||
2989 | m_interregionCommsOut.SendReleaseAgent(regionHandle, id, uri); | ||
2990 | } | ||
2991 | |||
2982 | /// <summary> | 2992 | /// <summary> |
2983 | /// Tell a single agent to disconnect from the region. | 2993 | /// Tell a single agent to disconnect from the region. |
2984 | /// </summary> | 2994 | /// </summary> |
2985 | /// <param name="regionHandle"></param> | 2995 | /// <param name="regionHandle"></param> |
2986 | /// <param name="agentID"></param> | 2996 | /// <param name="agentID"></param> |
2987 | public bool CloseConnection(UUID agentID) | 2997 | public bool IncomingCloseAgent(UUID agentID) |
2988 | { | 2998 | { |
2989 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | 2999 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); |
2990 | if (presence != null) | 3000 | if (presence != null) |
@@ -3013,9 +3023,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
3013 | presence.ControllingClient.SendShutdownConnectionNotice(); | 3023 | presence.ControllingClient.SendShutdownConnectionNotice(); |
3014 | } | 3024 | } |
3015 | presence.ControllingClient.Close(true); | 3025 | presence.ControllingClient.Close(true); |
3016 | 3026 | return true; | |
3017 | } | 3027 | } |
3018 | return true; | 3028 | // Agent not here |
3029 | return false; | ||
3019 | } | 3030 | } |
3020 | 3031 | ||
3021 | /// <summary> | 3032 | /// <summary> |
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index 2bf81d8..da3a9d3 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | |||
@@ -55,6 +55,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
55 | 55 | ||
56 | protected RegionCommsListener regionCommsHost; | 56 | protected RegionCommsListener regionCommsHost; |
57 | 57 | ||
58 | protected List<UUID> m_agentsInTransit; | ||
59 | |||
58 | public event AgentCrossing OnAvatarCrossingIntoRegion; | 60 | public event AgentCrossing OnAvatarCrossingIntoRegion; |
59 | public event ExpectUserDelegate OnExpectUser; | 61 | public event ExpectUserDelegate OnExpectUser; |
60 | public event ExpectPrimDelegate OnExpectPrim; | 62 | public event ExpectPrimDelegate OnExpectPrim; |
@@ -82,6 +84,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
82 | public SceneCommunicationService(CommunicationsManager commsMan) | 84 | public SceneCommunicationService(CommunicationsManager commsMan) |
83 | { | 85 | { |
84 | m_commsProvider = commsMan; | 86 | m_commsProvider = commsMan; |
87 | m_agentsInTransit = new List<UUID>(); | ||
85 | } | 88 | } |
86 | 89 | ||
87 | /// <summary> | 90 | /// <summary> |
@@ -546,8 +549,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
546 | /// </summary> | 549 | /// </summary> |
547 | private void SendChildAgentDataUpdateAsync(AgentData cAgentData, ulong regionHandle) | 550 | private void SendChildAgentDataUpdateAsync(AgentData cAgentData, ulong regionHandle) |
548 | { | 551 | { |
549 | m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); | 552 | //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); |
550 | //bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); | ||
551 | try | 553 | try |
552 | { | 554 | { |
553 | //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); | 555 | //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); |
@@ -608,29 +610,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
608 | { | 610 | { |
609 | 611 | ||
610 | m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); | 612 | m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); |
611 | //bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | ||
612 | // let's do our best, but there's not much we can do if the neighbour doesn't accept. | 613 | // let's do our best, but there's not much we can do if the neighbour doesn't accept. |
613 | m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | ||
614 | |||
615 | //if (regionAccepted) | ||
616 | //{ | ||
617 | // m_log.Info("[INTERGRID]: Completed sending agent Close agent Request to neighbor"); | ||
618 | |||
619 | //} | ||
620 | //else | ||
621 | //{ | ||
622 | // m_log.Info("[INTERGRID]: Failed sending agent Close agent Request to neighbor"); | ||
623 | 614 | ||
624 | //} | 615 | //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); |
625 | 616 | m_interregionCommsOut.SendCloseAgent(regionHandle, agentID); | |
626 | //// We remove the list of known regions from the agent's known region list through an event | ||
627 | //// to scene, because, if an agent logged of, it's likely that there will be no scene presence | ||
628 | //// by the time we get to this part of the method. | ||
629 | //handlerRemoveKnownRegionFromAvatar = OnRemoveKnownRegionFromAvatar; | ||
630 | //if (handlerRemoveKnownRegionFromAvatar != null) | ||
631 | //{ | ||
632 | // handlerRemoveKnownRegionFromAvatar(agentID, regionlst); | ||
633 | //} | ||
634 | } | 617 | } |
635 | 618 | ||
636 | private void SendCloseChildAgentCompleted(IAsyncResult iar) | 619 | private void SendCloseChildAgentCompleted(IAsyncResult iar) |
@@ -860,15 +843,16 @@ namespace OpenSim.Region.Environment.Scenes | |||
860 | // return; | 843 | // return; |
861 | //} | 844 | //} |
862 | 845 | ||
846 | SetInTransit(avatar.UUID); | ||
863 | // Let's send a full update of the agent. This is a synchronous call. | 847 | // Let's send a full update of the agent. This is a synchronous call. |
864 | AgentData agent = new AgentData(); | 848 | AgentData agent = new AgentData(); |
865 | avatar.CopyTo(agent); | 849 | avatar.CopyTo(agent); |
866 | agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!! | 850 | agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!! |
851 | agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort + | ||
852 | "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; | ||
867 | 853 | ||
868 | m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); | 854 | m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); |
869 | 855 | ||
870 | avatar.MakeChildAgent(); | ||
871 | |||
872 | m_log.DebugFormat( | 856 | m_log.DebugFormat( |
873 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); | 857 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); |
874 | 858 | ||
@@ -885,17 +869,32 @@ namespace OpenSim.Region.Environment.Scenes | |||
885 | teleportFlags, capsPath); | 869 | teleportFlags, capsPath); |
886 | } | 870 | } |
887 | 871 | ||
872 | |||
873 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | ||
874 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | ||
875 | // that the client contacted the destination before we send the attachments and close things here. | ||
876 | if (!WaitForCallback(avatar.UUID)) | ||
877 | { | ||
878 | // Client never contacted destination. Let's restore everything back | ||
879 | avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | ||
880 | |||
881 | ResetFromTransit(avatar.UUID); | ||
882 | // Yikes! We should just have a ref to scene here. | ||
883 | avatar.Scene.InformClientOfNeighbours(avatar); | ||
884 | |||
885 | // Finally, kill the agent we just created at the destination. | ||
886 | m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID); | ||
887 | |||
888 | return; | ||
889 | } | ||
890 | |||
891 | // Can't go back from here | ||
888 | if (KiPrimitive != null) | 892 | if (KiPrimitive != null) |
889 | { | 893 | { |
890 | KiPrimitive(avatar.LocalId); | 894 | KiPrimitive(avatar.LocalId); |
891 | } | 895 | } |
892 | 896 | ||
893 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 897 | avatar.MakeChildAgent(); |
894 | // trigers a whole shebang of things there, including MakeRoot. So let's wait plenty before | ||
895 | // we send the attachments and close things here. | ||
896 | // We need to change this part of the protocol. The receiving region should tell this region | ||
897 | // when it's ok to continue. | ||
898 | Thread.Sleep(4000); | ||
899 | 898 | ||
900 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 899 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it |
901 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | 900 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); |
@@ -904,7 +903,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
904 | 903 | ||
905 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) | 904 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) |
906 | { | 905 | { |
907 | Thread.Sleep(8000); | 906 | Thread.Sleep(5000); |
908 | avatar.Close(); | 907 | avatar.Close(); |
909 | CloseConnection(avatar.UUID); | 908 | CloseConnection(avatar.UUID); |
910 | } | 909 | } |
@@ -947,6 +946,49 @@ namespace OpenSim.Region.Environment.Scenes | |||
947 | } | 946 | } |
948 | } | 947 | } |
949 | 948 | ||
949 | protected bool WaitForCallback(UUID id) | ||
950 | { | ||
951 | int count = 20; | ||
952 | while (m_agentsInTransit.Contains(id) && count-- > 0) | ||
953 | { | ||
954 | //Console.WriteLine(" >>> Waiting... " + count); | ||
955 | Thread.Sleep(1000); | ||
956 | } | ||
957 | |||
958 | if (count > 0) | ||
959 | return true; | ||
960 | else | ||
961 | return false; | ||
962 | } | ||
963 | |||
964 | public bool ReleaseAgent(UUID id) | ||
965 | { | ||
966 | //Console.WriteLine(" >>> ReleaseAgent called <<< "); | ||
967 | return ResetFromTransit(id); | ||
968 | } | ||
969 | |||
970 | protected void SetInTransit(UUID id) | ||
971 | { | ||
972 | lock (m_agentsInTransit) | ||
973 | { | ||
974 | if (!m_agentsInTransit.Contains(id)) | ||
975 | m_agentsInTransit.Add(id); | ||
976 | } | ||
977 | } | ||
978 | |||
979 | protected bool ResetFromTransit(UUID id) | ||
980 | { | ||
981 | lock (m_agentsInTransit) | ||
982 | { | ||
983 | if (m_agentsInTransit.Contains(id)) | ||
984 | { | ||
985 | m_agentsInTransit.Remove(id); | ||
986 | return true; | ||
987 | } | ||
988 | } | ||
989 | return false; | ||
990 | } | ||
991 | |||
950 | private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours) | 992 | private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours) |
951 | { | 993 | { |
952 | List<ulong> handles = new List<ulong>(); | 994 | List<ulong> handles = new List<ulong>(); |
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 23dc9be..166e051 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs | |||
@@ -217,6 +217,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
217 | 217 | ||
218 | private Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); | 218 | private Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); |
219 | 219 | ||
220 | // For teleports and crossings callbacks | ||
221 | string m_callbackURI; | ||
222 | ulong m_rootRegionHandle; | ||
223 | |||
220 | #region Properties | 224 | #region Properties |
221 | 225 | ||
222 | /// <summary> | 226 | /// <summary> |
@@ -1000,6 +1004,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1000 | /// </summary> | 1004 | /// </summary> |
1001 | public void CompleteMovement() | 1005 | public void CompleteMovement() |
1002 | { | 1006 | { |
1007 | //Console.WriteLine("\n CompleteMovement \n"); | ||
1003 | Vector3 look = Velocity; | 1008 | Vector3 look = Velocity; |
1004 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1009 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
1005 | { | 1010 | { |
@@ -1013,6 +1018,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
1013 | m_isChildAgent = false; | 1018 | m_isChildAgent = false; |
1014 | 1019 | ||
1015 | MakeRootAgent(AbsolutePosition, false); | 1020 | MakeRootAgent(AbsolutePosition, false); |
1021 | |||
1022 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) | ||
1023 | { | ||
1024 | Scene.SendReleaseAgent(m_rootRegionHandle, UUID, m_callbackURI); | ||
1025 | m_callbackURI = null; | ||
1026 | } | ||
1016 | } | 1027 | } |
1017 | } | 1028 | } |
1018 | 1029 | ||
@@ -2582,7 +2593,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
2582 | if (!IsChildAgent) | 2593 | if (!IsChildAgent) |
2583 | return; | 2594 | return; |
2584 | 2595 | ||
2585 | //Console.WriteLine(" >>> ChildAgentDataUpdate <<<"); | 2596 | //Console.WriteLine(" >>> ChildAgentDataUpdate <<< " + rRegionX + "-" + rRegionY); |
2586 | int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; | 2597 | int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; |
2587 | int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; | 2598 | int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; |
2588 | 2599 | ||
@@ -2615,6 +2626,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
2615 | if (m_scene.m_seeIntoRegionFromNeighbor) | 2626 | if (m_scene.m_seeIntoRegionFromNeighbor) |
2616 | m_pendingObjects = null; | 2627 | m_pendingObjects = null; |
2617 | 2628 | ||
2629 | m_callbackURI = cAgentData.CallbackURI; | ||
2630 | m_rootRegionHandle = Util.UIntsToLong(rRegionX * Constants.RegionSize, rRegionY * Constants.RegionSize); | ||
2631 | |||
2618 | //cAgentData.AVHeight; | 2632 | //cAgentData.AVHeight; |
2619 | //cAgentData.regionHandle; | 2633 | //cAgentData.regionHandle; |
2620 | //m_velocity = cAgentData.Velocity; | 2634 | //m_velocity = cAgentData.Velocity; |