Introduce an EntityTransferContext carrying the version numbers to pass

to all interested functions. Should fix the varregion conditional.
Still a testing version, do NOT use in production!
avinationmerge
Melanie Thielker 2015-10-31 18:13:02 +01:00
parent e8e0ba6d8f
commit ea56f4f27c
10 changed files with 81 additions and 59 deletions

View File

@ -719,9 +719,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, sp.Scene.Name, finalDestination.RegionName);
string reason;
float version;
EntityTransferContext ctx = new EntityTransferContext();
if (!Scene.SimulationService.QueryAccess(
finalDestination, sp.ControllingClient.AgentId, homeURI, true, position, sp.Scene.GetFormatsOffered(), out version, out reason))
finalDestination, sp.ControllingClient.AgentId, homeURI, true, position, sp.Scene.GetFormatsOffered(), ctx, out reason))
{
sp.ControllingClient.SendTeleportFailed(reason);
@ -738,8 +739,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_interRegionTeleportAttempts.Value++;
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: {0} transfer protocol version to {1} is SIMULATION/{2}",
sp.Scene.Name, finalDestination.RegionName, version);
"[ENTITY TRANSFER MODULE]: {0} transfer protocol version to {1} is {2} / {3}",
sp.Scene.Name, finalDestination.RegionName, ctx.OutboundVersion, ctx.InboundVersion);
// Fixing a bug where teleporting while sitting results in the avatar ending up removed from
// both regions
@ -788,14 +789,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
// We're going to fallback to V1 if the destination gives us anything smaller than 0.2
if (version >= 0.2f)
TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
if (ctx.OutboundVersion >= 0.2f)
TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason);
else
TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason);
}
private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, float version, out string reason)
IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason)
{
ulong destinationHandle = finalDestination.RegionHandle;
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
@ -1008,6 +1009,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
/*
// TODO: This may be 0.6. Check if still needed
// For backwards compatibility
if (version == 0f)
{
@ -1015,6 +1018,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one...");
CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
}
*/
// May need to logout or other cleanup
AgentHasMovedAway(sp, logout);
@ -1050,7 +1054,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, float version, out string reason)
IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason)
{
ulong destinationHandle = finalDestination.RegionHandle;
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
@ -1430,9 +1434,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// point is actually in.
// Returns the coordinates and information of the new region or 'null' of it doesn't exist.
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
out float version, out Vector3 newpos, out string failureReason)
EntityTransferContext ctx, out Vector3 newpos, out string failureReason)
{
version = 0f;
newpos = pos;
failureReason = string.Empty;
string homeURI = scene.GetAgentHomeURI(agentID);
@ -1469,7 +1472,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Check to see if we have access to the target region.
if (neighbourRegion != null
&& !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), out version, out failureReason))
&& !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), ctx, out failureReason))
{
// remember banned
m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
@ -1500,11 +1503,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public bool Cross(ScenePresence agent, bool isFlying)
{
Vector3 newpos;
float version;
EntityTransferContext ctx = new EntityTransferContext();
string failureReason;
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition,
out version, out newpos, out failureReason);
ctx, out newpos, out failureReason);
if (neighbourRegion == null)
{
agent.ControllingClient.SendAlertMessage(failureReason);
@ -1514,7 +1517,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.IsInTransit = true;
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, ctx, CrossAgentToNewRegionCompleted, d);
Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion);
@ -1612,7 +1615,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// </summary>
public ScenePresence CrossAgentToNewRegionAsync(
ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
bool isFlying, float version)
bool isFlying, EntityTransferContext ctx)
{
try
{
@ -1631,7 +1634,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
}
CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, ctx);
}
catch (Exception e)
{
@ -1688,7 +1691,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
bool isFlying, float version)
bool isFlying, EntityTransferContext ctx)
{
agent.ControllingClient.RequestClientInfo();
@ -1740,6 +1743,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.SendOtherAgentsAvatarDataToClient();
agent.SendOtherAgentsAppearanceToClient();
// TODO: Check since what version this wasn't needed anymore. May be as old as 0.6
/*
// Backwards compatibility. Best effort
if (version == 0f)
{
@ -1747,7 +1752,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
}
*/
// Next, let's close the child agent connections that are too far away.
uint neighbourx;
uint neighboury;

View File

@ -244,10 +244,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return true;
}
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, out float version, out string reason)
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, EntityTransferContext ctx, out string reason)
{
reason = "Communications failure";
version = VersionInfo.SimulationServiceVersionAcceptedMax; // If it's within the process, use max. If it's not, the connector will overwrite this
if (destination == null)
return false;
@ -260,7 +259,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// Var regions here, and the requesting simulator is in an older version.
// We will forbide this, because it crashes the viewers
if (version < 0.3f && size != 256)
if (ctx.OutboundVersion < 0.3f && size != 256)
{
reason = "Destination is a variable-sized region, and source is an old simulator. Consider upgrading.";
m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Request to access this variable-sized region from older simulator was denied");

View File

@ -205,21 +205,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return m_remoteConnector.UpdateAgent(destination, cAgentData);
}
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, out float version, out string reason)
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, EntityTransferContext ctx, out string reason)
{
reason = "Communications failure";
version = 0f;
if (destination == null)
return false;
// Try local first
if (m_localBackend.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, out version, out reason))
if (m_localBackend.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, ctx, out reason))
return true;
// else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionID))
return m_remoteConnector.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, out version, out reason);
return m_remoteConnector.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, ctx, out reason);
return false;
}

