Attachments, attachments, and, did I say attachments?

Too many fixes to list.
0.6.0-stable
Melanie Thielker 2008-11-07 05:48:44 +00:00
parent f0bf3df024
commit 48c6d052d9
17 changed files with 180 additions and 139 deletions

View File

@ -55,9 +55,9 @@ namespace OpenSim.Framework
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
bool RezSelected, bool RemoveItem, UUID fromTaskID); 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( public delegate void ModifyTerrain(
float height, float seconds, byte size, byte action, float north, float west, float south, float east, float height, float seconds, byte size, byte action, float north, float west, float south, float east,

View File

@ -4293,7 +4293,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (att.ObjectData.Length > 0) 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);
} }
} }
} }

View File

@ -1116,7 +1116,9 @@ namespace OpenSim.Region.Communications.OGS1
if (remObject != null) if (remObject != null)
{ {
m_log.DebugFormat("[INTERREGION]: Sending prim crossing message for prim {0}", primID.ToString());
retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod); 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 else
{ {
@ -1497,6 +1499,7 @@ namespace OpenSim.Region.Communications.OGS1
/// <returns></returns> /// <returns></returns>
public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod) 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); m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod);
return true; return true;

View File

@ -32,7 +32,6 @@ using System.IO;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Timers;
using System.Xml; using System.Xml;
using OpenMetaverse; using OpenMetaverse;
using log4net; using log4net;
@ -71,12 +70,10 @@ namespace OpenSim.Region.DataSnapshot
public string m_hostname = "127.0.0.1"; public string m_hostname = "127.0.0.1";
//Update timers //Update timers
private Timer m_periodic = null;
private int m_period = 20; // in seconds private int m_period = 20; // in seconds
private int m_maxStales = 500; private int m_maxStales = 500;
private int m_stales = 0; private int m_stales = 0;
private Timer m_passedCheck = null; private int m_lastUpdate = 0;
private bool m_periodPassed = false;
//Program objects //Program objects
private SnapshotStore m_snapStore = null; private SnapshotStore m_snapStore = null;
@ -126,6 +123,7 @@ namespace OpenSim.Region.DataSnapshot
{ {
m_disabledModules.Add(bloody_wanker); m_disabledModules.Add(bloody_wanker);
} }
m_lastUpdate = System.Environment.TickCount;
} }
catch (Exception) catch (Exception)
{ {
@ -137,17 +135,6 @@ namespace OpenSim.Region.DataSnapshot
if (m_enabled) 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 //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer
new DataRequestHandler(scene, this); new DataRequestHandler(scene, this);
@ -253,6 +240,8 @@ namespace OpenSim.Region.DataSnapshot
*/ */
public XmlDocument GetSnapshot(string regionName) public XmlDocument GetSnapshot(string regionName)
{ {
CheckStale();
XmlDocument requestedSnap = new XmlDocument(); XmlDocument requestedSnap = new XmlDocument();
requestedSnap.AppendChild(requestedSnap.CreateXmlDeclaration("1.0", null, null)); requestedSnap.AppendChild(requestedSnap.CreateXmlDeclaration("1.0", null, null));
requestedSnap.AppendChild(requestedSnap.CreateWhitespace("\r\n")); 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 //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 //or m_maxStales has been exceeded
m_stales++; m_stales++;
}
if ((m_stales >= m_maxStales) && m_periodPassed) private void CheckStale()
SnapshotTimerCallback(m_periodic, null); {
else if (m_periodic.Enabled == false) // Wrap check
m_periodic.Start(); 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 else
{ {
m_periodic.Stop(); if (m_lastUpdate + 1000 * m_period < System.Environment.TickCount)
m_periodic.Start(); {
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() public void MakeEverythingStale()
{ {
m_log.Debug("[DATASNAPSHOT]: Marking all scenes as stale."); m_log.Debug("[DATASNAPSHOT]: Marking all scenes as stale.");

View File

@ -70,7 +70,7 @@ namespace OpenSim.Region.DataSnapshot.Providers
client.OnGrabUpdate += delegate(UUID objectID, Vector3 offset, Vector3 grapPos, client.OnGrabUpdate += delegate(UUID objectID, Vector3 offset, Vector3 grapPos,
IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) { this.Stale = true; }; IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) { this.Stale = true; };
client.OnObjectAttach += delegate(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, 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, client.OnObjectDuplicate += delegate(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID,
UUID GroupID) { this.Stale = true; }; UUID GroupID) { this.Stale = true; };
client.OnObjectDuplicateOnRay += delegate(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, client.OnObjectDuplicateOnRay += delegate(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,

View File

@ -262,7 +262,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
scene.SendKillObject(scene.Entities[uuid].LocalId); scene.SendKillObject(scene.Entities[uuid].LocalId);
scene.m_innerScene.DeleteSceneObject(uuid, false); scene.m_innerScene.DeleteSceneObject(uuid, false);
((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(); ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(false);
} }
catch(Exception e) catch(Exception e)
{ {

View File

@ -211,14 +211,13 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
public void SendFullUpdate(IClientAPI client, uint clientFlags) public void SendFullUpdate(IClientAPI client, uint clientFlags)
{ {
m_Entity.SendFullUpdateToClient(client, clientFlags); m_Entity.SendFullUpdateToClient(client);
} }
public void SendFullUpdateToAll() public void SendFullUpdateToAll()
{ {
uint clientFlags = 0;
m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller)
{ m_Entity.SendFullUpdateToClient(controller, clientFlags); } { m_Entity.SendFullUpdateToClient(controller); }
); );
} }

View File

@ -181,7 +181,7 @@ namespace OpenSim.Region.Environment.Modules.World.TreePopulator
if (Util.RandomClass.NextDouble() < killLikelyhood) if (Util.RandomClass.NextDouble() < killLikelyhood)
{ {
m_scene.DeleteSceneObject(selectedTree.ParentGroup); m_scene.DeleteSceneObject(selectedTree.ParentGroup, false);
m_trees.Remove(selectedTree.ParentGroup.UUID); m_trees.Remove(selectedTree.ParentGroup.UUID);
m_scene.ForEachClient(delegate(IClientAPI controller) m_scene.ForEachClient(delegate(IClientAPI controller)

View File

@ -433,7 +433,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="objectLocalID"></param> /// <param name="objectLocalID"></param>
/// <param name="AttachmentPt"></param> /// <param name="AttachmentPt"></param>
/// <param name="rot"></param> /// <param name="rot"></param>
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! // 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 // Calls attach with a Zero position
// //
AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero); AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false);
} }
public SceneObjectGroup RezSingleAttachment( public SceneObjectGroup RezSingleAttachment(
@ -464,7 +464,7 @@ namespace OpenSim.Region.Environment.Scenes
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
tainted = true; tainted = true;
AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition); AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
objatt.ScheduleGroupForFullUpdate(); objatt.ScheduleGroupForFullUpdate();
if (tainted) if (tainted)
objatt.HasGroupChanged = true; objatt.HasGroupChanged = true;
@ -491,14 +491,14 @@ namespace OpenSim.Region.Environment.Scenes
group.DetachToInventoryPrep(); group.DetachToInventoryPrep();
m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(), group.OwnerID); m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(), group.OwnerID);
m_parentScene.DeleteSceneObject(group); m_parentScene.DeleteSceneObject(group, false);
} }
} }
} }
} }
protected internal void AttachObject( 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<EntityBase> EntityList = GetEntities(); List<EntityBase> EntityList = GetEntities();
foreach (EntityBase obj in EntityList) foreach (EntityBase obj in EntityList)
@ -553,7 +553,7 @@ namespace OpenSim.Region.Environment.Scenes
m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); 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 // In case it is later dropped again, don't let
// it get cleaned up // it get cleaned up
// //

View File

@ -1601,7 +1601,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
else if (permissionToDelete) 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. // Finally remove the item, for reals this time.
if (permissionToDelete) if (permissionToDelete)
DeleteSceneObject(objectGroup); DeleteSceneObject(objectGroup, false);
} }
public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID) public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID)
@ -2279,7 +2279,7 @@ namespace OpenSim.Region.Environment.Scenes
returnobjects[i] = null; returnobjects[i] = null;
DeleteSceneObject(ObjectDeleting); DeleteSceneObject(ObjectDeleting, false);
ObjectDeleting = null; ObjectDeleting = null;
} }
else else
@ -2320,7 +2320,7 @@ namespace OpenSim.Region.Environment.Scenes
EventManager.TriggerStopScript(part.LocalId, itemID); EventManager.TriggerStopScript(part.LocalId, itemID);
} }
public void RezSingleAttachment(IClientAPI remoteClient, UUID itemID, public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID,
uint AttachmentPt) uint AttachmentPt)
{ {
SceneObjectGroup att = m_innerScene.RezSingleAttachment(remoteClient, itemID, AttachmentPt); SceneObjectGroup att = m_innerScene.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
@ -2328,13 +2328,13 @@ namespace OpenSim.Region.Environment.Scenes
if (att == null) if (att == null)
{ {
DetachSingleAttachmentToInv(itemID, remoteClient); 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) IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{ {
if (att.RootPart != null) 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) 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) public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)

View File

@ -1831,7 +1831,7 @@ namespace OpenSim.Region.Environment.Scenes
foreach (EntityBase e in entities) foreach (EntityBase e in entities)
{ {
if (e is SceneObjectGroup) 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. /// Delete the given object from the scene.
/// </summary> /// </summary>
/// <param name="group"></param> /// <param name="group"></param>
public void DeleteSceneObject(SceneObjectGroup group) public void DeleteSceneObject(SceneObjectGroup group, bool silent)
{ {
//SceneObjectPart rootPart = group.GetChildPart(group.UUID); //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
@ -1866,7 +1866,7 @@ namespace OpenSim.Region.Environment.Scenes
EventManager.TriggerParcelPrimCountTainted(); EventManager.TriggerParcelPrimCountTainted();
} }
group.DeleteGroup(); group.DeleteGroup(silent);
} }
/// <summary> /// <summary>
@ -1982,7 +1982,7 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary> /// </summary>
/// <param name="attemptedPosition">the attempted out of region position of the scene object</param> /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
/// <param name="grp">the scene object that we're crossing</param> /// <param name="grp">the scene object that we're crossing</param>
public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp) public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
{ {
if (grp == null) if (grp == null)
return; return;
@ -1994,7 +1994,7 @@ namespace OpenSim.Region.Environment.Scenes
// We remove the object here // We remove the object here
try try
{ {
DeleteSceneObject(grp); DeleteSceneObject(grp, false);
} }
catch (Exception) catch (Exception)
{ {
@ -2044,7 +2044,7 @@ namespace OpenSim.Region.Environment.Scenes
grp.OffsetForNewRegion(pos); grp.OffsetForNewRegion(pos);
// If we fail to cross the border, then reset the position of the scene object on that border. // 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); grp.OffsetForNewRegion(oldGroupPosition);
} }
@ -2059,7 +2059,7 @@ namespace OpenSim.Region.Environment.Scenes
/// true if the crossing itself was successful, false on failure /// 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 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
/// </returns> /// </returns>
public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp) public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent)
{ {
bool successYN = false; bool successYN = false;
int primcrossingXMLmethod = 0; int primcrossingXMLmethod = 0;
@ -2075,7 +2075,7 @@ namespace OpenSim.Region.Environment.Scenes
// We remove the object here // We remove the object here
try try
{ {
DeleteSceneObject(grp); DeleteSceneObject(grp, silent);
} }
catch (Exception e) catch (Exception e)
{ {
@ -2115,7 +2115,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <returns></returns> /// <returns></returns>
public bool IncomingInterRegionPrimGroup(ulong regionHandle, UUID primID, string objXMLData, int XMLMethod) 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) if (XMLMethod == 0)
{ {
SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData); SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData);
@ -2129,7 +2129,7 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectGroup grp = RootPrim.ParentGroup; SceneObjectGroup grp = RootPrim.ParentGroup;
if (grp != null) if (grp != null)
{ {
DeleteSceneObject(grp); DeleteSceneObject(grp, false);
} }
m_log.Info("[INTERREGION]: Denied prim crossing for banned avatar"); m_log.Info("[INTERREGION]: Denied prim crossing for banned avatar");
@ -2145,6 +2145,8 @@ namespace OpenSim.Region.Environment.Scenes
{ {
// Never persist // Never persist
m_log.DebugFormat("[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.RootPart.LastOwnerID.ToString(), grp.UUID.ToString());
grp.DetachFromBackup(); grp.DetachFromBackup();
// Attachment // Attachment
@ -2156,6 +2158,7 @@ namespace OpenSim.Region.Environment.Scenes
// with the deeded object, it goes back to them // with the deeded object, it goes back to them
grp.SetFromAssetID(grp.RootPart.LastOwnerID); 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); AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition);
} }
else else
@ -4354,7 +4357,7 @@ namespace OpenSim.Region.Environment.Scenes
if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
{ {
if (grp.RootPart.Expires <= DateTime.Now) if (grp.RootPart.Expires <= DateTime.Now)
DeleteSceneObject(grp); DeleteSceneObject(grp, false);
} }
} }
} }

