aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs779
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs319
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs222
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs120
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs93
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs22
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs36
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs2
11 files changed, 1250 insertions, 375 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 47476a9..a130ed2 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -47,7 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 protected Scene m_scene = null; 50 private Scene m_scene;
51 private IDialogModule m_dialogModule;
51 52
52 public string Name { get { return "Attachments Module"; } } 53 public string Name { get { return "Attachments Module"; } }
53 public Type ReplaceableInterface { get { return null; } } 54 public Type ReplaceableInterface { get { return null; } }
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
57 public void AddRegion(Scene scene) 58 public void AddRegion(Scene scene)
58 { 59 {
59 m_scene = scene; 60 m_scene = scene;
61 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
60 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 62 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
61 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 63 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
62 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 64 // 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
81 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory; 83 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
82 client.OnObjectAttach += AttachObject; 84 client.OnObjectAttach += AttachObject;
83 client.OnObjectDetach += DetachObject; 85 client.OnObjectDetach += DetachObject;
84 client.OnDetachAttachmentIntoInv += ShowDetachInUserInventory; 86 client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
87 client.OnObjectDrop += DetachSingleAttachmentToGround;
85 } 88 }
86 89
87 public void UnsubscribeFromClientEvents(IClientAPI client) 90 public void UnsubscribeFromClientEvents(IClientAPI client)
@@ -90,7 +93,83 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
90 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory; 93 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
91 client.OnObjectAttach -= AttachObject; 94 client.OnObjectAttach -= AttachObject;
92 client.OnObjectDetach -= DetachObject; 95 client.OnObjectDetach -= DetachObject;
93 client.OnDetachAttachmentIntoInv -= ShowDetachInUserInventory; 96 client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
97 client.OnObjectDrop -= DetachSingleAttachmentToGround;
98 }
99
100 /// <summary>
101 /// RezAttachments. This should only be called upon login on the first region.
102 /// Attachment rezzings on crossings and TPs are done in a different way.
103 /// </summary>
104 public void RezAttachments(IScenePresence sp)
105 {
106 if (null == sp.Appearance)
107 {
108 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
109 return;
110 }
111
112 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
113 foreach (AvatarAttachment attach in attachments)
114 {
115 uint p = (uint)attach.AttachPoint;
116
117// m_log.DebugFormat(
118// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
119// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName);
120
121 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
122 // But they're not used anyway, the item is being looked up for now, so let's proceed.
123 //if (UUID.Zero == assetID)
124 //{
125 // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
126 // continue;
127 //}
128
129 try
130 {
131 // If we're an NPC then skip all the item checks and manipulations since we don't have an
132 // inventory right now.
133 if (sp.PresenceType == PresenceType.Npc)
134 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
135 else
136 RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p);
137 }
138 catch (Exception e)
139 {
140 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace);
141 }
142 }
143 }
144
145 public void SaveChangedAttachments(IScenePresence sp)
146 {
147// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
148
149 foreach (SceneObjectGroup grp in sp.GetAttachments())
150 {
151// if (grp.HasGroupChanged) // Resizer scripts?
152// {
153 grp.IsAttachment = false;
154 grp.AbsolutePosition = grp.RootPart.AttachedPos;
155 UpdateKnownItem(sp.ControllingClient, grp);
156 grp.IsAttachment = true;
157// }
158 }
159 }
160
161 public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
162 {
163// m_log.DebugFormat(
164// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
165// m_scene.RegionInfo.RegionName, sp.Name, silent);
166
167 foreach (SceneObjectGroup sop in sp.GetAttachments())
168 {
169 sop.Scene.DeleteSceneObject(sop, silent);
170 }
171
172 sp.ClearAttachments();
94 } 173 }
95 174
96 /// <summary> 175 /// <summary>
@@ -102,10 +181,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
102 /// <param name="silent"></param> 181 /// <param name="silent"></param>
103 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) 182 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
104 { 183 {
105 m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); 184// m_log.DebugFormat(
185// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
186// objectLocalID, remoteClient.Name, AttachmentPt, silent);
106 187
107 try 188 try
108 { 189 {
190 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
191
192 if (sp == null)
193 {
194 m_log.ErrorFormat(
195 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
196 return;
197 }
198
109 // If we can't take it, we can't attach it! 199 // If we can't take it, we can't attach it!
110 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); 200 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
111 if (part == null) 201 if (part == null)
@@ -131,12 +221,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
131 AttachmentPt &= 0x7f; 221 AttachmentPt &= 0x7f;
132 222
133 // Calls attach with a Zero position 223 // Calls attach with a Zero position
134 if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) 224 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
135 { 225 {
136 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); 226 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
137 227
138 // Save avatar attachment information 228 // Save avatar attachment information
139 m_log.Info( 229 m_log.Debug(
140 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 230 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
141 + ", AttachmentPoint: " + AttachmentPt); 231 + ", AttachmentPoint: " + AttachmentPt);
142 232
@@ -144,74 +234,103 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
144 } 234 }
145 catch (Exception e) 235 catch (Exception e)
146 { 236 {
147 m_log.DebugFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}", e); 237 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
148 } 238 }
149 } 239 }
150 240
151 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) 241 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
152 { 242 {
153 Vector3 attachPos = group.AbsolutePosition; 243 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
154
155 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
156 // be removed when that functionality is implemented in opensim
157 AttachmentPt &= 0x7f;
158
159 // If the attachment point isn't the same as the one previously used
160 // set it's offset position = 0 so that it appears on the attachment point
161 // and not in a weird location somewhere unknown.
162 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
163 {
164 attachPos = Vector3.Zero;
165 }
166
167 // AttachmentPt 0 means the client chose to 'wear' the attachment.
168 if (AttachmentPt == 0)
169 {
170 // Check object for stored attachment point
171 AttachmentPt = (uint)group.GetAttachmentPoint();
172 }
173 244
174 // if we still didn't find a suitable attachment point....... 245 if (sp == null)
175 if (AttachmentPt == 0)
176 { 246 {
177 // Stick it on left hand with Zero Offset from the attachment point. 247 m_log.ErrorFormat(
178 AttachmentPt = (uint)AttachmentPoint.LeftHand; 248 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
179 attachPos = Vector3.Zero; 249 return false;
180 } 250 }
181 251
182 group.SetAttachmentPoint((byte)AttachmentPt); 252 return AttachObject(sp, group, AttachmentPt, silent);
183 group.AbsolutePosition = attachPos; 253 }
184 254
185 // Remove any previous attachments 255 private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
186 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 256 {
187 UUID itemID = UUID.Zero; 257 lock (sp.AttachmentsSyncLock)
188 if (sp != null)
189 { 258 {
190 foreach (SceneObjectGroup grp in sp.Attachments) 259// m_log.DebugFormat(
260// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
261// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
262
263 if (sp.GetAttachments(attachmentPt).Contains(group))
264 {
265 // m_log.WarnFormat(
266 // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
267 // group.Name, group.LocalId, sp.Name, AttachmentPt);
268
269 return false;
270 }
271
272 Vector3 attachPos = group.AbsolutePosition;
273
274 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
275 // be removed when that functionality is implemented in opensim
276 attachmentPt &= 0x7f;
277
278 // If the attachment point isn't the same as the one previously used
279 // set it's offset position = 0 so that it appears on the attachment point
280 // and not in a weird location somewhere unknown.
281 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
282 {
283 attachPos = Vector3.Zero;
284 }
285
286 // AttachmentPt 0 means the client chose to 'wear' the attachment.
287 if (attachmentPt == 0)
288 {
289 // Check object for stored attachment point
290 attachmentPt = group.AttachmentPoint;
291 }
292
293 // if we still didn't find a suitable attachment point.......
294 if (attachmentPt == 0)
191 { 295 {
192 if (grp.GetAttachmentPoint() == (byte)AttachmentPt) 296 // Stick it on left hand with Zero Offset from the attachment point.
297 attachmentPt = (uint)AttachmentPoint.LeftHand;
298 attachPos = Vector3.Zero;
299 }
300
301 group.AttachmentPoint = attachmentPt;
302 group.AbsolutePosition = attachPos;
303
304 // We also don't want to do any of the inventory operations for an NPC.
305 if (sp.PresenceType != PresenceType.Npc)
306 {
307 // Remove any previous attachments
308 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
309
310 // At the moment we can only deal with a single attachment
311 if (attachments.Count != 0)
193 { 312 {
194 itemID = grp.GetFromItemID(); 313 UUID oldAttachmentItemID = attachments[0].GetFromItemID();
195 break; 314
315 if (oldAttachmentItemID != UUID.Zero)
316 DetachSingleAttachmentToInv(oldAttachmentItemID, sp);
317 else
318 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
320 attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
196 } 321 }
322
323 // Add the new attachment to inventory if we don't already have it.
324 UUID newAttachmentItemID = group.GetFromItemID();
325 if (newAttachmentItemID == UUID.Zero)
326 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID;
327
328 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
197 } 329 }
198 if (itemID != UUID.Zero) 330
199 DetachSingleAttachmentToInv(itemID, remoteClient); 331 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
200 } 332 }
201 333
202 if (group.GetFromItemID() == UUID.Zero)
203 {
204 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID);
205 }
206 else
207 {
208 itemID = group.GetFromItemID();
209 }
210
211 ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group);
212
213 AttachToAgent(sp, group, AttachmentPt, attachPos, silent);
214
215 return true; 334 return true;
216 } 335 }
217 336
@@ -220,84 +339,159 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
220 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, 339 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
221 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) 340 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
222 { 341 {
223 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) 342 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
343
344 if (sp == null)
224 { 345 {
225 RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt); 346 m_log.ErrorFormat(
347 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
348 remoteClient.Name, remoteClient.AgentId);
349 return;
350 }
351
352 lock (sp.AttachmentsSyncLock)
353 {
354// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
355
356 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
357 {
358 RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
359 }
226 } 360 }
227 } 361 }
228 362
229 public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 363 public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
230 { 364 {
231 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); 365 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
232 } 366 }
233 367
234 public UUID RezSingleAttachmentFromInventory( 368 public ISceneEntity RezSingleAttachmentFromInventory(
235 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) 369 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
236 { 370 {
237 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); 371 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
372
373 if (sp == null)
374 {
375 m_log.ErrorFormat(
376 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
377 remoteClient.Name, remoteClient.AgentId);
378 return null;
379 }
380
381 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
238 } 382 }
239 383
240 public UUID RezSingleAttachmentFromInventory( 384 public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt)
241 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
242 { 385 {
386// m_log.DebugFormat(
387// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
388// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
389
243 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 390 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
244 // be removed when that functionality is implemented in opensim 391 // be removed when that functionality is implemented in opensim
245 AttachmentPt &= 0x7f; 392 AttachmentPt &= 0x7f;
246 393
247 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt, doc); 394 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
395 // This often happens during login - not sure the exact reason.
396 // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the
397 // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login
398 // before anything has actually been attached.
399 bool alreadyOn = false;
400 List<SceneObjectGroup> existingAttachments = sp.GetAttachments();
401 foreach (SceneObjectGroup so in existingAttachments)
402 {
403 if (so.GetFromItemID() == itemID)
404 {
405 alreadyOn = true;
406 break;
407 }
408 }
248 409
249 if (updateInventoryStatus) 410// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
411 if (alreadyOn)
250 { 412 {
251 if (att == null) 413// m_log.WarnFormat(
252 ShowDetachInUserInventory(itemID, remoteClient); 414// "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn",
253 else 415// sp.Name, itemID, AttachmentPt);
254 ShowAttachInUserInventory(att, remoteClient, itemID, AttachmentPt); 416
417 return null;
255 } 418 }
256 419
257 if (null == att) 420 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, null);
258 return UUID.Zero; 421
259 else 422 if (att == null)
260 return att.UUID; 423 DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
424
425 return att;
261 } 426 }
262 427
263 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 428 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
264 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, XmlDocument doc) 429 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
265 { 430 {
266 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 431 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
267 if (invAccess != null) 432 if (invAccess != null)
268 { 433 {
269 SceneObjectGroup objatt = invAccess.RezObject(remoteClient, 434 lock (sp.AttachmentsSyncLock)
270 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
271 false, false, remoteClient.AgentId, true);
272
273// m_log.DebugFormat(
274// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
275// objatt.Name, remoteClient.Name, AttachmentPt);
276
277 if (objatt != null)
278 { 435 {
279 // Loading the inventory from XML will have set this, but 436 SceneObjectGroup objatt;
280 // there is no way the object could have changed yet, 437
281 // since scripts aren't running yet. So, clear it here. 438 if (itemID != UUID.Zero)
282 objatt.HasGroupChanged = false; 439 objatt = invAccess.RezObject(sp.ControllingClient,
283 bool tainted = false; 440 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
284 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 441 false, false, sp.UUID, true);
285 tainted = true; 442 else
286 443 objatt = invAccess.RezObject(sp.ControllingClient,
287 // This will throw if the attachment fails 444 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
288 try 445 false, false, sp.UUID, true);
446
447 // m_log.DebugFormat(
448 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
449 // objatt.Name, remoteClient.Name, AttachmentPt);
450
451 if (objatt != null)
289 { 452 {
290 AttachObject(remoteClient, objatt, AttachmentPt, false); 453 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
454 objatt.HasGroupChanged = false;
455 bool tainted = false;
456 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
457 tainted = true;
458
459 // This will throw if the attachment fails
460 try
461 {
462 AttachObject(sp, objatt, attachmentPt, false);
463 }
464 catch (Exception e)
465 {
466 m_log.ErrorFormat(
467 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
468 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
469
470 // Make sure the object doesn't stick around and bail
471 sp.RemoveAttachment(objatt);
472 m_scene.DeleteSceneObject(objatt, false);
473 return null;
474 }
475
476 if (tainted)
477 objatt.HasGroupChanged = true;
478
479 // Fire after attach, so we don't get messy perms dialogs
480 // 4 == AttachedRez
481 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
482 objatt.ResumeScripts();
483
484 // Do this last so that event listeners have access to all the effects of the attachment
485 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
486
487 return objatt;
291 } 488 }
292 catch 489 else
293 { 490 {
294 // Make sure the object doesn't stick around and bail 491 m_log.WarnFormat(
295 m_scene.DeleteSceneObject(objatt, false); 492 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
296 return null; 493 itemID, sp.Name, attachmentPt);
297 } 494 }
298
299 if (tainted)
300 objatt.HasGroupChanged = true;
301 495
302 if (doc != null) 496 if (doc != null)
303 { 497 {
@@ -311,67 +505,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
311 objatt.ResumeScripts(); 505 objatt.ResumeScripts();
312 506
313 // Do this last so that event listeners have access to all the effects of the attachment 507 // Do this last so that event listeners have access to all the effects of the attachment
314 //m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); 508 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
315 } 509 }
316 else
317 {
318 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
320 itemID, remoteClient.Name, AttachmentPt);
321 }
322
323 return objatt;
324 } 510 }
325 511
326 return null; 512 return null;
327 } 513 }
328
329 /// <summary>
330 /// Update the user inventory to the attachment of an item
331 /// </summary>
332 /// <param name="att"></param>
333 /// <param name="remoteClient"></param>
334 /// <param name="itemID"></param>
335 /// <param name="AttachmentPt"></param>
336 /// <returns></returns>
337 protected UUID ShowAttachInUserInventory(
338 SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
339 {
340// m_log.DebugFormat(
341// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
342// remoteClient.Name, att.Name, itemID);
343
344 if (!att.IsDeleted)
345 AttachmentPt = att.RootPart.AttachmentPoint;
346
347 ScenePresence presence;
348 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
349 {
350 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
351 if (m_scene.InventoryService != null)
352 item = m_scene.InventoryService.GetItem(item);
353
354 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
355 if (changed && m_scene.AvatarFactory != null)
356 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
357 }
358
359 return att.UUID;
360 }
361 514
362 /// <summary> 515 /// <summary>
363 /// Update the user inventory to reflect an attachment 516 /// Update the user inventory to reflect an attachment
364 /// </summary> 517 /// </summary>
365 /// <param name="remoteClient"></param> 518 /// <param name="sp"></param>
366 /// <param name="AttachmentPt"></param> 519 /// <param name="AttachmentPt"></param>
367 /// <param name="itemID"></param> 520 /// <param name="itemID"></param>
368 /// <param name="att"></param> 521 /// <param name="att"></param>
369 protected void ShowAttachInUserInventory( 522 private void ShowAttachInUserInventory(
370 IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 523 IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
371 { 524 {
372// m_log.DebugFormat( 525// m_log.DebugFormat(
373// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 526// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
374// att.Name, remoteClient.Name, AttachmentPt, itemID); 527// att.Name, sp.Name, AttachmentPt, itemID);
375 528
376 if (UUID.Zero == itemID) 529 if (UUID.Zero == itemID)
377 { 530 {
@@ -390,88 +543,129 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
390 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!"); 543 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
391 return; 544 return;
392 } 545 }
546 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
393 547
394 ScenePresence presence; 548
395 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 549
396 { 550
397 // XXYY!! 551
398 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 552
399 if (item == null) 553 item = m_scene.InventoryService.GetItem(item);
400 m_log.Error("[ATTACHMENT]: item == null"); 554 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
401 if (m_scene == null) 555 if (changed && m_scene.AvatarFactory != null)
402 m_log.Error("[ATTACHMENT]: m_scene == null"); 556 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
403 if (m_scene.InventoryService == null)
404 m_log.Error("[ATTACHMENT]: m_scene.InventoryService == null");
405 item = m_scene.InventoryService.GetItem(item);
406 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
407 if (changed && m_scene.AvatarFactory != null)
408 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
409 }
410 } 557 }
411 558
412 public void DetachObject(uint objectLocalID, IClientAPI remoteClient) 559 public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
413 { 560 {
561// m_log.DebugFormat(
562// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name);
563
414 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); 564 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
415 if (group != null) 565 if (group != null)
416 { 566 {
417 //group.DetachToGround(); 567 DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
418 ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
419 } 568 }
420 } 569 }
421 570
422 public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient) 571 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
423 { 572 {
424 ScenePresence presence; 573 ScenePresence presence;
425 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 574 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
426 { 575 {
427 // Save avatar attachment information 576 lock (presence.AttachmentsSyncLock)
428 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); 577 {
578 // Save avatar attachment information
579 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
429 580
430 bool changed = presence.Appearance.DetachAttachment(itemID); 581 bool changed = presence.Appearance.DetachAttachment(itemID);
431 if (changed && m_scene.AvatarFactory != null) 582 if (changed && m_scene.AvatarFactory != null)
432 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 583 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
584
585 DetachSingleAttachmentToInv(itemID, presence);
586 }
433 } 587 }
434
435 DetachSingleAttachmentToInv(itemID, remoteClient);
436 } 588 }
437 589
438 public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) 590 public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient)
439 { 591 {
440 SceneObjectPart part = m_scene.GetSceneObjectPart(itemID); 592// m_log.DebugFormat(
441 if (part == null || part.ParentGroup == null) 593// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
594// remoteClient.Name, soLocalId);
595
596 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
597
598 if (so == null)
442 return; 599 return;
443 600
444 if (part.ParentGroup.RootPart.AttachedAvatar != remoteClient.AgentId) 601 if (so.AttachedAvatar != remoteClient.AgentId)
445 return; 602 return;
446 603
447 UUID inventoryID = part.ParentGroup.GetFromItemID(); 604 UUID inventoryID = so.GetFromItemID();
605
606// m_log.DebugFormat(
607// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
608// so.Name, so.LocalId, inventoryID);
448 609
449 ScenePresence presence; 610 ScenePresence presence;
450 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 611 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
451 { 612 {
452 if (!m_scene.Permissions.CanRezObject( 613 lock (presence.AttachmentsSyncLock)
453 part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) 614 {
454 return; 615 if (!m_scene.Permissions.CanRezObject(
616 so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
617 return;
455 618
456 bool changed = presence.Appearance.DetachAttachment(itemID); 619 bool changed = presence.Appearance.DetachAttachment(inventoryID);
457 if (changed && m_scene.AvatarFactory != null) 620 if (changed && m_scene.AvatarFactory != null)
458 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 621 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
459 622
460 part.ParentGroup.DetachToGround(); 623 presence.RemoveAttachment(so);
624 DetachSceneObjectToGround(so, presence);
461 625
462 List<UUID> uuids = new List<UUID>(); 626 List<UUID> uuids = new List<UUID>();
463 uuids.Add(inventoryID); 627 uuids.Add(inventoryID);
464 m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); 628 m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
465 remoteClient.SendRemoveInventoryItem(inventoryID); 629 remoteClient.SendRemoveInventoryItem(inventoryID);
630 }
631
632 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
466 } 633 }
634 }
467 635
468 m_scene.EventManager.TriggerOnAttach(part.ParentGroup.LocalId, itemID, UUID.Zero); 636 /// <summary>
637 /// Detach the given scene object to the ground.
638 /// </summary>
639 /// <remarks>
640 /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
641 /// </remarks>
642 /// <param name="so">The scene object to detach.</param>
643 /// <param name="sp">The scene presence from which the scene object is being detached.</param>
644 private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
645 {
646 SceneObjectPart rootPart = so.RootPart;
647
648 rootPart.FromItemID = UUID.Zero;
649 so.AbsolutePosition = sp.AbsolutePosition;
650 so.AttachedAvatar = UUID.Zero;
651 rootPart.SetParentLocalId(0);
652 so.ClearPartAttachmentData();
653 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
654 so.HasGroupChanged = true;
655 rootPart.Rezzed = DateTime.Now;
656 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
657 so.AttachToBackup();
658 m_scene.EventManager.TriggerParcelPrimCountTainted();
659 rootPart.ScheduleFullUpdate();
660 rootPart.ClearUndoState();
469 } 661 }
470 662
471 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. 663 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
472 // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? 664 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
473 protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) 665 private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
474 { 666 {
667// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
668
475 if (itemID == UUID.Zero) // If this happened, someone made a mistake.... 669 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
476 return; 670 return;
477 671
@@ -480,60 +674,70 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
480 EntityBase[] detachEntities = m_scene.GetEntities(); 674 EntityBase[] detachEntities = m_scene.GetEntities();
481 SceneObjectGroup group; 675 SceneObjectGroup group;
482 676
483 foreach (EntityBase entity in detachEntities) 677 lock (sp.AttachmentsSyncLock)
484 { 678 {
485 if (entity is SceneObjectGroup) 679 foreach (EntityBase entity in detachEntities)
486 { 680 {
487 group = (SceneObjectGroup)entity; 681 if (entity is SceneObjectGroup)
488 if (group.GetFromItemID() == itemID)
489 { 682 {
490 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); 683 group = (SceneObjectGroup)entity; if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
491 // CM / XMREngine!!!! Needed to conclude attach event 684 // CM / XMREngine!!!! Needed to conclude attach event
492 //SceneObjectSerializer.ToOriginalXmlFormat(group); 685 //SceneObjectSerializer.ToOriginalXmlFormat(group);
493 group.DetachToInventoryPrep(); 686 group.DetachToInventoryPrep();
494 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); 687 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
495 688
496 // If an item contains scripts, it's always changed. 689 // Prepare sog for storage
497 // This ensures script state is saved on detach 690 group.AttachedAvatar = UUID.Zero;
498 foreach (SceneObjectPart p in group.Parts) 691 group.RootPart.SetParentLocalId(0);
499 if (p.Inventory.ContainsScripts()) 692 group.IsAttachment = false;
500 group.HasGroupChanged = true; 693 group.AbsolutePosition = group.RootPart.AttachedPos;
501 694
502 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); 695 UpdateKnownItem(sp.ControllingClient, group);
503 m_scene.DeleteSceneObject(group, false); 696 m_scene.DeleteSceneObject(group, false);
504 return; 697
698 return;
699 }
505 } 700 }
506 } 701 }
507 } 702 }
508 } 703 }
509 704
705 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
706 {
707 // First we save the
708 // attachment point information, then we update the relative
709 // positioning. Then we have to mark the object as NOT an
710 // attachment. This is necessary in order to correctly save
711 // and retrieve GroupPosition information for the attachment.
712 // Finally, we restore the object's attachment status.
713 uint attachmentPoint = sog.AttachmentPoint;
714 sog.UpdateGroupPosition(pos);
715 sog.IsAttachment = false;
716 sog.AbsolutePosition = sog.RootPart.AttachedPos;
717 sog.AttachmentPoint = attachmentPoint;
718 sog.HasGroupChanged = true;
719 }
720
510 /// <summary> 721 /// <summary>
511 /// Update the attachment asset for the new sog details if they have changed. 722 /// Update the attachment asset for the new sog details if they have changed.
512 /// </summary> 723 /// </summary>
513 /// 724 /// <remarks>
514 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, 725 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
515 /// these details are not stored on the region. 726 /// these details are not stored on the region.
516 /// 727 /// </remarks>
517 /// <param name="remoteClient"></param> 728 /// <param name="remoteClient"></param>
518 /// <param name="grp"></param> 729 /// <param name="grp"></param>
519 /// <param name="itemID"></param> 730 private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp)
520 /// <param name="agentID"></param>
521 public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
522 { 731 {
523 if (grp != null) 732 if (grp.HasGroupChanged || grp.ContainsScripts())
524 { 733 {
525 if (!grp.HasGroupChanged)
526 {
527 m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID);
528 return;
529 }
530
531 m_log.DebugFormat( 734 m_log.DebugFormat(
532 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 735 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
533 grp.UUID, grp.GetAttachmentPoint()); 736 grp.UUID, grp.AttachmentPoint);
534 737
535 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 738 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
536 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 739
740 InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId);
537 item = m_scene.InventoryService.GetItem(item); 741 item = m_scene.InventoryService.GetItem(item);
538 742
539 if (item != null) 743 if (item != null)
@@ -559,25 +763,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
559 remoteClient.SendInventoryItemCreateUpdate(item, 0); 763 remoteClient.SendInventoryItemCreateUpdate(item, 0);
560 } 764 }
561 } 765 }
766 else
767 {
768 m_log.DebugFormat(
769 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
770 grp.UUID, grp.AttachmentPoint);
771 }
562 } 772 }
563 773
564 /// <summary> 774 /// <summary>
565 /// Attach this scene object to the given avatar. 775 /// Attach this scene object to the given avatar.
566 /// </summary> 776 /// </summary>
567 /// 777 /// <remarks>
568 /// This isn't publicly available since attachments should always perform the corresponding inventory 778 /// This isn't publicly available since attachments should always perform the corresponding inventory
569 /// operation (to show the attach in user inventory and update the asset with positional information). 779 /// operation (to show the attach in user inventory and update the asset with positional information).
570 /// 780 /// </remarks>
571 /// <param name="sp"></param> 781 /// <param name="sp"></param>
572 /// <param name="so"></param> 782 /// <param name="so"></param>
573 /// <param name="attachmentpoint"></param> 783 /// <param name="attachmentpoint"></param>
574 /// <param name="attachOffset"></param> 784 /// <param name="attachOffset"></param>
575 /// <param name="silent"></param> 785 /// <param name="silent"></param>
576 protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 786 private void AttachToAgent(
787 IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
577 { 788 {
578 789// m_log.DebugFormat(
579 m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, 790// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
580 attachmentpoint, attachOffset, so.RootPart.AttachedPos); 791// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
581 792
582 so.DetachFromBackup(); 793 so.DetachFromBackup();
583 794
@@ -585,12 +796,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
585 m_scene.DeleteFromStorage(so.UUID); 796 m_scene.DeleteFromStorage(so.UUID);
586 m_scene.EventManager.TriggerParcelPrimCountTainted(); 797 m_scene.EventManager.TriggerParcelPrimCountTainted();
587 798
588 so.RootPart.AttachedAvatar = avatar.UUID; 799 so.AttachedAvatar = avatar.UUID;
589
590 //Anakin Lohner bug #3839
591 SceneObjectPart[] parts = so.Parts;
592 for (int i = 0; i < parts.Length; i++)
593 parts[i].AttachedAvatar = avatar.UUID;
594 800
595 if (so.RootPart.PhysActor != null) 801 if (so.RootPart.PhysActor != null)
596 { 802 {
@@ -600,10 +806,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
600 806
601 so.AbsolutePosition = attachOffset; 807 so.AbsolutePosition = attachOffset;
602 so.RootPart.AttachedPos = attachOffset; 808 so.RootPart.AttachedPos = attachOffset;
603 so.RootPart.IsAttachment = true; 809 so.IsAttachment = true;
604
605 so.RootPart.SetParentLocalId(avatar.LocalId); 810 so.RootPart.SetParentLocalId(avatar.LocalId);
606 so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); 811 so.AttachmentPoint = attachmentpoint;
607 812
608 avatar.AddAttachment(so); 813 avatar.AddAttachment(so);
609 814
@@ -617,5 +822,99 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
617 // it get cleaned up 822 // it get cleaned up
618 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 823 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
619 } 824 }
825
826 /// <summary>
827 /// Add a scene object as a new attachment in the user inventory.
828 /// </summary>
829 /// <param name="remoteClient"></param>
830 /// <param name="grp"></param>
831 /// <returns>The user inventory item created that holds the attachment.</returns>
832 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp)
833 {
834// m_log.DebugFormat(
835// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
836// grp.Name, grp.LocalId, remoteClient.Name);
837 uint regionSize = Constants.RegionSize; //Avoid VS error "The operation overflows at compile time in checked mode"
838 Vector3 inventoryStoredPosition = new Vector3
839 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
840 ? regionSize - 6
841 : grp.AbsolutePosition.X)
842 ,
843 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
844 ? regionSize - 6
845 : grp.AbsolutePosition.Y,
846 grp.AbsolutePosition.Z);
847
848 Vector3 originalPosition = grp.AbsolutePosition;
849
850 grp.AbsolutePosition = inventoryStoredPosition;
851
852 // If we're being called from a script, then trying to serialize that same script's state will not complete
853 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
854 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
855 // without state on relog. Arguably, this is what we want anyway.
856 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
857
858 grp.AbsolutePosition = originalPosition;
859
860 AssetBase asset = m_scene.CreateAsset(
861 grp.GetPartName(grp.LocalId),
862 grp.GetPartDescription(grp.LocalId),
863 (sbyte)AssetType.Object,
864 Utils.StringToBytes(sceneObjectXml),
865 remoteClient.AgentId);
866
867 m_scene.AssetService.Store(asset);
868
869 InventoryItemBase item = new InventoryItemBase();
870 item.CreatorId = grp.RootPart.CreatorID.ToString();
871 item.CreatorData = grp.RootPart.CreatorData;
872 item.Owner = remoteClient.AgentId;
873 item.ID = UUID.Random();
874 item.AssetID = asset.FullID;
875 item.Description = asset.Description;
876 item.Name = asset.Name;
877 item.AssetType = asset.Type;
878 item.InvType = (int)InventoryType.Object;
879
880 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
881 if (folder != null)
882 item.Folder = folder.ID;
883 else // oopsies
884 item.Folder = UUID.Zero;
885
886 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
887 {
888 item.BasePermissions = grp.RootPart.NextOwnerMask;
889 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
890 item.NextPermissions = grp.RootPart.NextOwnerMask;
891 item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
892 item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
893 }
894 else
895 {
896 item.BasePermissions = grp.RootPart.BaseMask;
897 item.CurrentPermissions = grp.RootPart.OwnerMask;
898 item.NextPermissions = grp.RootPart.NextOwnerMask;
899 item.EveryOnePermissions = grp.RootPart.EveryoneMask;
900 item.GroupPermissions = grp.RootPart.GroupMask;
901 }
902 item.CreationDate = Util.UnixTimeSinceEpoch();
903
904 // sets itemID so client can show item as 'attached' in inventory
905 grp.SetFromItemID(item.ID);
906
907 if (m_scene.AddInventoryItem(item))
908 {
909 remoteClient.SendInventoryItemCreateUpdate(item, 0);
910 }
911 else
912 {
913 if (m_dialogModule != null)
914 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
915 }
916
917 return item;
918 }
620 } 919 }
621} 920} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
new file mode 100644
index 0000000..ff3358f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -0,0 +1,319 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Attachments;
41using OpenSim.Region.CoreModules.Framework.InventoryAccess;
42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48
49namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
50{
51 /// <summary>
52 /// Attachment tests
53 /// </summary>
54 [TestFixture]
55 public class AttachmentsModuleTests
56 {
57 private Scene scene;
58 private AttachmentsModule m_attMod;
59 private ScenePresence m_presence;
60
61 [TestFixtureSetUp]
62 public void FixtureInit()
63 {
64 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
65 Util.FireAndForgetMethod = FireAndForgetMethod.None;
66 }
67
68 [SetUp]
69 public void Init()
70 {
71 IConfigSource config = new IniConfigSource();
72 config.AddConfig("Modules");
73 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
74
75 scene = SceneHelpers.SetupScene();
76 m_attMod = new AttachmentsModule();
77 SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
78 }
79
80 [TestFixtureTearDown]
81 public void TearDown()
82 {
83 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
84 // threads. Possibly, later tests should be rewritten not to worry about such things.
85 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
86 }
87
88 /// <summary>
89 /// Add the standard presence for a test.
90 /// </summary>
91 private void AddPresence()
92 {
93 UUID userId = TestHelpers.ParseTail(0x1);
94 UserAccountHelpers.CreateUserWithInventory(scene, userId);
95 m_presence = SceneHelpers.AddScenePresence(scene, userId);
96 }
97
98 [Test]
99 public void TestAddAttachmentFromGround()
100 {
101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure();
103
104 AddPresence();
105 string attName = "att";
106
107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
108
109 m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
110
111 // Check status on scene presence
112 Assert.That(m_presence.HasAttachments(), Is.True);
113 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
114 Assert.That(attachments.Count, Is.EqualTo(1));
115 SceneObjectGroup attSo = attachments[0];
116 Assert.That(attSo.Name, Is.EqualTo(attName));
117 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
118 Assert.That(attSo.IsAttachment);
119 Assert.That(attSo.UsesPhysics, Is.False);
120 Assert.That(attSo.IsTemporary, Is.False);
121
122 // Check item status
123 Assert.That(m_presence.Appearance.GetAttachpoint(
124 attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
125 }
126
127 [Test]
128 public void TestAddAttachmentFromInventory()
129 {
130 TestHelpers.InMethod();
131// log4net.Config.XmlConfigurator.Configure();
132
133 AddPresence();
134
135 UUID attItemId = TestHelpers.ParseTail(0x2);
136 UUID attAssetId = TestHelpers.ParseTail(0x3);
137 string attName = "att";
138
139 UserInventoryHelpers.CreateInventoryItem(
140 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
141
142 m_attMod.RezSingleAttachmentFromInventory(
143 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
144
145 // Check scene presence status
146 Assert.That(m_presence.HasAttachments(), Is.True);
147 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
148 Assert.That(attachments.Count, Is.EqualTo(1));
149 SceneObjectGroup attSo = attachments[0];
150 Assert.That(attSo.Name, Is.EqualTo(attName));
151 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
152 Assert.That(attSo.IsAttachment);
153 Assert.That(attSo.UsesPhysics, Is.False);
154 Assert.That(attSo.IsTemporary, Is.False);
155
156 // Check appearance status
157 Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1));
158 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
159 }
160
161 [Test]
162 public void TestDetachAttachmentToGround()
163 {
164 TestHelpers.InMethod();
165// log4net.Config.XmlConfigurator.Configure();
166
167 AddPresence();
168
169 UUID attItemId = TestHelpers.ParseTail(0x2);
170 UUID attAssetId = TestHelpers.ParseTail(0x3);
171 string attName = "att";
172
173 UserInventoryHelpers.CreateInventoryItem(
174 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
175
176 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
177 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
178 m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
179
180 // Check scene presence status
181 Assert.That(m_presence.HasAttachments(), Is.False);
182 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
183 Assert.That(attachments.Count, Is.EqualTo(0));
184
185 // Check appearance status
186 Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
187
188 // Check item status
189 Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
190
191 // Check object in scene
192 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
193 }
194
195 [Test]
196 public void TestDetachAttachmentToInventory()
197 {
198 TestHelpers.InMethod();
199// log4net.Config.XmlConfigurator.Configure();
200
201 AddPresence();
202
203 UUID attItemId = TestHelpers.ParseTail(0x2);
204 UUID attAssetId = TestHelpers.ParseTail(0x3);
205 string attName = "att";
206
207 UserInventoryHelpers.CreateInventoryItem(
208 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
209
210 m_attMod.RezSingleAttachmentFromInventory(
211 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
212 m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
213
214 // Check status on scene presence
215 Assert.That(m_presence.HasAttachments(), Is.False);
216 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
217 Assert.That(attachments.Count, Is.EqualTo(0));
218
219 // Check item status
220 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
221 }
222
223 /// <summary>
224 /// Test that attachments don't hang about in the scene when the agent is closed
225 /// </summary>
226 [Test]
227 public void TestRemoveAttachmentsOnAvatarExit()
228 {
229 TestHelpers.InMethod();
230// log4net.Config.XmlConfigurator.Configure();
231
232 UUID userId = TestHelpers.ParseTail(0x1);
233 UUID attItemId = TestHelpers.ParseTail(0x2);
234 UUID attAssetId = TestHelpers.ParseTail(0x3);
235 string attName = "att";
236
237 UserAccountHelpers.CreateUserWithInventory(scene, userId);
238 InventoryItemBase attItem
239 = UserInventoryHelpers.CreateInventoryItem(
240 scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
241
242 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
243 acd.Appearance = new AvatarAppearance();
244 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
245 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
246
247 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
248
249 scene.IncomingCloseAgent(presence.UUID);
250
251 // Check that we can't retrieve this attachment from the scene.
252 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
253 }
254
255 [Test]
256 public void TestRezAttachmentsOnAvatarEntrance()
257 {
258 TestHelpers.InMethod();
259// log4net.Config.XmlConfigurator.Configure();
260
261 UUID userId = TestHelpers.ParseTail(0x1);
262 UUID attItemId = TestHelpers.ParseTail(0x2);
263 UUID attAssetId = TestHelpers.ParseTail(0x3);
264 string attName = "att";
265
266 UserAccountHelpers.CreateUserWithInventory(scene, userId);
267 InventoryItemBase attItem
268 = UserInventoryHelpers.CreateInventoryItem(
269 scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
270
271 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
272 acd.Appearance = new AvatarAppearance();
273 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
274 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
275
276 Assert.That(presence.HasAttachments(), Is.True);
277 List<SceneObjectGroup> attachments = presence.GetAttachments();
278
279 Assert.That(attachments.Count, Is.EqualTo(1));
280 SceneObjectGroup attSo = attachments[0];
281 Assert.That(attSo.Name, Is.EqualTo(attName));
282 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
283 Assert.That(attSo.IsAttachment);
284 Assert.That(attSo.UsesPhysics, Is.False);
285 Assert.That(attSo.IsTemporary, Is.False);
286
287 // Check appearance status
288 List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
289 Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
290 Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
291 Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId));
292 Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId));
293 Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
294 }
295
296 // I'm commenting this test because scene setup NEEDS InventoryService to
297 // be non-null
298 //[Test]
299// public void T032_CrossAttachments()
300// {
301// TestHelpers.InMethod();
302//
303// ScenePresence presence = scene.GetScenePresence(agent1);
304// ScenePresence presence2 = scene2.GetScenePresence(agent1);
305// presence2.AddAttachment(sog1);
306// presence2.AddAttachment(sog2);
307//
308// ISharedRegionModule serialiser = new SerialiserModule();
309// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
310// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
311//
312// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
313//
314// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
315// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
316// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
317// }
318 }
319} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index d02a305..b6a1564 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
104 public void NewClient(IClientAPI client) 104 public void NewClient(IClientAPI client)
105 { 105 {
106 client.OnRequestWearables += SendWearables; 106 client.OnRequestWearables += SendWearables;
107 client.OnSetAppearance += SetAppearance; 107 client.OnSetAppearance += SetAppearanceFromClient;
108 client.OnAvatarNowWearing += AvatarIsWearing; 108 client.OnAvatarNowWearing += AvatarIsWearing;
109 } 109 }
110 110
@@ -116,16 +116,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
116 #endregion 116 #endregion
117 117
118 /// <summary> 118 /// <summary>
119 /// Check for the existence of the baked texture assets. Request a rebake 119 /// Check for the existence of the baked texture assets.
120 /// unless checkonly is true.
121 /// </summary> 120 /// </summary>
122 /// <param name="client"></param> 121 /// <param name="client"></param>
123 /// <param name="checkonly"></param>
124 public bool ValidateBakedTextureCache(IClientAPI client) 122 public bool ValidateBakedTextureCache(IClientAPI client)
125 { 123 {
126 return ValidateBakedTextureCache(client, true); 124 return ValidateBakedTextureCache(client, true);
127 } 125 }
128 126
127 /// <summary>
128 /// Check for the existence of the baked texture assets. Request a rebake
129 /// unless checkonly is true.
130 /// </summary>
131 /// <param name="client"></param>
132 /// <param name="checkonly"></param>
129 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly) 133 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
130 { 134 {
131 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 135 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
@@ -147,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
147 if (face == null) 151 if (face == null)
148 continue; 152 continue;
149 153
154// m_log.DebugFormat(
155// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
156// face.TextureID, idx, client.Name, client.AgentId);
157
150 // if the texture is one of the "defaults" then skip it 158 // if the texture is one of the "defaults" then skip it
151 // this should probably be more intelligent (skirt texture doesnt matter 159 // this should probably be more intelligent (skirt texture doesnt matter
152 // if the avatar isnt wearing a skirt) but if any of the main baked 160 // if the avatar isnt wearing a skirt) but if any of the main baked
@@ -156,13 +164,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
156 164
157 defonly = false; // found a non-default texture reference 165 defonly = false; // found a non-default texture reference
158 166
159 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 167 if (!CheckBakedTextureAsset(client, face.TextureID, idx))
160 { 168 {
161 // the asset didn't exist if we are only checking, then we found a bad 169 // the asset didn't exist if we are only checking, then we found a bad
162 // one and we're done otherwise, ask for a rebake 170 // one and we're done otherwise, ask for a rebake
163 if (checkonly) return false; 171 if (checkonly)
172 return false;
164 173
165 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID); 174 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID);
175
166 client.SendRebakeAvatarTextures(face.TextureID); 176 client.SendRebakeAvatarTextures(face.TextureID);
167 } 177 }
168 } 178 }
@@ -174,16 +184,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
174 } 184 }
175 185
176 /// <summary> 186 /// <summary>
177 /// Set appearance data (textureentry and slider settings) received from the client 187 /// Set appearance data (texture asset IDs and slider settings) received from the client
178 /// </summary> 188 /// </summary>
189 /// <param name="client"></param>
179 /// <param name="texture"></param> 190 /// <param name="texture"></param>
180 /// <param name="visualParam"></param> 191 /// <param name="visualParam"></param>
181 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 192 public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
182 { 193 {
183 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 194 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
184 if (sp == null) 195 if (sp == null)
185 { 196 {
186 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId); 197 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
187 return; 198 return;
188 } 199 }
189 200
@@ -211,18 +222,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
211 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 222 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
212 223
213 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId); 224 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
214 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); }); 225 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });
215 226
216 // This appears to be set only in the final stage of the appearance 227 // This appears to be set only in the final stage of the appearance
217 // update transaction. In theory, we should be able to do an immediate 228 // update transaction. In theory, we should be able to do an immediate
218 // appearance send and save here. 229 // appearance send and save here.
219 230
220 // save only if there were changes, send no matter what (doesn't hurt to send twice)
221 if (changed)
222 QueueAppearanceSave(client.AgentId);
223 QueueAppearanceSend(client.AgentId);
224 } 231 }
232 // save only if there were changes, send no matter what (doesn't hurt to send twice)
233 if (changed)
234 QueueAppearanceSave(client.AgentId);
225 235
236 QueueAppearanceSend(client.AgentId);
226 } 237 }
227 238
228 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); 239 // 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
246 return true; 257 return true;
247 } 258 }
248 259
260 public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
261 {
262 ScenePresence sp = m_scene.GetScenePresence(agentId);
263
264 if (sp == null)
265 return new Dictionary<BakeType, Primitive.TextureEntryFace>();
266
267 return GetBakedTextureFaces(sp);
268 }
269
270 private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
271 {
272 if (sp.IsChildAgent)
273 return new Dictionary<BakeType, Primitive.TextureEntryFace>();
274
275 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
276 = new Dictionary<BakeType, Primitive.TextureEntryFace>();
277
278 AvatarAppearance appearance = sp.Appearance;
279 Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
280
281 foreach (int i in Enum.GetValues(typeof(BakeType)))
282 {
283 BakeType bakeType = (BakeType)i;
284
285 if (bakeType == BakeType.Unknown)
286 continue;
287
288// m_log.DebugFormat(
289// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
290// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
291
292 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
293 bakedTextures[bakeType] = faceTextures[ftIndex];
294 }
295
296 return bakedTextures;
297 }
298
299 public bool SaveBakedTextures(UUID agentId)
300 {
301 ScenePresence sp = m_scene.GetScenePresence(agentId);
302
303 if (sp == null)
304 return false;
305
306 m_log.DebugFormat(
307 "[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
308 sp.Name, m_scene.RegionInfo.RegionName);
309
310 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
311
312 if (bakedTextures.Count == 0)
313 return false;
314
315 foreach (BakeType bakeType in bakedTextures.Keys)
316 {
317 Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
318
319 if (bakedTextureFace == null)
320 {
321 m_log.WarnFormat(
322 "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
323 bakeType, sp.Name, m_scene.RegionInfo.RegionName);
324
325 continue;
326 }
327
328 AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
329
330 if (asset != null)
331 {
332 asset.Temporary = false;
333 asset.Local = false;
334 m_scene.AssetService.Store(asset);
335 }
336 else
337 {
338 m_log.WarnFormat(
339 "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
340 bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
341 }
342 }
343
344// for (int i = 0; i < faceTextures.Length; i++)
345// {
346//// m_log.DebugFormat(
347//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
348//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
349//
350// if (faceTextures[i] == null)
351// continue;
352//
353// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString());
354//
355// if (asset != null)
356// {
357// asset.Temporary = false;
358// m_scene.AssetService.Store(asset);
359// }
360// else
361// {
362// m_log.WarnFormat(
363// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently",
364// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName);
365// }
366// }
367
368 return true;
369 }
370
249 #region UpdateAppearanceTimer 371 #region UpdateAppearanceTimer
250 372
251 /// <summary> 373 /// <summary>
@@ -278,26 +400,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
278 } 400 }
279 } 401 }
280 402
281 private void HandleAppearanceSend(UUID agentid) 403 private void SaveAppearance(UUID agentid)
282 { 404 {
283 ScenePresence sp = m_scene.GetScenePresence(agentid); 405 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
284 if (sp == null) 406 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
285 { 407 // number seperators.
286 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 408 Culture.SetCurrentCulture();
287 return;
288 }
289
290 // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
291 409
292 // Send the appearance to everyone in the scene
293 sp.SendAppearanceToAllOtherAgents();
294
295 // Send animations back to the avatar as well
296 sp.Animator.SendAnimPack();
297 }
298
299 private void HandleAppearanceSave(UUID agentid)
300 {
301 ScenePresence sp = m_scene.GetScenePresence(agentid); 410 ScenePresence sp = m_scene.GetScenePresence(agentid);
302 if (sp == null) 411 if (sp == null)
303 { 412 {
@@ -321,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
321 { 430 {
322 if (kvp.Value < now) 431 if (kvp.Value < now)
323 { 432 {
324 Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); 433 Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); });
325 m_sendqueue.Remove(kvp.Key); 434 m_sendqueue.Remove(kvp.Key);
326 } 435 }
327 } 436 }
@@ -334,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
334 { 443 {
335 if (kvp.Value < now) 444 if (kvp.Value < now)
336 { 445 {
337 Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); 446 Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); });
338 m_savequeue.Remove(kvp.Key); 447 m_savequeue.Remove(kvp.Key);
339 } 448 }
340 } 449 }
@@ -380,11 +489,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
380 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); 489 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
381 490
382 // we need to clean out the existing textures 491 // we need to clean out the existing textures
383 sp.Appearance.ResetAppearance(); 492 sp.Appearance.ResetAppearance();
384 493
385 // operate on a copy of the appearance so we don't have to lock anything 494 // operate on a copy of the appearance so we don't have to lock anything yet
386 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 495 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
387 496
388 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 497 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
389 { 498 {
390 if (wear.Type < AvatarWearable.MAX_WEARABLES) 499 if (wear.Type < AvatarWearable.MAX_WEARABLES)
@@ -396,12 +505,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
396 // This could take awhile since it needs to pull inventory 505 // This could take awhile since it needs to pull inventory
397 SetAppearanceAssets(sp.UUID, ref avatAppearance); 506 SetAppearanceAssets(sp.UUID, ref avatAppearance);
398 507
399 // could get fancier with the locks here, but in the spirit of "last write wins" 508 lock (m_setAppearanceLock)
400 // this should work correctly, also, we don't need to send the appearance here 509 {
401 // since the "iswearing" will trigger a new set of visual param and baked texture changes 510 // Update only those fields that we have changed. This is important because the viewer
402 // when those complete, the new appearance will be sent 511 // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
403 sp.Appearance = avatAppearance; 512 // shouldn't overwrite the changes made in SetAppearance.
404 QueueAppearanceSave(client.AgentId); 513 sp.Appearance.Wearables = avatAppearance.Wearables;
514 sp.Appearance.Texture = avatAppearance.Texture;
515
516 // We don't need to send the appearance here since the "iswearing" will trigger a new set
517 // of visual param and baked texture changes. When those complete, the new appearance will be sent
518
519 QueueAppearanceSave(client.AgentId);
520 }
521 }
522
523 public bool SendAppearance(UUID agentId)
524 {
525 ScenePresence sp = m_scene.GetScenePresence(agentId);
526 if (sp == null)
527 {
528 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
529 return false;
530 }
531
532 // Send the appearance to everyone in the scene
533 sp.SendAppearanceToAllOtherAgents();
534
535 // Send animations back to the avatar as well
536 sp.Animator.SendAnimPack();
537
538 return true;
405 } 539 }
406 540
407 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 541 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
new file mode 100644
index 0000000..7b2f14e
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using Nini.Config;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Asset;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{
41 [TestFixture]
42 public class AvatarFactoryModuleTests
43 {
44 /// <summary>
45 /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.
46 /// </summary>
47 [Test]
48 public void TestSetAppearance()
49 {
50 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure();
52
53 UUID userId = TestHelpers.ParseTail(0x1);
54
55 AvatarFactoryModule afm = new AvatarFactoryModule();
56 TestScene scene = SceneHelpers.SetupScene();
57 SceneHelpers.SetupSceneModules(scene, afm);
58 IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
59
60 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i;
63
64 afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
65
66 ScenePresence sp = scene.GetScenePresence(userId);
67
68 // TODO: Check baked texture
69 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
70 }
71
72 [Test]
73 public void TestSaveBakedTextures()
74 {
75 TestHelpers.InMethod();
76// log4net.Config.XmlConfigurator.Configure();
77
78 UUID userId = TestHelpers.ParseTail(0x1);
79 UUID eyesTextureId = TestHelpers.ParseTail(0x2);
80
81 // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
82 // to the AssetService, which will then store temporary and local assets permanently
83 CoreAssetCache assetCache = new CoreAssetCache();
84
85 AvatarFactoryModule afm = new AvatarFactoryModule();
86 TestScene scene = SceneHelpers.SetupScene(assetCache);
87 SceneHelpers.SetupSceneModules(scene, afm);
88 IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
89
90 // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
91 AssetBase uploadedAsset;
92 uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString());
93 uploadedAsset.Data = new byte[] { 2 };
94 uploadedAsset.Temporary = true;
95 uploadedAsset.Local = true; // Local assets aren't persisted, non-local are
96 scene.AssetService.Store(uploadedAsset);
97
98 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
99 for (byte i = 0; i < visualParams.Length; i++)
100 visualParams[i] = i;
101
102 Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
103 uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
104 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
105 eyesFace.TextureID = eyesTextureId;
106
107 afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
108 afm.SaveBakedTextures(userId);
109// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
110
111 // We should also inpsect the asset data store layer directly, but this is difficult to get at right now.
112 assetCache.Clear();
113
114 AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString());
115 Assert.That(eyesBake, Is.Not.Null);
116 Assert.That(eyesBake.Temporary, Is.False);
117 Assert.That(eyesBake.Local, Is.False);
118 }
119 }
120} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 1a0b914..3373bd5 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -172,69 +172,62 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
172 private void RetrieveInstantMessages(IClientAPI client) 172 private void RetrieveInstantMessages(IClientAPI client)
173 { 173 {
174 if (m_RestURL == String.Empty) 174 if (m_RestURL == String.Empty)
175 {
175 return; 176 return;
177 }
178 else
179 {
180 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
176 181
177 m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); 182 List<GridInstantMessage> msglist
178 183 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
179 List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
180 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 184 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
181 185
182 if (msglist != null) 186 if (msglist != null)
183 {
184 foreach (GridInstantMessage im in msglist)
185 { 187 {
186 // client.SendInstantMessage(im); 188 foreach (GridInstantMessage im in msglist)
187 189 {
188 // Send through scene event manager so all modules get a chance 190 // client.SendInstantMessage(im);
189 // to look at this message before it gets delivered. 191
190 // 192 // Send through scene event manager so all modules get a chance
191 // Needed for proper state management for stored group 193 // to look at this message before it gets delivered.
192 // invitations 194 //
193 // 195 // Needed for proper state management for stored group
194 196 // invitations
195 im.offline = 1; 197 //
196 198
197 Scene s = FindScene(client.AgentId); 199 im.offline = 1;
198 if (s != null) 200
199 s.EventManager.TriggerIncomingInstantMessage(im); 201 Scene s = FindScene(client.AgentId);
202 if (s != null)
203 s.EventManager.TriggerIncomingInstantMessage(im);
204 }
200 } 205 }
201 } 206 }
202 } 207 }
203 208
204 private void UndeliveredMessage(GridInstantMessage im) 209 private void UndeliveredMessage(GridInstantMessage im)
205 { 210 {
206 if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && 211 if ((im.offline != 0)
207 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 212 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
208 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
209 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
210 im.dialog != (byte)InstantMessageDialog.InventoryOffered)
211 { 213 {
212 return; 214 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
213 } 215 "POST", m_RestURL + "/SaveMessage/", im);
214
215 // It's not delivered. Make sure the scope id is saved
216 // We don't need the imSessionID here anymore, overwrite it
217 Scene scene = FindScene(new UUID(im.fromAgentID));
218 if (scene == null)
219 scene = m_SceneList[0];
220
221 bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
222 "POST", m_RestURL+"/SaveMessage/?scope=" +
223 scene.RegionInfo.ScopeID.ToString(), im);
224 216
225 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 217 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
226 { 218 {
227 IClientAPI client = FindClient(new UUID(im.fromAgentID)); 219 IClientAPI client = FindClient(new UUID(im.fromAgentID));
228 if (client == null) 220 if (client == null)
229 return; 221 return;
230 222
231 client.SendInstantMessage(new GridInstantMessage( 223 client.SendInstantMessage(new GridInstantMessage(
232 null, new UUID(im.toAgentID), 224 null, new UUID(im.toAgentID),
233 "System", new UUID(im.fromAgentID), 225 "System", new UUID(im.fromAgentID),
234 (byte)InstantMessageDialog.MessageFromAgent, 226 (byte)InstantMessageDialog.MessageFromAgent,
235 "User is not logged in. "+ 227 "User is not logged in. " +
236 (success ? "Message saved." : "Message not saved"), 228 (success ? "Message saved." : "Message not saved"),
237 false, new Vector3())); 229 false, new Vector3()));
230 }
238 } 231 }
239 } 232 }
240 } 233 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index aadeedb..19ef571 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -100,8 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
100// log4net.Config.XmlConfigurator.Configure(); 100// log4net.Config.XmlConfigurator.Configure();
101 101
102 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 102 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
103 Scene scene = SceneSetupHelpers.SetupScene(); 103 Scene scene = SceneHelpers.SetupScene();
104 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 104 SceneHelpers.SetupSceneModules(scene, archiverModule);
105 105
106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
107 107
@@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
109 109
110 // Create scene object asset 110 // Create scene object asset
111 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 111 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
112 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50); 112 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
113 113
114 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 114 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
115 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 115 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -127,10 +127,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
127 scene.AddInventoryItem(item1); 127 scene.AddInventoryItem(item1);
128 128
129 // Create coalesced objects asset 129 // Create coalesced objects asset
130 SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120); 130 SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
131 cobj1.AbsolutePosition = new Vector3(15, 30, 45); 131 cobj1.AbsolutePosition = new Vector3(15, 30, 45);
132 132
133 SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140); 133 SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
134 cobj2.AbsolutePosition = new Vector3(25, 50, 75); 134 cobj2.AbsolutePosition = new Vector3(25, 50, 75);
135 135
136 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2); 136 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index ae3ab21..e409c8e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -61,14 +61,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
61 SerialiserModule serialiserModule = new SerialiserModule(); 61 SerialiserModule serialiserModule = new SerialiserModule();
62 m_archiverModule = new InventoryArchiverModule(); 62 m_archiverModule = new InventoryArchiverModule();
63 63
64 m_scene = SceneSetupHelpers.SetupScene(); 64 m_scene = SceneHelpers.SetupScene();
65 SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); 65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
66 } 66 }
67 67
68 [Test] 68 [Test]
69 public void TestLoadCoalesecedItem() 69 public void TestLoadCoalesecedItem()
70 { 70 {
71 TestHelper.InMethod(); 71 TestHelpers.InMethod();
72// log4net.Config.XmlConfigurator.Configure(); 72// log4net.Config.XmlConfigurator.Configure();
73 73
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); 74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
104 [Test] 104 [Test]
105 public void TestOrder() 105 public void TestOrder()
106 { 106 {
107 TestHelper.InMethod(); 107 TestHelpers.InMethod();
108// log4net.Config.XmlConfigurator.Configure(); 108// log4net.Config.XmlConfigurator.Configure();
109 109
110 MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); 110 MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes);
@@ -129,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
129 [Test] 129 [Test]
130 public void TestSaveItemToIar() 130 public void TestSaveItemToIar()
131 { 131 {
132 TestHelper.InMethod(); 132 TestHelpers.InMethod();
133// log4net.Config.XmlConfigurator.Configure(); 133// log4net.Config.XmlConfigurator.Configure();
134 134
135 // Create user 135 // Create user
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
141 141
142 // Create asset 142 // Create asset
143 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 143 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
144 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); 144 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
145 145
146 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 146 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
147 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 147 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
224 [Test] 224 [Test]
225 public void TestSaveItemToIarNoAssets() 225 public void TestSaveItemToIarNoAssets()
226 { 226 {
227 TestHelper.InMethod(); 227 TestHelpers.InMethod();
228// log4net.Config.XmlConfigurator.Configure(); 228// log4net.Config.XmlConfigurator.Configure();
229 229
230 // Create user 230 // Create user
@@ -236,7 +236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
236 236
237 // Create asset 237 // Create asset
238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
239 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); 239 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
240 240
241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
325 [Test] 325 [Test]
326 public void TestLoadIarCreatorAccountPresent() 326 public void TestLoadIarCreatorAccountPresent()
327 { 327 {
328 TestHelper.InMethod(); 328 TestHelpers.InMethod();
329// log4net.Config.XmlConfigurator.Configure(); 329// log4net.Config.XmlConfigurator.Configure();
330 330
331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); 331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
@@ -357,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
357 [Test] 357 [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358 public void TestLoadIarV0_1SameNameCreator()
359 { 359 {
360 TestHelper.InMethod(); 360 TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// log4net.Config.XmlConfigurator.Configure();
362 362
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
@@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
390 [Test] 390 [Test]
391 public void TestLoadIarV0_1AbsentCreator() 391 public void TestLoadIarV0_1AbsentCreator()
392 { 392 {
393 TestHelper.InMethod(); 393 TestHelpers.InMethod();
394// log4net.Config.XmlConfigurator.Configure(); 394// log4net.Config.XmlConfigurator.Configure();
395 395
396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); 396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
index 127d5f8..417c20c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
@@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
57 [Test] 57 [Test]
58 public void TestSavePathToIarV0_1() 58 public void TestSavePathToIarV0_1()
59 { 59 {
60 TestHelper.InMethod(); 60 TestHelpers.InMethod();
61// log4net.Config.XmlConfigurator.Configure(); 61// log4net.Config.XmlConfigurator.Configure();
62 62
63 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 63 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
64 64
65 Scene scene = SceneSetupHelpers.SetupScene(); 65 Scene scene = SceneHelpers.SetupScene();
66 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 66 SceneHelpers.SetupSceneModules(scene, archiverModule);
67 67
68 // Create user 68 // Create user
69 string userFirstName = "Jock"; 69 string userFirstName = "Jock";
@@ -172,16 +172,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
172 [Test] 172 [Test]
173 public void TestLoadIarToInventoryPaths() 173 public void TestLoadIarToInventoryPaths()
174 { 174 {
175 TestHelper.InMethod(); 175 TestHelpers.InMethod();
176// log4net.Config.XmlConfigurator.Configure(); 176// log4net.Config.XmlConfigurator.Configure();
177 177
178 SerialiserModule serialiserModule = new SerialiserModule(); 178 SerialiserModule serialiserModule = new SerialiserModule();
179 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 179 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
180 180
181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene 181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
182 Scene scene = SceneSetupHelpers.SetupScene(); 182 Scene scene = SceneHelpers.SetupScene();
183 183
184 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 184 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
185 185
186 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); 186 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
187 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 187 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
@@ -217,13 +217,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
217 [Test] 217 [Test]
218 public void TestLoadIarPathStartsWithSlash() 218 public void TestLoadIarPathStartsWithSlash()
219 { 219 {
220 TestHelper.InMethod(); 220 TestHelpers.InMethod();
221// log4net.Config.XmlConfigurator.Configure(); 221// log4net.Config.XmlConfigurator.Configure();
222 222
223 SerialiserModule serialiserModule = new SerialiserModule(); 223 SerialiserModule serialiserModule = new SerialiserModule();
224 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 224 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
225 Scene scene = SceneSetupHelpers.SetupScene(); 225 Scene scene = SceneHelpers.SetupScene();
226 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 226 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
227 227
228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); 228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
229 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); 229 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
238 [Test] 238 [Test]
239 public void TestLoadIarPathWithEscapedChars() 239 public void TestLoadIarPathWithEscapedChars()
240 { 240 {
241 TestHelper.InMethod(); 241 TestHelpers.InMethod();
242// log4net.Config.XmlConfigurator.Configure(); 242// log4net.Config.XmlConfigurator.Configure();
243 243
244 string itemName = "You & you are a mean/man/"; 244 string itemName = "You & you are a mean/man/";
@@ -247,8 +247,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
247 247
248 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 248 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
249 249
250 Scene scene = SceneSetupHelpers.SetupScene(); 250 Scene scene = SceneHelpers.SetupScene();
251 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 251 SceneHelpers.SetupSceneModules(scene, archiverModule);
252 252
253 // Create user 253 // Create user
254 string userFirstName = "Jock"; 254 string userFirstName = "Jock";
@@ -323,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
323 [Test] 323 [Test]
324 public void TestNewIarPath() 324 public void TestNewIarPath()
325 { 325 {
326 TestHelper.InMethod(); 326 TestHelpers.InMethod();
327// log4net.Config.XmlConfigurator.Configure(); 327// log4net.Config.XmlConfigurator.Configure();
328 328
329 Scene scene = SceneSetupHelpers.SetupScene(); 329 Scene scene = SceneHelpers.SetupScene();
330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
331 331
332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); 332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
@@ -390,10 +390,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
390 [Test] 390 [Test]
391 public void TestPartExistingIarPath() 391 public void TestPartExistingIarPath()
392 { 392 {
393 TestHelper.InMethod(); 393 TestHelpers.InMethod();
394 //log4net.Config.XmlConfigurator.Configure(); 394 //log4net.Config.XmlConfigurator.Configure();
395 395
396 Scene scene = SceneSetupHelpers.SetupScene(); 396 Scene scene = SceneHelpers.SetupScene();
397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
398 398
399 string folder1ExistingName = "a"; 399 string folder1ExistingName = "a";
@@ -441,10 +441,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
441 [Test] 441 [Test]
442 public void TestMergeIarPath() 442 public void TestMergeIarPath()
443 { 443 {
444 TestHelper.InMethod(); 444 TestHelpers.InMethod();
445// log4net.Config.XmlConfigurator.Configure(); 445// log4net.Config.XmlConfigurator.Configure();
446 446
447 Scene scene = SceneSetupHelpers.SetupScene(); 447 Scene scene = SceneHelpers.SetupScene();
448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
449 449
450 string folder1ExistingName = "a"; 450 string folder1ExistingName = "a";
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 528bc8d..120fd43 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -208,9 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
208 Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); 208 Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length);
209 209
210 if (user != null) 210 if (user != null)
211 {
212 user.ControllingClient.SendBulkUpdateInventory(folderCopy); 211 user.ControllingClient.SendBulkUpdateInventory(folderCopy);
213 }
214 212
215 // HACK!! 213 // HACK!!
216 im.imSessionID = folderID.Guid; 214 im.imSessionID = folderID.Guid;
@@ -240,9 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
240 Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); 238 Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16);
241 239
242 if (user != null) 240 if (user != null)
243 {
244 user.ControllingClient.SendBulkUpdateInventory(itemCopy); 241 user.ControllingClient.SendBulkUpdateInventory(itemCopy);
245 }
246 242
247 // HACK!! 243 // HACK!!
248 im.imSessionID = itemID.Guid; 244 im.imSessionID = itemID.Guid;
@@ -280,7 +276,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
280 else 276 else
281 { 277 {
282 if (m_TransferModule != null) 278 if (m_TransferModule != null)
283 m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); 279 m_TransferModule.SendInstantMessage(im, delegate(bool success) {
280 // Send BulkUpdateInventory
281 IInventoryService invService = scene.InventoryService;
282 UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
283
284 InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
285 folder = invService.GetFolder(folder);
286
287 ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
288
289 // If the user has left the scene by the time the message comes back then we can't send
290 // them the update.
291 if (fromUser != null)
292 fromUser.ControllingClient.SendBulkUpdateInventory(folder);
293 });
284 } 294 }
285 } 295 }
286 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) 296 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index c82cfd2..d687e6a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
196 if (!(client.Scene is Scene)) 196 if (!(client.Scene is Scene))
197 return; 197 return;
198 198
199 Scene scene = (Scene)(client.Scene); 199// Scene scene = (Scene)(client.Scene);
200 200
201 GridInstantMessage im = null; 201 GridInstantMessage im = null;
202 if (m_PendingLures.TryGetValue(lureID, out im)) 202 if (m_PendingLures.TryGetValue(lureID, out im))
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
index 079e1b6..dee0ad4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
134 if (!(s is Scene)) 134 if (!(s is Scene))
135 return; 135 return;
136 136
137 Scene scene = (Scene)s; 137// Scene scene = (Scene)s;
138 138
139 string profileUrl = String.Empty; 139 string profileUrl = String.Empty;
140 string aboutText = String.Empty; 140 string aboutText = String.Empty;