View File

@ -35,7 +35,7 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces
{
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, float version);
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx);
public interface IEntityTransferModule
{
@ -92,12 +92,12 @@ namespace OpenSim.Region.Framework.Interfaces
void EnableChildAgent(ScenePresence agent, GridRegion region);
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out float version,
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, EntityTransferContext ctx,
out Vector3 newpos, out string reason);
void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, float version);
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx);
bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition);
}

View File

@ -41,6 +41,7 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.PhysicsModules.SharedBase;
using OpenSim.Region.Framework.Scenes.Serialization;
using PermissionMask = OpenSim.Framework.PermissionMask;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.Framework.Scenes
{
@ -476,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
)
{
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
float version = 0f;
EntityTransferContext ctx = new EntityTransferContext();
Vector3 newpos = Vector3.Zero;
string failureReason = String.Empty;
OpenSim.Services.Interfaces.GridRegion destination = null;
@ -496,7 +497,7 @@ namespace OpenSim.Region.Framework.Scenes
// We set the avatar position as being the object
// position to get the region to send to
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos, out failureReason)) == null)
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, ctx, out newpos, out failureReason)) == null)
{
canCross = false;
break;
@ -557,14 +558,14 @@ namespace OpenSim.Region.Framework.Scenes
// threads rather than any replace threadpool that we might be using.
if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{
entityTransfer.CrossAgentToNewRegionAsync(av, val, destination, av.Flying, version);
entityTransfer.CrossAgentToNewRegionAsync(av, val, destination, av.Flying, ctx);
CrossAgentToNewRegionCompleted(av);
}
else
{
CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
d.BeginInvoke(
av, val, destination, av.Flying, version,
av, val, destination, av.Flying, ctx,
ar => CrossAgentToNewRegionCompleted(d.EndInvoke(ar)), null);
}
}

View File

@ -176,6 +176,8 @@ namespace OpenSim.Server.Handlers.Simulation
float version;
float outboundVersion = 0f;
float inboundVersion = 0f;
if (minVersionProvided == 0f) // string version or older
{
@ -221,24 +223,22 @@ namespace OpenSim.Server.Handlers.Simulation
}
// Determine versions to use
float inboundVersion = Math.Min(maxVersionProvided, VersionInfo.SimulationServiceVersionAcceptedMax);
float outboundVersion = Math.Min(maxVersionRequired, VersionInfo.SimulationServiceVersionSupportedMax);
// This is intentionally inverted. Inbound and Outbound refer to the direction of the transfer.
// Therefore outbound means from the sender to the receier and inbound means from the receiver to the sender.
// So outbound is what we will accept and inbound is what we will send. Confused yet?
outboundVersion = Math.Min(maxVersionProvided, VersionInfo.SimulationServiceVersionAcceptedMax);
inboundVersion = Math.Min(maxVersionRequired, VersionInfo.SimulationServiceVersionSupportedMax);
// In this stage, we use only a single version number. Future regions may use asymmetrical protocols.
// Here, the two versions we determined are combined into a single version for now.
// Here, the two versions we determined are combined into a single version for legacy response.
version = Math.Max(inboundVersion, outboundVersion);
// Since only using a single version, we must do this check. Once the plumbing is in for asymmetrical
// protocols, this will go away, allowing more working combinations.
if (version < VersionInfo.SimulationServiceVersionAcceptedMin ||
version > VersionInfo.SimulationServiceVersionAcceptedMax ||
version < VersionInfo.SimulationServiceVersionSupportedMin ||
version > VersionInfo.SimulationServiceVersionSupportedMax)
{
resp["success"] = OSD.FromBoolean(false);
resp["reason"] = OSD.FromString(String.Format("The region protocol version we determined, {0}, is incompatible with the version windows, {1} - {2} and {3} - {4}. No version overlap.", version, VersionInfo.SimulationServiceVersionAcceptedMin, VersionInfo.SimulationServiceVersionAcceptedMax, VersionInfo.SimulationServiceVersionSupportedMin, VersionInfo.SimulationServiceVersionSupportedMax));
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true);
return;
// If the single version can't resolve, fall back to safest. This will only affect very old regions.
version = 0.1f;
}
}
@ -256,15 +256,18 @@ namespace OpenSim.Server.Handlers.Simulation
destination.RegionID = regionID;
string reason;
float dummyVersion;
bool result = m_SimulationService.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, out dummyVersion, out reason);
// We're sending the version numbers down to the local connector to do the varregion check.
EntityTransferContext ctx = new EntityTransferContext();
ctx.InboundVersion = inboundVersion;
ctx.OutboundVersion = outboundVersion;
bool result = m_SimulationService.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, ctx, out reason);
resp["success"] = OSD.FromBoolean(result);
resp["reason"] = OSD.FromString(reason);
string legacyVersion = String.Format("SIMULATION/{0}", version);
resp["version"] = OSD.FromString(legacyVersion);
resp["negotiated_inbound_version"] = OSD.FromReal(version); //inboundVersion);
resp["negotiated_outbound_version"] = OSD.FromReal(version); //outboundVersion);
resp["negotiated_inbound_version"] = OSD.FromReal(inboundVersion);
resp["negotiated_outbound_version"] = OSD.FromReal(outboundVersion);
resp["variable_wearables_count_supported"] = OSD.FromBoolean(true);
OSDArray featuresWanted = new OSDArray();

