Fix issue where only one of multiple attachments on the same attachpoint for NPCs would be seen by other viewers.

It appears that at least Singularity 1.8.5 (but probably others) rely on attachment FromItemIDs being different to display more than one.
This commit resolves this by generating random IDs instead of always using UUID.Zero for NPCs.
Resolves http://opensimulator.org/mantis/view.php?id=7110
0.8.0.3
Justin Clark-Casey (justincc) 2014-05-01 22:24:21 +01:00
parent f0411dc128
commit c31d93cb6f
4 changed files with 74 additions and 7 deletions

View File

@ -5304,10 +5304,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//update.JointType = 0; //update.JointType = 0;
update.Material = data.Material; update.Material = data.Material;
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
if (data.ParentGroup.IsAttachment) if (data.ParentGroup.IsAttachment)
{ {
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID); update.NameValue
= Util.StringToBytes256(
string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID));
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
// m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending NameValue {0} for {1} {2} to {3}",
// Util.UTF8.GetString(update.NameValue), data.Name, data.LocalId, Name);
//
// m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}",
// update.State, data.Name, data.LocalId, Name);
} }
else else
{ {
@ -5318,10 +5330,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.State = data.ParentGroup.RootPart.Shape.State; update.State = data.ParentGroup.RootPart.Shape.State;
} }
// m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}",
// update.State, data.Name, data.LocalId, Name);
update.ObjectData = objectData; update.ObjectData = objectData;
update.ParentID = data.ParentID; update.ParentID = data.ParentID;
update.PathBegin = data.Shape.PathBegin; update.PathBegin = data.Shape.PathBegin;

View File

@ -991,6 +991,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return null; return null;
} }
else if (itemID == UUID.Zero)
{
// We need to have a FromItemID for multiple attachments on a single attach point to appear. This is
// true on Singularity 1.8.5 and quite possibly other viewers as well. As NPCs don't have an inventory
// we will satisfy this requirement by inserting a random UUID.
objatt.FromItemID = UUID.Random();
}
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat( m_log.DebugFormat(

View File

@ -178,8 +178,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
acd.lastname = lastname; acd.lastname = lastname;
acd.ServiceURLs = new Dictionary<string, object>(); acd.ServiceURLs = new Dictionary<string, object>();
AvatarAppearance npcAppearance = new AvatarAppearance(appearance, AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
true);
acd.Appearance = npcAppearance; acd.Appearance = npcAppearance;
/* /*

View File

@ -198,6 +198,59 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID)); Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID));
} }
[Test]
public void TestCreateWithMultiAttachments()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
SetUpScene();
// m_attMod.DebugLevel = 1;
UUID userId = TestHelpers.ParseTail(0x1);
UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
InventoryItemBase att1Item
= UserInventoryHelpers.CreateInventoryItem(
m_scene, "att1", TestHelpers.ParseTail(0x2), TestHelpers.ParseTail(0x3), sp.UUID, InventoryType.Object);
InventoryItemBase att2Item
= UserInventoryHelpers.CreateInventoryItem(
m_scene, "att2", TestHelpers.ParseTail(0x12), TestHelpers.ParseTail(0x13), sp.UUID, InventoryType.Object);
m_attMod.RezSingleAttachmentFromInventory(sp, att1Item.ID, (uint)AttachmentPoint.Chest);
m_attMod.RezSingleAttachmentFromInventory(sp, att2Item.ID, (uint)AttachmentPoint.Chest | 0x80);
UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
ScenePresence npc = m_scene.GetScenePresence(npcId);
// Check scene presence status
Assert.That(npc.HasAttachments(), Is.True);
List<SceneObjectGroup> attachments = npc.GetAttachments();
Assert.That(attachments.Count, Is.EqualTo(2));
// Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
// name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
// Assert.That(attSo.Name, Is.EqualTo(attName));
TestAttachedObject(attachments[0], AttachmentPoint.Chest, npc.UUID);
TestAttachedObject(attachments[1], AttachmentPoint.Chest, npc.UUID);
// Attached objects on the same point must have different FromItemIDs to be shown to other avatars, at least
// on Singularity 1.8.5. Otherwise, only one (the first ObjectUpdate sent) appears.
Assert.AreNotEqual(attachments[0].FromItemID, attachments[1].FromItemID);
}
private void TestAttachedObject(SceneObjectGroup attSo, AttachmentPoint attPoint, UUID ownerId)
{
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)attPoint));
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
Assert.That(attSo.IsTemporary, Is.False);
Assert.That(attSo.OwnerID, Is.EqualTo(ownerId));
}
[Test] [Test]
public void TestLoadAppearance() public void TestLoadAppearance()
{ {