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.0.6.2-post-fixes
parent
ba9d9a9019
commit
d8ebf2fc9d
|
@ -144,6 +144,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
byte[] VisualParams;
|
byte[] VisualParams;
|
||||||
|
|
||||||
|
public string CallbackURI;
|
||||||
|
|
||||||
public OSDMap PackUpdateMessage()
|
public OSDMap PackUpdateMessage()
|
||||||
{
|
{
|
||||||
|
@ -191,6 +192,9 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
// Last few fields are still missing
|
// Last few fields are still missing
|
||||||
|
|
||||||
|
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
|
||||||
|
args["callback_uri"] = OSD.FromString(CallbackURI);
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +288,9 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (args["active_group_id"] != null)
|
if (args["active_group_id"] != null)
|
||||||
ActiveGroupID = args["active_group_id"].AsUUID();
|
ActiveGroupID = args["active_group_id"].AsUUID();
|
||||||
|
|
||||||
|
if (args["callback_uri"] != null)
|
||||||
|
CallbackURI = args["callback_uri"].AsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AgentData()
|
public AgentData()
|
||||||
|
|
|
@ -177,7 +177,7 @@ namespace OpenSim
|
||||||
presence.UUID,
|
presence.UUID,
|
||||||
regionInfo.RegionName));
|
regionInfo.RegionName));
|
||||||
|
|
||||||
presence.Scene.CloseConnection(presence.UUID);
|
presence.Scene.IncomingCloseAgent(presence.UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_console.Notice("");
|
m_console.Notice("");
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace OpenSim.Region.Environment.Interfaces
|
||||||
public interface IInterregionCommsOut
|
public interface IInterregionCommsOut
|
||||||
{
|
{
|
||||||
bool SendChildAgentUpdate(ulong regionHandle, AgentData data);
|
bool SendChildAgentUpdate(ulong regionHandle, AgentData data);
|
||||||
|
bool SendReleaseAgent(ulong regionHandle, UUID id, string uri);
|
||||||
|
bool SendCloseAgent(ulong regionHandle, UUID id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This may not be needed, but having it here for now.
|
// This may not be needed, but having it here for now.
|
||||||
|
|
|
@ -119,24 +119,58 @@ namespace OpenSim.Region.Environment.Modules.Communications.Local
|
||||||
#region IInterregionComms
|
#region IInterregionComms
|
||||||
|
|
||||||
public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData)
|
public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData)
|
||||||
{
|
|
||||||
lock (m_sceneList)
|
|
||||||
{
|
{
|
||||||
foreach (Scene s in m_sceneList)
|
foreach (Scene s in m_sceneList)
|
||||||
{
|
{
|
||||||
if (s.RegionInfo.RegionHandle == regionHandle)
|
if (s.RegionInfo.RegionHandle == regionHandle)
|
||||||
{
|
{
|
||||||
//m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
|
//m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
|
||||||
return s.IncomingChildAgentDataUpdate(cAgentData);
|
s.IncomingChildAgentDataUpdate(cAgentData);
|
||||||
//if (OnChildAgentUpdate != null)
|
return true;
|
||||||
// return OnChildAgentUpdate(cAgentData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
|
//m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
|
||||||
|
{
|
||||||
|
//uint x, y;
|
||||||
|
//Utils.LongToUInts(regionHandle, out x, out y);
|
||||||
|
//x = x / Constants.RegionSize;
|
||||||
|
//y = y / Constants.RegionSize;
|
||||||
|
//Console.WriteLine("\n >>> Local SendReleaseAgent " + x + "-" + y);
|
||||||
|
foreach (Scene s in m_sceneList)
|
||||||
|
{
|
||||||
|
if (s.RegionInfo.RegionHandle == regionHandle)
|
||||||
|
{
|
||||||
|
//m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent");
|
||||||
|
return s.IncomingReleaseAgent(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendCloseAgent(ulong regionHandle, UUID id)
|
||||||
|
{
|
||||||
|
//uint x, y;
|
||||||
|
//Utils.LongToUInts(regionHandle, out x, out y);
|
||||||
|
//x = x / Constants.RegionSize;
|
||||||
|
//y = y / Constants.RegionSize;
|
||||||
|
//Console.WriteLine("\n >>> Local SendCloseAgent " + x + "-" + y);
|
||||||
|
foreach (Scene s in m_sceneList)
|
||||||
|
{
|
||||||
|
if (s.RegionInfo.RegionHandle == regionHandle)
|
||||||
|
{
|
||||||
|
//m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent");
|
||||||
|
return s.IncomingCloseAgent(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion /* IInterregionComms */
|
#endregion /* IInterregionComms */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,40 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
|
||||||
|
{
|
||||||
|
// Try local first
|
||||||
|
if (m_localBackend.SendReleaseAgent(regionHandle, id, uri))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// else do the remote thing
|
||||||
|
return DoReleaseAgentCall(regionHandle, id, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendCloseAgent(ulong regionHandle, UUID id)
|
||||||
|
{
|
||||||
|
// Try local first
|
||||||
|
if (m_localBackend.SendCloseAgent(regionHandle, id))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// else do the remote thing
|
||||||
|
RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
|
||||||
|
if (regInfo != null)
|
||||||
|
{
|
||||||
|
return DoCloseAgentCall(regInfo, id);
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
// m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion /* IInterregionComms */
|
||||||
|
|
||||||
|
#region DoWork functions for the above public interface
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Internal functions for the above public interface
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
protected bool DoChildAgentUpdateCall(RegionInfo region, AgentData cAgentData)
|
protected bool DoChildAgentUpdateCall(RegionInfo region, AgentData cAgentData)
|
||||||
{
|
{
|
||||||
// Eventually, we want to use a caps url instead of the agentID
|
// Eventually, we want to use a caps url instead of the agentID
|
||||||
|
@ -168,7 +202,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
m_log.Debug("[REST COMMS]: PackUpdateMessage failed with exception: " + e.Message);
|
m_log.Debug("[REST COMMS]: PackUpdateMessage failed with exception: " + e.Message);
|
||||||
}
|
}
|
||||||
// Add the regionhandle of the destination region
|
// Add the regionhandle of the destination region
|
||||||
ulong regionHandle = GetRegionHandle(region);
|
ulong regionHandle = GetRegionHandle(region.RegionHandle);
|
||||||
args["destination_handle"] = OSD.FromString(regionHandle.ToString());
|
args["destination_handle"] = OSD.FromString(regionHandle.ToString());
|
||||||
|
|
||||||
string strBuffer = "";
|
string strBuffer = "";
|
||||||
|
@ -231,9 +265,77 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion /* IInterregionComms */
|
protected bool DoReleaseAgentCall(ulong regionHandle, UUID id, string uri)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(" >>> DoReleaseAgentCall <<< " + uri);
|
||||||
|
|
||||||
#region Called from remote instances on this instance
|
WebRequest request = WebRequest.Create(uri);
|
||||||
|
request.Method = "DELETE";
|
||||||
|
request.Timeout = 10000;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebResponse webResponse = request.GetResponse();
|
||||||
|
if (webResponse == null)
|
||||||
|
{
|
||||||
|
m_log.Info("[REST COMMS]: Null reply on agent get ");
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
|
||||||
|
//reply = sr.ReadToEnd().Trim();
|
||||||
|
sr.ReadToEnd().Trim();
|
||||||
|
sr.Close();
|
||||||
|
//m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (WebException ex)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message);
|
||||||
|
// ignore, really
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool DoCloseAgentCall(RegionInfo region, UUID id)
|
||||||
|
{
|
||||||
|
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() +"/";
|
||||||
|
|
||||||
|
//Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(uri);
|
||||||
|
request.Method = "DELETE";
|
||||||
|
request.Timeout = 10000;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebResponse webResponse = request.GetResponse();
|
||||||
|
if (webResponse == null)
|
||||||
|
{
|
||||||
|
m_log.Info("[REST COMMS]: Null reply on agent get ");
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
|
||||||
|
//reply = sr.ReadToEnd().Trim();
|
||||||
|
sr.ReadToEnd().Trim();
|
||||||
|
sr.Close();
|
||||||
|
//m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (WebException ex)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message);
|
||||||
|
// ignore, really
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion /* DoWork */
|
||||||
|
|
||||||
|
#region Incoming calls from remote instances
|
||||||
|
|
||||||
public Hashtable AgentHandler(Hashtable request)
|
public Hashtable AgentHandler(Hashtable request)
|
||||||
{
|
{
|
||||||
|
@ -250,7 +352,8 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
|
|
||||||
UUID agentID;
|
UUID agentID;
|
||||||
string action;
|
string action;
|
||||||
if (!GetParams((string)request["uri"], out agentID, out action))
|
ulong regionHandle;
|
||||||
|
if (!GetParams((string)request["uri"], out agentID, out regionHandle, out action))
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]);
|
m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]);
|
||||||
responsedata["int_response_code"] = 404;
|
responsedata["int_response_code"] = 404;
|
||||||
|
@ -274,11 +377,9 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
|
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
else if (method.Equals("GET"))
|
else if (method.Equals("DELETE"))
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[REST COMMS]: method {0} not implemented yet in agent message", method);
|
DoDelete(request, responsedata, agentID, action, regionHandle);
|
||||||
responsedata["int_response_code"] = 404;
|
|
||||||
responsedata["str_response_string"] = "false";
|
|
||||||
|
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +394,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void DoPut(Hashtable request, Hashtable responsedata)
|
protected OSDMap GetOSDMap(Hashtable request)
|
||||||
{
|
{
|
||||||
OSDMap args = null;
|
OSDMap args = null;
|
||||||
try
|
try
|
||||||
|
@ -302,20 +403,32 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
// We should pay attention to the content-type, but let's assume we know it's Json
|
// We should pay attention to the content-type, but let's assume we know it's Json
|
||||||
buffer = OSDParser.DeserializeJson((string)request["body"]);
|
buffer = OSDParser.DeserializeJson((string)request["body"]);
|
||||||
if (buffer.Type == OSDType.Map)
|
if (buffer.Type == OSDType.Map)
|
||||||
|
{
|
||||||
args = (OSDMap)buffer;
|
args = (OSDMap)buffer;
|
||||||
|
return args;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// uh?
|
// uh?
|
||||||
m_log.Debug("[REST COMMS]: Got OSD of type " + buffer.Type.ToString());
|
m_log.Debug("[REST COMMS]: Got OSD of type " + buffer.Type.ToString());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[REST COMMS]: exception on parse of ChildAgentUpdate message {0}", ex.Message);
|
m_log.InfoFormat("[REST COMMS]: exception on parse of ChildAgentUpdate message {0}", ex.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void DoPut(Hashtable request, Hashtable responsedata)
|
||||||
|
{
|
||||||
|
OSDMap args = GetOSDMap(request);
|
||||||
|
if (args == null)
|
||||||
|
{
|
||||||
responsedata["int_response_code"] = 400;
|
responsedata["int_response_code"] = 400;
|
||||||
responsedata["str_response_string"] = "false";
|
responsedata["str_response_string"] = "false";
|
||||||
|
return;
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve the regionhandle
|
// retrieve the regionhandle
|
||||||
|
@ -343,19 +456,34 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
responsedata["str_response_string"] = result.ToString();
|
responsedata["str_response_string"] = result.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void DoDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle);
|
||||||
|
bool result = true;
|
||||||
|
if (action.Equals("release"))
|
||||||
|
{
|
||||||
|
result = m_localBackend.SendReleaseAgent(regionHandle, id, "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = m_localBackend.SendCloseAgent(regionHandle, id);
|
||||||
|
|
||||||
|
responsedata["int_response_code"] = 200;
|
||||||
|
responsedata["str_response_string"] = "OpenSim agent " + id.ToString();
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Misc
|
#region Misc
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extract the param from an uri.
|
/// Extract the param from an uri.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/release</param>
|
/// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/handle/release</param>
|
||||||
/// <param name="uri">uuid on uuid field</param>
|
/// <param name="uri">uuid on uuid field</param>
|
||||||
/// <param name="action">optional action</param>
|
/// <param name="action">optional action</param>
|
||||||
protected bool GetParams(string uri, out UUID uuid, out string action)
|
protected bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action)
|
||||||
{
|
{
|
||||||
uuid = UUID.Zero;
|
uuid = UUID.Zero;
|
||||||
action = "";
|
action = "";
|
||||||
|
regionHandle = 0;
|
||||||
|
|
||||||
uri = uri.Trim(new char[] { '/' });
|
uri = uri.Trim(new char[] { '/' });
|
||||||
string[] parts = uri.Split('/');
|
string[] parts = uri.Split('/');
|
||||||
|
@ -369,20 +497,29 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (parts.Length >= 3)
|
if (parts.Length >= 3)
|
||||||
action = parts[2];
|
UInt64.TryParse(parts[2], out regionHandle);
|
||||||
|
if (parts.Length >= 4)
|
||||||
|
action = parts[3];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual ulong GetRegionHandle(RegionInfo region)
|
protected virtual ulong GetRegionHandle(ulong handle)
|
||||||
{
|
{
|
||||||
if (m_aScene.SceneGridService is HGSceneCommunicationService)
|
if (m_aScene.SceneGridService is HGSceneCommunicationService)
|
||||||
return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(region.RegionHandle);
|
return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(handle);
|
||||||
|
|
||||||
return region.RegionHandle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual bool IsHyperlink(ulong handle)
|
||||||
|
{
|
||||||
|
if (m_aScene.SceneGridService is HGSceneCommunicationService)
|
||||||
|
return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.IsHyperlinkRegion(handle);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endregion /* Misc */
|
#endregion /* Misc */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,15 +256,16 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
SetInTransit(avatar.UUID);
|
||||||
// Let's send a full update of the agent. This is a synchronous call.
|
// Let's send a full update of the agent. This is a synchronous call.
|
||||||
AgentData agent = new AgentData();
|
AgentData agent = new AgentData();
|
||||||
avatar.CopyTo(agent);
|
avatar.CopyTo(agent);
|
||||||
agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!!
|
agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!!
|
||||||
|
agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort +
|
||||||
|
"/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/";
|
||||||
|
|
||||||
m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
|
m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
|
||||||
|
|
||||||
avatar.MakeChildAgent();
|
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID);
|
"[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID);
|
||||||
|
|
||||||
|
@ -288,17 +289,32 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
|
||||||
/// Hypergrid mod stop
|
/// Hypergrid mod stop
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
|
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
||||||
|
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
|
||||||
|
// that the client contacted the destination before we send the attachments and close things here.
|
||||||
|
if (!WaitForCallback(avatar.UUID))
|
||||||
|
{
|
||||||
|
// Client never contacted destination. Let's restore everything back
|
||||||
|
avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
|
||||||
|
|
||||||
|
ResetFromTransit(avatar.UUID);
|
||||||
|
// Yikes! We should just have a ref to scene here.
|
||||||
|
avatar.Scene.InformClientOfNeighbours(avatar);
|
||||||
|
|
||||||
|
// Finally, kill the agent we just created at the destination.
|
||||||
|
m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't go back from here
|
||||||
if (KiPrimitive != null)
|
if (KiPrimitive != null)
|
||||||
{
|
{
|
||||||
KiPrimitive(avatar.LocalId);
|
KiPrimitive(avatar.LocalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
avatar.MakeChildAgent();
|
||||||
// trigers a whole shebang of things there, including MakeRoot. So let's wait plenty before
|
|
||||||
// we send the attachments and close things here.
|
|
||||||
// It would be nice if the client would tell us when that whole thing is done, so we wouldn't have
|
|
||||||
// to use this Thread.Sleep voodoo
|
|
||||||
Thread.Sleep(4000);
|
|
||||||
|
|
||||||
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
|
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
|
||||||
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
|
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
|
||||||
|
@ -310,7 +326,7 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
|
||||||
///
|
///
|
||||||
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
|
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
|
||||||
{
|
{
|
||||||
Thread.Sleep(8000);
|
Thread.Sleep(5000);
|
||||||
avatar.Close();
|
avatar.Close();
|
||||||
CloseConnection(avatar.UUID);
|
CloseConnection(avatar.UUID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2692,7 +2692,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
m_sceneGridService.OnExpectUser += NewUserConnection;
|
m_sceneGridService.OnExpectUser += NewUserConnection;
|
||||||
m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
|
m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
|
||||||
m_sceneGridService.OnCloseAgentConnection += CloseConnection;
|
m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent;
|
||||||
m_sceneGridService.OnRegionUp += OtherRegionUp;
|
m_sceneGridService.OnRegionUp += OtherRegionUp;
|
||||||
//m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
|
//m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
|
||||||
m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup;
|
m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup;
|
||||||
|
@ -2724,7 +2724,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_sceneGridService.OnRegionUp -= OtherRegionUp;
|
m_sceneGridService.OnRegionUp -= OtherRegionUp;
|
||||||
m_sceneGridService.OnExpectUser -= NewUserConnection;
|
m_sceneGridService.OnExpectUser -= NewUserConnection;
|
||||||
m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
|
m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
|
||||||
m_sceneGridService.OnCloseAgentConnection -= CloseConnection;
|
m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent;
|
||||||
m_sceneGridService.OnGetLandData -= GetLandData;
|
m_sceneGridService.OnGetLandData -= GetLandData;
|
||||||
|
|
||||||
if (m_interregionCommsIn != null)
|
if (m_interregionCommsIn != null)
|
||||||
|
@ -2979,12 +2979,22 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool IncomingReleaseAgent(UUID id)
|
||||||
|
{
|
||||||
|
return m_sceneGridService.ReleaseAgent(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendReleaseAgent(ulong regionHandle, UUID id, string uri)
|
||||||
|
{
|
||||||
|
m_interregionCommsOut.SendReleaseAgent(regionHandle, id, uri);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tell a single agent to disconnect from the region.
|
/// Tell a single agent to disconnect from the region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="regionHandle"></param>
|
/// <param name="regionHandle"></param>
|
||||||
/// <param name="agentID"></param>
|
/// <param name="agentID"></param>
|
||||||
public bool CloseConnection(UUID agentID)
|
public bool IncomingCloseAgent(UUID agentID)
|
||||||
{
|
{
|
||||||
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
||||||
if (presence != null)
|
if (presence != null)
|
||||||
|
@ -3013,10 +3023,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
presence.ControllingClient.SendShutdownConnectionNotice();
|
presence.ControllingClient.SendShutdownConnectionNotice();
|
||||||
}
|
}
|
||||||
presence.ControllingClient.Close(true);
|
presence.ControllingClient.Close(true);
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Agent not here
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tell neighboring regions about this agent
|
/// Tell neighboring regions about this agent
|
||||||
|
|
|
@ -55,6 +55,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
protected RegionCommsListener regionCommsHost;
|
protected RegionCommsListener regionCommsHost;
|
||||||
|
|
||||||
|
protected List<UUID> m_agentsInTransit;
|
||||||
|
|
||||||
public event AgentCrossing OnAvatarCrossingIntoRegion;
|
public event AgentCrossing OnAvatarCrossingIntoRegion;
|
||||||
public event ExpectUserDelegate OnExpectUser;
|
public event ExpectUserDelegate OnExpectUser;
|
||||||
public event ExpectPrimDelegate OnExpectPrim;
|
public event ExpectPrimDelegate OnExpectPrim;
|
||||||
|
@ -82,6 +84,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public SceneCommunicationService(CommunicationsManager commsMan)
|
public SceneCommunicationService(CommunicationsManager commsMan)
|
||||||
{
|
{
|
||||||
m_commsProvider = commsMan;
|
m_commsProvider = commsMan;
|
||||||
|
m_agentsInTransit = new List<UUID>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -546,8 +549,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SendChildAgentDataUpdateAsync(AgentData cAgentData, ulong regionHandle)
|
private void SendChildAgentDataUpdateAsync(AgentData cAgentData, ulong regionHandle)
|
||||||
{
|
{
|
||||||
m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
|
//m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
|
||||||
//bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
|
//m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
|
||||||
|
@ -608,29 +610,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
|
|
||||||
m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle);
|
m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle);
|
||||||
//bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
|
|
||||||
// let's do our best, but there's not much we can do if the neighbour doesn't accept.
|
// let's do our best, but there's not much we can do if the neighbour doesn't accept.
|
||||||
m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
|
|
||||||
|
|
||||||
//if (regionAccepted)
|
//m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
|
||||||
//{
|
m_interregionCommsOut.SendCloseAgent(regionHandle, agentID);
|
||||||
// m_log.Info("[INTERGRID]: Completed sending agent Close agent Request to neighbor");
|
|
||||||
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// m_log.Info("[INTERGRID]: Failed sending agent Close agent Request to neighbor");
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// We remove the list of known regions from the agent's known region list through an event
|
|
||||||
//// to scene, because, if an agent logged of, it's likely that there will be no scene presence
|
|
||||||
//// by the time we get to this part of the method.
|
|
||||||
//handlerRemoveKnownRegionFromAvatar = OnRemoveKnownRegionFromAvatar;
|
|
||||||
//if (handlerRemoveKnownRegionFromAvatar != null)
|
|
||||||
//{
|
|
||||||
// handlerRemoveKnownRegionFromAvatar(agentID, regionlst);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendCloseChildAgentCompleted(IAsyncResult iar)
|
private void SendCloseChildAgentCompleted(IAsyncResult iar)
|
||||||
|
@ -860,15 +843,16 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
SetInTransit(avatar.UUID);
|
||||||
// Let's send a full update of the agent. This is a synchronous call.
|
// Let's send a full update of the agent. This is a synchronous call.
|
||||||
AgentData agent = new AgentData();
|
AgentData agent = new AgentData();
|
||||||
avatar.CopyTo(agent);
|
avatar.CopyTo(agent);
|
||||||
agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!!
|
agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!!
|
||||||
|
agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort +
|
||||||
|
"/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/";
|
||||||
|
|
||||||
m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
|
m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
|
||||||
|
|
||||||
avatar.MakeChildAgent();
|
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
|
"[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
|
||||||
|
|
||||||
|
@ -885,17 +869,32 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
teleportFlags, capsPath);
|
teleportFlags, capsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
||||||
|
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
|
||||||
|
// that the client contacted the destination before we send the attachments and close things here.
|
||||||
|
if (!WaitForCallback(avatar.UUID))
|
||||||
|
{
|
||||||
|
// Client never contacted destination. Let's restore everything back
|
||||||
|
avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
|
||||||
|
|
||||||
|
ResetFromTransit(avatar.UUID);
|
||||||
|
// Yikes! We should just have a ref to scene here.
|
||||||
|
avatar.Scene.InformClientOfNeighbours(avatar);
|
||||||
|
|
||||||
|
// Finally, kill the agent we just created at the destination.
|
||||||
|
m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't go back from here
|
||||||
if (KiPrimitive != null)
|
if (KiPrimitive != null)
|
||||||
{
|
{
|
||||||
KiPrimitive(avatar.LocalId);
|
KiPrimitive(avatar.LocalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
avatar.MakeChildAgent();
|
||||||
// trigers a whole shebang of things there, including MakeRoot. So let's wait plenty before
|
|
||||||
// we send the attachments and close things here.
|
|
||||||
// We need to change this part of the protocol. The receiving region should tell this region
|
|
||||||
// when it's ok to continue.
|
|
||||||
Thread.Sleep(4000);
|
|
||||||
|
|
||||||
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
|
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
|
||||||
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
|
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
|
||||||
|
@ -904,7 +903,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
|
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
|
||||||
{
|
{
|
||||||
Thread.Sleep(8000);
|
Thread.Sleep(5000);
|
||||||
avatar.Close();
|
avatar.Close();
|
||||||
CloseConnection(avatar.UUID);
|
CloseConnection(avatar.UUID);
|
||||||
}
|
}
|
||||||
|
@ -947,6 +946,49 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool WaitForCallback(UUID id)
|
||||||
|
{
|
||||||
|
int count = 20;
|
||||||
|
while (m_agentsInTransit.Contains(id) && count-- > 0)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(" >>> Waiting... " + count);
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ReleaseAgent(UUID id)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(" >>> ReleaseAgent called <<< ");
|
||||||
|
return ResetFromTransit(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SetInTransit(UUID id)
|
||||||
|
{
|
||||||
|
lock (m_agentsInTransit)
|
||||||
|
{
|
||||||
|
if (!m_agentsInTransit.Contains(id))
|
||||||
|
m_agentsInTransit.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool ResetFromTransit(UUID id)
|
||||||
|
{
|
||||||
|
lock (m_agentsInTransit)
|
||||||
|
{
|
||||||
|
if (m_agentsInTransit.Contains(id))
|
||||||
|
{
|
||||||
|
m_agentsInTransit.Remove(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours)
|
private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours)
|
||||||
{
|
{
|
||||||
List<ulong> handles = new List<ulong>();
|
List<ulong> handles = new List<ulong>();
|
||||||
|
|
|
@ -217,6 +217,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
private Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
|
private Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
|
||||||
|
|
||||||
|
// For teleports and crossings callbacks
|
||||||
|
string m_callbackURI;
|
||||||
|
ulong m_rootRegionHandle;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1000,6 +1004,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CompleteMovement()
|
public void CompleteMovement()
|
||||||
{
|
{
|
||||||
|
//Console.WriteLine("\n CompleteMovement \n");
|
||||||
Vector3 look = Velocity;
|
Vector3 look = Velocity;
|
||||||
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
|
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
|
||||||
{
|
{
|
||||||
|
@ -1013,6 +1018,12 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_isChildAgent = false;
|
m_isChildAgent = false;
|
||||||
|
|
||||||
MakeRootAgent(AbsolutePosition, false);
|
MakeRootAgent(AbsolutePosition, false);
|
||||||
|
|
||||||
|
if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
|
||||||
|
{
|
||||||
|
Scene.SendReleaseAgent(m_rootRegionHandle, UUID, m_callbackURI);
|
||||||
|
m_callbackURI = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2582,7 +2593,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
if (!IsChildAgent)
|
if (!IsChildAgent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Console.WriteLine(" >>> ChildAgentDataUpdate <<<");
|
//Console.WriteLine(" >>> ChildAgentDataUpdate <<< " + rRegionX + "-" + rRegionY);
|
||||||
int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
|
int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
|
||||||
int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
|
int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
|
||||||
|
|
||||||
|
@ -2615,6 +2626,9 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
if (m_scene.m_seeIntoRegionFromNeighbor)
|
if (m_scene.m_seeIntoRegionFromNeighbor)
|
||||||
m_pendingObjects = null;
|
m_pendingObjects = null;
|
||||||
|
|
||||||
|
m_callbackURI = cAgentData.CallbackURI;
|
||||||
|
m_rootRegionHandle = Util.UIntsToLong(rRegionX * Constants.RegionSize, rRegionY * Constants.RegionSize);
|
||||||
|
|
||||||
//cAgentData.AVHeight;
|
//cAgentData.AVHeight;
|
||||||
//cAgentData.regionHandle;
|
//cAgentData.regionHandle;
|
||||||
//m_velocity = cAgentData.Velocity;
|
//m_velocity = cAgentData.Velocity;
|
||||||
|
|
Loading…
Reference in New Issue