View File

@ -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) // 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). // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
avatar.Close();
// Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // 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 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
// once we reach here... // once we reach here...
@ -712,11 +710,14 @@ namespace OpenSim.Region.Environment.Scenes
avatar.MakeChildAgent(); avatar.MakeChildAgent();
Thread.Sleep(5000); Thread.Sleep(5000);
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle); avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
if (KiPrimitive != null) if (KiPrimitive != null)
{ {
KiPrimitive(avatar.LocalId); KiPrimitive(avatar.LocalId);
} }
avatar.Close();
uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionX = (uint)(reg.RegionHandle >> 40);
uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);

View File

@ -227,7 +227,7 @@ namespace OpenSim.Region.Environment.Scenes
if ((val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) && !IsAttachment) 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) lock (m_parts)
@ -319,7 +319,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
m_isSelected = value; m_isSelected = value;
// Tell physics engine that group is selected // 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; m_rootPart.PhysActor.Selected = value;
// Pass it on to the children. // Pass it on to the children.
@ -746,7 +746,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="agentID"></param> /// <param name="agentID"></param>
/// <param name="attachmentpoint"></param> /// <param name="attachmentpoint"></param>
/// <param name="AttachOffset"></param> /// <param name="AttachOffset"></param>
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); ScenePresence avatar = m_scene.GetScenePresence(agentID);
if (avatar != null) if (avatar != null)
@ -777,19 +777,24 @@ namespace OpenSim.Region.Environment.Scenes
SetAttachmentPoint(Convert.ToByte(attachmentpoint)); SetAttachmentPoint(Convert.ToByte(attachmentpoint));
avatar.AddAttachment(this); 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.... if(!silent)
ScheduleGroupForFullUpdate(); {
// 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() public byte GetAttachmentPoint()
{ {
if (m_rootPart != null) if (m_rootPart != null)
@ -994,7 +999,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <summary> /// <summary>
/// Delete this group from its scene and tell all the scene presences about that deletion. /// Delete this group from its scene and tell all the scene presences about that deletion.
/// </summary> /// </summary>
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. // 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 // 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(); avatars[i].StandUp();
} }
if (m_rootPart != null && part == m_rootPart) if (!silent)
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); {
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 #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) lock (m_parts)
{ {
foreach (SceneObjectPart part in m_parts.Values) 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) public void ScheduleFullUpdateToAvatar(ScenePresence presence)
{ {
RootPart.AddFullUpdateToAvatar(presence);
lock (m_parts) lock (m_parts)
{ {
foreach (SceneObjectPart part in m_parts.Values) 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() public void ScheduleGroupForFullUpdate()
{ {
checkAtTargets(); checkAtTargets();
RootPart.ScheduleFullUpdate();
lock (m_parts) lock (m_parts)
{ {
foreach (SceneObjectPart part in m_parts.Values) foreach (SceneObjectPart part in m_parts.Values)
{ {
part.ScheduleFullUpdate(); if (part != RootPart)
part.ScheduleFullUpdate();
} }
} }
} }
@ -1680,11 +1697,14 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary> /// </summary>
public void SendGroupFullUpdate() public void SendGroupFullUpdate()
{ {
RootPart.SendFullUpdateToAllClients();
lock (m_parts) lock (m_parts)
{ {
foreach (SceneObjectPart part in m_parts.Values) foreach (SceneObjectPart part in m_parts.Values)
{ {
part.SendFullUpdateToAllClients(); if (part != RootPart)
part.SendFullUpdateToAllClients();
} }
} }
} }

View File

@ -114,8 +114,6 @@ namespace OpenSim.Region.Environment.Scenes
private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f); private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f);
private float m_godlevel = 0; private float m_godlevel = 0;
private bool m_attachmentsTransported = true;
private bool m_invulnerable = true; private bool m_invulnerable = true;
private Vector3 m_LastChildAgentUpdatePosition = new Vector3(); private Vector3 m_LastChildAgentUpdatePosition = new Vector3();
@ -611,8 +609,10 @@ namespace OpenSim.Region.Environment.Scenes
} }
foreach (EntityBase e in ents) foreach (EntityBase e in ents)
{
if (e is SceneObjectGroup) if (e is SceneObjectGroup)
m_pendingObjects.Enqueue((SceneObjectGroup)e); m_pendingObjects.Enqueue((SceneObjectGroup)e);
}
} }
} }
@ -626,7 +626,7 @@ namespace OpenSim.Region.Environment.Scenes
// So it's not implemented now. // 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)) if (!m_updateTimes.ContainsKey(g.UUID))
g.ScheduleFullUpdateToAvatar(this); g.ScheduleFullUpdateToAvatar(this);
@ -637,6 +637,8 @@ namespace OpenSim.Region.Environment.Scenes
while (m_partsUpdateQueue.Count > 0) while (m_partsUpdateQueue.Count > 0)
{ {
SceneObjectPart part = m_partsUpdateQueue.Dequeue(); SceneObjectPart part = m_partsUpdateQueue.Dequeue();
if (part.ParentGroup == null || part.ParentGroup.RootPart == null)
continue;
if (m_updateTimes.ContainsKey(part.UUID)) if (m_updateTimes.ContainsKey(part.UUID))
{ {
ScenePartUpdate update = m_updateTimes[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 //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(); ScenePartUpdate update = new ScenePartUpdate();
update.FullID = part.UUID; update.FullID = part.UUID;
update.LastFullUpdateTime = part.TimeStampFull; update.LastFullUpdateTime = part.TimeStampFull;
m_updateTimes.Add(part.UUID, update); m_updateTimes.Add(part.UUID, update);
part.SendFullUpdate(ControllingClient,
GenerateClientFlags(part.UUID));
updateCount++; updateCount++;
} }
@ -1115,7 +1130,7 @@ namespace OpenSim.Region.Environment.Scenes
// { // {
proxyObjectGroup.SendGroupFullUpdate(); proxyObjectGroup.SendGroupFullUpdate();
remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); 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 // 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 // now we have a child agent in this region. Request all interesting data about other (root) agents
SendInitialFullUpdateToAllClients(); SendInitialFullUpdateToAllClients();
CrossAttachmentsIntoNewRegion(neighbourHandle); CrossAttachmentsIntoNewRegion(neighbourHandle, true);
m_scene.SendKillObject(m_localId); // m_scene.SendKillObject(m_localId);
m_scene.NotifyMyCoarseLocationChange(); m_scene.NotifyMyCoarseLocationChange();
// the user may change their profile information in other region, // the user may change their profile information in other region,
@ -2473,22 +2488,19 @@ namespace OpenSim.Region.Environment.Scenes
{ {
lock (m_attachments) 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) lock (m_knownChildRegions)
{ {
@ -2582,9 +2594,8 @@ namespace OpenSim.Region.Environment.Scenes
return true; return true;
} }
public bool CrossAttachmentsIntoNewRegion(ulong regionHandle) public bool CrossAttachmentsIntoNewRegion(ulong regionHandle, bool silent)
{ {
m_attachmentsTransported = true;
lock (m_attachments) lock (m_attachments)
{ {
// Validate // Validate
@ -2604,7 +2615,8 @@ namespace OpenSim.Region.Environment.Scenes
gobj.RootPart.IsAttachment = false; gobj.RootPart.IsAttachment = false;
gobj.AbsolutePosition = gobj.RootPart.AttachedPos; gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); 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(); m_attachments.Clear();
@ -3130,6 +3142,9 @@ namespace OpenSim.Region.Environment.Scenes
private void ItemReceived(UUID itemID) private void ItemReceived(UUID itemID)
{ {
if (IsChildAgent)
return;
if (null == m_appearance) if (null == m_appearance)
{ {
m_log.Warn("[ATTACHMENT] Appearance has not been initialized"); m_log.Warn("[ATTACHMENT] Appearance has not been initialized");
@ -3143,14 +3158,20 @@ namespace OpenSim.Region.Environment.Scenes
UUID asset = m_appearance.GetAttachedAsset(attachpoint); UUID asset = m_appearance.GetAttachedAsset(attachpoint);
if (UUID.Zero == asset) // We have just logged in if (UUID.Zero == asset) // We have just logged in
{ {
m_log.InfoFormat("[ATTACHMENT] Rez attachment {0}",
itemID.ToString());
try try
{ {
// Rez from inventory // Rez from inventory
m_scene.RezSingleAttachment(ControllingClient, itemID, asset = m_scene.RezSingleAttachment(ControllingClient,
(uint)attachpoint); 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) catch (Exception e)
{ {
@ -3160,20 +3181,28 @@ namespace OpenSim.Region.Environment.Scenes
return; 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 // If this is null, then the asset has not yet appeared in world
// so we revisit this when it does // 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}", m_log.DebugFormat("[ATTACHMENT]: Attach from in world: ItemID {0}, Asset ID {1}, Attachment inworld: {2}", itemID.ToString(), asset.ToString(), att.UUID.ToString());
itemID.ToString());
// Attach from world, if not already attached // This will throw if crossing katty-korner
if (att.ParentGroup != null && !att.IsAttachment) // So catch it here to avoid the noid
m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, (uint)0, att.ParentGroup.GroupRotation, Vector3.Zero); //
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)
{
}
} }
} }
} }

View File

@ -122,7 +122,7 @@ namespace OpenSim.Region.Examples.SimpleModule
if (m_parts.Count == 1) if (m_parts.Count == 1)
{ {
m_parts.Remove(m_rootPart.UUID); m_parts.Remove(m_rootPart.UUID);
m_scene.DeleteSceneObject(this); m_scene.DeleteSceneObject(this, false);
remoteClient.SendKillObject(m_regionHandle, m_rootPart.LocalId); remoteClient.SendKillObject(m_regionHandle, m_rootPart.LocalId);
remoteClient.AddMoney(50); remoteClient.AddMoney(50);
remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);

View File

@ -198,7 +198,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
lastLocalID); lastLocalID);
if (part != null && part.ParentGroup != null) if (part != null && part.ParentGroup != null)
lastScriptEngine.World.DeleteSceneObject( lastScriptEngine.World.DeleteSceneObject(
part.ParentGroup); part.ParentGroup, false);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -641,7 +641,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{ {
m_InSelfDelete = true; m_InSelfDelete = true;
if (part != null && part.ParentGroup != null) if (part != null && part.ParentGroup != null)
m_Engine.World.DeleteSceneObject(part.ParentGroup); m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
} }
} }
} }