Attachments, attachments, and, did I say attachments?

Too many fixes to list.
This commit is contained in:
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

@@ -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)
{

View File

@@ -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); }
);
}

View File

@@ -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)

View File

@@ -433,7 +433,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="objectLocalID"></param>
/// <param name="AttachmentPt"></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!
//
@@ -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<EntityBase> 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
//

View File

@@ -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)

View File

@@ -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.
/// </summary>
/// <param name="group"></param>
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);
}
/// <summary>
@@ -1982,7 +1982,7 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
/// <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>
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
/// </returns>
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
/// <returns></returns>
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);
}
}
}

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)
// 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());
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);

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)
{
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
/// <param name="agentID"></param>
/// <param name="attachmentpoint"></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);
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
/// <summary>
/// Delete this group from its scene and tell all the scene presences about that deletion.
/// </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.
// 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
/// </summary>
public void SendGroupFullUpdate()
{
RootPart.SendFullUpdateToAllClients();
lock (m_parts)
{
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 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)
{
}
}
}
}