Check viewer 2/3 attachment calls against avatar appearance attachment data rather than actually attached objects

By checking against the grid's Avatar data, we can ignore viewer side attachments but still initiate these calls simulator-side.
Initiating simulator-side is always necessary for version 1 viewers.
This is a further commit to resolve http://opensimulator.org/mantis/view.php?id=6581
user_profiles
Justin Clark-Casey (justincc) 2013-03-29 23:10:28 +00:00
parent 23ae4c0a4d
commit 023faa227e
3 changed files with 23 additions and 26 deletions

View File

@ -256,10 +256,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{ {
// If we're an NPC then skip all the item checks and manipulations since we don't have an // If we're an NPC then skip all the item checks and manipulations since we don't have an
// inventory right now. // inventory right now.
if (sp.PresenceType == PresenceType.Npc) RezSingleAttachmentFromInventoryInternal(
RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, true); sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p | (uint)0x80);
else
RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80);
} }
catch (Exception e) catch (Exception e)
{ {
@ -456,26 +454,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
"[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
(AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
bool append = (AttachmentPt & 0x80) != 0; // We check the attachments in the avatar appearance here rather than the objects attached to the
AttachmentPt &= 0x7f; // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are
// already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done
// Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). // because pre-outfit folder viewers (most version 1 viewers) require it.
// This often happens during login - not sure the exact reason.
// For now, we will ignore the request. Unfortunately, this means that we need to dig through all the
// ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login
// before anything has actually been attached.
bool alreadyOn = false; bool alreadyOn = false;
List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); List<AvatarAttachment> existingAttachments = sp.Appearance.GetAttachments();
foreach (SceneObjectGroup so in existingAttachments) foreach (AvatarAttachment existingAttachment in existingAttachments)
{ {
if (so.FromItemID == itemID) if (existingAttachment.ItemID == itemID)
{ {
alreadyOn = true; alreadyOn = true;
break; break;
} }
} }
// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
if (alreadyOn) if (alreadyOn)
{ {
if (DebugLevel > 0) if (DebugLevel > 0)
@ -486,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return null; return null;
} }
return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
} }
public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@ -495,7 +488,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return; return;
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); m_log.DebugFormat(
"[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}",
rezlist.Count, sp.Name, m_scene.Name);
foreach (KeyValuePair<UUID, uint> rez in rezlist) foreach (KeyValuePair<UUID, uint> rez in rezlist)
{ {
@ -894,11 +889,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt)
{ {
if (m_invAccessModule == null) if (m_invAccessModule == null)
return null; return null;
bool append = (attachmentPt & 0x80) != 0;
attachmentPt &= 0x7f;
SceneObjectGroup objatt; SceneObjectGroup objatt;
if (itemID != UUID.Zero) if (itemID != UUID.Zero)

View File

@ -130,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
config.AddConfig("Modules"); config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
modules.Add(new AttachmentsModule()); AttachmentsModule attMod = new AttachmentsModule();
attMod.DebugLevel = 1;
modules.Add(attMod);
modules.Add(new BasicInventoryAccessModule()); modules.Add(new BasicInventoryAccessModule());
} }
@ -728,7 +730,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
public void TestRezAttachmentsOnAvatarEntrance() public void TestRezAttachmentsOnAvatarEntrance()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // TestHelpers.EnableLogging();
Scene scene = CreateTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);

View File

@ -955,15 +955,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
// Viewers which have a current outfit folder will actually rez their own attachments. However, // Viewers which have a current outfit folder will actually rez their own attachments. However,
// viewers without (e.g. v1 viewers) will not, so we still need to make this call. // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
//
// However, we leave a 5 second pause to try and avoid a clash with viewers that are rezzing
// attachments themselves. This should then mean that this call ends up doing nothing.
if (Scene.AttachmentsModule != null) if (Scene.AttachmentsModule != null)
Util.FireAndForget( Util.FireAndForget(
o => o =>
{ {
if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) // if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None)
System.Threading.Thread.Sleep(5000); // System.Threading.Thread.Sleep(7000);
Scene.AttachmentsModule.RezAttachments(this); Scene.AttachmentsModule.RezAttachments(this);
}); });