mirror of
https://github.com/opensim/opensim.git
synced 2026-08-11 11:57:03 +08:00
Resolve merge commits, stage 1
This commit is contained in:
@@ -47,7 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected Scene m_scene = null;
|
||||
private Scene m_scene;
|
||||
private IDialogModule m_dialogModule;
|
||||
|
||||
public string Name { get { return "Attachments Module"; } }
|
||||
public Type ReplaceableInterface { get { return null; } }
|
||||
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
|
||||
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
|
||||
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
||||
// TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
|
||||
@@ -81,7 +83,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
|
||||
client.OnObjectAttach += AttachObject;
|
||||
client.OnObjectDetach += DetachObject;
|
||||
client.OnDetachAttachmentIntoInv += ShowDetachInUserInventory;
|
||||
client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
|
||||
client.OnObjectDrop += DetachSingleAttachmentToGround;
|
||||
}
|
||||
|
||||
public void UnsubscribeFromClientEvents(IClientAPI client)
|
||||
@@ -90,7 +93,77 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
|
||||
client.OnObjectAttach -= AttachObject;
|
||||
client.OnObjectDetach -= DetachObject;
|
||||
client.OnDetachAttachmentIntoInv -= ShowDetachInUserInventory;
|
||||
client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
|
||||
client.OnObjectDrop -= DetachSingleAttachmentToGround;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RezAttachments. This should only be called upon login on the first region.
|
||||
/// Attachment rezzings on crossings and TPs are done in a different way.
|
||||
/// </summary>
|
||||
public void RezAttachments(IScenePresence sp)
|
||||
{
|
||||
if (null == sp.Appearance)
|
||||
{
|
||||
m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
|
||||
return;
|
||||
}
|
||||
|
||||
List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
|
||||
foreach (AvatarAttachment attach in attachments)
|
||||
{
|
||||
uint p = (uint)attach.AttachPoint;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
|
||||
// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
// For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
|
||||
// But they're not used anyway, the item is being looked up for now, so let's proceed.
|
||||
//if (UUID.Zero == assetID)
|
||||
//{
|
||||
// m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
|
||||
// continue;
|
||||
//}
|
||||
|
||||
try
|
||||
{
|
||||
// If we're an NPC then skip all the item checks and manipulations since we don't have an
|
||||
// inventory right now.
|
||||
if (sp.PresenceType == PresenceType.Npc)
|
||||
RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p);
|
||||
else
|
||||
RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveChangedAttachments(IScenePresence sp)
|
||||
{
|
||||
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
||||
{
|
||||
if (grp.HasGroupChanged) // Resizer scripts?
|
||||
{
|
||||
grp.IsAttachment = false;
|
||||
grp.AbsolutePosition = grp.RootPart.AttachedPos;
|
||||
UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID);
|
||||
grp.IsAttachment = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
|
||||
{
|
||||
foreach (SceneObjectGroup sop in sp.GetAttachments())
|
||||
{
|
||||
sop.Scene.DeleteSceneObject(sop, silent);
|
||||
}
|
||||
|
||||
sp.ClearAttachments();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -102,10 +175,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// <param name="silent"></param>
|
||||
public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
|
||||
{
|
||||
m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject");
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
|
||||
// objectLocalID, remoteClient.Name, AttachmentPt, silent);
|
||||
|
||||
try
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we can't take it, we can't attach it!
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
|
||||
if (part == null)
|
||||
@@ -131,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
AttachmentPt &= 0x7f;
|
||||
|
||||
// Calls attach with a Zero position
|
||||
if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false))
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||
|
||||
@@ -144,73 +228,94 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}", e);
|
||||
m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return AttachObject(sp, group, AttachmentPt, silent);
|
||||
}
|
||||
|
||||
private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
|
||||
// group.Name, group.LocalId, sp.Name, AttachmentPt, silent);
|
||||
|
||||
if (sp.GetAttachments(attachmentPt).Contains(group))
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
|
||||
// group.Name, group.LocalId, sp.Name, AttachmentPt);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 attachPos = group.AbsolutePosition;
|
||||
|
||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||
// be removed when that functionality is implemented in opensim
|
||||
AttachmentPt &= 0x7f;
|
||||
attachmentPt &= 0x7f;
|
||||
|
||||
// If the attachment point isn't the same as the one previously used
|
||||
// set it's offset position = 0 so that it appears on the attachment point
|
||||
// and not in a weird location somewhere unknown.
|
||||
if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
|
||||
if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
|
||||
{
|
||||
attachPos = Vector3.Zero;
|
||||
}
|
||||
|
||||
// AttachmentPt 0 means the client chose to 'wear' the attachment.
|
||||
if (AttachmentPt == 0)
|
||||
if (attachmentPt == 0)
|
||||
{
|
||||
// Check object for stored attachment point
|
||||
AttachmentPt = (uint)group.GetAttachmentPoint();
|
||||
attachmentPt = group.AttachmentPoint;
|
||||
}
|
||||
|
||||
// if we still didn't find a suitable attachment point.......
|
||||
if (AttachmentPt == 0)
|
||||
if (attachmentPt == 0)
|
||||
{
|
||||
// Stick it on left hand with Zero Offset from the attachment point.
|
||||
AttachmentPt = (uint)AttachmentPoint.LeftHand;
|
||||
attachmentPt = (uint)AttachmentPoint.LeftHand;
|
||||
attachPos = Vector3.Zero;
|
||||
}
|
||||
|
||||
group.SetAttachmentPoint((byte)AttachmentPt);
|
||||
group.AttachmentPoint = attachmentPt;
|
||||
group.AbsolutePosition = attachPos;
|
||||
|
||||
// Remove any previous attachments
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
UUID itemID = UUID.Zero;
|
||||
if (sp != null)
|
||||
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||
|
||||
// At the moment we can only deal with a single attachment
|
||||
// We also don't want to do any of the inventory operations for an NPC.
|
||||
if (sp.PresenceType != PresenceType.Npc)
|
||||
{
|
||||
foreach (SceneObjectGroup grp in sp.Attachments)
|
||||
{
|
||||
if (grp.GetAttachmentPoint() == (byte)AttachmentPt)
|
||||
{
|
||||
itemID = grp.GetFromItemID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attachments.Count != 0)
|
||||
itemID = attachments[0].GetFromItemID();
|
||||
|
||||
if (itemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInv(itemID, remoteClient);
|
||||
}
|
||||
|
||||
if (group.GetFromItemID() == UUID.Zero)
|
||||
{
|
||||
m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
DetachSingleAttachmentToInv(itemID, sp);
|
||||
|
||||
itemID = group.GetFromItemID();
|
||||
if (itemID == UUID.Zero)
|
||||
itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID;
|
||||
|
||||
ShowAttachInUserInventory(sp, attachmentPt, itemID, group);
|
||||
}
|
||||
|
||||
ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group);
|
||||
|
||||
AttachToAgent(sp, group, AttachmentPt, attachPos, silent);
|
||||
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -226,12 +331,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
}
|
||||
}
|
||||
|
||||
public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
||||
public ISceneEntity RezSingleAttachmentFromInventory(
|
||||
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
||||
{
|
||||
return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true);
|
||||
}
|
||||
|
||||
public UUID RezSingleAttachmentFromInventory(
|
||||
public ISceneEntity RezSingleAttachmentFromInventory(
|
||||
IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus)
|
||||
{
|
||||
return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
|
||||
@@ -239,7 +345,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
public UUID RezSingleAttachmentFromInventory(
|
||||
IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
|
||||
{
|
||||
if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); return null; }
|
||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||
// be removed when that functionality is implemented in opensim
|
||||
AttachmentPt &= 0x7f;
|
||||
@@ -249,15 +358,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (updateInventoryStatus)
|
||||
{
|
||||
if (att == null)
|
||||
ShowDetachInUserInventory(itemID, remoteClient);
|
||||
DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
|
||||
else
|
||||
ShowAttachInUserInventory(att, remoteClient, itemID, AttachmentPt);
|
||||
ShowAttachInUserInventory(att, sp, itemID, AttachmentPt);
|
||||
}
|
||||
|
||||
if (null == att)
|
||||
return UUID.Zero;
|
||||
else
|
||||
return att.UUID;
|
||||
return att;
|
||||
}
|
||||
|
||||
protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
|
||||
@@ -266,12 +372,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
if (invAccess != null)
|
||||
{
|
||||
SceneObjectGroup objatt = invAccess.RezObject(remoteClient,
|
||||
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, remoteClient.AgentId, true);
|
||||
SceneObjectGroup objatt;
|
||||
|
||||
if (itemID != UUID.Zero)
|
||||
objatt = invAccess.RezObject(sp.ControllingClient,
|
||||
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
else
|
||||
objatt = invAccess.RezObject(sp.ControllingClient,
|
||||
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
||||
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
||||
// objatt.Name, remoteClient.Name, AttachmentPt);
|
||||
|
||||
if (objatt != null)
|
||||
@@ -281,17 +394,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// since scripts aren't running yet. So, clear it here.
|
||||
objatt.HasGroupChanged = false;
|
||||
bool tainted = false;
|
||||
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
|
||||
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
|
||||
tainted = true;
|
||||
|
||||
// This will throw if the attachment fails
|
||||
try
|
||||
{
|
||||
AttachObject(remoteClient, objatt, AttachmentPt, false);
|
||||
AttachObject(sp, objatt, attachmentPt, false);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
|
||||
objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
|
||||
|
||||
// Make sure the object doesn't stick around and bail
|
||||
sp.RemoveAttachment(objatt);
|
||||
m_scene.DeleteSceneObject(objatt, false);
|
||||
return null;
|
||||
}
|
||||
@@ -311,13 +429,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
objatt.ResumeScripts();
|
||||
|
||||
// Do this last so that event listeners have access to all the effects of the attachment
|
||||
//m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
|
||||
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
|
||||
itemID, remoteClient.Name, AttachmentPt);
|
||||
itemID, sp.Name, attachmentPt);
|
||||
}
|
||||
|
||||
return objatt;
|
||||
@@ -330,31 +448,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// Update the user inventory to the attachment of an item
|
||||
/// </summary>
|
||||
/// <param name="att"></param>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="itemID"></param>
|
||||
/// <param name="AttachmentPt"></param>
|
||||
/// <param name="attachmentPoint"></param>
|
||||
/// <returns></returns>
|
||||
protected UUID ShowAttachInUserInventory(
|
||||
SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
||||
private UUID ShowAttachInUserInventory(
|
||||
SceneObjectGroup att, IScenePresence sp, UUID itemID, uint attachmentPoint)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
|
||||
// remoteClient.Name, att.Name, itemID);
|
||||
// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}",
|
||||
// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt);
|
||||
|
||||
if (!att.IsDeleted)
|
||||
AttachmentPt = att.RootPart.AttachmentPoint;
|
||||
attachmentPoint = att.AttachmentPoint;
|
||||
|
||||
ScenePresence presence;
|
||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||
{
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
|
||||
if (m_scene.InventoryService != null)
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
|
||||
bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||
}
|
||||
bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
|
||||
return att.UUID;
|
||||
}
|
||||
@@ -362,12 +479,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// <summary>
|
||||
/// Update the user inventory to reflect an attachment
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="AttachmentPt"></param>
|
||||
/// <param name="itemID"></param>
|
||||
/// <param name="att"></param>
|
||||
protected void ShowAttachInUserInventory(
|
||||
IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
|
||||
private void ShowAttachInUserInventory(
|
||||
IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
|
||||
@@ -390,23 +507,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
|
||||
return;
|
||||
}
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
|
||||
|
||||
ScenePresence presence;
|
||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||
{
|
||||
// XXYY!!
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
|
||||
if (item == null)
|
||||
m_log.Error("[ATTACHMENT]: item == null");
|
||||
if (m_scene == null)
|
||||
m_log.Error("[ATTACHMENT]: m_scene == null");
|
||||
if (m_scene.InventoryService == null)
|
||||
m_log.Error("[ATTACHMENT]: m_scene.InventoryService == null");
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
}
|
||||
|
||||
public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
|
||||
@@ -414,12 +525,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
||||
if (group != null)
|
||||
{
|
||||
//group.DetachToGround();
|
||||
ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
|
||||
DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient)
|
||||
public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
|
||||
{
|
||||
ScenePresence presence;
|
||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||
@@ -430,34 +540,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
bool changed = presence.Appearance.DetachAttachment(itemID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||
}
|
||||
|
||||
DetachSingleAttachmentToInv(itemID, remoteClient);
|
||||
DetachSingleAttachmentToInv(itemID, presence);
|
||||
}
|
||||
}
|
||||
|
||||
public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient)
|
||||
public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient)
|
||||
{
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(itemID);
|
||||
if (part == null || part.ParentGroup == null)
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
|
||||
// remoteClient.Name, sceneObjectID);
|
||||
|
||||
SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
|
||||
|
||||
if (so == null)
|
||||
return;
|
||||
|
||||
if (part.ParentGroup.RootPart.AttachedAvatar != remoteClient.AgentId)
|
||||
if (so.AttachedAvatar != remoteClient.AgentId)
|
||||
return;
|
||||
|
||||
UUID inventoryID = part.ParentGroup.GetFromItemID();
|
||||
UUID inventoryID = so.GetFromItemID();
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
|
||||
// so.Name, so.LocalId, inventoryID);
|
||||
|
||||
ScenePresence presence;
|
||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||
{
|
||||
if (!m_scene.Permissions.CanRezObject(
|
||||
part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
|
||||
so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
|
||||
return;
|
||||
|
||||
bool changed = presence.Appearance.DetachAttachment(itemID);
|
||||
bool changed = presence.Appearance.DetachAttachment(inventoryID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||
|
||||
part.ParentGroup.DetachToGround();
|
||||
presence.RemoveAttachment(so);
|
||||
DetachSceneObjectToGround(so, presence);
|
||||
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
uuids.Add(inventoryID);
|
||||
@@ -465,12 +585,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
remoteClient.SendRemoveInventoryItem(inventoryID);
|
||||
}
|
||||
|
||||
m_scene.EventManager.TriggerOnAttach(part.ParentGroup.LocalId, itemID, UUID.Zero);
|
||||
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detach the given scene object to the ground.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
|
||||
/// </remarks>
|
||||
/// <param name="so">The scene object to detach.</param>
|
||||
/// <param name="sp">The scene presence from which the scene object is being detached.</param>
|
||||
private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
|
||||
{
|
||||
SceneObjectPart rootPart = so.RootPart;
|
||||
|
||||
rootPart.FromItemID = UUID.Zero;
|
||||
so.AbsolutePosition = sp.AbsolutePosition;
|
||||
so.AttachedAvatar = UUID.Zero;
|
||||
rootPart.SetParentLocalId(0);
|
||||
so.ClearPartAttachmentData();
|
||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
|
||||
so.HasGroupChanged = true;
|
||||
rootPart.Rezzed = DateTime.Now;
|
||||
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
so.AttachToBackup();
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
rootPart.ScheduleFullUpdate();
|
||||
rootPart.ClearUndoState();
|
||||
}
|
||||
|
||||
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
|
||||
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
|
||||
protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
|
||||
private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
|
||||
{
|
||||
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
|
||||
return;
|
||||
@@ -493,27 +640,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
group.DetachToInventoryPrep();
|
||||
m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
|
||||
|
||||
// If an item contains scripts, it's always changed.
|
||||
// This ensures script state is saved on detach
|
||||
foreach (SceneObjectPart p in group.Parts)
|
||||
if (p.Inventory.ContainsScripts())
|
||||
group.HasGroupChanged = true;
|
||||
// Prepare sog for storage
|
||||
group.AttachedAvatar = UUID.Zero;
|
||||
|
||||
UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID);
|
||||
group.ForEachPart(
|
||||
delegate(SceneObjectPart part)
|
||||
{
|
||||
// If there are any scripts,
|
||||
// then always trigger a new object and state persistence in UpdateKnownItem()
|
||||
if (part.Inventory.ContainsScripts())
|
||||
group.HasGroupChanged = true;
|
||||
}
|
||||
);
|
||||
|
||||
group.RootPart.SetParentLocalId(0);
|
||||
group.IsAttachment = false;
|
||||
group.AbsolutePosition = group.RootPart.AttachedPos;
|
||||
|
||||
UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
|
||||
m_scene.DeleteSceneObject(group, false);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
|
||||
{
|
||||
// First we save the
|
||||
// attachment point information, then we update the relative
|
||||
// positioning. Then we have to mark the object as NOT an
|
||||
// attachment. This is necessary in order to correctly save
|
||||
// and retrieve GroupPosition information for the attachment.
|
||||
// Finally, we restore the object's attachment status.
|
||||
uint attachmentPoint = sog.AttachmentPoint;
|
||||
sog.UpdateGroupPosition(pos);
|
||||
sog.IsAttachment = false;
|
||||
sog.AbsolutePosition = sog.RootPart.AttachedPos;
|
||||
sog.AttachmentPoint = attachmentPoint;
|
||||
sog.HasGroupChanged = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the attachment asset for the new sog details if they have changed.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
|
||||
/// these details are not stored on the region.
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="grp"></param>
|
||||
/// <param name="itemID"></param>
|
||||
@@ -524,15 +699,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
{
|
||||
if (!grp.HasGroupChanged)
|
||||
{
|
||||
m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID);
|
||||
m_log.DebugFormat(
|
||||
"[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
|
||||
grp.UUID, grp.AttachmentPoint);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
|
||||
grp.UUID, grp.GetAttachmentPoint());
|
||||
grp.UUID, grp.AttachmentPoint);
|
||||
|
||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
|
||||
@@ -564,20 +743,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// <summary>
|
||||
/// Attach this scene object to the given avatar.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This isn't publicly available since attachments should always perform the corresponding inventory
|
||||
/// operation (to show the attach in user inventory and update the asset with positional information).
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="so"></param>
|
||||
/// <param name="attachmentpoint"></param>
|
||||
/// <param name="attachOffset"></param>
|
||||
/// <param name="silent"></param>
|
||||
protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
|
||||
private void AttachToAgent(
|
||||
IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
|
||||
{
|
||||
|
||||
m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name,
|
||||
attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
|
||||
// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
||||
|
||||
so.DetachFromBackup();
|
||||
|
||||
@@ -585,12 +764,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
m_scene.DeleteFromStorage(so.UUID);
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
|
||||
so.RootPart.AttachedAvatar = avatar.UUID;
|
||||
|
||||
//Anakin Lohner bug #3839
|
||||
SceneObjectPart[] parts = so.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i].AttachedAvatar = avatar.UUID;
|
||||
so.AttachedAvatar = avatar.UUID;
|
||||
|
||||
if (so.RootPart.PhysActor != null)
|
||||
{
|
||||
@@ -600,10 +774,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
so.AbsolutePosition = attachOffset;
|
||||
so.RootPart.AttachedPos = attachOffset;
|
||||
so.RootPart.IsAttachment = true;
|
||||
|
||||
so.IsAttachment = true;
|
||||
so.RootPart.SetParentLocalId(avatar.LocalId);
|
||||
so.SetAttachmentPoint(Convert.ToByte(attachmentpoint));
|
||||
so.AttachmentPoint = attachmentpoint;
|
||||
|
||||
avatar.AddAttachment(so);
|
||||
|
||||
@@ -617,5 +790,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// it get cleaned up
|
||||
so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a scene object that was previously free in the scene as an attachment to an avatar.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="grp"></param>
|
||||
/// <returns>The user inventory item created that holds the attachment.</returns>
|
||||
private InventoryItemBase AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp)
|
||||
{
|
||||
// m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId);
|
||||
|
||||
Vector3 inventoryStoredPosition = new Vector3
|
||||
(((grp.AbsolutePosition.X > (int)Constants.RegionSize)
|
||||
? Constants.RegionSize - 6
|
||||
: grp.AbsolutePosition.X)
|
||||
,
|
||||
(grp.AbsolutePosition.Y > (int)Constants.RegionSize)
|
||||
? Constants.RegionSize - 6
|
||||
: grp.AbsolutePosition.Y,
|
||||
grp.AbsolutePosition.Z);
|
||||
|
||||
Vector3 originalPosition = grp.AbsolutePosition;
|
||||
|
||||
grp.AbsolutePosition = inventoryStoredPosition;
|
||||
|
||||
// If we're being called from a script, then trying to serialize that same script's state will not complete
|
||||
// in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
|
||||
// the client/server crashes rather than logging out normally, the attachment's scripts will resume
|
||||
// without state on relog. Arguably, this is what we want anyway.
|
||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
|
||||
|
||||
grp.AbsolutePosition = originalPosition;
|
||||
|
||||
AssetBase asset = m_scene.CreateAsset(
|
||||
grp.GetPartName(grp.LocalId),
|
||||
grp.GetPartDescription(grp.LocalId),
|
||||
(sbyte)AssetType.Object,
|
||||
Utils.StringToBytes(sceneObjectXml),
|
||||
remoteClient.AgentId);
|
||||
|
||||
m_scene.AssetService.Store(asset);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.CreatorId = grp.RootPart.CreatorID.ToString();
|
||||
item.CreatorData = grp.RootPart.CreatorData;
|
||||
item.Owner = remoteClient.AgentId;
|
||||
item.ID = UUID.Random();
|
||||
item.AssetID = asset.FullID;
|
||||
item.Description = asset.Description;
|
||||
item.Name = asset.Name;
|
||||
item.AssetType = asset.Type;
|
||||
item.InvType = (int)InventoryType.Object;
|
||||
|
||||
InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
|
||||
if (folder != null)
|
||||
item.Folder = folder.ID;
|
||||
else // oopsies
|
||||
item.Folder = UUID.Zero;
|
||||
|
||||
if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
|
||||
{
|
||||
item.BasePermissions = grp.RootPart.NextOwnerMask;
|
||||
item.CurrentPermissions = grp.RootPart.NextOwnerMask;
|
||||
item.NextPermissions = grp.RootPart.NextOwnerMask;
|
||||
item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
|
||||
item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.BasePermissions = grp.RootPart.BaseMask;
|
||||
item.CurrentPermissions = grp.RootPart.OwnerMask;
|
||||
item.NextPermissions = grp.RootPart.NextOwnerMask;
|
||||
item.EveryOnePermissions = grp.RootPart.EveryoneMask;
|
||||
item.GroupPermissions = grp.RootPart.GroupMask;
|
||||
}
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
|
||||
// sets itemID so client can show item as 'attached' in inventory
|
||||
grp.SetFromItemID(item.ID);
|
||||
|
||||
if (m_scene.AddInventoryItem(item))
|
||||
{
|
||||
remoteClient.SendInventoryItemCreateUpdate(item, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_dialogModule != null)
|
||||
m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
using Timer=System.Timers.Timer;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Region.CoreModules.Avatar.Attachments;
|
||||
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
|
||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Attachment tests
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class AttachmentsModuleTests
|
||||
{
|
||||
private Scene scene;
|
||||
private AttachmentsModule m_attMod;
|
||||
private ScenePresence m_presence;
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.None;
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
scene = SceneHelpers.SetupScene();
|
||||
m_attMod = new AttachmentsModule();
|
||||
SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten not to worry about such things.
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the standard presence for a test.
|
||||
/// </summary>
|
||||
private void AddPresence()
|
||||
{
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
m_presence = SceneHelpers.AddScenePresence(scene, userId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddAttachmentFromGround()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
string attName = "att";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
|
||||
|
||||
m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(
|
||||
attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddAttachmentFromInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDetachAttachmentToGround()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(0));
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
|
||||
|
||||
// Check item status
|
||||
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
|
||||
|
||||
// Check object in scene
|
||||
Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDetachAttachmentToInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(0));
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRezAttachmentsOnAvatarEntrance()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
InventoryItemBase attItem
|
||||
= UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
acd.Appearance = new AvatarAppearance();
|
||||
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
|
||||
|
||||
Assert.That(presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = presence.GetAttachments();
|
||||
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
}
|
||||
|
||||
// I'm commenting this test because scene setup NEEDS InventoryService to
|
||||
// be non-null
|
||||
//[Test]
|
||||
// public void T032_CrossAttachments()
|
||||
// {
|
||||
// TestHelpers.InMethod();
|
||||
//
|
||||
// ScenePresence presence = scene.GetScenePresence(agent1);
|
||||
// ScenePresence presence2 = scene2.GetScenePresence(agent1);
|
||||
// presence2.AddAttachment(sog1);
|
||||
// presence2.AddAttachment(sog2);
|
||||
//
|
||||
// ISharedRegionModule serialiser = new SerialiserModule();
|
||||
// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
|
||||
// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
|
||||
//
|
||||
// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
|
||||
//
|
||||
// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
|
||||
// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
|
||||
// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestWearables += SendWearables;
|
||||
client.OnSetAppearance += SetAppearance;
|
||||
client.OnSetAppearance += SetAppearanceFromClient;
|
||||
client.OnAvatarNowWearing += AvatarIsWearing;
|
||||
}
|
||||
|
||||
@@ -115,17 +115,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Check for the existence of the baked texture assets.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||
{
|
||||
return ValidateBakedTextureCache(client, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check for the existence of the baked texture assets. Request a rebake
|
||||
/// unless checkonly is true.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="checkonly"></param>
|
||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||
{
|
||||
return ValidateBakedTextureCache(client, true);
|
||||
}
|
||||
|
||||
private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
@@ -147,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
if (face == null)
|
||||
continue;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
||||
// face.TextureID, idx, client.Name, client.AgentId);
|
||||
|
||||
// if the texture is one of the "defaults" then skip it
|
||||
// this should probably be more intelligent (skirt texture doesnt matter
|
||||
// if the avatar isnt wearing a skirt) but if any of the main baked
|
||||
@@ -156,13 +164,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
defonly = false; // found a non-default texture reference
|
||||
|
||||
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
|
||||
if (!CheckBakedTextureAsset(client, face.TextureID, idx))
|
||||
{
|
||||
// the asset didn't exist if we are only checking, then we found a bad
|
||||
// one and we're done otherwise, ask for a rebake
|
||||
if (checkonly) return false;
|
||||
if (checkonly)
|
||||
return false;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID);
|
||||
|
||||
client.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
}
|
||||
@@ -174,16 +184,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (textureentry and slider settings) received from the client
|
||||
/// Set appearance data (texture asset IDs and slider settings) received from the client
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId);
|
||||
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,18 +222,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
|
||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); });
|
||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });
|
||||
|
||||
// This appears to be set only in the final stage of the appearance
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
// appearance send and save here.
|
||||
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
}
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
@@ -246,6 +257,117 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
return true;
|
||||
}
|
||||
|
||||
public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
|
||||
if (sp == null)
|
||||
return new Dictionary<BakeType, Primitive.TextureEntryFace>();
|
||||
|
||||
return GetBakedTextureFaces(sp);
|
||||
}
|
||||
|
||||
private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
|
||||
{
|
||||
if (sp.IsChildAgent)
|
||||
return new Dictionary<BakeType, Primitive.TextureEntryFace>();
|
||||
|
||||
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
|
||||
= new Dictionary<BakeType, Primitive.TextureEntryFace>();
|
||||
|
||||
AvatarAppearance appearance = sp.Appearance;
|
||||
Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
|
||||
|
||||
foreach (int i in Enum.GetValues(typeof(BakeType)))
|
||||
{
|
||||
BakeType bakeType = (BakeType)i;
|
||||
|
||||
if (bakeType == BakeType.Unknown)
|
||||
continue;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
|
||||
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
|
||||
|
||||
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
|
||||
bakedTextures[bakeType] = faceTextures[ftIndex];
|
||||
}
|
||||
|
||||
return bakedTextures;
|
||||
}
|
||||
|
||||
public bool SaveBakedTextures(UUID agentId)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
|
||||
if (sp == null)
|
||||
return false;
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
|
||||
sp.Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
|
||||
|
||||
if (bakedTextures.Count == 0)
|
||||
return false;
|
||||
|
||||
foreach (BakeType bakeType in bakedTextures.Keys)
|
||||
{
|
||||
Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
|
||||
|
||||
if (bakedTextureFace == null)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
|
||||
bakeType, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
|
||||
|
||||
if (asset != null)
|
||||
{
|
||||
asset.Temporary = false;
|
||||
asset.Local = false;
|
||||
m_scene.AssetService.Store(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
|
||||
bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
// for (int i = 0; i < faceTextures.Length; i++)
|
||||
// {
|
||||
//// m_log.DebugFormat(
|
||||
//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
|
||||
//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
|
||||
//
|
||||
// if (faceTextures[i] == null)
|
||||
// continue;
|
||||
//
|
||||
// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString());
|
||||
//
|
||||
// if (asset != null)
|
||||
// {
|
||||
// asset.Temporary = false;
|
||||
// m_scene.AssetService.Store(asset);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_log.WarnFormat(
|
||||
// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently",
|
||||
// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region UpdateAppearanceTimer
|
||||
|
||||
/// <summary>
|
||||
@@ -278,26 +400,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAppearanceSend(UUID agentid)
|
||||
private void SaveAppearance(UUID agentid)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||
return;
|
||||
}
|
||||
// We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
|
||||
// in a culture where decimal points are commas and then reloaded in a culture which just treats them as
|
||||
// number seperators.
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
private void HandleAppearanceSave(UUID agentid)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
if (sp == null)
|
||||
{
|
||||
@@ -321,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
if (kvp.Value < now)
|
||||
{
|
||||
Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); });
|
||||
Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); });
|
||||
m_sendqueue.Remove(kvp.Key);
|
||||
}
|
||||
}
|
||||
@@ -334,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
if (kvp.Value < now)
|
||||
{
|
||||
Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); });
|
||||
Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); });
|
||||
m_savequeue.Remove(kvp.Key);
|
||||
}
|
||||
}
|
||||
@@ -380,11 +489,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
|
||||
|
||||
// we need to clean out the existing textures
|
||||
sp.Appearance.ResetAppearance();
|
||||
sp.Appearance.ResetAppearance();
|
||||
|
||||
// operate on a copy of the appearance so we don't have to lock anything
|
||||
// operate on a copy of the appearance so we don't have to lock anything yet
|
||||
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
|
||||
|
||||
|
||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||
{
|
||||
if (wear.Type < AvatarWearable.MAX_WEARABLES)
|
||||
@@ -396,12 +505,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// This could take awhile since it needs to pull inventory
|
||||
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
||||
|
||||
// could get fancier with the locks here, but in the spirit of "last write wins"
|
||||
// this should work correctly, also, we don't need to send the appearance here
|
||||
// since the "iswearing" will trigger a new set of visual param and baked texture changes
|
||||
// when those complete, the new appearance will be sent
|
||||
sp.Appearance = avatAppearance;
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
lock (m_setAppearanceLock)
|
||||
{
|
||||
// Update only those fields that we have changed. This is important because the viewer
|
||||
// often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
|
||||
// shouldn't overwrite the changes made in SetAppearance.
|
||||
sp.Appearance.Wearables = avatAppearance.Wearables;
|
||||
sp.Appearance.Texture = avatAppearance.Texture;
|
||||
|
||||
// We don't need to send the appearance here since the "iswearing" will trigger a new set
|
||||
// of visual param and baked texture changes. When those complete, the new appearance will be sent
|
||||
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
}
|
||||
}
|
||||
|
||||
public bool SendAppearance(UUID agentId)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Asset;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
[TestFixture]
|
||||
public class AvatarFactoryModuleTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSetAppearance()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
|
||||
|
||||
byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
|
||||
for (byte i = 0; i < visualParams.Length; i++)
|
||||
visualParams[i] = i;
|
||||
|
||||
afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
|
||||
|
||||
ScenePresence sp = scene.GetScenePresence(userId);
|
||||
|
||||
// TODO: Check baked texture
|
||||
Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSaveBakedTextures()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID eyesTextureId = TestHelpers.ParseTail(0x2);
|
||||
|
||||
// We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
|
||||
// to the AssetService, which will then store temporary and local assets permanently
|
||||
CoreAssetCache assetCache = new CoreAssetCache();
|
||||
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene(assetCache);
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
|
||||
|
||||
// TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
|
||||
AssetBase uploadedAsset;
|
||||
uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString());
|
||||
uploadedAsset.Data = new byte[] { 2 };
|
||||
uploadedAsset.Temporary = true;
|
||||
uploadedAsset.Local = true; // Local assets aren't persisted, non-local are
|
||||
scene.AssetService.Store(uploadedAsset);
|
||||
|
||||
byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
|
||||
for (byte i = 0; i < visualParams.Length; i++)
|
||||
visualParams[i] = i;
|
||||
|
||||
Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
|
||||
uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
|
||||
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
|
||||
eyesFace.TextureID = eyesTextureId;
|
||||
|
||||
afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
|
||||
afm.SaveBakedTextures(userId);
|
||||
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
|
||||
|
||||
// We should also inpsect the asset data store layer directly, but this is difficult to get at right now.
|
||||
assetCache.Clear();
|
||||
|
||||
AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString());
|
||||
Assert.That(eyesBake, Is.Not.Null);
|
||||
Assert.That(eyesBake.Temporary, Is.False);
|
||||
Assert.That(eyesBake.Local, Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,11 +172,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
private void RetrieveInstantMessages(IClientAPI client)
|
||||
{
|
||||
if (m_RestURL == String.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
|
||||
|
||||
m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId);
|
||||
|
||||
List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
|
||||
List<GridInstantMessage> msglist
|
||||
= SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
|
||||
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
|
||||
|
||||
if (msglist != null)
|
||||
@@ -209,6 +213,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
|
||||
im.dialog != (byte)InstantMessageDialog.InventoryOffered)
|
||||
{
|
||||
bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
|
||||
"POST", m_RestURL+"/SaveMessage/", im);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
// Create scene object asset
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
|
||||
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||
@@ -127,10 +127,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
scene.AddInventoryItem(item1);
|
||||
|
||||
// Create coalesced objects asset
|
||||
SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
|
||||
SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
|
||||
cobj1.AbsolutePosition = new Vector3(15, 30, 45);
|
||||
|
||||
SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
|
||||
SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
|
||||
cobj2.AbsolutePosition = new Vector3(25, 50, 75);
|
||||
|
||||
CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2);
|
||||
|
||||
@@ -61,14 +61,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
m_archiverModule = new InventoryArchiverModule();
|
||||
|
||||
m_scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoadCoalesecedItem()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
|
||||
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestOrder()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes);
|
||||
@@ -129,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestSaveItemToIar()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
// Create user
|
||||
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
// Create asset
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestSaveItemToIarNoAssets()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
// Create user
|
||||
@@ -236,7 +236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
// Create asset
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarCreatorAccountPresent()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
|
||||
@@ -357,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarV0_1SameNameCreator()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
|
||||
@@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarV0_1AbsentCreator()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
|
||||
|
||||
@@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestSavePathToIarV0_1()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
// Create user
|
||||
string userFirstName = "Jock";
|
||||
@@ -172,16 +172,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarToInventoryPaths()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
|
||||
@@ -217,13 +217,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarPathStartsWithSlash()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
|
||||
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
|
||||
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarPathWithEscapedChars()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
string itemName = "You & you are a mean/man/";
|
||||
@@ -247,8 +247,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
// Create user
|
||||
string userFirstName = "Jock";
|
||||
@@ -323,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestNewIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
|
||||
@@ -390,10 +390,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestPartExistingIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
//log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
@@ -441,10 +441,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestMergeIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
|
||||
@@ -208,9 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
user.ControllingClient.SendBulkUpdateInventory(folderCopy);
|
||||
}
|
||||
|
||||
// HACK!!
|
||||
im.imSessionID = folderID.Guid;
|
||||
@@ -240,9 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
user.ControllingClient.SendBulkUpdateInventory(itemCopy);
|
||||
}
|
||||
|
||||
// HACK!!
|
||||
im.imSessionID = itemID.Guid;
|
||||
@@ -280,7 +276,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
else
|
||||
{
|
||||
if (m_TransferModule != null)
|
||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
|
||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) {
|
||||
// Send BulkUpdateInventory
|
||||
IInventoryService invService = scene.InventoryService;
|
||||
UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
|
||||
|
||||
InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
|
||||
folder = invService.GetFolder(folder);
|
||||
|
||||
ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
|
||||
|
||||
// If the user has left the scene by the time the message comes back then we can't send
|
||||
// them the update.
|
||||
if (fromUser != null)
|
||||
fromUser.ControllingClient.SendBulkUpdateInventory(folder);
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
if (!(client.Scene is Scene))
|
||||
return;
|
||||
|
||||
Scene scene = (Scene)(client.Scene);
|
||||
// Scene scene = (Scene)(client.Scene);
|
||||
|
||||
GridInstantMessage im = null;
|
||||
if (m_PendingLures.TryGetValue(lureID, out im))
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
if (!(s is Scene))
|
||||
return;
|
||||
|
||||
Scene scene = (Scene)s;
|
||||
// Scene scene = (Scene)s;
|
||||
|
||||
string profileUrl = String.Empty;
|
||||
string aboutText = String.Empty;
|
||||
|
||||
Reference in New Issue
Block a user