View File

@ -282,10 +282,9 @@ namespace OpenSim.Services.Connectors.Simulation
}
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> featuresAvailable, out float version, out string reason)
public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> featuresAvailable, EntityTransferContext ctx, out string reason)
{
reason = "Failed to contact destination";
version = 0f;
// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position);
@ -333,22 +332,26 @@ namespace OpenSim.Services.Connectors.Simulation
// TODO: lay the pipe for version plumbing
if (data.ContainsKey("negotiated_inbound_version") && data["negotiated_inbound_version"] != null)
{
version = (float)data["negotiated_version"].AsReal();
ctx.InboundVersion = (float)data["negotiated_inbound_version"].AsReal();
ctx.OutboundVersion = (float)data["negotiated_outbound_version"].AsReal();
}
else if (data["version"] != null && data["version"].AsString() != string.Empty)
{
string versionString = data["version"].AsString();
String[] parts = versionString.Split(new char[] {'/'});
if (parts.Length > 1)
version = float.Parse(parts[1]);
{
ctx.InboundVersion = float.Parse(parts[1]);
ctx.OutboundVersion = float.Parse(parts[1]);
}
}
m_log.DebugFormat(
"[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}, reason {2}, version SIMULATION/{3}",
uri, success, reason, version);
"[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}, reason {2}, version {3}/{4}",
uri, success, reason, ctx.InboundVersion, ctx.OutboundVersion);
}
if (!success || version == 0f)
if (!success || ctx.InboundVersion == 0f || ctx.OutboundVersion == 0f)
{
// If we don't check this then OpenSimulator 0.7.3.1 and some period before will never see the
// actual failure message

View File

@ -452,11 +452,11 @@ namespace OpenSim.Services.HypergridService
m_log.DebugFormat("[GATEKEEPER SERVICE]: Launching {0}, Teleport Flags: {1}", aCircuit.Name, loginFlag);
float version;
EntityTransferContext ctx = new EntityTransferContext();
if (!m_SimulationService.QueryAccess(
destination, aCircuit.AgentID, aCircuit.ServiceURLs["HomeURI"].ToString(),
true, aCircuit.startpos, new List<UUID>(), out version, out reason))
true, aCircuit.startpos, new List<UUID>(), ctx, out reason))
return false;
return m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, out reason);

View File

@ -34,6 +34,18 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Services.Interfaces
{
public class EntityTransferContext
{
public EntityTransferContext()
{
InboundVersion = VersionInfo.SimulationServiceVersionAcceptedMax;
OutboundVersion = VersionInfo.SimulationServiceVersionSupportedMax;
}
public float InboundVersion { get; set; }
public float OutboundVersion { get; set; }
}
public interface ISimulationService
{
/// <summary>
@ -92,7 +104,7 @@ namespace OpenSim.Services.Interfaces
/// <param name="version">Version that the target simulator is running</param>
/// <param name="reason">[out] Optional error message</param>
/// <returns>True: ok; False: not allowed</returns>
bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, out float version, out string reason);
bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, EntityTransferContext ctx, out string reason);
/// <summary>
/// Message from receiving region to departing region, telling it got contacted by the client.

View File

@ -983,10 +983,10 @@ namespace OpenSim.Services.LLLoginService
private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, TeleportFlags flags, out string reason)
{
float version;
EntityTransferContext ctx = new EntityTransferContext();
if (!simConnector.QueryAccess(
region, aCircuit.AgentID, null, true, aCircuit.startpos, new List<UUID>(), out version, out reason))
region, aCircuit.AgentID, null, true, aCircuit.startpos, new List<UUID>(), ctx, out reason))
return false;
return simConnector.CreateAgent(null, region, aCircuit, (uint)flags, out reason);