aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authordiva2009-01-01 19:42:24 +0000
committerdiva2009-01-01 19:42:24 +0000
commitd8ebf2fc9d7d2e50735d50e75f7153f487efe958 (patch)
treec14d5e80e3d34d0a2f547cb3d0b965dea8e55e90 /OpenSim
parentMinor fix for HG request neighbors. Should not return hyperlink neighbors, on... (diff)
downloadopensim-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 'OpenSim')
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs7
-rw-r--r--OpenSim/Region/Application/OpenSim.cs2
-rw-r--r--OpenSim/Region/Environment/Interfaces/IInterregionComms.cs2
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs52
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs173
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs34
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs21
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs106
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs16
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;