aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
authorTom2011-09-04 07:06:36 -0700
committerTom2011-09-04 07:06:36 -0700
commit66dec3b8742eff04fbbcc6e3249fe4ba87986500 (patch)
tree76cc708a821d35fac5cdbbce2de304b47064e732 /OpenSim/Region/CoreModules/Avatar
parentGuard another nullref (diff)
parentFixed BulletSim config files for Linux *.so libraries. (diff)
downloadopensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.zip
opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.tar.gz
opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.tar.bz2
opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.tar.xz
Resolve merge commits, stage 1
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs513
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs274
-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.cs12
-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, 1021 insertions, 212 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 47476a9..8be0455 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,77 @@ 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);
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 foreach (SceneObjectGroup grp in sp.GetAttachments())
148 {
149 if (grp.HasGroupChanged) // Resizer scripts?
150 {
151 grp.IsAttachment = false;
152 grp.AbsolutePosition = grp.RootPart.AttachedPos;
153 UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID);
154 grp.IsAttachment = true;
155 }
156 }
157 }
158
159 public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
160 {
161 foreach (SceneObjectGroup sop in sp.GetAttachments())
162 {
163 sop.Scene.DeleteSceneObject(sop, silent);
164 }
165
166 sp.ClearAttachments();
94 } 167 }
95 168
96 /// <summary> 169 /// <summary>
@@ -102,10 +175,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
102 /// <param name="silent"></param> 175 /// <param name="silent"></param>
103 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) 176 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
104 { 177 {
105 m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); 178// m_log.DebugFormat(
179// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
180// objectLocalID, remoteClient.Name, AttachmentPt, silent);
106 181
107 try 182 try
108 { 183 {
184 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
185
186 if (sp == null)
187 {
188 m_log.ErrorFormat(
189 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
190 return;
191 }
192
109 // If we can't take it, we can't attach it! 193 // If we can't take it, we can't attach it!
110 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); 194 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
111 if (part == null) 195 if (part == null)
@@ -131,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
131 AttachmentPt &= 0x7f; 215 AttachmentPt &= 0x7f;
132 216
133 // Calls attach with a Zero position 217 // Calls attach with a Zero position
134 if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) 218 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
135 { 219 {
136 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); 220 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
137 221
@@ -144,73 +228,94 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
144 } 228 }
145 catch (Exception e) 229 catch (Exception e)
146 { 230 {
147 m_log.DebugFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}", e); 231 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
148 } 232 }
149 } 233 }
150 234
151 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) 235 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
152 { 236 {
237 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
238
239 if (sp == null)
240 {
241 m_log.ErrorFormat(
242 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
243 return false;
244 }
245
246 return AttachObject(sp, group, AttachmentPt, silent);
247 }
248
249 private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
250 {
251// m_log.DebugFormat(
252// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
253// group.Name, group.LocalId, sp.Name, AttachmentPt, silent);
254
255 if (sp.GetAttachments(attachmentPt).Contains(group))
256 {
257// m_log.WarnFormat(
258// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
259// group.Name, group.LocalId, sp.Name, AttachmentPt);
260
261 return false;
262 }
263
153 Vector3 attachPos = group.AbsolutePosition; 264 Vector3 attachPos = group.AbsolutePosition;
154 265
155 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 266 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
156 // be removed when that functionality is implemented in opensim 267 // be removed when that functionality is implemented in opensim
157 AttachmentPt &= 0x7f; 268 attachmentPt &= 0x7f;
158 269
159 // If the attachment point isn't the same as the one previously used 270 // 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 271 // set it's offset position = 0 so that it appears on the attachment point
161 // and not in a weird location somewhere unknown. 272 // and not in a weird location somewhere unknown.
162 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) 273 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
163 { 274 {
164 attachPos = Vector3.Zero; 275 attachPos = Vector3.Zero;
165 } 276 }
166 277
167 // AttachmentPt 0 means the client chose to 'wear' the attachment. 278 // AttachmentPt 0 means the client chose to 'wear' the attachment.
168 if (AttachmentPt == 0) 279 if (attachmentPt == 0)
169 { 280 {
170 // Check object for stored attachment point 281 // Check object for stored attachment point
171 AttachmentPt = (uint)group.GetAttachmentPoint(); 282 attachmentPt = group.AttachmentPoint;
172 } 283 }
173 284
174 // if we still didn't find a suitable attachment point....... 285 // if we still didn't find a suitable attachment point.......
175 if (AttachmentPt == 0) 286 if (attachmentPt == 0)
176 { 287 {
177 // Stick it on left hand with Zero Offset from the attachment point. 288 // Stick it on left hand with Zero Offset from the attachment point.
178 AttachmentPt = (uint)AttachmentPoint.LeftHand; 289 attachmentPt = (uint)AttachmentPoint.LeftHand;
179 attachPos = Vector3.Zero; 290 attachPos = Vector3.Zero;
180 } 291 }
181 292
182 group.SetAttachmentPoint((byte)AttachmentPt); 293 group.AttachmentPoint = attachmentPt;
183 group.AbsolutePosition = attachPos; 294 group.AbsolutePosition = attachPos;
184 295
185 // Remove any previous attachments 296 // Remove any previous attachments
186 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
187 UUID itemID = UUID.Zero; 297 UUID itemID = UUID.Zero;
188 if (sp != null)
189 {
190 foreach (SceneObjectGroup grp in sp.Attachments)
191 {
192 if (grp.GetAttachmentPoint() == (byte)AttachmentPt)
193 {
194 itemID = grp.GetFromItemID();
195 break;
196 }
197 }
198 if (itemID != UUID.Zero)
199 DetachSingleAttachmentToInv(itemID, remoteClient);
200 }
201 298
202 if (group.GetFromItemID() == UUID.Zero) 299 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
203 { 300
204 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); 301 // At the moment we can only deal with a single attachment
205 } 302 // We also don't want to do any of the inventory operations for an NPC.
206 else 303 if (sp.PresenceType != PresenceType.Npc)
207 { 304 {
305 if (attachments.Count != 0)
306 itemID = attachments[0].GetFromItemID();
307
308 if (itemID != UUID.Zero)
309 DetachSingleAttachmentToInv(itemID, sp);
310
208 itemID = group.GetFromItemID(); 311 itemID = group.GetFromItemID();
312 if (itemID == UUID.Zero)
313 itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID;
314
315 ShowAttachInUserInventory(sp, attachmentPt, itemID, group);
209 } 316 }
210 317
211 ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group); 318 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
212
213 AttachToAgent(sp, group, AttachmentPt, attachPos, silent);
214 319
215 return true; 320 return true;
216 } 321 }
@@ -226,12 +331,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
226 } 331 }
227 } 332 }
228 333
229 public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 334 public ISceneEntity RezSingleAttachmentFromInventory(
335 IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
230 { 336 {
231 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); 337 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true);
232 } 338 }
233 339
234 public UUID RezSingleAttachmentFromInventory( 340 public ISceneEntity RezSingleAttachmentFromInventory(
235 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) 341 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus)
236 { 342 {
237 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); 343 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
@@ -239,7 +345,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
239 345
240 public UUID RezSingleAttachmentFromInventory( 346 public UUID RezSingleAttachmentFromInventory(
241 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) 347 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
348 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
349
242 { 350 {
351 if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); return null; }
243 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 352 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
244 // be removed when that functionality is implemented in opensim 353 // be removed when that functionality is implemented in opensim
245 AttachmentPt &= 0x7f; 354 AttachmentPt &= 0x7f;
@@ -249,15 +358,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
249 if (updateInventoryStatus) 358 if (updateInventoryStatus)
250 { 359 {
251 if (att == null) 360 if (att == null)
252 ShowDetachInUserInventory(itemID, remoteClient); 361 DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
253 else 362 else
254 ShowAttachInUserInventory(att, remoteClient, itemID, AttachmentPt); 363 ShowAttachInUserInventory(att, sp, itemID, AttachmentPt);
255 } 364 }
256 365
257 if (null == att) 366 return att;
258 return UUID.Zero;
259 else
260 return att.UUID;
261 } 367 }
262 368
263 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 369 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
@@ -266,12 +372,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
266 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 372 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
267 if (invAccess != null) 373 if (invAccess != null)
268 { 374 {
269 SceneObjectGroup objatt = invAccess.RezObject(remoteClient, 375 SceneObjectGroup objatt;
270 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 376
271 false, false, remoteClient.AgentId, true); 377 if (itemID != UUID.Zero)
378 objatt = invAccess.RezObject(sp.ControllingClient,
379 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
380 false, false, sp.UUID, true);
381 else
382 objatt = invAccess.RezObject(sp.ControllingClient,
383 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
384 false, false, sp.UUID, true);
272 385
273// m_log.DebugFormat( 386// m_log.DebugFormat(
274// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", 387// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
275// objatt.Name, remoteClient.Name, AttachmentPt); 388// objatt.Name, remoteClient.Name, AttachmentPt);
276 389
277 if (objatt != null) 390 if (objatt != null)
@@ -281,17 +394,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
281 // since scripts aren't running yet. So, clear it here. 394 // since scripts aren't running yet. So, clear it here.
282 objatt.HasGroupChanged = false; 395 objatt.HasGroupChanged = false;
283 bool tainted = false; 396 bool tainted = false;
284 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 397 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
285 tainted = true; 398 tainted = true;
286 399
287 // This will throw if the attachment fails 400 // This will throw if the attachment fails
288 try 401 try
289 { 402 {
290 AttachObject(remoteClient, objatt, AttachmentPt, false); 403 AttachObject(sp, objatt, attachmentPt, false);
291 } 404 }
292 catch 405 catch (Exception e)
293 { 406 {
407 m_log.ErrorFormat(
408 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
409 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
410
294 // Make sure the object doesn't stick around and bail 411 // Make sure the object doesn't stick around and bail
412 sp.RemoveAttachment(objatt);
295 m_scene.DeleteSceneObject(objatt, false); 413 m_scene.DeleteSceneObject(objatt, false);
296 return null; 414 return null;
297 } 415 }
@@ -311,13 +429,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
311 objatt.ResumeScripts(); 429 objatt.ResumeScripts();
312 430
313 // Do this last so that event listeners have access to all the effects of the attachment 431 // 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); 432 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
315 } 433 }
316 else 434 else
317 { 435 {
318 m_log.WarnFormat( 436 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", 437 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
320 itemID, remoteClient.Name, AttachmentPt); 438 itemID, sp.Name, attachmentPt);
321 } 439 }
322 440
323 return objatt; 441 return objatt;
@@ -330,31 +448,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
330 /// Update the user inventory to the attachment of an item 448 /// Update the user inventory to the attachment of an item
331 /// </summary> 449 /// </summary>
332 /// <param name="att"></param> 450 /// <param name="att"></param>
333 /// <param name="remoteClient"></param> 451 /// <param name="sp"></param>
334 /// <param name="itemID"></param> 452 /// <param name="itemID"></param>
335 /// <param name="AttachmentPt"></param> 453 /// <param name="attachmentPoint"></param>
336 /// <returns></returns> 454 /// <returns></returns>
337 protected UUID ShowAttachInUserInventory( 455 private UUID ShowAttachInUserInventory(
338 SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 456 SceneObjectGroup att, IScenePresence sp, UUID itemID, uint attachmentPoint)
339 { 457 {
340// m_log.DebugFormat( 458// m_log.DebugFormat(
341// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", 459// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}",
342// remoteClient.Name, att.Name, itemID); 460// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt);
343 461
344 if (!att.IsDeleted) 462 if (!att.IsDeleted)
345 AttachmentPt = att.RootPart.AttachmentPoint; 463 attachmentPoint = att.AttachmentPoint;
346 464
347 ScenePresence presence; 465 ScenePresence presence;
348 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 466 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
349 { 467 {
350 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 468 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
351 if (m_scene.InventoryService != null) 469 if (m_scene.InventoryService != null)
352 item = m_scene.InventoryService.GetItem(item); 470 item = m_scene.InventoryService.GetItem(item);
353 471
354 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 472 bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID);
355 if (changed && m_scene.AvatarFactory != null) 473 if (changed && m_scene.AvatarFactory != null)
356 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 474 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
357 }
358 475
359 return att.UUID; 476 return att.UUID;
360 } 477 }
@@ -362,12 +479,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
362 /// <summary> 479 /// <summary>
363 /// Update the user inventory to reflect an attachment 480 /// Update the user inventory to reflect an attachment
364 /// </summary> 481 /// </summary>
365 /// <param name="remoteClient"></param> 482 /// <param name="sp"></param>
366 /// <param name="AttachmentPt"></param> 483 /// <param name="AttachmentPt"></param>
367 /// <param name="itemID"></param> 484 /// <param name="itemID"></param>
368 /// <param name="att"></param> 485 /// <param name="att"></param>
369 protected void ShowAttachInUserInventory( 486 private void ShowAttachInUserInventory(
370 IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 487 IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
371 { 488 {
372// m_log.DebugFormat( 489// m_log.DebugFormat(
373// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 490// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -390,23 +507,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
390 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!"); 507 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
391 return; 508 return;
392 } 509 }
510 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
393 511
394 ScenePresence presence; 512
395 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 513
396 { 514
397 // XXYY!! 515
398 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 516
399 if (item == null) 517 item = m_scene.InventoryService.GetItem(item);
400 m_log.Error("[ATTACHMENT]: item == null"); 518 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
401 if (m_scene == null) 519 if (changed && m_scene.AvatarFactory != null)
402 m_log.Error("[ATTACHMENT]: m_scene == null"); 520 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 } 521 }
411 522
412 public void DetachObject(uint objectLocalID, IClientAPI remoteClient) 523 public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
@@ -414,12 +525,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
414 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); 525 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
415 if (group != null) 526 if (group != null)
416 { 527 {
417 //group.DetachToGround(); 528 DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
418 ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
419 } 529 }
420 } 530 }
421 531
422 public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient) 532 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
423 { 533 {
424 ScenePresence presence; 534 ScenePresence presence;
425 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 535 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
@@ -430,34 +540,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
430 bool changed = presence.Appearance.DetachAttachment(itemID); 540 bool changed = presence.Appearance.DetachAttachment(itemID);
431 if (changed && m_scene.AvatarFactory != null) 541 if (changed && m_scene.AvatarFactory != null)
432 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 542 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
433 }
434 543
435 DetachSingleAttachmentToInv(itemID, remoteClient); 544 DetachSingleAttachmentToInv(itemID, presence);
545 }
436 } 546 }
437 547
438 public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) 548 public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient)
439 { 549 {
440 SceneObjectPart part = m_scene.GetSceneObjectPart(itemID); 550// m_log.DebugFormat(
441 if (part == null || part.ParentGroup == null) 551// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
552// remoteClient.Name, sceneObjectID);
553
554 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
555
556 if (so == null)
442 return; 557 return;
443 558
444 if (part.ParentGroup.RootPart.AttachedAvatar != remoteClient.AgentId) 559 if (so.AttachedAvatar != remoteClient.AgentId)
445 return; 560 return;
446 561
447 UUID inventoryID = part.ParentGroup.GetFromItemID(); 562 UUID inventoryID = so.GetFromItemID();
563
564// m_log.DebugFormat(
565// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
566// so.Name, so.LocalId, inventoryID);
448 567
449 ScenePresence presence; 568 ScenePresence presence;
450 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 569 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
451 { 570 {
452 if (!m_scene.Permissions.CanRezObject( 571 if (!m_scene.Permissions.CanRezObject(
453 part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) 572 so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
454 return; 573 return;
455 574
456 bool changed = presence.Appearance.DetachAttachment(itemID); 575 bool changed = presence.Appearance.DetachAttachment(inventoryID);
457 if (changed && m_scene.AvatarFactory != null) 576 if (changed && m_scene.AvatarFactory != null)
458 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 577 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
459 578
460 part.ParentGroup.DetachToGround(); 579 presence.RemoveAttachment(so);
580 DetachSceneObjectToGround(so, presence);
461 581
462 List<UUID> uuids = new List<UUID>(); 582 List<UUID> uuids = new List<UUID>();
463 uuids.Add(inventoryID); 583 uuids.Add(inventoryID);
@@ -465,12 +585,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
465 remoteClient.SendRemoveInventoryItem(inventoryID); 585 remoteClient.SendRemoveInventoryItem(inventoryID);
466 } 586 }
467 587
468 m_scene.EventManager.TriggerOnAttach(part.ParentGroup.LocalId, itemID, UUID.Zero); 588 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
589 }
590
591 /// <summary>
592 /// Detach the given scene object to the ground.
593 /// </summary>
594 /// <remarks>
595 /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
596 /// </remarks>
597 /// <param name="so">The scene object to detach.</param>
598 /// <param name="sp">The scene presence from which the scene object is being detached.</param>
599 private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
600 {
601 SceneObjectPart rootPart = so.RootPart;
602
603 rootPart.FromItemID = UUID.Zero;
604 so.AbsolutePosition = sp.AbsolutePosition;
605 so.AttachedAvatar = UUID.Zero;
606 rootPart.SetParentLocalId(0);
607 so.ClearPartAttachmentData();
608 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
609 so.HasGroupChanged = true;
610 rootPart.Rezzed = DateTime.Now;
611 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
612 so.AttachToBackup();
613 m_scene.EventManager.TriggerParcelPrimCountTainted();
614 rootPart.ScheduleFullUpdate();
615 rootPart.ClearUndoState();
469 } 616 }
470 617
471 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. 618 // 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?? 619 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
473 protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) 620 private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
474 { 621 {
475 if (itemID == UUID.Zero) // If this happened, someone made a mistake.... 622 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
476 return; 623 return;
@@ -493,27 +640,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
493 group.DetachToInventoryPrep(); 640 group.DetachToInventoryPrep();
494 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); 641 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
495 642
496 // If an item contains scripts, it's always changed. 643 // Prepare sog for storage
497 // This ensures script state is saved on detach 644 group.AttachedAvatar = UUID.Zero;
498 foreach (SceneObjectPart p in group.Parts) 645
499 if (p.Inventory.ContainsScripts()) 646 group.ForEachPart(
500 group.HasGroupChanged = true; 647 delegate(SceneObjectPart part)
648 {
649 // If there are any scripts,
650 // then always trigger a new object and state persistence in UpdateKnownItem()
651 if (part.Inventory.ContainsScripts())
652 group.HasGroupChanged = true;
653 }
654 );
501 655
502 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); 656 group.RootPart.SetParentLocalId(0);
657 group.IsAttachment = false;
658 group.AbsolutePosition = group.RootPart.AttachedPos;
659
660 UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
503 m_scene.DeleteSceneObject(group, false); 661 m_scene.DeleteSceneObject(group, false);
662
504 return; 663 return;
505 } 664 }
506 } 665 }
507 } 666 }
508 } 667 }
509 668
669 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
670 {
671 // First we save the
672 // attachment point information, then we update the relative
673 // positioning. Then we have to mark the object as NOT an
674 // attachment. This is necessary in order to correctly save
675 // and retrieve GroupPosition information for the attachment.
676 // Finally, we restore the object's attachment status.
677 uint attachmentPoint = sog.AttachmentPoint;
678 sog.UpdateGroupPosition(pos);
679 sog.IsAttachment = false;
680 sog.AbsolutePosition = sog.RootPart.AttachedPos;
681 sog.AttachmentPoint = attachmentPoint;
682 sog.HasGroupChanged = true;
683 }
684
510 /// <summary> 685 /// <summary>
511 /// Update the attachment asset for the new sog details if they have changed. 686 /// Update the attachment asset for the new sog details if they have changed.
512 /// </summary> 687 /// </summary>
513 /// 688 /// <remarks>
514 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, 689 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
515 /// these details are not stored on the region. 690 /// these details are not stored on the region.
516 /// 691 /// </remarks>
517 /// <param name="remoteClient"></param> 692 /// <param name="remoteClient"></param>
518 /// <param name="grp"></param> 693 /// <param name="grp"></param>
519 /// <param name="itemID"></param> 694 /// <param name="itemID"></param>
@@ -524,15 +699,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
524 { 699 {
525 if (!grp.HasGroupChanged) 700 if (!grp.HasGroupChanged)
526 { 701 {
527 m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); 702 m_log.DebugFormat(
703 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
704 grp.UUID, grp.AttachmentPoint);
705
528 return; 706 return;
529 } 707 }
530 708
531 m_log.DebugFormat( 709 m_log.DebugFormat(
532 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 710 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
533 grp.UUID, grp.GetAttachmentPoint()); 711 grp.UUID, grp.AttachmentPoint);
534 712
535 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 713 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
714
536 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 715 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
537 item = m_scene.InventoryService.GetItem(item); 716 item = m_scene.InventoryService.GetItem(item);
538 717
@@ -564,20 +743,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
564 /// <summary> 743 /// <summary>
565 /// Attach this scene object to the given avatar. 744 /// Attach this scene object to the given avatar.
566 /// </summary> 745 /// </summary>
567 /// 746 /// <remarks>
568 /// This isn't publicly available since attachments should always perform the corresponding inventory 747 /// 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). 748 /// operation (to show the attach in user inventory and update the asset with positional information).
570 /// 749 /// </remarks>
571 /// <param name="sp"></param> 750 /// <param name="sp"></param>
572 /// <param name="so"></param> 751 /// <param name="so"></param>
573 /// <param name="attachmentpoint"></param> 752 /// <param name="attachmentpoint"></param>
574 /// <param name="attachOffset"></param> 753 /// <param name="attachOffset"></param>
575 /// <param name="silent"></param> 754 /// <param name="silent"></param>
576 protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 755 private void AttachToAgent(
756 IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
577 { 757 {
578 758// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
579 m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, 759// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
580 attachmentpoint, attachOffset, so.RootPart.AttachedPos);
581 760
582 so.DetachFromBackup(); 761 so.DetachFromBackup();
583 762
@@ -585,12 +764,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
585 m_scene.DeleteFromStorage(so.UUID); 764 m_scene.DeleteFromStorage(so.UUID);
586 m_scene.EventManager.TriggerParcelPrimCountTainted(); 765 m_scene.EventManager.TriggerParcelPrimCountTainted();
587 766
588 so.RootPart.AttachedAvatar = avatar.UUID; 767 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 768
595 if (so.RootPart.PhysActor != null) 769 if (so.RootPart.PhysActor != null)
596 { 770 {
@@ -600,10 +774,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
600 774
601 so.AbsolutePosition = attachOffset; 775 so.AbsolutePosition = attachOffset;
602 so.RootPart.AttachedPos = attachOffset; 776 so.RootPart.AttachedPos = attachOffset;
603 so.RootPart.IsAttachment = true; 777 so.IsAttachment = true;
604
605 so.RootPart.SetParentLocalId(avatar.LocalId); 778 so.RootPart.SetParentLocalId(avatar.LocalId);
606 so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); 779 so.AttachmentPoint = attachmentpoint;
607 780
608 avatar.AddAttachment(so); 781 avatar.AddAttachment(so);
609 782
@@ -617,5 +790,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
617 // it get cleaned up 790 // it get cleaned up
618 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 791 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
619 } 792 }
793
794 /// <summary>
795 /// Add a scene object that was previously free in the scene as an attachment to an avatar.
796 /// </summary>
797 /// <param name="remoteClient"></param>
798 /// <param name="grp"></param>
799 /// <returns>The user inventory item created that holds the attachment.</returns>
800 private InventoryItemBase AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp)
801 {
802// m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId);
803
804 Vector3 inventoryStoredPosition = new Vector3
805 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
806 ? Constants.RegionSize - 6
807 : grp.AbsolutePosition.X)
808 ,
809 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
810 ? Constants.RegionSize - 6
811 : grp.AbsolutePosition.Y,
812 grp.AbsolutePosition.Z);
813
814 Vector3 originalPosition = grp.AbsolutePosition;
815
816 grp.AbsolutePosition = inventoryStoredPosition;
817
818 // If we're being called from a script, then trying to serialize that same script's state will not complete
819 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
820 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
821 // without state on relog. Arguably, this is what we want anyway.
822 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
823
824 grp.AbsolutePosition = originalPosition;
825
826 AssetBase asset = m_scene.CreateAsset(
827 grp.GetPartName(grp.LocalId),
828 grp.GetPartDescription(grp.LocalId),
829 (sbyte)AssetType.Object,
830 Utils.StringToBytes(sceneObjectXml),
831 remoteClient.AgentId);
832
833 m_scene.AssetService.Store(asset);
834
835 InventoryItemBase item = new InventoryItemBase();
836 item.CreatorId = grp.RootPart.CreatorID.ToString();
837 item.CreatorData = grp.RootPart.CreatorData;
838 item.Owner = remoteClient.AgentId;
839 item.ID = UUID.Random();
840 item.AssetID = asset.FullID;
841 item.Description = asset.Description;
842 item.Name = asset.Name;
843 item.AssetType = asset.Type;
844 item.InvType = (int)InventoryType.Object;
845
846 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
847 if (folder != null)
848 item.Folder = folder.ID;
849 else // oopsies
850 item.Folder = UUID.Zero;
851
852 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
853 {
854 item.BasePermissions = grp.RootPart.NextOwnerMask;
855 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
856 item.NextPermissions = grp.RootPart.NextOwnerMask;
857 item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
858 item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
859 }
860 else
861 {
862 item.BasePermissions = grp.RootPart.BaseMask;
863 item.CurrentPermissions = grp.RootPart.OwnerMask;
864 item.NextPermissions = grp.RootPart.NextOwnerMask;
865 item.EveryOnePermissions = grp.RootPart.EveryoneMask;
866 item.GroupPermissions = grp.RootPart.GroupMask;
867 }
868 item.CreationDate = Util.UnixTimeSinceEpoch();
869
870 // sets itemID so client can show item as 'attached' in inventory
871 grp.SetFromItemID(item.ID);
872
873 if (m_scene.AddInventoryItem(item))
874 {
875 remoteClient.SendInventoryItemCreateUpdate(item, 0);
876 }
877 else
878 {
879 if (m_dialogModule != null)
880 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
881 }
882
883 return item;
884 }
620 } 885 }
621} 886}
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..363e258
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -0,0 +1,274 @@
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 [SetUp]
62 public void Init()
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 IConfigSource config = new IniConfigSource();
68 config.AddConfig("Modules");
69 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
70
71 scene = SceneHelpers.SetupScene();
72 m_attMod = new AttachmentsModule();
73 SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
74 }
75
76 [TearDown]
77 public void TearDown()
78 {
79 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
80 // threads. Possibly, later tests should be rewritten not to worry about such things.
81 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
82 }
83
84 /// <summary>
85 /// Add the standard presence for a test.
86 /// </summary>
87 private void AddPresence()
88 {
89 UUID userId = TestHelpers.ParseTail(0x1);
90 UserAccountHelpers.CreateUserWithInventory(scene, userId);
91 m_presence = SceneHelpers.AddScenePresence(scene, userId);
92 }
93
94 [Test]
95 public void TestAddAttachmentFromGround()
96 {
97 TestHelpers.InMethod();
98// log4net.Config.XmlConfigurator.Configure();
99
100 AddPresence();
101 string attName = "att";
102
103 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
104
105 m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
106
107 // Check status on scene presence
108 Assert.That(m_presence.HasAttachments(), Is.True);
109 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
110 Assert.That(attachments.Count, Is.EqualTo(1));
111 SceneObjectGroup attSo = attachments[0];
112 Assert.That(attSo.Name, Is.EqualTo(attName));
113 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
114 Assert.That(attSo.IsAttachment);
115 Assert.That(attSo.UsesPhysics, Is.False);
116 Assert.That(attSo.IsTemporary, Is.False);
117
118 // Check item status
119 Assert.That(m_presence.Appearance.GetAttachpoint(
120 attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
121 }
122
123 [Test]
124 public void TestAddAttachmentFromInventory()
125 {
126 TestHelpers.InMethod();
127// log4net.Config.XmlConfigurator.Configure();
128
129 AddPresence();
130
131 UUID attItemId = TestHelpers.ParseTail(0x2);
132 UUID attAssetId = TestHelpers.ParseTail(0x3);
133 string attName = "att";
134
135 UserInventoryHelpers.CreateInventoryItem(
136 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
137
138 m_attMod.RezSingleAttachmentFromInventory(
139 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
140
141 // Check scene presence status
142 Assert.That(m_presence.HasAttachments(), Is.True);
143 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
144 Assert.That(attachments.Count, Is.EqualTo(1));
145 SceneObjectGroup attSo = attachments[0];
146 Assert.That(attSo.Name, Is.EqualTo(attName));
147 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
148 Assert.That(attSo.IsAttachment);
149 Assert.That(attSo.UsesPhysics, Is.False);
150 Assert.That(attSo.IsTemporary, Is.False);
151
152 // Check appearance status
153 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
154 }
155
156 [Test]
157 public void TestDetachAttachmentToGround()
158 {
159 TestHelpers.InMethod();
160// log4net.Config.XmlConfigurator.Configure();
161
162 AddPresence();
163
164 UUID attItemId = TestHelpers.ParseTail(0x2);
165 UUID attAssetId = TestHelpers.ParseTail(0x3);
166 string attName = "att";
167
168 UserInventoryHelpers.CreateInventoryItem(
169 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
170
171 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
172 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
173 m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
174
175 // Check scene presence status
176 Assert.That(m_presence.HasAttachments(), Is.False);
177 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
178 Assert.That(attachments.Count, Is.EqualTo(0));
179
180 // Check appearance status
181 Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
182
183 // Check item status
184 Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
185
186 // Check object in scene
187 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
188 }
189
190 [Test]
191 public void TestDetachAttachmentToInventory()
192 {
193 TestHelpers.InMethod();
194// log4net.Config.XmlConfigurator.Configure();
195
196 AddPresence();
197
198 UUID attItemId = TestHelpers.ParseTail(0x2);
199 UUID attAssetId = TestHelpers.ParseTail(0x3);
200 string attName = "att";
201
202 UserInventoryHelpers.CreateInventoryItem(
203 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
204
205 m_attMod.RezSingleAttachmentFromInventory(
206 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
207 m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
208
209 // Check status on scene presence
210 Assert.That(m_presence.HasAttachments(), Is.False);
211 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
212 Assert.That(attachments.Count, Is.EqualTo(0));
213
214 // Check item status
215 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
216 }
217
218 [Test]
219 public void TestRezAttachmentsOnAvatarEntrance()
220 {
221 TestHelpers.InMethod();
222// log4net.Config.XmlConfigurator.Configure();
223
224 UUID userId = TestHelpers.ParseTail(0x1);
225 UUID attItemId = TestHelpers.ParseTail(0x2);
226 UUID attAssetId = TestHelpers.ParseTail(0x3);
227 string attName = "att";
228
229 UserAccountHelpers.CreateUserWithInventory(scene, userId);
230 InventoryItemBase attItem
231 = UserInventoryHelpers.CreateInventoryItem(
232 scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
233
234 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
235 acd.Appearance = new AvatarAppearance();
236 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
237 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
238
239 Assert.That(presence.HasAttachments(), Is.True);
240 List<SceneObjectGroup> attachments = presence.GetAttachments();
241
242 Assert.That(attachments.Count, Is.EqualTo(1));
243 SceneObjectGroup attSo = attachments[0];
244 Assert.That(attSo.Name, Is.EqualTo(attName));
245 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
246 Assert.That(attSo.IsAttachment);
247 Assert.That(attSo.UsesPhysics, Is.False);
248 Assert.That(attSo.IsTemporary, Is.False);
249 }
250
251 // I'm commenting this test because scene setup NEEDS InventoryService to
252 // be non-null
253 //[Test]
254// public void T032_CrossAttachments()
255// {
256// TestHelpers.InMethod();
257//
258// ScenePresence presence = scene.GetScenePresence(agent1);
259// ScenePresence presence2 = scene2.GetScenePresence(agent1);
260// presence2.AddAttachment(sog1);
261// presence2.AddAttachment(sog2);
262//
263// ISharedRegionModule serialiser = new SerialiserModule();
264// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
265// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
266//
267// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
268//
269// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
270// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
271// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
272// }
273 }
274} \ 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..d9dcee7 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -172,11 +172,15 @@ 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)
@@ -209,6 +213,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
209 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 213 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
210 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 214 im.dialog != (byte)InstantMessageDialog.InventoryOffered)
211 { 215 {
216 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
217 "POST", m_RestURL+"/SaveMessage/", im);
212 return; 218 return;
213 } 219 }
214 220
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;