diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 94bf3aaffc..e0823b23e7 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -55,9 +55,9 @@ namespace OpenSim.Framework UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID); - public delegate void RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); + public delegate UUID RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); - public delegate void ObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot); + public delegate void ObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent); public delegate void ModifyTerrain( float height, float seconds, byte size, byte action, float north, float west, float south, float east, diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index dee5d80efd..1a0fb2930d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4293,7 +4293,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (att.ObjectData.Length > 0) { - handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation); + handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation, false); } } } diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs index f51a5e2d38..c4c2ffdb1b 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs @@ -1116,7 +1116,9 @@ namespace OpenSim.Region.Communications.OGS1 if (remObject != null) { + m_log.DebugFormat("[INTERREGION]: Sending prim crossing message for prim {0}", primID.ToString()); retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod); + m_log.DebugFormat("[INTERREGION]: Return from prim crossing message for prim {0}: {1}", primID.ToString(), retValue.ToString()); } else { @@ -1497,6 +1499,7 @@ namespace OpenSim.Region.Communications.OGS1 /// public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod) { + m_log.DebugFormat("[INTERREGION]: Got prim crosssing request for {0}", primID); m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod); return true; diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 3f934c9ebf..782b4310ce 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -32,7 +32,6 @@ using System.IO; using System.Net; using System.Reflection; using System.Text; -using System.Timers; using System.Xml; using OpenMetaverse; using log4net; @@ -71,12 +70,10 @@ namespace OpenSim.Region.DataSnapshot public string m_hostname = "127.0.0.1"; //Update timers - private Timer m_periodic = null; private int m_period = 20; // in seconds private int m_maxStales = 500; private int m_stales = 0; - private Timer m_passedCheck = null; - private bool m_periodPassed = false; + private int m_lastUpdate = 0; //Program objects private SnapshotStore m_snapStore = null; @@ -126,6 +123,7 @@ namespace OpenSim.Region.DataSnapshot { m_disabledModules.Add(bloody_wanker); } + m_lastUpdate = System.Environment.TickCount; } catch (Exception) { @@ -137,17 +135,6 @@ namespace OpenSim.Region.DataSnapshot if (m_enabled) { - //Create update timer - m_periodic = new Timer(); - m_periodic.Interval = m_period * 1000; - m_periodic.Elapsed += SnapshotTimerCallback; - - //Create update eligibility timer - m_passedCheck = new Timer(); - m_passedCheck.Interval = m_period * 1000; - m_passedCheck.Elapsed += UpdateEligibilityCallback; - m_passedCheck.Start(); - //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer new DataRequestHandler(scene, this); @@ -253,6 +240,8 @@ namespace OpenSim.Region.DataSnapshot */ public XmlDocument GetSnapshot(string regionName) { + CheckStale(); + XmlDocument requestedSnap = new XmlDocument(); requestedSnap.AppendChild(requestedSnap.CreateXmlDeclaration("1.0", null, null)); requestedSnap.AppendChild(requestedSnap.CreateWhitespace("\r\n")); @@ -369,40 +358,36 @@ namespace OpenSim.Region.DataSnapshot //Behavior here: Wait m_period seconds, then update if there has not been a request in m_period seconds //or m_maxStales has been exceeded m_stales++; + } - if ((m_stales >= m_maxStales) && m_periodPassed) - SnapshotTimerCallback(m_periodic, null); - else if (m_periodic.Enabled == false) - m_periodic.Start(); + private void CheckStale() + { + // Wrap check + if (System.Environment.TickCount < m_lastUpdate) + { + m_lastUpdate = System.Environment.TickCount; + } + + if (m_stales >= m_maxStales) + { + if (System.Environment.TickCount - m_lastUpdate >= 20000) + { + m_stales = 0; + m_lastUpdate = System.Environment.TickCount; + MakeEverythingStale(); + } + } else { - m_periodic.Stop(); - m_periodic.Start(); + if (m_lastUpdate + 1000 * m_period < System.Environment.TickCount) + { + m_stales = 0; + m_lastUpdate = System.Environment.TickCount; + MakeEverythingStale(); + } } } - private void SnapshotTimerCallback(object timer, ElapsedEventArgs args) - { - m_log.Debug("[DATASNAPSHOT]: Marking scenes for snapshot updates."); - - //Finally generate those snapshot updates - MakeEverythingStale(); - - //Stop the update delay timer - m_periodic.Stop(); - - //Reset the eligibility flag and timer - m_periodPassed = false; - m_passedCheck.Stop(); - m_passedCheck.Start(); - } - - private void UpdateEligibilityCallback(object timer, ElapsedEventArgs args) - { - //Set eligibility, so we can start making updates - m_periodPassed = true; - } - public void MakeEverythingStale() { m_log.Debug("[DATASNAPSHOT]: Marking all scenes as stale."); diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs index c77de96c29..12e0f0fc24 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.DataSnapshot.Providers client.OnGrabUpdate += delegate(UUID objectID, Vector3 offset, Vector3 grapPos, IClientAPI remoteClient, List surfaceArgs) { this.Stale = true; }; client.OnObjectAttach += delegate(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, - Quaternion rot) { this.Stale = true; }; + Quaternion rot, bool silent) { this.Stale = true; }; client.OnObjectDuplicate += delegate(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID) { this.Stale = true; }; client.OnObjectDuplicateOnRay += delegate(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs index edf5ec1322..9d812627b2 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs @@ -262,7 +262,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); scene.SendKillObject(scene.Entities[uuid].LocalId); scene.m_innerScene.DeleteSceneObject(uuid, false); - ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(); + ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(false); } catch(Exception e) { diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs index d6fca7b6db..16edc2c60e 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs @@ -211,14 +211,13 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement public void SendFullUpdate(IClientAPI client, uint clientFlags) { - m_Entity.SendFullUpdateToClient(client, clientFlags); + m_Entity.SendFullUpdateToClient(client); } public void SendFullUpdateToAll() { - uint clientFlags = 0; m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) - { m_Entity.SendFullUpdateToClient(controller, clientFlags); } + { m_Entity.SendFullUpdateToClient(controller); } ); } diff --git a/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs index 827540d503..b6879b044c 100644 --- a/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs @@ -181,7 +181,7 @@ namespace OpenSim.Region.Environment.Modules.World.TreePopulator if (Util.RandomClass.NextDouble() < killLikelyhood) { - m_scene.DeleteSceneObject(selectedTree.ParentGroup); + m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); m_trees.Remove(selectedTree.ParentGroup.UUID); m_scene.ForEachClient(delegate(IClientAPI controller) diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 4e7494eecf..6c0f57b0e3 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -433,7 +433,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot) + protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) { // If we can't take it, we can't attach it! // @@ -447,7 +447,7 @@ namespace OpenSim.Region.Environment.Scenes // Calls attach with a Zero position // - AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero); + AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); } public SceneObjectGroup RezSingleAttachment( @@ -464,7 +464,7 @@ namespace OpenSim.Region.Environment.Scenes if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; - AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition); + AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); objatt.ScheduleGroupForFullUpdate(); if (tainted) objatt.HasGroupChanged = true; @@ -491,14 +491,14 @@ namespace OpenSim.Region.Environment.Scenes group.DetachToInventoryPrep(); m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(), group.OwnerID); - m_parentScene.DeleteSceneObject(group); + m_parentScene.DeleteSceneObject(group, false); } } } } protected internal void AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos) + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { List EntityList = GetEntities(); foreach (EntityBase obj in EntityList) @@ -553,7 +553,7 @@ namespace OpenSim.Region.Environment.Scenes m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); - group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos); + group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); // In case it is later dropped again, don't let // it get cleaned up // diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 42986ecbac..c59fffc209 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1601,7 +1601,7 @@ namespace OpenSim.Region.Environment.Scenes } else if (permissionToDelete) { - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } } @@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Environment.Scenes // Finally remove the item, for reals this time. if (permissionToDelete) - DeleteSceneObject(objectGroup); + DeleteSceneObject(objectGroup, false); } public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID) @@ -2279,7 +2279,7 @@ namespace OpenSim.Region.Environment.Scenes returnobjects[i] = null; - DeleteSceneObject(ObjectDeleting); + DeleteSceneObject(ObjectDeleting, false); ObjectDeleting = null; } else @@ -2320,7 +2320,7 @@ namespace OpenSim.Region.Environment.Scenes EventManager.TriggerStopScript(part.LocalId, itemID); } - public void RezSingleAttachment(IClientAPI remoteClient, UUID itemID, + public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { SceneObjectGroup att = m_innerScene.RezSingleAttachment(remoteClient, itemID, AttachmentPt); @@ -2328,13 +2328,13 @@ namespace OpenSim.Region.Environment.Scenes if (att == null) { DetachSingleAttachmentToInv(itemID, remoteClient); - return; + return UUID.Zero; } - RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); + return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); } - public void RezSingleAttachment(SceneObjectGroup att, + public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { if (att.RootPart != null) @@ -2351,11 +2351,12 @@ namespace OpenSim.Region.Environment.Scenes } } + return att.UUID; } public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos) { - m_innerScene.AttachObject(controllingClient, localID, attachPoint, rot, pos); + m_innerScene.AttachObject(controllingClient, localID, attachPoint, rot, pos, false); } public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index cee183ce4d..40f86056a0 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1831,7 +1831,7 @@ namespace OpenSim.Region.Environment.Scenes foreach (EntityBase e in entities) { if (e is SceneObjectGroup) - DeleteSceneObject((SceneObjectGroup)e); + DeleteSceneObject((SceneObjectGroup)e, false); } } } @@ -1840,7 +1840,7 @@ namespace OpenSim.Region.Environment.Scenes /// Delete the given object from the scene. /// /// - public void DeleteSceneObject(SceneObjectGroup group) + public void DeleteSceneObject(SceneObjectGroup group, bool silent) { //SceneObjectPart rootPart = group.GetChildPart(group.UUID); @@ -1866,7 +1866,7 @@ namespace OpenSim.Region.Environment.Scenes EventManager.TriggerParcelPrimCountTainted(); } - group.DeleteGroup(); + group.DeleteGroup(silent); } /// @@ -1982,7 +1982,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// the attempted out of region position of the scene object /// the scene object that we're crossing - public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp) + public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent) { if (grp == null) return; @@ -1994,7 +1994,7 @@ namespace OpenSim.Region.Environment.Scenes // We remove the object here try { - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } catch (Exception) { @@ -2044,7 +2044,7 @@ namespace OpenSim.Region.Environment.Scenes grp.OffsetForNewRegion(pos); // If we fail to cross the border, then reset the position of the scene object on that border. - if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp)) + if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent)) { grp.OffsetForNewRegion(oldGroupPosition); } @@ -2059,7 +2059,7 @@ namespace OpenSim.Region.Environment.Scenes /// true if the crossing itself was successful, false on failure /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region /// - public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp) + public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent) { bool successYN = false; int primcrossingXMLmethod = 0; @@ -2075,7 +2075,7 @@ namespace OpenSim.Region.Environment.Scenes // We remove the object here try { - DeleteSceneObject(grp); + DeleteSceneObject(grp, silent); } catch (Exception e) { @@ -2115,7 +2115,7 @@ namespace OpenSim.Region.Environment.Scenes /// public bool IncomingInterRegionPrimGroup(ulong regionHandle, UUID primID, string objXMLData, int XMLMethod) { - m_log.Warn("{[INTERREGION]: A new prim arrived from a neighbor"); + m_log.Warn("[INTERREGION]: A new prim arrived from a neighbor"); if (XMLMethod == 0) { SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData); @@ -2129,7 +2129,7 @@ namespace OpenSim.Region.Environment.Scenes SceneObjectGroup grp = RootPrim.ParentGroup; if (grp != null) { - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } m_log.Info("[INTERREGION]: Denied prim crossing for banned avatar"); @@ -2145,6 +2145,8 @@ namespace OpenSim.Region.Environment.Scenes { // Never persist + m_log.DebugFormat("[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.RootPart.LastOwnerID.ToString(), grp.UUID.ToString()); + grp.DetachFromBackup(); // Attachment @@ -2156,6 +2158,7 @@ namespace OpenSim.Region.Environment.Scenes // with the deeded object, it goes back to them grp.SetFromAssetID(grp.RootPart.LastOwnerID); + m_log.DebugFormat("[ATTACHMENT]: Attach to avatar {0}", sp.UUID.ToString()); AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition); } else @@ -4354,7 +4357,7 @@ namespace OpenSim.Region.Environment.Scenes if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) { if (grp.RootPart.Expires <= DateTime.Now) - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index fb8ec947be..be21460df2 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -675,8 +675,6 @@ namespace OpenSim.Region.Environment.Scenes // the avatar.Close below will clear the child region list. We need this below for (possibly) // closing the child agents, so save it here (we need a copy as it is Clear()-ed). List childRegions = new List(avatar.GetKnownRegionList()); - avatar.Close(); - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // failure at this point (unlike a border crossing failure). So perhaps this can never fail // once we reach here... @@ -712,11 +710,14 @@ namespace OpenSim.Region.Environment.Scenes avatar.MakeChildAgent(); Thread.Sleep(5000); - avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle); + avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); if (KiPrimitive != null) { KiPrimitive(avatar.LocalId); } + + avatar.Close(); + uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 2f2547821f..a19564fa1f 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -227,7 +227,7 @@ namespace OpenSim.Region.Environment.Scenes if ((val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) && !IsAttachment) { - m_scene.CrossPrimGroupIntoNewRegion(val, this); + m_scene.CrossPrimGroupIntoNewRegion(val, this, true); } lock (m_parts) @@ -319,7 +319,7 @@ namespace OpenSim.Region.Environment.Scenes { m_isSelected = value; // Tell physics engine that group is selected - if (m_rootPart.PhysActor != null) + if (m_rootPart != null && m_rootPart.PhysActor != null) { m_rootPart.PhysActor.Selected = value; // Pass it on to the children. @@ -746,7 +746,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset) + public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset, bool silent) { ScenePresence avatar = m_scene.GetScenePresence(agentID); if (avatar != null) @@ -777,19 +777,24 @@ namespace OpenSim.Region.Environment.Scenes SetAttachmentPoint(Convert.ToByte(attachmentpoint)); avatar.AddAttachment(this); - // Killing it here will cause the client to deselect it - // It then reappears on the avatar, deselected - // through the full update below - // - if (IsSelected) - { - m_scene.SendKillObject(m_rootPart.LocalId); - } - IsSelected = false; // fudge.... - ScheduleGroupForFullUpdate(); + if(!silent) + { + // Killing it here will cause the client to deselect it + // It then reappears on the avatar, deselected + // through the full update below + // + if (IsSelected) + { + m_scene.SendKillObject(m_rootPart.LocalId); + } + + IsSelected = false; // fudge.... + ScheduleGroupForFullUpdate(); + } } } + public byte GetAttachmentPoint() { if (m_rootPart != null) @@ -994,7 +999,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// Delete this group from its scene and tell all the scene presences about that deletion. /// - public void DeleteGroup() + public void DeleteGroup(bool silent) { // We need to keep track of this state in case this group is still queued for backup. // FIXME: This is a poor temporary solution, since it still leaves plenty of scope for race @@ -1018,8 +1023,11 @@ namespace OpenSim.Region.Environment.Scenes avatars[i].StandUp(); } - if (m_rootPart != null && part == m_rootPart) - avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); + if (!silent) + { + if (m_rootPart != null && part == m_rootPart) + avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); + } } } @@ -1257,13 +1265,16 @@ namespace OpenSim.Region.Environment.Scenes #region Client Updating - public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientFlags) + public void SendFullUpdateToClient(IClientAPI remoteClient) { + SendPartFullUpdate(remoteClient, RootPart, m_scene.ExternalChecks.ExternalChecksGenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - SendPartFullUpdate(remoteClient, part, clientFlags); + if (part != RootPart) + SendPartFullUpdate(remoteClient, part, m_scene.ExternalChecks.ExternalChecksGenerateClientFlags(remoteClient.AgentId, part.UUID)); } } } @@ -1626,11 +1637,14 @@ namespace OpenSim.Region.Environment.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { + RootPart.AddFullUpdateToAvatar(presence); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.AddFullUpdateToAvatar(presence); + if (part != RootPart) + part.AddFullUpdateToAvatar(presence); } } } @@ -1652,11 +1666,14 @@ namespace OpenSim.Region.Environment.Scenes public void ScheduleGroupForFullUpdate() { checkAtTargets(); + RootPart.ScheduleFullUpdate(); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.ScheduleFullUpdate(); + if (part != RootPart) + part.ScheduleFullUpdate(); } } } @@ -1680,11 +1697,14 @@ namespace OpenSim.Region.Environment.Scenes /// public void SendGroupFullUpdate() { + RootPart.SendFullUpdateToAllClients(); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.SendFullUpdateToAllClients(); + if (part != RootPart) + part.SendFullUpdateToAllClients(); } } } diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index db4ab52de9..ad12420f1c 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -114,8 +114,6 @@ namespace OpenSim.Region.Environment.Scenes private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f); private float m_godlevel = 0; - private bool m_attachmentsTransported = true; - private bool m_invulnerable = true; private Vector3 m_LastChildAgentUpdatePosition = new Vector3(); @@ -611,8 +609,10 @@ namespace OpenSim.Region.Environment.Scenes } foreach (EntityBase e in ents) + { if (e is SceneObjectGroup) m_pendingObjects.Enqueue((SceneObjectGroup)e); + } } } @@ -626,7 +626,7 @@ namespace OpenSim.Region.Environment.Scenes // So it's not implemented now. // - // Don't even queue if we have seent this one + // Don't even queue if we have sent this one // if (!m_updateTimes.ContainsKey(g.UUID)) g.ScheduleFullUpdateToAvatar(this); @@ -637,6 +637,8 @@ namespace OpenSim.Region.Environment.Scenes while (m_partsUpdateQueue.Count > 0) { SceneObjectPart part = m_partsUpdateQueue.Dequeue(); + if (part.ParentGroup == null || part.ParentGroup.RootPart == null) + continue; if (m_updateTimes.ContainsKey(part.UUID)) { ScenePartUpdate update = m_updateTimes[part.UUID]; @@ -680,12 +682,25 @@ namespace OpenSim.Region.Environment.Scenes { //never been sent to client before so do full update - part.SendFullUpdate(ControllingClient, - GenerateClientFlags(part.UUID)); + + // Attachment handling + // + if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) + { + if (part != part.ParentGroup.RootPart) + continue; + + part.ParentGroup.SendFullUpdateToClient(ControllingClient); + continue; + } + ScenePartUpdate update = new ScenePartUpdate(); update.FullID = part.UUID; update.LastFullUpdateTime = part.TimeStampFull; m_updateTimes.Add(part.UUID, update); + + part.SendFullUpdate(ControllingClient, + GenerateClientFlags(part.UUID)); updateCount++; } @@ -1115,7 +1130,7 @@ namespace OpenSim.Region.Environment.Scenes // { proxyObjectGroup.SendGroupFullUpdate(); remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - m_scene.DeleteSceneObject(proxyObjectGroup); + m_scene.DeleteSceneObject(proxyObjectGroup, false); // } // else // { @@ -2206,9 +2221,9 @@ namespace OpenSim.Region.Environment.Scenes // now we have a child agent in this region. Request all interesting data about other (root) agents SendInitialFullUpdateToAllClients(); - CrossAttachmentsIntoNewRegion(neighbourHandle); + CrossAttachmentsIntoNewRegion(neighbourHandle, true); - m_scene.SendKillObject(m_localId); +// m_scene.SendKillObject(m_localId); m_scene.NotifyMyCoarseLocationChange(); // the user may change their profile information in other region, @@ -2473,22 +2488,19 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_attachments) { - if (!m_attachmentsTransported) + try { - try + foreach (SceneObjectGroup grp in m_attachments) { - foreach (SceneObjectGroup grp in m_attachments) - { - // ControllingClient may be null at this point! - m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); - } + // ControllingClient may be null at this point! + m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); } - catch (InvalidOperationException) - { - m_log.Info("[CLIENT]: Couldn't save attachments. :("); - } - m_attachments.Clear(); } + catch (InvalidOperationException) + { + m_log.Info("[CLIENT]: Couldn't save attachments. :("); + } + m_attachments.Clear(); } lock (m_knownChildRegions) { @@ -2582,9 +2594,8 @@ namespace OpenSim.Region.Environment.Scenes return true; } - public bool CrossAttachmentsIntoNewRegion(ulong regionHandle) + public bool CrossAttachmentsIntoNewRegion(ulong regionHandle, bool silent) { - m_attachmentsTransported = true; lock (m_attachments) { // Validate @@ -2604,7 +2615,8 @@ namespace OpenSim.Region.Environment.Scenes gobj.RootPart.IsAttachment = false; gobj.AbsolutePosition = gobj.RootPart.AttachedPos; gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); - m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj); + m_log.DebugFormat("[ATTACHMENT]: Sending attachment {0} to region {1}", gobj.UUID, regionHandle); + m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj, silent); } } m_attachments.Clear(); @@ -3130,6 +3142,9 @@ namespace OpenSim.Region.Environment.Scenes private void ItemReceived(UUID itemID) { + if (IsChildAgent) + return; + if (null == m_appearance) { m_log.Warn("[ATTACHMENT] Appearance has not been initialized"); @@ -3143,14 +3158,20 @@ namespace OpenSim.Region.Environment.Scenes UUID asset = m_appearance.GetAttachedAsset(attachpoint); if (UUID.Zero == asset) // We have just logged in { - m_log.InfoFormat("[ATTACHMENT] Rez attachment {0}", - itemID.ToString()); - try { // Rez from inventory - m_scene.RezSingleAttachment(ControllingClient, itemID, - (uint)attachpoint); + asset = m_scene.RezSingleAttachment(ControllingClient, + itemID, (uint)attachpoint); + // Corner case: We are not yet a Scene Entity + // Setting attachment info in RezSingleAttachment will fail + // Set it here + // + m_appearance.SetAttachment((int)attachpoint, itemID, + asset); + m_log.InfoFormat("[ATTACHMENT] Rezzed attachment {0}, inworld asset {1}", + itemID.ToString(), asset); + } catch (Exception e) { @@ -3160,20 +3181,28 @@ namespace OpenSim.Region.Environment.Scenes return; } - SceneObjectPart att = m_scene.GetSceneObjectPart(m_appearance.GetAttachedAsset(attachpoint)); + SceneObjectPart att = m_scene.GetSceneObjectPart(asset); // If this is null, then the asset has not yet appeared in world // so we revisit this when it does // - if (att != null) + if (att != null && att.UUID != asset) // Yes. It's really needed { - m_log.InfoFormat("[ATTACHEMENT] Attach from world {0}", - itemID.ToString()); + m_log.DebugFormat("[ATTACHMENT]: Attach from in world: ItemID {0}, Asset ID {1}, Attachment inworld: {2}", itemID.ToString(), asset.ToString(), att.UUID.ToString()); - // Attach from world, if not already attached - if (att.ParentGroup != null && !att.IsAttachment) - m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, (uint)0, att.ParentGroup.GroupRotation, Vector3.Zero); + // This will throw if crossing katty-korner + // So catch it here to avoid the noid + // + try + { + // Attach from world, if not already attached + if (att.ParentGroup != null && !att.IsAttachment) + m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, (uint)0, att.ParentGroup.GroupRotation, Vector3.Zero); + } + catch (System.NullReferenceException e) + { + } } } } diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs index 9ad4897278..910bb280c1 100644 --- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs +++ b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.Examples.SimpleModule if (m_parts.Count == 1) { m_parts.Remove(m_rootPart.UUID); - m_scene.DeleteSceneObject(this); + m_scene.DeleteSceneObject(this, false); remoteClient.SendKillObject(m_regionHandle, m_rootPart.LocalId); remoteClient.AddMoney(50); remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs index 918898c4b6..5ac57c2487 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs @@ -198,7 +198,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine lastLocalID); if (part != null && part.ParentGroup != null) lastScriptEngine.World.DeleteSceneObject( - part.ParentGroup); + part.ParentGroup, false); } catch (Exception e) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 9d07de20c8..98d7bbe0fa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -641,7 +641,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { m_InSelfDelete = true; if (part != null && part.ParentGroup != null) - m_Engine.World.DeleteSceneObject(part.ParentGroup); + m_Engine.World.DeleteSceneObject(part.ParentGroup, false); } } }