diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index e2bdee01ac..edfc94fa09 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1785,11 +1785,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected void ReInstantiateScripts(ScenePresence sp) { + int i = 0; sp.Attachments.ForEach(delegate(SceneObjectGroup sog) { + sog.SetState(sp.InTransitScriptStates[i++], sp.Scene); sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); sog.ResumeScripts(); }); + + sp.InTransitScriptStates.Clear(); } #endregion diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index a165bbd123..184b2232f7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -594,9 +594,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } + + // This is a hook to do some per-asset post-processing for subclasses that need that + if (remoteClient != null) + ExportAsset(remoteClient.AgentId, assetID); + return assetID; } + protected virtual void ExportAsset(UUID agentID, UUID assetID) + { + // nothing to do here + } /// /// Rez an object into the scene from the user's inventory @@ -1025,9 +1034,5 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } #endregion - - protected virtual void ExportAsset(UUID agentID, UUID assetID) - { - } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 553b575b2c..079223d31e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -252,6 +252,16 @@ namespace OpenSim.Region.Framework.Scenes // holds the seed cap for the child agent in that region private Dictionary m_knownChildRegions = new Dictionary(); + /// + /// Copy of the script states while the agent is in transit. This state may + /// need to be placed back in case of transfer fail. + /// + public List InTransitScriptStates + { + get { return m_InTransitScriptStates; } + } + private List m_InTransitScriptStates = new List(); + /// /// Implemented Control Flags /// @@ -2812,6 +2822,7 @@ namespace OpenSim.Region.Framework.Scenes // vars to support reduced update frequency when velocity is unchanged private Vector3 lastVelocitySentToAllClients = Vector3.Zero; + private Vector3 lastPositionSentToAllClients = Vector3.Zero; private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount(); /// @@ -2821,14 +2832,29 @@ namespace OpenSim.Region.Framework.Scenes { int currentTick = Util.EnvironmentTickCount(); - // decrease update frequency when avatar is moving but velocity is not changing - if (m_velocity.Length() < 0.01f - || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f - || currentTick - lastTerseUpdateToAllClientsTick > 1500) + // Decrease update frequency when avatar is moving but velocity is + // not changing. + // If there is a mismatch between distance travelled and expected + // distance based on last velocity sent and velocity hasnt changed, + // then send a new terse update + + float timeSinceLastUpdate = (currentTick - lastTerseUpdateToAllClientsTick) * 0.001f; + + Vector3 expectedPosition = lastPositionSentToAllClients + lastVelocitySentToAllClients * timeSinceLastUpdate; + + float distanceError = Vector3.Distance(OffsetPosition, expectedPosition); + + float speed = Velocity.Length(); + float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); + + if (speed < 0.01f // allow rotation updates if avatar position is unchanged + || Math.Abs(distanceError) > 0.25f // arbitrary distance error threshold + || velocidyDiff > 0.01f) // did velocity change from last update? { m_perfMonMS = currentTick; - lastVelocitySentToAllClients = m_velocity; + lastVelocitySentToAllClients = Velocity; lastTerseUpdateToAllClientsTick = currentTick; + lastPositionSentToAllClients = OffsetPosition; m_scene.ForEachClient(SendTerseUpdateToClient); @@ -3543,6 +3569,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.AttachmentObjects = new List(); cAgent.AttachmentObjectStates = new List(); IScriptModule se = m_scene.RequestModuleInterface(); + m_InTransitScriptStates.Clear(); foreach (SceneObjectGroup sog in m_attachments) { // We need to make a copy and pass that copy @@ -3552,7 +3579,9 @@ namespace OpenSim.Region.Framework.Scenes ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; ((SceneObjectGroup)clone).RootPart.IsAttachment = false; cAgent.AttachmentObjects.Add(clone); - cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); + string state = sog.GetStateSnapshot(); + cAgent.AttachmentObjectStates.Add(state); + m_InTransitScriptStates.Add(state); // Let's remove the scripts of the original object here sog.RemoveScriptInstances(true); }