diff options
Diffstat (limited to '')
36 files changed, 1181 insertions, 582 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index fae8be7..92ccb06 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -269,13 +269,15 @@ namespace OpenSim | |||
269 | 269 | ||
270 | m_console.Commands.AddCommand("region", false, "save oar", | 270 | m_console.Commands.AddCommand("region", false, "save oar", |
271 | //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", | 271 | //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", |
272 | "save oar [-p|--profile=<url>] [--noassets] [<OAR path>]", | 272 | "save oar [-p|--profile=<url>] [--noassets] [--perm=<permissions>] [<OAR path>]", |
273 | "Save a region's data to an OAR archive.", | 273 | "Save a region's data to an OAR archive.", |
274 | // "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine | 274 | // "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine |
275 | "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine | 275 | "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine |
276 | + " The OAR path must be a filesystem path." | 276 | + "--noassets stops assets being saved to the OAR." + Environment.NewLine |
277 | + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine | 277 | + "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine |
278 | + "--noassets stops assets being saved to the OAR.", | 278 | + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine |
279 | + "The OAR path must be a filesystem path." | ||
280 | + " If this is not given then the oar is saved to region.oar in the current directory.", | ||
279 | SaveOar); | 281 | SaveOar); |
280 | 282 | ||
281 | m_console.Commands.AddCommand("region", false, "edit scale", | 283 | m_console.Commands.AddCommand("region", false, "edit scale", |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index dbfd0f2..dd0ea67 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -489,6 +489,8 @@ namespace OpenSim | |||
489 | scene.StartTimer(); | 489 | scene.StartTimer(); |
490 | scene.StartTimerWatchdog(); | 490 | scene.StartTimerWatchdog(); |
491 | 491 | ||
492 | scene.StartScripts(); | ||
493 | |||
492 | return clientServer; | 494 | return clientServer; |
493 | } | 495 | } |
494 | 496 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 218b7b8..2bf418d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -144,20 +144,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
144 | 144 | ||
145 | public void SaveChangedAttachments(IScenePresence sp) | 145 | public void SaveChangedAttachments(IScenePresence sp) |
146 | { | 146 | { |
147 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
148 | |||
147 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 149 | foreach (SceneObjectGroup grp in sp.GetAttachments()) |
148 | { | 150 | { |
149 | if (grp.HasGroupChanged) // Resizer scripts? | 151 | // if (grp.HasGroupChanged) // Resizer scripts? |
150 | { | 152 | // { |
151 | grp.IsAttachment = false; | 153 | grp.IsAttachment = false; |
152 | grp.AbsolutePosition = grp.RootPart.AttachedPos; | 154 | grp.AbsolutePosition = grp.RootPart.AttachedPos; |
153 | UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); | 155 | UpdateKnownItem(sp.ControllingClient, grp); |
154 | grp.IsAttachment = true; | 156 | grp.IsAttachment = true; |
155 | } | 157 | // } |
156 | } | 158 | } |
157 | } | 159 | } |
158 | 160 | ||
159 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) | 161 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) |
160 | { | 162 | { |
163 | // m_log.DebugFormat( | ||
164 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | ||
165 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
166 | |||
161 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 167 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
162 | { | 168 | { |
163 | sop.Scene.DeleteSceneObject(sop, silent); | 169 | sop.Scene.DeleteSceneObject(sop, silent); |
@@ -220,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
220 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 226 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
221 | 227 | ||
222 | // Save avatar attachment information | 228 | // Save avatar attachment information |
223 | m_log.Info( | 229 | m_log.Debug( |
224 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | 230 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
225 | + ", AttachmentPoint: " + AttachmentPt); | 231 | + ", AttachmentPoint: " + AttachmentPt); |
226 | 232 | ||
@@ -248,75 +254,83 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
248 | 254 | ||
249 | private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) | 255 | private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) |
250 | { | 256 | { |
251 | // m_log.DebugFormat( | 257 | lock (sp.AttachmentsSyncLock) |
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 | |||
264 | Vector3 attachPos = group.AbsolutePosition; | ||
265 | |||
266 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | ||
267 | // be removed when that functionality is implemented in opensim | ||
268 | attachmentPt &= 0x7f; | ||
269 | |||
270 | // If the attachment point isn't the same as the one previously used | ||
271 | // set it's offset position = 0 so that it appears on the attachment point | ||
272 | // and not in a weird location somewhere unknown. | ||
273 | if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) | ||
274 | { | ||
275 | attachPos = Vector3.Zero; | ||
276 | } | ||
277 | |||
278 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
279 | if (attachmentPt == 0) | ||
280 | { | 258 | { |
281 | // Check object for stored attachment point | 259 | // m_log.DebugFormat( |
282 | attachmentPt = group.AttachmentPoint; | 260 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
283 | } | 261 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); |
284 | 262 | ||
285 | // if we still didn't find a suitable attachment point....... | 263 | if (sp.GetAttachments(attachmentPt).Contains(group)) |
286 | if (attachmentPt == 0) | 264 | { |
287 | { | 265 | // m_log.WarnFormat( |
288 | // Stick it on left hand with Zero Offset from the attachment point. | 266 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", |
289 | attachmentPt = (uint)AttachmentPoint.LeftHand; | 267 | // group.Name, group.LocalId, sp.Name, AttachmentPt); |
290 | attachPos = Vector3.Zero; | 268 | |
291 | } | 269 | return false; |
292 | 270 | } | |
293 | group.AttachmentPoint = attachmentPt; | 271 | |
294 | group.AbsolutePosition = attachPos; | 272 | Vector3 attachPos = group.AbsolutePosition; |
295 | 273 | ||
296 | // Remove any previous attachments | 274 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should |
297 | UUID itemID = UUID.Zero; | 275 | // be removed when that functionality is implemented in opensim |
298 | 276 | attachmentPt &= 0x7f; | |
299 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | 277 | |
300 | 278 | // If the attachment point isn't the same as the one previously used | |
301 | // At the moment we can only deal with a single attachment | 279 | // set it's offset position = 0 so that it appears on the attachment point |
302 | // We also don't want to do any of the inventory operations for an NPC. | 280 | // and not in a weird location somewhere unknown. |
303 | if (sp.PresenceType != PresenceType.Npc) | 281 | if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) |
304 | { | 282 | { |
305 | if (attachments.Count != 0) | 283 | attachPos = Vector3.Zero; |
306 | itemID = attachments[0].GetFromItemID(); | 284 | } |
285 | |||
286 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
287 | if (attachmentPt == 0) | ||
288 | { | ||
289 | // Check object for stored attachment point | ||
290 | attachmentPt = group.AttachmentPoint; | ||
291 | } | ||
292 | |||
293 | // if we still didn't find a suitable attachment point....... | ||
294 | if (attachmentPt == 0) | ||
295 | { | ||
296 | // Stick it on left hand with Zero Offset from the attachment point. | ||
297 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
298 | attachPos = Vector3.Zero; | ||
299 | } | ||
300 | |||
301 | group.AttachmentPoint = attachmentPt; | ||
302 | group.AbsolutePosition = attachPos; | ||
303 | |||
304 | // We also don't want to do any of the inventory operations for an NPC. | ||
305 | if (sp.PresenceType != PresenceType.Npc) | ||
306 | { | ||
307 | // Remove any previous attachments | ||
308 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
307 | 309 | ||
308 | if (itemID != UUID.Zero) | 310 | // At the moment we can only deal with a single attachment |
309 | DetachSingleAttachmentToInv(itemID, sp); | 311 | if (attachments.Count != 0) |
312 | { | ||
313 | UUID oldAttachmentItemID = attachments[0].GetFromItemID(); | ||
314 | |||
315 | if (oldAttachmentItemID != UUID.Zero) | ||
316 | DetachSingleAttachmentToInv(oldAttachmentItemID, sp); | ||
317 | else | ||
318 | m_log.WarnFormat( | ||
319 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", | ||
320 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
321 | } | ||
310 | 322 | ||
311 | itemID = group.GetFromItemID(); | 323 | // Add the new attachment to inventory if we don't already have it. |
312 | if (itemID == UUID.Zero) | 324 | UUID newAttachmentItemID = group.GetFromItemID(); |
313 | itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; | 325 | if (newAttachmentItemID == UUID.Zero) |
326 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID; | ||
327 | |||
328 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | ||
329 | } | ||
314 | 330 | ||
315 | ShowAttachInUserInventory(sp, attachmentPt, itemID, group); | 331 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); |
316 | } | 332 | } |
317 | 333 | ||
318 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | ||
319 | |||
320 | return true; | 334 | return true; |
321 | } | 335 | } |
322 | 336 | ||
@@ -325,20 +339,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
325 | RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, | 339 | RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, |
326 | RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) | 340 | RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) |
327 | { | 341 | { |
328 | foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) | 342 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
343 | |||
344 | if (sp == null) | ||
329 | { | 345 | { |
330 | RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt); | 346 | m_log.ErrorFormat( |
347 | "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", | ||
348 | remoteClient.Name, remoteClient.AgentId); | ||
349 | return; | ||
350 | } | ||
351 | |||
352 | lock (sp.AttachmentsSyncLock) | ||
353 | { | ||
354 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | ||
355 | |||
356 | foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) | ||
357 | { | ||
358 | RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt); | ||
359 | } | ||
331 | } | 360 | } |
332 | } | 361 | } |
333 | 362 | ||
334 | public ISceneEntity RezSingleAttachmentFromInventory( | 363 | public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) |
335 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | ||
336 | { | ||
337 | return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); | ||
338 | } | ||
339 | |||
340 | public ISceneEntity RezSingleAttachmentFromInventory( | ||
341 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) | ||
342 | { | 364 | { |
343 | return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); | 365 | return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); |
344 | } | 366 | } |
@@ -347,21 +369,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
347 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) | 369 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) |
348 | { | 370 | { |
349 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 371 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
350 | if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); return null; } | 372 | |
373 | if (sp == null) | ||
374 | { | ||
375 | m_log.ErrorFormat( | ||
376 | "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", | ||
377 | remoteClient.Name, remoteClient.AgentId); | ||
378 | return null; | ||
379 | } | ||
380 | |||
381 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); | ||
382 | } | ||
383 | |||
384 | public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt) | ||
385 | { | ||
386 | // m_log.DebugFormat( | ||
387 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", | ||
388 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name); | ||
389 | |||
351 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | 390 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should |
352 | // be removed when that functionality is implemented in opensim | 391 | // be removed when that functionality is implemented in opensim |
353 | AttachmentPt &= 0x7f; | 392 | AttachmentPt &= 0x7f; |
354 | 393 | ||
355 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); | 394 | // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). |
395 | // This often happens during login - not sure the exact reason. | ||
396 | // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the | ||
397 | // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login | ||
398 | // before anything has actually been attached. | ||
399 | bool alreadyOn = false; | ||
400 | List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); | ||
401 | foreach (SceneObjectGroup so in existingAttachments) | ||
402 | { | ||
403 | if (so.GetFromItemID() == itemID) | ||
404 | { | ||
405 | alreadyOn = true; | ||
406 | break; | ||
407 | } | ||
408 | } | ||
356 | 409 | ||
357 | if (updateInventoryStatus) | 410 | // if (sp.Appearance.GetAttachmentForItem(itemID) != null) |
411 | if (alreadyOn) | ||
358 | { | 412 | { |
359 | if (att == null) | 413 | // m_log.WarnFormat( |
360 | DetachSingleAttachmentToInv(itemID, sp.ControllingClient); | 414 | // "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", |
361 | else | 415 | // sp.Name, itemID, AttachmentPt); |
362 | ShowAttachInUserInventory(att, sp, itemID, AttachmentPt); | 416 | |
417 | return null; | ||
363 | } | 418 | } |
364 | 419 | ||
420 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, null); | ||
421 | |||
422 | if (att == null) | ||
423 | DetachSingleAttachmentToInv(itemID, sp.ControllingClient); | ||
424 | |||
365 | return att; | 425 | return att; |
366 | } | 426 | } |
367 | 427 | ||
@@ -371,50 +431,67 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
371 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | 431 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); |
372 | if (invAccess != null) | 432 | if (invAccess != null) |
373 | { | 433 | { |
374 | SceneObjectGroup objatt; | 434 | lock (sp.AttachmentsSyncLock) |
375 | |||
376 | if (itemID != UUID.Zero) | ||
377 | objatt = invAccess.RezObject(sp.ControllingClient, | ||
378 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
379 | false, false, sp.UUID, true); | ||
380 | else | ||
381 | objatt = invAccess.RezObject(sp.ControllingClient, | ||
382 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
383 | false, false, sp.UUID, true); | ||
384 | |||
385 | // m_log.DebugFormat( | ||
386 | // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", | ||
387 | // objatt.Name, remoteClient.Name, AttachmentPt); | ||
388 | |||
389 | if (objatt != null) | ||
390 | { | 435 | { |
391 | // Loading the inventory from XML will have set this, but | 436 | SceneObjectGroup objatt; |
392 | // there is no way the object could have changed yet, | 437 | |
393 | // since scripts aren't running yet. So, clear it here. | 438 | if (itemID != UUID.Zero) |
394 | objatt.HasGroupChanged = false; | 439 | objatt = invAccess.RezObject(sp.ControllingClient, |
395 | bool tainted = false; | 440 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, |
396 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | 441 | false, false, sp.UUID, true); |
397 | tainted = true; | 442 | else |
398 | 443 | objatt = invAccess.RezObject(sp.ControllingClient, | |
399 | // This will throw if the attachment fails | 444 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, |
400 | try | 445 | false, false, sp.UUID, true); |
446 | |||
447 | // m_log.DebugFormat( | ||
448 | // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", | ||
449 | // objatt.Name, remoteClient.Name, AttachmentPt); | ||
450 | |||
451 | if (objatt != null) | ||
401 | { | 452 | { |
402 | AttachObject(sp, objatt, attachmentPt, false); | 453 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
454 | objatt.HasGroupChanged = false; | ||
455 | bool tainted = false; | ||
456 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | ||
457 | tainted = true; | ||
458 | |||
459 | // This will throw if the attachment fails | ||
460 | try | ||
461 | { | ||
462 | AttachObject(sp, objatt, attachmentPt, false); | ||
463 | } | ||
464 | catch (Exception e) | ||
465 | { | ||
466 | m_log.ErrorFormat( | ||
467 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
468 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
469 | |||
470 | // Make sure the object doesn't stick around and bail | ||
471 | sp.RemoveAttachment(objatt); | ||
472 | m_scene.DeleteSceneObject(objatt, false); | ||
473 | return null; | ||
474 | } | ||
475 | |||
476 | if (tainted) | ||
477 | objatt.HasGroupChanged = true; | ||
478 | |||
479 | // Fire after attach, so we don't get messy perms dialogs | ||
480 | // 4 == AttachedRez | ||
481 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
482 | objatt.ResumeScripts(); | ||
483 | |||
484 | // Do this last so that event listeners have access to all the effects of the attachment | ||
485 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
486 | |||
487 | return objatt; | ||
403 | } | 488 | } |
404 | catch (Exception e) | 489 | else |
405 | { | 490 | { |
406 | m_log.ErrorFormat( | 491 | m_log.WarnFormat( |
407 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | 492 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", |
408 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | 493 | itemID, sp.Name, attachmentPt); |
409 | |||
410 | // Make sure the object doesn't stick around and bail | ||
411 | sp.RemoveAttachment(objatt); | ||
412 | m_scene.DeleteSceneObject(objatt, false); | ||
413 | return null; | ||
414 | } | 494 | } |
415 | |||
416 | if (tainted) | ||
417 | objatt.HasGroupChanged = true; | ||
418 | 495 | ||
419 | if (doc != null) | 496 | if (doc != null) |
420 | { | 497 | { |
@@ -430,47 +507,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
430 | // Do this last so that event listeners have access to all the effects of the attachment | 507 | // Do this last so that event listeners have access to all the effects of the attachment |
431 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | 508 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); |
432 | } | 509 | } |
433 | else | ||
434 | { | ||
435 | m_log.WarnFormat( | ||
436 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
437 | itemID, sp.Name, attachmentPt); | ||
438 | } | ||
439 | |||
440 | return objatt; | ||
441 | } | 510 | } |
442 | 511 | ||
443 | return null; | 512 | return null; |
444 | } | 513 | } |
445 | |||
446 | /// <summary> | ||
447 | /// Update the user inventory to the attachment of an item | ||
448 | /// </summary> | ||
449 | /// <param name="att"></param> | ||
450 | /// <param name="sp"></param> | ||
451 | /// <param name="itemID"></param> | ||
452 | /// <param name="attachmentPoint"></param> | ||
453 | /// <returns></returns> | ||
454 | private UUID ShowAttachInUserInventory( | ||
455 | SceneObjectGroup att, IScenePresence sp, UUID itemID, uint attachmentPoint) | ||
456 | { | ||
457 | // m_log.DebugFormat( | ||
458 | // "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}", | ||
459 | // sp.Name, att.Name, att.LocalId, itemID, AttachmentPt); | ||
460 | |||
461 | if (!att.IsDeleted) | ||
462 | attachmentPoint = att.AttachmentPoint; | ||
463 | |||
464 | InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); | ||
465 | if (m_scene.InventoryService != null) | ||
466 | item = m_scene.InventoryService.GetItem(item); | ||
467 | |||
468 | bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID); | ||
469 | if (changed && m_scene.AvatarFactory != null) | ||
470 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | ||
471 | |||
472 | return att.UUID; | ||
473 | } | ||
474 | 514 | ||
475 | /// <summary> | 515 | /// <summary> |
476 | /// Update the user inventory to reflect an attachment | 516 | /// Update the user inventory to reflect an attachment |
@@ -483,8 +523,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
483 | IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) | 523 | IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) |
484 | { | 524 | { |
485 | // m_log.DebugFormat( | 525 | // m_log.DebugFormat( |
486 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", | 526 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", |
487 | // att.Name, remoteClient.Name, AttachmentPt, itemID); | 527 | // att.Name, sp.Name, AttachmentPt, itemID); |
488 | 528 | ||
489 | if (UUID.Zero == itemID) | 529 | if (UUID.Zero == itemID) |
490 | { | 530 | { |
@@ -518,6 +558,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
518 | 558 | ||
519 | public void DetachObject(uint objectLocalID, IClientAPI remoteClient) | 559 | public void DetachObject(uint objectLocalID, IClientAPI remoteClient) |
520 | { | 560 | { |
561 | // m_log.DebugFormat( | ||
562 | // "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name); | ||
563 | |||
521 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 564 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |
522 | if (group != null) | 565 | if (group != null) |
523 | { | 566 | { |
@@ -530,14 +573,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
530 | ScenePresence presence; | 573 | ScenePresence presence; |
531 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 574 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) |
532 | { | 575 | { |
533 | // Save avatar attachment information | 576 | lock (presence.AttachmentsSyncLock) |
534 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); | 577 | { |
535 | 578 | // Save avatar attachment information | |
536 | bool changed = presence.Appearance.DetachAttachment(itemID); | 579 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); |
537 | if (changed && m_scene.AvatarFactory != null) | ||
538 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | ||
539 | 580 | ||
540 | DetachSingleAttachmentToInv(itemID, presence); | 581 | bool changed = presence.Appearance.DetachAttachment(itemID); |
582 | if (changed && m_scene.AvatarFactory != null) | ||
583 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | ||
584 | |||
585 | DetachSingleAttachmentToInv(itemID, presence); | ||
586 | } | ||
541 | } | 587 | } |
542 | } | 588 | } |
543 | 589 | ||
@@ -545,7 +591,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
545 | { | 591 | { |
546 | // m_log.DebugFormat( | 592 | // m_log.DebugFormat( |
547 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", | 593 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", |
548 | // remoteClient.Name, sceneObjectID); | 594 | // remoteClient.Name, soLocalId); |
549 | 595 | ||
550 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); | 596 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); |
551 | 597 | ||
@@ -564,24 +610,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
564 | ScenePresence presence; | 610 | ScenePresence presence; |
565 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 611 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) |
566 | { | 612 | { |
567 | if (!m_scene.Permissions.CanRezObject( | 613 | lock (presence.AttachmentsSyncLock) |
568 | so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) | 614 | { |
569 | return; | 615 | if (!m_scene.Permissions.CanRezObject( |
616 | so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) | ||
617 | return; | ||
570 | 618 | ||
571 | bool changed = presence.Appearance.DetachAttachment(inventoryID); | 619 | bool changed = presence.Appearance.DetachAttachment(inventoryID); |
572 | if (changed && m_scene.AvatarFactory != null) | 620 | if (changed && m_scene.AvatarFactory != null) |
573 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | 621 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
574 | 622 | ||
575 | presence.RemoveAttachment(so); | 623 | presence.RemoveAttachment(so); |
576 | DetachSceneObjectToGround(so, presence); | 624 | DetachSceneObjectToGround(so, presence); |
577 | 625 | ||
578 | List<UUID> uuids = new List<UUID>(); | 626 | List<UUID> uuids = new List<UUID>(); |
579 | uuids.Add(inventoryID); | 627 | uuids.Add(inventoryID); |
580 | m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); | 628 | m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); |
581 | remoteClient.SendRemoveInventoryItem(inventoryID); | 629 | remoteClient.SendRemoveInventoryItem(inventoryID); |
582 | } | 630 | } |
583 | 631 | ||
584 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 632 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
633 | } | ||
585 | } | 634 | } |
586 | 635 | ||
587 | /// <summary> | 636 | /// <summary> |
@@ -615,6 +664,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
615 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | 664 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? |
616 | private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp) | 665 | private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp) |
617 | { | 666 | { |
667 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | ||
668 | |||
618 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | 669 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... |
619 | return; | 670 | return; |
620 | 671 | ||
@@ -623,40 +674,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
623 | EntityBase[] detachEntities = m_scene.GetEntities(); | 674 | EntityBase[] detachEntities = m_scene.GetEntities(); |
624 | SceneObjectGroup group; | 675 | SceneObjectGroup group; |
625 | 676 | ||
626 | foreach (EntityBase entity in detachEntities) | 677 | lock (sp.AttachmentsSyncLock) |
627 | { | 678 | { |
628 | if (entity is SceneObjectGroup) | 679 | foreach (EntityBase entity in detachEntities) |
629 | { | 680 | { |
630 | group = (SceneObjectGroup)entity; | 681 | if (entity is SceneObjectGroup) |
631 | if (group.GetFromItemID() == itemID) | ||
632 | { | 682 | { |
633 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); | 683 | group = (SceneObjectGroup)entity; if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); |
634 | // CM / XMREngine!!!! Needed to conclude attach event | 684 | // CM / XMREngine!!!! Needed to conclude attach event |
635 | //SceneObjectSerializer.ToOriginalXmlFormat(group); | 685 | //SceneObjectSerializer.ToOriginalXmlFormat(group); |
636 | group.DetachToInventoryPrep(); | 686 | group.DetachToInventoryPrep(); |
637 | m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); | 687 | m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); |
638 | 688 | ||
639 | // Prepare sog for storage | 689 | // Prepare sog for storage |
640 | group.AttachedAvatar = UUID.Zero; | 690 | group.AttachedAvatar = UUID.Zero; |
641 | 691 | group.RootPart.SetParentLocalId(0); | |
642 | group.ForEachPart( | 692 | group.IsAttachment = false; |
643 | delegate(SceneObjectPart part) | 693 | group.AbsolutePosition = group.RootPart.AttachedPos; |
644 | { | ||
645 | // If there are any scripts, | ||
646 | // then always trigger a new object and state persistence in UpdateKnownItem() | ||
647 | if (part.Inventory.ContainsScripts()) | ||
648 | group.HasGroupChanged = true; | ||
649 | } | ||
650 | ); | ||
651 | |||
652 | group.RootPart.SetParentLocalId(0); | ||
653 | group.IsAttachment = false; | ||
654 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
655 | 694 | ||
656 | UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); | 695 | UpdateKnownItem(sp.ControllingClient, group); |
657 | m_scene.DeleteSceneObject(group, false); | 696 | m_scene.DeleteSceneObject(group, false); |
658 | 697 | ||
659 | return; | 698 | return; |
699 | } | ||
660 | } | 700 | } |
661 | } | 701 | } |
662 | } | 702 | } |
@@ -687,28 +727,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
687 | /// </remarks> | 727 | /// </remarks> |
688 | /// <param name="remoteClient"></param> | 728 | /// <param name="remoteClient"></param> |
689 | /// <param name="grp"></param> | 729 | /// <param name="grp"></param> |
690 | /// <param name="itemID"></param> | 730 | private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp) |
691 | /// <param name="agentID"></param> | ||
692 | public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) | ||
693 | { | 731 | { |
694 | if (grp != null) | 732 | if (grp.HasGroupChanged || grp.ContainsScripts()) |
695 | { | 733 | { |
696 | if (!grp.HasGroupChanged) | ||
697 | { | ||
698 | m_log.DebugFormat( | ||
699 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | ||
700 | grp.UUID, grp.AttachmentPoint); | ||
701 | |||
702 | return; | ||
703 | } | ||
704 | |||
705 | m_log.DebugFormat( | 734 | m_log.DebugFormat( |
706 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", | 735 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", |
707 | grp.UUID, grp.AttachmentPoint); | 736 | grp.UUID, grp.AttachmentPoint); |
708 | 737 | ||
709 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); | 738 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); |
710 | 739 | ||
711 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | 740 | InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId); |
712 | item = m_scene.InventoryService.GetItem(item); | 741 | item = m_scene.InventoryService.GetItem(item); |
713 | 742 | ||
714 | if (item != null) | 743 | if (item != null) |
@@ -734,6 +763,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
734 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 763 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
735 | } | 764 | } |
736 | } | 765 | } |
766 | else | ||
767 | { | ||
768 | m_log.DebugFormat( | ||
769 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | ||
770 | grp.UUID, grp.AttachmentPoint); | ||
771 | } | ||
737 | } | 772 | } |
738 | 773 | ||
739 | /// <summary> | 774 | /// <summary> |
@@ -751,7 +786,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
751 | private void AttachToAgent( | 786 | private void AttachToAgent( |
752 | IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 787 | IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
753 | { | 788 | { |
754 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 789 | // m_log.DebugFormat( |
790 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | ||
755 | // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 791 | // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); |
756 | 792 | ||
757 | so.DetachFromBackup(); | 793 | so.DetachFromBackup(); |
@@ -788,14 +824,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
788 | } | 824 | } |
789 | 825 | ||
790 | /// <summary> | 826 | /// <summary> |
791 | /// Add a scene object that was previously free in the scene as an attachment to an avatar. | 827 | /// Add a scene object as a new attachment in the user inventory. |
792 | /// </summary> | 828 | /// </summary> |
793 | /// <param name="remoteClient"></param> | 829 | /// <param name="remoteClient"></param> |
794 | /// <param name="grp"></param> | 830 | /// <param name="grp"></param> |
795 | /// <returns>The user inventory item created that holds the attachment.</returns> | 831 | /// <returns>The user inventory item created that holds the attachment.</returns> |
796 | private InventoryItemBase AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp) | 832 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp) |
797 | { | 833 | { |
798 | // m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); | 834 | // m_log.DebugFormat( |
835 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | ||
836 | // grp.Name, grp.LocalId, remoteClient.Name); | ||
799 | 837 | ||
800 | Vector3 inventoryStoredPosition = new Vector3 | 838 | Vector3 inventoryStoredPosition = new Vector3 |
801 | (((grp.AbsolutePosition.X > (int)Constants.RegionSize) | 839 | (((grp.AbsolutePosition.X > (int)Constants.RegionSize) |
@@ -879,4 +917,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
879 | return item; | 917 | return item; |
880 | } | 918 | } |
881 | } | 919 | } |
882 | } | 920 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 363e258..ff3358f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -58,12 +58,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
58 | private AttachmentsModule m_attMod; | 58 | private AttachmentsModule m_attMod; |
59 | private ScenePresence m_presence; | 59 | private ScenePresence m_presence; |
60 | 60 | ||
61 | [SetUp] | 61 | [TestFixtureSetUp] |
62 | public void Init() | 62 | public void FixtureInit() |
63 | { | 63 | { |
64 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. | 64 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. |
65 | Util.FireAndForgetMethod = FireAndForgetMethod.None; | 65 | Util.FireAndForgetMethod = FireAndForgetMethod.None; |
66 | } | ||
66 | 67 | ||
68 | [SetUp] | ||
69 | public void Init() | ||
70 | { | ||
67 | IConfigSource config = new IniConfigSource(); | 71 | IConfigSource config = new IniConfigSource(); |
68 | config.AddConfig("Modules"); | 72 | config.AddConfig("Modules"); |
69 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | 73 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); |
@@ -73,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
73 | SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); | 77 | SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); |
74 | } | 78 | } |
75 | 79 | ||
76 | [TearDown] | 80 | [TestFixtureTearDown] |
77 | public void TearDown() | 81 | public void TearDown() |
78 | { | 82 | { |
79 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | 83 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple |
@@ -150,6 +154,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
150 | Assert.That(attSo.IsTemporary, Is.False); | 154 | Assert.That(attSo.IsTemporary, Is.False); |
151 | 155 | ||
152 | // Check appearance status | 156 | // Check appearance status |
157 | Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
153 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); | 158 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); |
154 | } | 159 | } |
155 | 160 | ||
@@ -215,6 +220,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
215 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); | 220 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); |
216 | } | 221 | } |
217 | 222 | ||
223 | /// <summary> | ||
224 | /// Test that attachments don't hang about in the scene when the agent is closed | ||
225 | /// </summary> | ||
226 | [Test] | ||
227 | public void TestRemoveAttachmentsOnAvatarExit() | ||
228 | { | ||
229 | TestHelpers.InMethod(); | ||
230 | // log4net.Config.XmlConfigurator.Configure(); | ||
231 | |||
232 | UUID userId = TestHelpers.ParseTail(0x1); | ||
233 | UUID attItemId = TestHelpers.ParseTail(0x2); | ||
234 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
235 | string attName = "att"; | ||
236 | |||
237 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | ||
238 | InventoryItemBase attItem | ||
239 | = UserInventoryHelpers.CreateInventoryItem( | ||
240 | scene, attName, attItemId, attAssetId, userId, InventoryType.Object); | ||
241 | |||
242 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | ||
243 | acd.Appearance = new AvatarAppearance(); | ||
244 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | ||
245 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | ||
246 | |||
247 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; | ||
248 | |||
249 | scene.IncomingCloseAgent(presence.UUID); | ||
250 | |||
251 | // Check that we can't retrieve this attachment from the scene. | ||
252 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); | ||
253 | } | ||
254 | |||
218 | [Test] | 255 | [Test] |
219 | public void TestRezAttachmentsOnAvatarEntrance() | 256 | public void TestRezAttachmentsOnAvatarEntrance() |
220 | { | 257 | { |
@@ -246,6 +283,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
246 | Assert.That(attSo.IsAttachment); | 283 | Assert.That(attSo.IsAttachment); |
247 | Assert.That(attSo.UsesPhysics, Is.False); | 284 | Assert.That(attSo.UsesPhysics, Is.False); |
248 | Assert.That(attSo.IsTemporary, Is.False); | 285 | Assert.That(attSo.IsTemporary, Is.False); |
286 | |||
287 | // Check appearance status | ||
288 | List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments(); | ||
289 | Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); | ||
290 | Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); | ||
291 | Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId)); | ||
292 | Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId)); | ||
293 | Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
249 | } | 294 | } |
250 | 295 | ||
251 | // I'm commenting this test because scene setup NEEDS InventoryService to | 296 | // I'm commenting this test because scene setup NEEDS InventoryService to |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index faccab2..25d5e0e 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -59,7 +59,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
59 | get { return m_MaxTransferDistance; } | 59 | get { return m_MaxTransferDistance; } |
60 | set { m_MaxTransferDistance = value; } | 60 | set { m_MaxTransferDistance = value; } |
61 | } | 61 | } |
62 | |||
63 | 62 | ||
64 | protected bool m_Enabled = false; | 63 | protected bool m_Enabled = false; |
65 | protected Scene m_aScene; | 64 | protected Scene m_aScene; |
@@ -68,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
68 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | 67 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = |
69 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 68 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); |
70 | 69 | ||
71 | |||
72 | #region ISharedRegionModule | 70 | #region ISharedRegionModule |
73 | 71 | ||
74 | public Type ReplaceableInterface | 72 | public Type ReplaceableInterface |
@@ -210,7 +208,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
210 | sp.Teleport(position); | 208 | sp.Teleport(position); |
211 | 209 | ||
212 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 210 | foreach (SceneObjectGroup grp in sp.GetAttachments()) |
213 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | 211 | { |
212 | if (grp.IsDeleted) | ||
213 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | ||
214 | } | ||
214 | } | 215 | } |
215 | else // Another region possibly in another simulator | 216 | else // Another region possibly in another simulator |
216 | { | 217 | { |
@@ -328,10 +329,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
328 | sp.StandUp(); | 329 | sp.StandUp(); |
329 | 330 | ||
330 | if (!sp.ValidateAttachments()) | 331 | if (!sp.ValidateAttachments()) |
331 | { | 332 | m_log.DebugFormat( |
332 | sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | 333 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", |
333 | return; | 334 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); |
334 | } | 335 | |
336 | // if (!sp.ValidateAttachments()) | ||
337 | // { | ||
338 | // sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | ||
339 | // return; | ||
340 | // } | ||
335 | 341 | ||
336 | string reason; | 342 | string reason; |
337 | string version; | 343 | string version; |
@@ -955,7 +961,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
955 | /// This Closes child agents on neighbouring regions | 961 | /// This Closes child agents on neighbouring regions |
956 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 962 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
957 | /// </summary> | 963 | /// </summary> |
958 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) | 964 | protected ScenePresence CrossAgentToNewRegionAsync( |
965 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | ||
966 | bool isFlying, string version) | ||
959 | { | 967 | { |
960 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 968 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
961 | 969 | ||
@@ -963,8 +971,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
963 | 971 | ||
964 | Scene m_scene = agent.Scene; | 972 | Scene m_scene = agent.Scene; |
965 | 973 | ||
966 | if (neighbourRegion != null && agent.ValidateAttachments()) | 974 | if (neighbourRegion != null) |
967 | { | 975 | { |
976 | if (!agent.ValidateAttachments()) | ||
977 | m_log.DebugFormat( | ||
978 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
979 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
980 | |||
968 | pos = pos + (agent.Velocity); | 981 | pos = pos + (agent.Velocity); |
969 | 982 | ||
970 | SetInTransit(agent.UUID); | 983 | SetInTransit(agent.UUID); |
@@ -1789,16 +1802,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1789 | List<SceneObjectGroup> m_attachments = sp.GetAttachments(); | 1802 | List<SceneObjectGroup> m_attachments = sp.GetAttachments(); |
1790 | 1803 | ||
1791 | // Validate | 1804 | // Validate |
1792 | foreach (SceneObjectGroup gobj in m_attachments) | 1805 | // foreach (SceneObjectGroup gobj in m_attachments) |
1793 | { | 1806 | // { |
1794 | if (gobj == null || gobj.IsDeleted) | 1807 | // if (gobj == null || gobj.IsDeleted) |
1795 | return false; | 1808 | // return false; |
1796 | } | 1809 | // } |
1797 | 1810 | ||
1798 | foreach (SceneObjectGroup gobj in m_attachments) | 1811 | foreach (SceneObjectGroup gobj in m_attachments) |
1799 | { | 1812 | { |
1800 | // If the prim group is null then something must have happened to it! | 1813 | // If the prim group is null then something must have happened to it! |
1801 | if (gobj != null) | 1814 | if (gobj != null && !gobj.IsDeleted) |
1802 | { | 1815 | { |
1803 | // Set the parent localID to 0 so it transfers over properly. | 1816 | // Set the parent localID to 0 so it transfers over properly. |
1804 | gobj.RootPart.SetParentLocalId(0); | 1817 | gobj.RootPart.SetParentLocalId(0); |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index a4bb40e..f05b090 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -726,8 +726,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
726 | SceneObjectGroup group = null; | 726 | SceneObjectGroup group = null; |
727 | 727 | ||
728 | string xmlData = Utils.BytesToString(rezAsset.Data); | 728 | string xmlData = Utils.BytesToString(rezAsset.Data); |
729 | List<SceneObjectGroup> objlist = | 729 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(); |
730 | new List<SceneObjectGroup>(); | ||
731 | List<Vector3> veclist = new List<Vector3>(); | 730 | List<Vector3> veclist = new List<Vector3>(); |
732 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | 731 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); |
733 | Vector3 pos; | 732 | Vector3 pos; |
@@ -799,6 +798,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
799 | m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); | 798 | m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); |
800 | } | 799 | } |
801 | 800 | ||
801 | foreach (SceneObjectPart part in group.Parts) | ||
802 | { | ||
803 | // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. | ||
804 | part.LastOwnerID = part.OwnerID; | ||
805 | part.OwnerID = remoteClient.AgentId; | ||
806 | } | ||
807 | |||
802 | if (!attachment) | 808 | if (!attachment) |
803 | { | 809 | { |
804 | // If it's rezzed in world, select it. Much easier to | 810 | // If it's rezzed in world, select it. Much easier to |
@@ -839,7 +845,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
839 | 845 | ||
840 | if (!attachment) | 846 | if (!attachment) |
841 | { | 847 | { |
842 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | 848 | if (rootPart.Shape.PCode == (byte)PCode.Prim) |
843 | group.ClearPartAttachmentData(); | 849 | group.ClearPartAttachmentData(); |
844 | 850 | ||
845 | // Fire on_rez | 851 | // Fire on_rez |
@@ -1017,11 +1023,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1017 | if ((part.OwnerID != item.Owner) || | 1023 | if ((part.OwnerID != item.Owner) || |
1018 | (item.CurrentPermissions & 16) != 0) | 1024 | (item.CurrentPermissions & 16) != 0) |
1019 | { | 1025 | { |
1020 | part.LastOwnerID = part.OwnerID; | ||
1021 | part.OwnerID = item.Owner; | ||
1022 | part.Inventory.ChangeInventoryOwner(item.Owner); | 1026 | part.Inventory.ChangeInventoryOwner(item.Owner); |
1023 | part.GroupMask = 0; // DO NOT propagate here | 1027 | part.GroupMask = 0; // DO NOT propagate here |
1024 | } | 1028 | } |
1029 | |||
1025 | part.EveryoneMask = item.EveryOnePermissions; | 1030 | part.EveryoneMask = item.EveryOnePermissions; |
1026 | part.NextOwnerMask = item.NextPermissions; | 1031 | part.NextOwnerMask = item.NextPermissions; |
1027 | } | 1032 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index b0b35e4..bef0d69 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -87,8 +87,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
87 | "Show the bindings between user UUIDs and user names", | 87 | "Show the bindings between user UUIDs and user names", |
88 | String.Empty, | 88 | String.Empty, |
89 | HandleShowUsers); | 89 | HandleShowUsers); |
90 | |||
91 | |||
92 | } | 90 | } |
93 | 91 | ||
94 | public bool IsSharedModule | 92 | public bool IsSharedModule |
@@ -365,9 +363,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
365 | lock (m_UserCache) | 363 | lock (m_UserCache) |
366 | m_UserCache[user.Id] = user; | 364 | m_UserCache[user.Id] = user; |
367 | 365 | ||
368 | m_log.DebugFormat( | 366 | // m_log.DebugFormat( |
369 | "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", | 367 | // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", |
370 | user.Id, user.FirstName, user.LastName, user.HomeURL); | 368 | // user.Id, user.FirstName, user.LastName, user.HomeURL); |
371 | } | 369 | } |
372 | 370 | ||
373 | //public void AddUser(UUID uuid, string userData) | 371 | //public void AddUser(UUID uuid, string userData) |
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index b20a875..a14a84b 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | |||
@@ -323,7 +323,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
323 | List<UUID> targets = new List<UUID>(); | 323 | List<UUID> targets = new List<UUID>(); |
324 | foreach (SceneObjectGroup sog in attachments) | 324 | foreach (SceneObjectGroup sog in attachments) |
325 | { | 325 | { |
326 | targets.Add(sog.UUID); | 326 | if (!sog.IsDeleted) |
327 | targets.Add(sog.UUID); | ||
327 | } | 328 | } |
328 | 329 | ||
329 | // Need to check each attachment | 330 | // Need to check each attachment |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index 72ae3363..0d121ed 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs | |||
@@ -64,7 +64,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
64 | get | 64 | get |
65 | { | 65 | { |
66 | if (m_UserManagement == null) | 66 | if (m_UserManagement == null) |
67 | { | ||
67 | m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 68 | m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>(); |
69 | |||
70 | if (m_UserManagement == null) | ||
71 | m_log.ErrorFormat( | ||
72 | "[HG INVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}", | ||
73 | m_Scenes[0].RegionInfo.RegionName); | ||
74 | } | ||
75 | |||
68 | return m_UserManagement; | 76 | return m_UserManagement; |
69 | } | 77 | } |
70 | } | 78 | } |
@@ -140,8 +148,29 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
140 | 148 | ||
141 | scene.RegisterModuleInterface<IInventoryService>(this); | 149 | scene.RegisterModuleInterface<IInventoryService>(this); |
142 | 150 | ||
143 | scene.EventManager.OnClientClosed += OnClientClosed; | 151 | if (m_Scenes.Count == 1) |
152 | { | ||
153 | // FIXME: The local connector needs the scene to extract the UserManager. However, it's not enabled so | ||
154 | // we can't just add the region. But this approach is super-messy. | ||
155 | if (m_LocalGridInventoryService is RemoteXInventoryServicesConnector) | ||
156 | { | ||
157 | m_log.DebugFormat( | ||
158 | "[HG INVENTORY BROKER]: Manually setting scene in RemoteXInventoryServicesConnector to {0}", | ||
159 | scene.RegionInfo.RegionName); | ||
160 | |||
161 | ((RemoteXInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene; | ||
162 | } | ||
163 | else if (m_LocalGridInventoryService is LocalInventoryServicesConnector) | ||
164 | { | ||
165 | m_log.DebugFormat( | ||
166 | "[HG INVENTORY BROKER]: Manually setting scene in LocalInventoryServicesConnector to {0}", | ||
167 | scene.RegionInfo.RegionName); | ||
144 | 168 | ||
169 | ((LocalInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene; | ||
170 | } | ||
171 | |||
172 | scene.EventManager.OnClientClosed += OnClientClosed; | ||
173 | } | ||
145 | } | 174 | } |
146 | 175 | ||
147 | public void RemoveRegion(Scene scene) | 176 | public void RemoveRegion(Scene scene) |
@@ -323,7 +352,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
323 | 352 | ||
324 | } | 353 | } |
325 | 354 | ||
326 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) | 355 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
327 | { | 356 | { |
328 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID); | 357 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID); |
329 | 358 | ||
@@ -338,7 +367,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
338 | 367 | ||
339 | } | 368 | } |
340 | 369 | ||
341 | public bool AddFolder(InventoryFolderBase folder) | 370 | public bool AddFolder(InventoryFolderBase folder) |
342 | { | 371 | { |
343 | if (folder == null) | 372 | if (folder == null) |
344 | return false; | 373 | return false; |
@@ -355,7 +384,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
355 | return connector.AddFolder(folder); | 384 | return connector.AddFolder(folder); |
356 | } | 385 | } |
357 | 386 | ||
358 | public bool UpdateFolder(InventoryFolderBase folder) | 387 | public bool UpdateFolder(InventoryFolderBase folder) |
359 | { | 388 | { |
360 | if (folder == null) | 389 | if (folder == null) |
361 | return false; | 390 | return false; |
@@ -372,7 +401,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
372 | return connector.UpdateFolder(folder); | 401 | return connector.UpdateFolder(folder); |
373 | } | 402 | } |
374 | 403 | ||
375 | public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs) | 404 | public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs) |
376 | { | 405 | { |
377 | if (folderIDs == null) | 406 | if (folderIDs == null) |
378 | return false; | 407 | return false; |
@@ -391,7 +420,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
391 | return connector.DeleteFolders(ownerID, folderIDs); | 420 | return connector.DeleteFolders(ownerID, folderIDs); |
392 | } | 421 | } |
393 | 422 | ||
394 | public bool MoveFolder(InventoryFolderBase folder) | 423 | public bool MoveFolder(InventoryFolderBase folder) |
395 | { | 424 | { |
396 | if (folder == null) | 425 | if (folder == null) |
397 | return false; | 426 | return false; |
@@ -408,7 +437,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
408 | return connector.MoveFolder(folder); | 437 | return connector.MoveFolder(folder); |
409 | } | 438 | } |
410 | 439 | ||
411 | public bool PurgeFolder(InventoryFolderBase folder) | 440 | public bool PurgeFolder(InventoryFolderBase folder) |
412 | { | 441 | { |
413 | if (folder == null) | 442 | if (folder == null) |
414 | return false; | 443 | return false; |
@@ -442,7 +471,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
442 | return connector.AddItem(item); | 471 | return connector.AddItem(item); |
443 | } | 472 | } |
444 | 473 | ||
445 | public bool UpdateItem(InventoryItemBase item) | 474 | public bool UpdateItem(InventoryItemBase item) |
446 | { | 475 | { |
447 | if (item == null) | 476 | if (item == null) |
448 | return false; | 477 | return false; |
@@ -459,7 +488,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
459 | return connector.UpdateItem(item); | 488 | return connector.UpdateItem(item); |
460 | } | 489 | } |
461 | 490 | ||
462 | public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) | 491 | public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) |
463 | { | 492 | { |
464 | if (items == null) | 493 | if (items == null) |
465 | return false; | 494 | return false; |
@@ -478,7 +507,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
478 | return connector.MoveItems(ownerID, items); | 507 | return connector.MoveItems(ownerID, items); |
479 | } | 508 | } |
480 | 509 | ||
481 | public bool DeleteItems(UUID ownerID, List<UUID> itemIDs) | 510 | public bool DeleteItems(UUID ownerID, List<UUID> itemIDs) |
482 | { | 511 | { |
483 | //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID); | 512 | //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID); |
484 | 513 | ||
@@ -497,7 +526,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
497 | return connector.DeleteItems(ownerID, itemIDs); | 526 | return connector.DeleteItems(ownerID, itemIDs); |
498 | } | 527 | } |
499 | 528 | ||
500 | public InventoryItemBase GetItem(InventoryItemBase item) | 529 | public InventoryItemBase GetItem(InventoryItemBase item) |
501 | { | 530 | { |
502 | if (item == null) | 531 | if (item == null) |
503 | return null; | 532 | return null; |
@@ -513,7 +542,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
513 | return connector.GetItem(item); | 542 | return connector.GetItem(item); |
514 | } | 543 | } |
515 | 544 | ||
516 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) | 545 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
517 | { | 546 | { |
518 | if (folder == null) | 547 | if (folder == null) |
519 | return null; | 548 | return null; |
@@ -530,17 +559,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
530 | return connector.GetFolder(folder); | 559 | return connector.GetFolder(folder); |
531 | } | 560 | } |
532 | 561 | ||
533 | public bool HasInventoryForUser(UUID userID) | 562 | public bool HasInventoryForUser(UUID userID) |
534 | { | 563 | { |
535 | return false; | 564 | return false; |
536 | } | 565 | } |
537 | 566 | ||
538 | public List<InventoryItemBase> GetActiveGestures(UUID userId) | 567 | public List<InventoryItemBase> GetActiveGestures(UUID userId) |
539 | { | 568 | { |
540 | return new List<InventoryItemBase>(); | 569 | return new List<InventoryItemBase>(); |
541 | } | 570 | } |
542 | 571 | ||
543 | public int GetAssetPermissions(UUID userID, UUID assetID) | 572 | public int GetAssetPermissions(UUID userID, UUID assetID) |
544 | { | 573 | { |
545 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID); | 574 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID); |
546 | 575 | ||
@@ -572,14 +601,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
572 | string connectorType = new HeloServicesConnector(url).Helo(); | 601 | string connectorType = new HeloServicesConnector(url).Helo(); |
573 | m_log.DebugFormat("[HG INVENTORY SERVICE]: HELO returned {0}", connectorType); | 602 | m_log.DebugFormat("[HG INVENTORY SERVICE]: HELO returned {0}", connectorType); |
574 | if (connectorType == "opensim-simian") | 603 | if (connectorType == "opensim-simian") |
604 | { | ||
575 | connector = new SimianInventoryServiceConnector(url); | 605 | connector = new SimianInventoryServiceConnector(url); |
606 | } | ||
576 | else | 607 | else |
577 | connector = new RemoteXInventoryServicesConnector(url); | 608 | { |
609 | RemoteXInventoryServicesConnector rxisc = new RemoteXInventoryServicesConnector(url); | ||
610 | rxisc.Scene = m_Scenes[0]; | ||
611 | connector = rxisc; | ||
612 | } | ||
613 | |||
578 | m_connectors.Add(url, connector); | 614 | m_connectors.Add(url, connector); |
579 | } | 615 | } |
580 | } | 616 | } |
617 | |||
581 | return connector; | 618 | return connector; |
582 | } | 619 | } |
583 | |||
584 | } | 620 | } |
585 | } | 621 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 65e39c0..1c83f8e 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs | |||
@@ -47,9 +47,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
47 | LogManager.GetLogger( | 47 | LogManager.GetLogger( |
48 | MethodBase.GetCurrentMethod().DeclaringType); | 48 | MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private IInventoryService m_InventoryService; | 50 | /// <summary> |
51 | /// Scene used by this module. This currently needs to be publicly settable for HGInventoryBroker. | ||
52 | /// </summary> | ||
53 | public Scene Scene { get; set; } | ||
51 | 54 | ||
52 | private Scene m_Scene; | 55 | private IInventoryService m_InventoryService; |
53 | 56 | ||
54 | private IUserManagement m_UserManager; | 57 | private IUserManagement m_UserManager; |
55 | private IUserManagement UserManager | 58 | private IUserManagement UserManager |
@@ -58,7 +61,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
58 | { | 61 | { |
59 | if (m_UserManager == null) | 62 | if (m_UserManager == null) |
60 | { | 63 | { |
61 | m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>(); | 64 | m_UserManager = Scene.RequestModuleInterface<IUserManagement>(); |
62 | } | 65 | } |
63 | return m_UserManager; | 66 | return m_UserManager; |
64 | } | 67 | } |
@@ -131,8 +134,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
131 | 134 | ||
132 | scene.RegisterModuleInterface<IInventoryService>(this); | 135 | scene.RegisterModuleInterface<IInventoryService>(this); |
133 | 136 | ||
134 | if (m_Scene == null) | 137 | if (Scene == null) |
135 | m_Scene = scene; | 138 | Scene = scene; |
136 | } | 139 | } |
137 | 140 | ||
138 | public void RemoveRegion(Scene scene) | 141 | public void RemoveRegion(Scene scene) |
@@ -185,8 +188,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
185 | Util.FireAndForget(delegate | 188 | Util.FireAndForget(delegate |
186 | { | 189 | { |
187 | if (UserManager != null) | 190 | if (UserManager != null) |
188 | foreach (InventoryItemBase item in invCol.Items) | 191 | { |
192 | // Protect ourselves against the caller subsequently modifying the items list | ||
193 | foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items)) | ||
189 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); | 194 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); |
195 | } | ||
190 | }); | 196 | }); |
191 | 197 | ||
192 | return invCol; | 198 | return invCol; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 8f1f257..c9c716c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs | |||
@@ -45,19 +45,30 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
45 | private static readonly ILog m_log = | 45 | private static readonly ILog m_log = |
46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | /// <summary> | ||
49 | /// Scene used by this module. This currently needs to be publicly settable for HGInventoryBroker. | ||
50 | /// </summary> | ||
51 | public Scene Scene { get; set; } | ||
52 | |||
48 | private bool m_Enabled = false; | 53 | private bool m_Enabled = false; |
49 | private Scene m_Scene; | 54 | private Scene m_Scene; |
50 | private XInventoryServicesConnector m_RemoteConnector; | 55 | private XInventoryServicesConnector m_RemoteConnector; |
51 | 56 | ||
52 | private IUserManagement m_UserManager; | 57 | private IUserManagement m_UserManager; |
53 | private IUserManagement UserManager | 58 | public IUserManagement UserManager |
54 | { | 59 | { |
55 | get | 60 | get |
56 | { | 61 | { |
57 | if (m_UserManager == null) | 62 | if (m_UserManager == null) |
58 | { | 63 | { |
59 | m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>(); | 64 | m_UserManager = Scene.RequestModuleInterface<IUserManagement>(); |
65 | |||
66 | if (m_UserManager == null) | ||
67 | m_log.ErrorFormat( | ||
68 | "[XINVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}", | ||
69 | Scene.RegionInfo.RegionName); | ||
60 | } | 70 | } |
71 | |||
61 | return m_UserManager; | 72 | return m_UserManager; |
62 | } | 73 | } |
63 | } | 74 | } |
@@ -86,12 +97,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
86 | Init(source); | 97 | Init(source); |
87 | } | 98 | } |
88 | 99 | ||
89 | protected void Init(IConfigSource source) | 100 | protected void Init(IConfigSource source) |
90 | { | 101 | { |
91 | m_RemoteConnector = new XInventoryServicesConnector(source); | 102 | m_RemoteConnector = new XInventoryServicesConnector(source); |
92 | } | 103 | } |
93 | 104 | ||
94 | |||
95 | #region ISharedRegionModule | 105 | #region ISharedRegionModule |
96 | 106 | ||
97 | public void Initialise(IConfigSource source) | 107 | public void Initialise(IConfigSource source) |
@@ -128,15 +138,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
128 | 138 | ||
129 | scene.RegisterModuleInterface<IInventoryService>(this); | 139 | scene.RegisterModuleInterface<IInventoryService>(this); |
130 | 140 | ||
131 | if (m_Scene == null) | 141 | if (Scene == null) |
132 | m_Scene = scene; | 142 | Scene = scene; |
133 | } | 143 | } |
134 | 144 | ||
135 | public void RemoveRegion(Scene scene) | 145 | public void RemoveRegion(Scene scene) |
136 | { | 146 | { |
137 | if (!m_Enabled) | 147 | if (!m_Enabled) |
138 | return; | 148 | return; |
139 | |||
140 | } | 149 | } |
141 | 150 | ||
142 | public void RegionLoaded(Scene scene) | 151 | public void RegionLoaded(Scene scene) |
@@ -181,14 +190,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
181 | return m_RemoteConnector.GetFolderForType(userID, type); | 190 | return m_RemoteConnector.GetFolderForType(userID, type); |
182 | } | 191 | } |
183 | 192 | ||
184 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) | 193 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) |
185 | { | 194 | { |
186 | InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); | 195 | InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); |
187 | Util.FireAndForget(delegate | 196 | Util.FireAndForget(delegate |
188 | { | 197 | { |
189 | if (UserManager != null) | 198 | if (UserManager != null) |
190 | foreach (InventoryItemBase item in invCol.Items) | 199 | { |
200 | // Protect ourselves against the caller subsequently modifying the items list | ||
201 | foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items)) | ||
191 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); | 202 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); |
203 | } | ||
192 | }); | 204 | }); |
193 | 205 | ||
194 | return invCol; | 206 | return invCol; |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index f85a917..238863e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -284,8 +284,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
284 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 284 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
285 | 285 | ||
286 | // And zap any troublesome sit target information | 286 | // And zap any troublesome sit target information |
287 | part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | 287 | // part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); |
288 | part.SitTargetPosition = new Vector3(0, 0, 0); | 288 | // part.SitTargetPosition = new Vector3(0, 0, 0); |
289 | 289 | ||
290 | // Fix ownership/creator of inventory items | 290 | // Fix ownership/creator of inventory items |
291 | // Not doing so results in inventory items | 291 | // Not doing so results in inventory items |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 10a83ee..b895afe 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -127,6 +127,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
127 | 127 | ||
128 | EntityBase[] entities = m_scene.GetEntities(); | 128 | EntityBase[] entities = m_scene.GetEntities(); |
129 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 129 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
130 | |||
131 | string checkPermissions = null; | ||
132 | int numObjectsSkippedPermissions = 0; | ||
133 | Object temp; | ||
134 | if (options.TryGetValue("checkPermissions", out temp)) | ||
135 | checkPermissions = (string)temp; | ||
130 | 136 | ||
131 | // Filter entities so that we only have scene objects. | 137 | // Filter entities so that we only have scene objects. |
132 | // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods | 138 | // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods |
@@ -136,9 +142,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
136 | if (entity is SceneObjectGroup) | 142 | if (entity is SceneObjectGroup) |
137 | { | 143 | { |
138 | SceneObjectGroup sceneObject = (SceneObjectGroup)entity; | 144 | SceneObjectGroup sceneObject = (SceneObjectGroup)entity; |
139 | 145 | ||
140 | if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) | 146 | if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) |
141 | sceneObjects.Add((SceneObjectGroup)entity); | 147 | { |
148 | if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions)) | ||
149 | { | ||
150 | // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. | ||
151 | ++numObjectsSkippedPermissions; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | sceneObjects.Add(sceneObject); | ||
156 | } | ||
157 | } | ||
142 | } | 158 | } |
143 | } | 159 | } |
144 | 160 | ||
@@ -159,7 +175,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
159 | { | 175 | { |
160 | m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); | 176 | m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); |
161 | } | 177 | } |
162 | 178 | ||
179 | if (numObjectsSkippedPermissions > 0) | ||
180 | { | ||
181 | m_log.DebugFormat( | ||
182 | "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", | ||
183 | numObjectsSkippedPermissions); | ||
184 | } | ||
185 | |||
163 | // Make sure that we also request terrain texture assets | 186 | // Make sure that we also request terrain texture assets |
164 | RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; | 187 | RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; |
165 | 188 | ||
@@ -211,6 +234,83 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
211 | } | 234 | } |
212 | 235 | ||
213 | /// <summary> | 236 | /// <summary> |
237 | /// Checks whether the user has permission to export an object group to an OAR. | ||
238 | /// </summary> | ||
239 | /// <param name="user">The user</param> | ||
240 | /// <param name="objGroup">The object group</param> | ||
241 | /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param> | ||
242 | /// <returns>Whether the user is allowed to export the object to an OAR</returns> | ||
243 | private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions) | ||
244 | { | ||
245 | if (checkPermissions == null) | ||
246 | return true; | ||
247 | |||
248 | IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>(); | ||
249 | if (module == null) | ||
250 | return true; // this shouldn't happen | ||
251 | |||
252 | // Check whether the user is permitted to export all of the parts in the SOG. If any | ||
253 | // part can't be exported then the entire SOG can't be exported. | ||
254 | |||
255 | bool permitted = true; | ||
256 | //int primNumber = 1; | ||
257 | |||
258 | foreach (SceneObjectPart obj in objGroup.Parts) | ||
259 | { | ||
260 | uint perm; | ||
261 | PermissionClass permissionClass = module.GetPermissionClass(user, obj); | ||
262 | switch (permissionClass) | ||
263 | { | ||
264 | case PermissionClass.Owner: | ||
265 | perm = obj.BaseMask; | ||
266 | break; | ||
267 | case PermissionClass.Group: | ||
268 | perm = obj.GroupMask | obj.EveryoneMask; | ||
269 | break; | ||
270 | case PermissionClass.Everyone: | ||
271 | default: | ||
272 | perm = obj.EveryoneMask; | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | bool canCopy = (perm & (uint)PermissionMask.Copy) != 0; | ||
277 | bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0; | ||
278 | |||
279 | // Special case: if Everyone can copy the object then this implies it can also be | ||
280 | // Transferred. | ||
281 | // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask | ||
282 | // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer | ||
283 | // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. | ||
284 | if (permissionClass != PermissionClass.Owner) | ||
285 | { | ||
286 | canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | bool partPermitted = true; | ||
291 | if (checkPermissions.Contains("C") && !canCopy) | ||
292 | partPermitted = false; | ||
293 | if (checkPermissions.Contains("T") && !canTransfer) | ||
294 | partPermitted = false; | ||
295 | |||
296 | //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); | ||
297 | //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", | ||
298 | // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, | ||
299 | // permissionClass, checkPermissions, canCopy, canTransfer, permitted); | ||
300 | |||
301 | if (!partPermitted) | ||
302 | { | ||
303 | permitted = false; | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | //++primNumber; | ||
308 | } | ||
309 | |||
310 | return permitted; | ||
311 | } | ||
312 | |||
313 | /// <summary> | ||
214 | /// Create the control file for the most up to date archive | 314 | /// Create the control file for the most up to date archive |
215 | /// </summary> | 315 | /// </summary> |
216 | /// <returns></returns> | 316 | /// <returns></returns> |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index 08eb80c..f44a3ba 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); | 128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); |
129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); | 129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); |
130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
131 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); | ||
131 | 132 | ||
132 | List<string> mainParams = ops.Parse(cmdparams); | 133 | List<string> mainParams = ops.Parse(cmdparams); |
133 | 134 | ||
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index b185d9b..e798e5e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -318,6 +318,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
318 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); | 318 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); |
319 | 319 | ||
320 | SceneObjectPart part1 = CreateSceneObjectPart1(); | 320 | SceneObjectPart part1 = CreateSceneObjectPart1(); |
321 | |||
322 | part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f); | ||
323 | part1.SitTargetPosition = new Vector3(1, 2, 3); | ||
324 | |||
321 | SceneObjectGroup object1 = new SceneObjectGroup(part1); | 325 | SceneObjectGroup object1 = new SceneObjectGroup(part1); |
322 | 326 | ||
323 | // Let's put some inventory items into our object | 327 | // Let's put some inventory items into our object |
@@ -390,6 +394,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
390 | object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); | 394 | object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); |
391 | Assert.That( | 395 | Assert.That( |
392 | object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); | 396 | object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); |
397 | Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation)); | ||
398 | Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition)); | ||
393 | 399 | ||
394 | TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; | 400 | TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; |
395 | Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); | 401 | Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index fb32288..321f6b6 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -992,6 +992,11 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
992 | args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3; | 992 | args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3; |
993 | args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4; | 993 | args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4; |
994 | 994 | ||
995 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName); | ||
996 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName); | ||
997 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName); | ||
998 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName); | ||
999 | |||
995 | remoteClient.SendRegionHandshake(Scene.RegionInfo,args); | 1000 | remoteClient.SendRegionHandshake(Scene.RegionInfo,args); |
996 | } | 1001 | } |
997 | 1002 | ||
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index afb641f..2e877f0 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | |||
@@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces; | |||
39 | 39 | ||
40 | namespace OpenSim.Region.CoreModules.World.Permissions | 40 | namespace OpenSim.Region.CoreModules.World.Permissions |
41 | { | 41 | { |
42 | public class PermissionsModule : IRegionModule | 42 | public class PermissionsModule : IRegionModule, IPermissionsModule |
43 | { | 43 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
@@ -150,6 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
150 | else | 150 | else |
151 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); | 151 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); |
152 | 152 | ||
153 | scene.RegisterModuleInterface<IPermissionsModule>(this); | ||
154 | |||
153 | //Register functions with Scene External Checks! | 155 | //Register functions with Scene External Checks! |
154 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; | 156 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; |
155 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; | 157 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; |
@@ -574,46 +576,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
574 | if (objectOwner != UUID.Zero) | 576 | if (objectOwner != UUID.Zero) |
575 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; | 577 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; |
576 | 578 | ||
577 | if (m_bypassPermissions) | 579 | PermissionClass permissionClass = GetPermissionClass(user, task); |
578 | return objectOwnerMask; | ||
579 | |||
580 | // Object owners should be able to edit their own content | ||
581 | if (user == objectOwner) | ||
582 | return objectOwnerMask; | ||
583 | |||
584 | if (IsFriendWithPerms(user, objectOwner)) | ||
585 | { | ||
586 | return objectOwnerMask; | ||
587 | } | ||
588 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set | ||
589 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) | ||
590 | { | ||
591 | return objectOwnerMask; | ||
592 | } | ||
593 | |||
594 | // Admin should be able to edit anything in the sim (including admin objects) | ||
595 | if (IsAdministrator(user)) | ||
596 | { | ||
597 | return objectOwnerMask; | ||
598 | } | ||
599 | 580 | ||
600 | // Users should be able to edit what is over their land. | 581 | switch (permissionClass) |
601 | Vector3 taskPos = task.AbsolutePosition; | ||
602 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); | ||
603 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) | ||
604 | { | 582 | { |
605 | // Admin objects should not be editable by the above | 583 | case PermissionClass.Owner: |
606 | if (!IsAdministrator(objectOwner)) | ||
607 | { | ||
608 | return objectOwnerMask; | 584 | return objectOwnerMask; |
609 | } | 585 | case PermissionClass.Group: |
586 | return objectGroupMask | objectEveryoneMask; | ||
587 | case PermissionClass.Everyone: | ||
588 | default: | ||
589 | return objectEveryoneMask; | ||
610 | } | 590 | } |
611 | |||
612 | // Group permissions | ||
613 | if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) | ||
614 | return objectGroupMask | objectEveryoneMask; | ||
615 | |||
616 | return objectEveryoneMask; | ||
617 | } | 591 | } |
618 | 592 | ||
619 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) | 593 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) |
@@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
644 | return objectFlagsMask; | 618 | return objectFlagsMask; |
645 | } | 619 | } |
646 | 620 | ||
621 | public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj) | ||
622 | { | ||
623 | if (obj == null) | ||
624 | return PermissionClass.Everyone; | ||
625 | |||
626 | if (m_bypassPermissions) | ||
627 | return PermissionClass.Owner; | ||
628 | |||
629 | // Object owners should be able to edit their own content | ||
630 | UUID objectOwner = obj.OwnerID; | ||
631 | if (user == objectOwner) | ||
632 | return PermissionClass.Owner; | ||
633 | |||
634 | if (IsFriendWithPerms(user, objectOwner)) | ||
635 | return PermissionClass.Owner; | ||
636 | |||
637 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set | ||
638 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) | ||
639 | return PermissionClass.Owner; | ||
640 | |||
641 | // Admin should be able to edit anything in the sim (including admin objects) | ||
642 | if (IsAdministrator(user)) | ||
643 | return PermissionClass.Owner; | ||
644 | |||
645 | // Users should be able to edit what is over their land. | ||
646 | Vector3 taskPos = obj.AbsolutePosition; | ||
647 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); | ||
648 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) | ||
649 | { | ||
650 | // Admin objects should not be editable by the above | ||
651 | if (!IsAdministrator(objectOwner)) | ||
652 | return PermissionClass.Owner; | ||
653 | } | ||
654 | |||
655 | // Group permissions | ||
656 | if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0)) | ||
657 | return PermissionClass.Group; | ||
658 | |||
659 | return PermissionClass.Everyone; | ||
660 | } | ||
661 | |||
647 | /// <summary> | 662 | /// <summary> |
648 | /// General permissions checks for any operation involving an object. These supplement more specific checks | 663 | /// General permissions checks for any operation involving an object. These supplement more specific checks |
649 | /// implemented by callers. | 664 | /// implemented by callers. |
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 59c26e7..d1b7dc1 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | |||
@@ -89,18 +89,13 @@ namespace OpenSim.Region.Framework.Interfaces | |||
89 | ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); | 89 | ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); |
90 | 90 | ||
91 | /// <summary> | 91 | /// <summary> |
92 | /// Rez an attachment from user inventory | 92 | /// Rez an attachment from user inventory and change inventory status to match. |
93 | /// </summary> | 93 | /// </summary> |
94 | /// <param name="remoteClient"></param> | 94 | /// <param name="sp"></param> |
95 | /// <param name="itemID"></param> | 95 | /// <param name="itemID"></param> |
96 | /// <param name="AttachmentPt"></param> | 96 | /// <param name="AttachmentPt"></param> |
97 | /// <param name="updateinventoryStatus"> | 97 | /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> |
98 | /// If true, we also update the user's inventory to show that the attachment is set. If false, we do not. | 98 | ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt); |
99 | /// False is required so that we don't attempt to update information when a user enters a scene with the | ||
100 | /// attachment already correctly set up in inventory. | ||
101 | /// <returns>The uuid of the scene object that was attached. Null if the scene object could not be found</returns> | ||
102 | ISceneEntity RezSingleAttachmentFromInventory( | ||
103 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus); | ||
104 | 99 | ||
105 | // Same as above, but also load script states from a separate doc | 100 | // Same as above, but also load script states from a separate doc |
106 | ISceneEntity RezSingleAttachmentFromInventory( | 101 | ISceneEntity RezSingleAttachmentFromInventory( |
@@ -146,13 +141,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
146 | /// </param> | 141 | /// </param> |
147 | void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient); | 142 | void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient); |
148 | 143 | ||
149 | /// <summary> | 144 | /// Update the position of an attachment. |
150 | /// Update the user inventory with a changed attachment | ||
151 | /// </summary> | 145 | /// </summary> |
152 | /// <param name="remoteClient"></param> | 146 | /// <param name="sog"></param> |
153 | /// <param name="grp"></param> | 147 | /// <param name="pos"></param> |
154 | /// <param name="itemID"></param> | 148 | void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos); |
155 | /// <param name="agentID"></param> | ||
156 | void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID); | ||
157 | } | 149 | } |
158 | } | 150 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs new file mode 100644 index 0000000..1ed978b --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs | |||
@@ -0,0 +1,54 @@ | |||
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 | |||
28 | using OpenMetaverse; | ||
29 | using OpenSim.Region.Framework.Scenes; | ||
30 | |||
31 | namespace OpenSim.Region.Framework.Interfaces | ||
32 | { | ||
33 | /// <value> | ||
34 | /// Which set of permissions a user has. | ||
35 | /// </value> | ||
36 | public enum PermissionClass | ||
37 | { | ||
38 | Owner, | ||
39 | Group, | ||
40 | Everyone | ||
41 | }; | ||
42 | |||
43 | public interface IPermissionsModule | ||
44 | { | ||
45 | |||
46 | /// <summary> | ||
47 | /// Returns the type of permissions that the user has over an object. | ||
48 | /// </summary> | ||
49 | /// <param name="user">The user</param> | ||
50 | /// <param name="obj">The object</param> | ||
51 | /// <returns>The type of permissions the user has over the object</returns> | ||
52 | PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj); | ||
53 | } | ||
54 | } | ||
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 8913133..ff39283 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs | |||
@@ -61,6 +61,14 @@ namespace OpenSim.Region.Framework.Interfaces | |||
61 | AvatarAppearance Appearance { get; set; } | 61 | AvatarAppearance Appearance { get; set; } |
62 | 62 | ||
63 | /// <summary> | 63 | /// <summary> |
64 | /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments. | ||
65 | /// </summary> | ||
66 | /// <remarks> | ||
67 | /// All add and remove attachment operations must synchronize on this for the lifetime of their operations. | ||
68 | /// </remarks> | ||
69 | Object AttachmentsSyncLock { get; } | ||
70 | |||
71 | /// <summary> | ||
64 | /// The scene objects attached to this avatar. | 72 | /// The scene objects attached to this avatar. |
65 | /// </summary> | 73 | /// </summary> |
66 | /// <returns> | 74 | /// <returns> |
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs index 2397f22..e715e70 100644 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs | |||
@@ -30,12 +30,21 @@ using OpenSim.Region.Framework.Scenes; | |||
30 | 30 | ||
31 | namespace OpenSim.Region.Framework.Interfaces | 31 | namespace OpenSim.Region.Framework.Interfaces |
32 | { | 32 | { |
33 | /// <summary> | ||
34 | /// Sends scheduled updates to it's associated ScenePresence. | ||
35 | /// </summary> | ||
33 | public interface ISceneViewer | 36 | public interface ISceneViewer |
34 | { | 37 | { |
35 | void Reset(); | 38 | // void Reset(); |
36 | void Close(); | 39 | void Close(); |
40 | |||
41 | /// <summary> | ||
42 | /// Add the part to the queue of parts for which we need to send an update to the client | ||
43 | /// </summary> | ||
44 | /// <param name="part"></param> | ||
37 | void QueuePartForUpdate(SceneObjectPart part); | 45 | void QueuePartForUpdate(SceneObjectPart part); |
46 | |||
38 | void SendPrimUpdates(); | 47 | void SendPrimUpdates(); |
39 | int GetPendingObjectsCount(); | 48 | int GetPendingObjectsCount(); |
40 | } | 49 | } |
41 | } | 50 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 641e226..7dde586 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs | |||
@@ -54,5 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
54 | bool HasScript(UUID itemID, out bool running); | 54 | bool HasScript(UUID itemID, out bool running); |
55 | 55 | ||
56 | void SaveAllState(); | 56 | void SaveAllState(); |
57 | |||
58 | /// <summary> | ||
59 | /// Starts the processing threads. | ||
60 | /// </summary> | ||
61 | void StartProcessing(); | ||
57 | } | 62 | } |
58 | } | 63 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 63dd550..c2ec5d0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
57 | protected AsyncInventorySender m_asyncInventorySender; | 57 | protected AsyncInventorySender m_asyncInventorySender; |
58 | 58 | ||
59 | /// <summary> | 59 | /// <summary> |
60 | /// Start all the scripts in the scene which should be started. | 60 | /// Creates all the scripts in the scene which should be started. |
61 | /// </summary> | 61 | /// </summary> |
62 | public void CreateScriptInstances() | 62 | public void CreateScriptInstances() |
63 | { | 63 | { |
64 | m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); | 64 | m_log.Info("[PRIM INVENTORY]: Creating scripts in scene"); |
65 | 65 | ||
66 | EntityBase[] entities = Entities.GetEntities(); | 66 | EntityBase[] entities = Entities.GetEntities(); |
67 | foreach (EntityBase group in entities) | 67 | foreach (EntityBase group in entities) |
@@ -74,6 +74,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | /// <summary> | ||
78 | /// Lets the script engines start processing scripts. | ||
79 | /// </summary> | ||
80 | public void StartScripts() | ||
81 | { | ||
82 | m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); | ||
83 | |||
84 | IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); | ||
85 | if (engines != null) | ||
86 | { | ||
87 | foreach (IScriptModule engine in engines) | ||
88 | { | ||
89 | if (engine != null) | ||
90 | { | ||
91 | engine.StartProcessing(); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
77 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) | 97 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) |
78 | { | 98 | { |
79 | IMoneyModule money = RequestModuleInterface<IMoneyModule>(); | 99 | IMoneyModule money = RequestModuleInterface<IMoneyModule>(); |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a661ab8..c5bb2b2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -610,9 +610,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
610 | #region Region Settings | 610 | #region Region Settings |
611 | 611 | ||
612 | // Load region settings | 612 | // Load region settings |
613 | m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(m_regInfo.RegionID); | 613 | // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region. |
614 | // However, in this case, the default textures are not set in memory properly, so we need to do it here and | ||
615 | // resave. | ||
616 | // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new | ||
617 | // region is set up and avoid these gyrations. | ||
618 | RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID); | ||
619 | bool updatedTerrainTextures = false; | ||
620 | if (rs.TerrainTexture1 == UUID.Zero) | ||
621 | { | ||
622 | rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1; | ||
623 | updatedTerrainTextures = true; | ||
624 | } | ||
625 | |||
626 | if (rs.TerrainTexture2 == UUID.Zero) | ||
627 | { | ||
628 | rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2; | ||
629 | updatedTerrainTextures = true; | ||
630 | } | ||
631 | |||
632 | if (rs.TerrainTexture3 == UUID.Zero) | ||
633 | { | ||
634 | rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3; | ||
635 | updatedTerrainTextures = true; | ||
636 | } | ||
637 | |||
638 | if (rs.TerrainTexture4 == UUID.Zero) | ||
639 | { | ||
640 | rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4; | ||
641 | updatedTerrainTextures = true; | ||
642 | } | ||
643 | |||
644 | if (updatedTerrainTextures) | ||
645 | rs.Save(); | ||
646 | |||
647 | m_regInfo.RegionSettings = rs; | ||
614 | 648 | ||
615 | m_regInfo.RegionSettings = simDataService.LoadRegionSettings(m_regInfo.RegionID); | ||
616 | if (estateDataService != null) | 649 | if (estateDataService != null) |
617 | m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); | 650 | m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); |
618 | 651 | ||
@@ -645,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
645 | EventManager.OnLandObjectRemoved += | 678 | EventManager.OnLandObjectRemoved += |
646 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); | 679 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); |
647 | 680 | ||
648 | m_sceneGraph = new SceneGraph(this, m_regInfo); | 681 | m_sceneGraph = new SceneGraph(this); |
649 | 682 | ||
650 | // If the scene graph has an Unrecoverable error, restart this sim. | 683 | // If the scene graph has an Unrecoverable error, restart this sim. |
651 | // Currently the only thing that causes it to happen is two kinds of specific | 684 | // Currently the only thing that causes it to happen is two kinds of specific |
@@ -1575,7 +1608,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1575 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; | 1608 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; |
1576 | msg.Position = Vector3.Zero; | 1609 | msg.Position = Vector3.Zero; |
1577 | msg.RegionID = RegionInfo.RegionID.Guid; | 1610 | msg.RegionID = RegionInfo.RegionID.Guid; |
1578 | msg.binaryBucket = new byte[0]; | 1611 | |
1612 | // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3. | ||
1613 | msg.binaryBucket = Util.StringToBytes256("\0"); | ||
1579 | if (ret.Value.count > 1) | 1614 | if (ret.Value.count > 1) |
1580 | msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); | 1615 | msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); |
1581 | else | 1616 | else |
@@ -2492,14 +2527,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2492 | /// <returns>False</returns> | 2527 | /// <returns>False</returns> |
2493 | public virtual bool IncomingCreateObject(UUID userID, UUID itemID) | 2528 | public virtual bool IncomingCreateObject(UUID userID, UUID itemID) |
2494 | { | 2529 | { |
2495 | //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); | 2530 | m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); |
2496 | 2531 | ||
2497 | ScenePresence sp = GetScenePresence(userID); | 2532 | // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as |
2498 | if (sp != null && AttachmentsModule != null) | 2533 | // attachments are being rezzed elsewhere in AddNewClient() |
2499 | { | 2534 | // ScenePresence sp = GetScenePresence(userID); |
2500 | uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); | 2535 | // if (sp != null && AttachmentsModule != null) |
2501 | AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); | 2536 | // { |
2502 | } | 2537 | // uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); |
2538 | // AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); | ||
2539 | // } | ||
2503 | 2540 | ||
2504 | return false; | 2541 | return false; |
2505 | } | 2542 | } |
@@ -3272,8 +3309,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3272 | if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) | 3309 | if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) |
3273 | AttachmentsModule.SaveChangedAttachments(avatar); | 3310 | AttachmentsModule.SaveChangedAttachments(avatar); |
3274 | 3311 | ||
3275 | if (avatar != null && (!avatar.IsChildAgent)) | 3312 | if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) |
3276 | avatar.SaveChangedAttachments(); | 3313 | AttachmentsModule.SaveChangedAttachments(avatar); |
3277 | 3314 | ||
3278 | ForEachClient( | 3315 | ForEachClient( |
3279 | delegate(IClientAPI client) | 3316 | delegate(IClientAPI client) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 42e2502..d1ee990 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
83 | 83 | ||
84 | protected internal EntityManager Entities = new EntityManager(); | 84 | protected internal EntityManager Entities = new EntityManager(); |
85 | 85 | ||
86 | protected RegionInfo m_regInfo; | ||
87 | protected Scene m_parentScene; | 86 | protected Scene m_parentScene; |
88 | protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); | 87 | protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); |
89 | protected int m_numRootAgents = 0; | 88 | protected int m_numRootAgents = 0; |
@@ -117,10 +116,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
117 | 116 | ||
118 | #endregion | 117 | #endregion |
119 | 118 | ||
120 | protected internal SceneGraph(Scene parent, RegionInfo regInfo) | 119 | protected internal SceneGraph(Scene parent) |
121 | { | 120 | { |
122 | m_parentScene = parent; | 121 | m_parentScene = parent; |
123 | m_regInfo = regInfo; | ||
124 | } | 122 | } |
125 | 123 | ||
126 | public PhysicsScene PhysicsScene | 124 | public PhysicsScene PhysicsScene |
@@ -131,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
131 | // If we're not doing the initial set | 129 | // If we're not doing the initial set |
132 | // Then we've got to remove the previous | 130 | // Then we've got to remove the previous |
133 | // event handler | 131 | // event handler |
134 | |||
135 | if (_PhyScene != null) | 132 | if (_PhyScene != null) |
136 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; | 133 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; |
137 | 134 | ||
@@ -413,12 +410,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
413 | // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", | 410 | // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", |
414 | // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); | 411 | // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); |
415 | 412 | ||
416 | SceneObjectPart[] children = sceneObject.Parts; | 413 | SceneObjectPart[] parts = sceneObject.Parts; |
417 | 414 | ||
418 | // Clamp child prim sizes and add child prims to the m_numPrim count | 415 | // Clamp child prim sizes and add child prims to the m_numPrim count |
419 | if (m_parentScene.m_clampPrimSize) | 416 | if (m_parentScene.m_clampPrimSize) |
420 | { | 417 | { |
421 | foreach (SceneObjectPart part in children) | 418 | foreach (SceneObjectPart part in parts) |
422 | { | 419 | { |
423 | Vector3 scale = part.Shape.Scale; | 420 | Vector3 scale = part.Shape.Scale; |
424 | 421 | ||
@@ -432,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
432 | part.Shape.Scale = scale; | 429 | part.Shape.Scale = scale; |
433 | } | 430 | } |
434 | } | 431 | } |
435 | m_numPrim += children.Length; | 432 | m_numPrim += parts.Length; |
436 | 433 | ||
437 | sceneObject.AttachToScene(m_parentScene); | 434 | sceneObject.AttachToScene(m_parentScene); |
438 | 435 | ||
@@ -452,15 +449,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
452 | 449 | ||
453 | lock (SceneObjectGroupsByFullPartID) | 450 | lock (SceneObjectGroupsByFullPartID) |
454 | { | 451 | { |
455 | SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject; | 452 | foreach (SceneObjectPart part in parts) |
456 | foreach (SceneObjectPart part in children) | ||
457 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; | 453 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; |
458 | } | 454 | } |
459 | 455 | ||
460 | lock (SceneObjectGroupsByLocalPartID) | 456 | lock (SceneObjectGroupsByLocalPartID) |
461 | { | 457 | { |
462 | SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject; | 458 | // m_log.DebugFormat( |
463 | foreach (SceneObjectPart part in children) | 459 | // "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}", |
460 | // sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName); | ||
461 | |||
462 | foreach (SceneObjectPart part in parts) | ||
464 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; | 463 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; |
465 | } | 464 | } |
466 | 465 | ||
@@ -473,6 +472,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
473 | /// <returns>true if the object was deleted, false if there was no object to delete</returns> | 472 | /// <returns>true if the object was deleted, false if there was no object to delete</returns> |
474 | public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) | 473 | public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) |
475 | { | 474 | { |
475 | // m_log.DebugFormat( | ||
476 | // "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}", | ||
477 | // uuid, resultOfObjectLinked); | ||
478 | |||
476 | EntityBase entity; | 479 | EntityBase entity; |
477 | if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup))) | 480 | if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup))) |
478 | return false; | 481 | return false; |
@@ -501,7 +504,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
501 | SceneObjectPart[] parts = grp.Parts; | 504 | SceneObjectPart[] parts = grp.Parts; |
502 | for (int i = 0; i < parts.Length; i++) | 505 | for (int i = 0; i < parts.Length; i++) |
503 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); | 506 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); |
504 | SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID); | ||
505 | } | 507 | } |
506 | 508 | ||
507 | lock (SceneObjectGroupsByLocalPartID) | 509 | lock (SceneObjectGroupsByLocalPartID) |
@@ -509,7 +511,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
509 | SceneObjectPart[] parts = grp.Parts; | 511 | SceneObjectPart[] parts = grp.Parts; |
510 | for (int i = 0; i < parts.Length; i++) | 512 | for (int i = 0; i < parts.Length; i++) |
511 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); | 513 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); |
512 | SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId); | ||
513 | } | 514 | } |
514 | 515 | ||
515 | return Entities.Remove(uuid); | 516 | return Entities.Remove(uuid); |
@@ -654,7 +655,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
654 | ScenePresence newAvatar = null; | 655 | ScenePresence newAvatar = null; |
655 | 656 | ||
656 | // ScenePresence always defaults to child agent | 657 | // ScenePresence always defaults to child agent |
657 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type); | 658 | newAvatar = new ScenePresence(client, m_parentScene, appearance, type); |
658 | 659 | ||
659 | AddScenePresence(newAvatar); | 660 | AddScenePresence(newAvatar); |
660 | 661 | ||
@@ -721,7 +722,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
721 | if (!Entities.Remove(agentID)) | 722 | if (!Entities.Remove(agentID)) |
722 | { | 723 | { |
723 | m_log.WarnFormat( | 724 | m_log.WarnFormat( |
724 | "[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", | 725 | "[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", |
725 | agentID); | 726 | agentID); |
726 | } | 727 | } |
727 | 728 | ||
@@ -745,7 +746,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
745 | } | 746 | } |
746 | else | 747 | else |
747 | { | 748 | { |
748 | m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 749 | m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
749 | } | 750 | } |
750 | } | 751 | } |
751 | finally | 752 | finally |
@@ -956,7 +957,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
956 | if (Entities.TryGetValue(localID, out entity)) | 957 | if (Entities.TryGetValue(localID, out entity)) |
957 | return entity as SceneObjectGroup; | 958 | return entity as SceneObjectGroup; |
958 | 959 | ||
959 | //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); | 960 | // m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID); |
961 | |||
960 | SceneObjectGroup sog; | 962 | SceneObjectGroup sog; |
961 | lock (SceneObjectGroupsByLocalPartID) | 963 | lock (SceneObjectGroupsByLocalPartID) |
962 | SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); | 964 | SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); |
@@ -964,8 +966,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
964 | if (sog != null) | 966 | if (sog != null) |
965 | { | 967 | { |
966 | if (sog.HasChildPrim(localID)) | 968 | if (sog.HasChildPrim(localID)) |
969 | { | ||
970 | // m_log.DebugFormat( | ||
971 | // "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.", | ||
972 | // sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | ||
973 | |||
967 | return sog; | 974 | return sog; |
968 | SceneObjectGroupsByLocalPartID.Remove(localID); | 975 | } |
976 | else | ||
977 | { | ||
978 | lock (SceneObjectGroupsByLocalPartID) | ||
979 | { | ||
980 | m_log.WarnFormat( | ||
981 | "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.", | ||
982 | sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | ||
983 | |||
984 | SceneObjectGroupsByLocalPartID.Remove(localID); | ||
985 | } | ||
986 | } | ||
969 | } | 987 | } |
970 | 988 | ||
971 | EntityBase[] entityList = GetEntities(); | 989 | EntityBase[] entityList = GetEntities(); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 9f0ac4f..6bd9183 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | |||
@@ -388,5 +388,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
388 | for (int i = 0; i < parts.Length; i++) | 388 | for (int i = 0; i < parts.Length; i++) |
389 | parts[i].Inventory.ResumeScripts(); | 389 | parts[i].Inventory.ResumeScripts(); |
390 | } | 390 | } |
391 | |||
392 | /// <summary> | ||
393 | /// Returns true if any part in the scene object contains scripts, false otherwise. | ||
394 | /// </summary> | ||
395 | /// <returns></returns> | ||
396 | public bool ContainsScripts() | ||
397 | { | ||
398 | foreach (SceneObjectPart part in Parts) | ||
399 | if (part.Inventory.ContainsScripts()) | ||
400 | return true; | ||
401 | |||
402 | return false; | ||
403 | } | ||
391 | } | 404 | } |
392 | } | 405 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 1f0840d..f6b690c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -1239,10 +1239,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1239 | item.CurrentPermissions = perms; | 1239 | item.CurrentPermissions = perms; |
1240 | item.BasePermissions = perms; | 1240 | item.BasePermissions = perms; |
1241 | } | 1241 | } |
1242 | |||
1242 | m_inventorySerial++; | 1243 | m_inventorySerial++; |
1243 | HasInventoryChanged = true; | 1244 | HasInventoryChanged = true; |
1244 | } | 1245 | } |
1245 | 1246 | ||
1247 | /// <summary> | ||
1248 | /// Returns true if this part inventory contains any scripts. False otherwise. | ||
1249 | /// </summary> | ||
1250 | /// <returns></returns> | ||
1246 | public bool ContainsScripts() | 1251 | public bool ContainsScripts() |
1247 | { | 1252 | { |
1248 | foreach (TaskInventoryItem item in m_items.Values) | 1253 | foreach (TaskInventoryItem item in m_items.Values) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 35a8df7..7a86f98 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -124,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
124 | 124 | ||
125 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); | 125 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); |
126 | 126 | ||
127 | public Object AttachmentsSyncLock { get; private set; } | ||
128 | |||
127 | private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); | 129 | private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); |
128 | private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; | 130 | private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; |
129 | private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; | 131 | private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; |
@@ -199,7 +201,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
199 | 201 | ||
200 | private float m_health = 100f; | 202 | private float m_health = 100f; |
201 | 203 | ||
202 | protected RegionInfo m_regionInfo; | ||
203 | protected ulong crossingFromRegion; | 204 | protected ulong crossingFromRegion; |
204 | 205 | ||
205 | private readonly Vector3[] Dir_Vectors = new Vector3[11]; | 206 | private readonly Vector3[] Dir_Vectors = new Vector3[11]; |
@@ -770,23 +771,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
770 | #endregion | 771 | #endregion |
771 | 772 | ||
772 | #region Constructor(s) | 773 | #region Constructor(s) |
773 | 774 | ||
774 | public ScenePresence( | 775 | public ScenePresence( |
775 | IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) | 776 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) |
776 | { | 777 | { |
778 | AttachmentsSyncLock = new Object(); | ||
779 | |||
777 | m_sendCourseLocationsMethod = SendCoarseLocationsDefault; | 780 | m_sendCourseLocationsMethod = SendCoarseLocationsDefault; |
778 | m_sceneViewer = new SceneViewer(this); | 781 | m_sceneViewer = new SceneViewer(this); |
779 | m_animator = new ScenePresenceAnimator(this); | 782 | m_animator = new ScenePresenceAnimator(this); |
780 | PresenceType = type; | 783 | PresenceType = type; |
781 | m_DrawDistance = world.DefaultDrawDistance; | 784 | m_DrawDistance = world.DefaultDrawDistance; |
782 | m_rootRegionHandle = reginfo.RegionHandle; | 785 | m_rootRegionHandle = world.RegionInfo.RegionHandle; |
783 | m_controllingClient = client; | 786 | m_controllingClient = client; |
784 | m_firstname = m_controllingClient.FirstName; | 787 | m_firstname = m_controllingClient.FirstName; |
785 | m_lastname = m_controllingClient.LastName; | 788 | m_lastname = m_controllingClient.LastName; |
786 | m_name = String.Format("{0} {1}", m_firstname, m_lastname); | 789 | m_name = String.Format("{0} {1}", m_firstname, m_lastname); |
787 | m_scene = world; | 790 | m_scene = world; |
788 | m_uuid = client.AgentId; | 791 | m_uuid = client.AgentId; |
789 | m_regionInfo = reginfo; | ||
790 | m_localId = m_scene.AllocateLocalId(); | 792 | m_localId = m_scene.AllocateLocalId(); |
791 | 793 | ||
792 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); | 794 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); |
@@ -1302,7 +1304,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1302 | 1304 | ||
1303 | //m_log.DebugFormat("Completed movement"); | 1305 | //m_log.DebugFormat("Completed movement"); |
1304 | 1306 | ||
1305 | m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); | 1307 | m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |
1306 | SendInitialData(); | 1308 | SendInitialData(); |
1307 | 1309 | ||
1308 | // Create child agents in neighbouring regions | 1310 | // Create child agents in neighbouring regions |
@@ -3226,8 +3228,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3226 | /// </returns> | 3228 | /// </returns> |
3227 | protected int HaveNeighbor(Cardinals car, ref int[] fix) | 3229 | protected int HaveNeighbor(Cardinals car, ref int[] fix) |
3228 | { | 3230 | { |
3229 | uint neighbourx = m_regionInfo.RegionLocX; | 3231 | uint neighbourx = m_scene.RegionInfo.RegionLocX; |
3230 | uint neighboury = m_regionInfo.RegionLocY; | 3232 | uint neighboury = m_scene.RegionInfo.RegionLocY; |
3231 | 3233 | ||
3232 | int dir = (int)car; | 3234 | int dir = (int)car; |
3233 | 3235 | ||
@@ -3247,8 +3249,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3247 | 3249 | ||
3248 | if (neighbourRegion == null) | 3250 | if (neighbourRegion == null) |
3249 | { | 3251 | { |
3250 | fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); | 3252 | fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx); |
3251 | fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); | 3253 | fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury); |
3252 | return dir * (-1); | 3254 | return dir * (-1); |
3253 | } | 3255 | } |
3254 | else | 3256 | else |
@@ -3494,26 +3496,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
3494 | catch { } | 3496 | catch { } |
3495 | 3497 | ||
3496 | // Attachment objects | 3498 | // Attachment objects |
3497 | if (m_attachments != null && m_attachments.Count > 0) | 3499 | lock (m_attachments) |
3498 | { | 3500 | { |
3499 | cAgent.AttachmentObjects = new List<ISceneObject>(); | 3501 | if (m_attachments.Count > 0) |
3500 | cAgent.AttachmentObjectStates = new List<string>(); | ||
3501 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
3502 | m_InTransitScriptStates.Clear(); | ||
3503 | foreach (SceneObjectGroup sog in m_attachments) | ||
3504 | { | 3502 | { |
3505 | // We need to make a copy and pass that copy | 3503 | cAgent.AttachmentObjects = new List<ISceneObject>(); |
3506 | // because of transfers withn the same sim | 3504 | cAgent.AttachmentObjectStates = new List<string>(); |
3507 | ISceneObject clone = sog.CloneForNewScene(); | 3505 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); |
3508 | // Attachment module assumes that GroupPosition holds the offsets...! | 3506 | m_InTransitScriptStates.Clear(); |
3509 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | 3507 | |
3510 | ((SceneObjectGroup)clone).IsAttachment = false; | 3508 | foreach (SceneObjectGroup sog in m_attachments) |
3511 | cAgent.AttachmentObjects.Add(clone); | 3509 | { |
3512 | string state = sog.GetStateSnapshot(); | 3510 | // We need to make a copy and pass that copy |
3513 | cAgent.AttachmentObjectStates.Add(state); | 3511 | // because of transfers withn the same sim |
3514 | m_InTransitScriptStates.Add(state); | 3512 | ISceneObject clone = sog.CloneForNewScene(); |
3515 | // Let's remove the scripts of the original object here | 3513 | // Attachment module assumes that GroupPosition holds the offsets...! |
3516 | sog.RemoveScriptInstances(true); | 3514 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; |
3515 | ((SceneObjectGroup)clone).IsAttachment = false; | ||
3516 | cAgent.AttachmentObjects.Add(clone); | ||
3517 | string state = sog.GetStateSnapshot(); | ||
3518 | cAgent.AttachmentObjectStates.Add(state); | ||
3519 | m_InTransitScriptStates.Add(state); | ||
3520 | // Let's remove the scripts of the original object here | ||
3521 | sog.RemoveScriptInstances(true); | ||
3522 | } | ||
3517 | } | 3523 | } |
3518 | } | 3524 | } |
3519 | } | 3525 | } |
@@ -3931,7 +3937,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
3931 | 3937 | ||
3932 | public void Close() | 3938 | public void Close() |
3933 | { | 3939 | { |
3934 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); | 3940 | if (!IsChildAgent) |
3941 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); | ||
3935 | 3942 | ||
3936 | lock (m_knownChildRegions) | 3943 | lock (m_knownChildRegions) |
3937 | { | 3944 | { |
@@ -4035,8 +4042,13 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
4035 | m_attachments.Clear(); | 4042 | m_attachments.Clear(); |
4036 | } | 4043 | } |
4037 | 4044 | ||
4045 | /// <summary> | ||
4046 | /// This is currently just being done for information. | ||
4047 | /// </summary> | ||
4038 | public bool ValidateAttachments() | 4048 | public bool ValidateAttachments() |
4039 | { | 4049 | { |
4050 | bool validated = true; | ||
4051 | |||
4040 | lock (m_attachments) | 4052 | lock (m_attachments) |
4041 | { | 4053 | { |
4042 | // Validate | 4054 | // Validate |
@@ -4045,21 +4057,22 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
4045 | if (gobj == null) | 4057 | if (gobj == null) |
4046 | { | 4058 | { |
4047 | m_log.WarnFormat( | 4059 | m_log.WarnFormat( |
4048 | "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null", Name); | 4060 | "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name); |
4049 | return false; | ||
4050 | } | ||
4051 | 4061 | ||
4052 | if (gobj.IsDeleted) | 4062 | validated = false; |
4063 | } | ||
4064 | else if (gobj.IsDeleted) | ||
4053 | { | 4065 | { |
4054 | m_log.WarnFormat( | 4066 | m_log.WarnFormat( |
4055 | "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted", | 4067 | "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing", |
4056 | gobj.Name, gobj.UUID, Name); | 4068 | gobj.Name, gobj.UUID, Name); |
4057 | return false; | 4069 | |
4070 | validated = false; | ||
4058 | } | 4071 | } |
4059 | } | 4072 | } |
4060 | } | 4073 | } |
4061 | 4074 | ||
4062 | return true; | 4075 | return validated; |
4063 | } | 4076 | } |
4064 | 4077 | ||
4065 | /// <summary> | 4078 | /// <summary> |
@@ -4091,29 +4104,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
4091 | } | 4104 | } |
4092 | } | 4105 | } |
4093 | 4106 | ||
4094 | |||
4095 | public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) | ||
4096 | { | ||
4097 | m_controllingClient = client; | ||
4098 | m_regionInfo = region; | ||
4099 | m_scene = scene; | ||
4100 | |||
4101 | RegisterToEvents(); | ||
4102 | |||
4103 | /* | ||
4104 | AbsolutePosition = client.StartPos; | ||
4105 | |||
4106 | Animations = new AvatarAnimations(); | ||
4107 | Animations.LoadAnims(); | ||
4108 | |||
4109 | m_animations = new List<UUID>(); | ||
4110 | m_animations.Add(Animations.AnimsUUID["STAND"]); | ||
4111 | m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); | ||
4112 | |||
4113 | SetDirectionVectors(); | ||
4114 | */ | ||
4115 | } | ||
4116 | |||
4117 | internal void PushForce(Vector3 impulse) | 4107 | internal void PushForce(Vector3 impulse) |
4118 | { | 4108 | { |
4119 | if (PhysicsActor != null) | 4109 | if (PhysicsActor != null) |
@@ -4141,6 +4131,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
4141 | obj.ignoreControls = (ScriptControlled)controls; | 4131 | obj.ignoreControls = (ScriptControlled)controls; |
4142 | obj.eventControls = (ScriptControlled)controls; | 4132 | obj.eventControls = (ScriptControlled)controls; |
4143 | } | 4133 | } |
4134 | |||
4144 | if (pass_on == 1 && accept == 1) | 4135 | if (pass_on == 1 && accept == 1) |
4145 | { | 4136 | { |
4146 | IgnoredControls = ScriptControlled.CONTROL_ZERO; | 4137 | IgnoredControls = ScriptControlled.CONTROL_ZERO; |
@@ -4161,6 +4152,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
4161 | scriptedcontrols[Script_item_UUID] = obj; | 4152 | scriptedcontrols[Script_item_UUID] = obj; |
4162 | } | 4153 | } |
4163 | } | 4154 | } |
4155 | |||
4164 | ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); | 4156 | ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); |
4165 | } | 4157 | } |
4166 | 4158 | ||
@@ -4351,29 +4343,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju | |||
4351 | return(new Vector3(x,y,z)); | 4343 | return(new Vector3(x,y,z)); |
4352 | } | 4344 | } |
4353 | 4345 | ||
4354 | public void SaveChangedAttachments() | ||
4355 | { | ||
4356 | // Need to copy this list because DetachToInventoryPrep mods it | ||
4357 | List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(GetAttachments().ToArray()); | ||
4358 | |||
4359 | IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule; | ||
4360 | if (attachmentsModule != null) | ||
4361 | { | ||
4362 | foreach (SceneObjectGroup grp in attachments) | ||
4363 | { | ||
4364 | if (grp.HasGroupChanged) // Resizer scripts? | ||
4365 | { | ||
4366 | grp.IsAttachment = false; | ||
4367 | grp.AbsolutePosition = grp.RootPart.AttachedPos; | ||
4368 | // grp.DetachToInventoryPrep(); | ||
4369 | attachmentsModule.UpdateKnownItem(ControllingClient, | ||
4370 | grp, grp.GetFromItemID(), grp.OwnerID); | ||
4371 | grp.IsAttachment = true; | ||
4372 | } | ||
4373 | } | ||
4374 | } | ||
4375 | } | ||
4376 | |||
4377 | private void CheckLandingPoint(ref Vector3 pos) | 4346 | private void CheckLandingPoint(ref Vector3 pos) |
4378 | { | 4347 | { |
4379 | // Never constrain lures | 4348 | // Never constrain lures |
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 501487a..8a0d288 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs | |||
@@ -38,27 +38,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
38 | { | 38 | { |
39 | public class SceneViewer : ISceneViewer | 39 | public class SceneViewer : ISceneViewer |
40 | { | 40 | { |
41 | /// <summary> | ||
42 | /// Is this scene viewer enabled? | ||
43 | /// </summary> | ||
44 | private bool IsEnabled { get; set; } | ||
45 | |||
46 | /// <summary> | ||
47 | /// The scene presence serviced by this viewer. | ||
48 | /// </summary> | ||
41 | protected ScenePresence m_presence; | 49 | protected ScenePresence m_presence; |
50 | |||
51 | /// <summary> | ||
52 | /// The queue of parts for which we need to send out updates. | ||
53 | /// </summary> | ||
42 | protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); | 54 | protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); |
55 | |||
56 | /// <summary> | ||
57 | /// The queue of objects for which we need to send out updates. | ||
58 | /// </summary> | ||
43 | protected Queue<SceneObjectGroup> m_pendingObjects; | 59 | protected Queue<SceneObjectGroup> m_pendingObjects; |
44 | 60 | ||
61 | /// <summary> | ||
62 | /// The last update assocated with a given part update. | ||
63 | /// </summary> | ||
45 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); | 64 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); |
46 | 65 | ||
47 | public SceneViewer() | ||
48 | { | ||
49 | } | ||
50 | |||
51 | public SceneViewer(ScenePresence presence) | 66 | public SceneViewer(ScenePresence presence) |
52 | { | 67 | { |
53 | m_presence = presence; | 68 | m_presence = presence; |
69 | IsEnabled = true; | ||
54 | } | 70 | } |
55 | 71 | ||
56 | /// <summary> | ||
57 | /// Add the part to the queue of parts for which we need to send an update to the client | ||
58 | /// </summary> | ||
59 | /// <param name="part"></param> | ||
60 | public void QueuePartForUpdate(SceneObjectPart part) | 72 | public void QueuePartForUpdate(SceneObjectPart part) |
61 | { | 73 | { |
74 | if (!IsEnabled) | ||
75 | return; | ||
76 | |||
62 | lock (m_partsUpdateQueue) | 77 | lock (m_partsUpdateQueue) |
63 | { | 78 | { |
64 | m_partsUpdateQueue.Enqueue(part); | 79 | m_partsUpdateQueue.Enqueue(part); |
@@ -87,6 +102,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
87 | 102 | ||
88 | lock (m_pendingObjects) | 103 | lock (m_pendingObjects) |
89 | { | 104 | { |
105 | // We must do this under lock so that we don't suffer a race condition if another thread closes the | ||
106 | // viewer | ||
107 | if (!IsEnabled) | ||
108 | return; | ||
109 | |||
90 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) | 110 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) |
91 | { | 111 | { |
92 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | 112 | SceneObjectGroup g = m_pendingObjects.Dequeue(); |
@@ -119,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
119 | 139 | ||
120 | // We deal with the possibility that two updates occur at | 140 | // We deal with the possibility that two updates occur at |
121 | // the same unix time at the update point itself. | 141 | // the same unix time at the update point itself. |
122 | |||
123 | if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) | 142 | if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) |
124 | { | 143 | { |
125 | // m_log.DebugFormat( | 144 | // m_log.DebugFormat( |
@@ -135,9 +154,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
135 | // this update. If this happened, then subsequent | 154 | // this update. If this happened, then subsequent |
136 | // updates which occurred on the same tick or the | 155 | // updates which occurred on the same tick or the |
137 | // next tick of the last update would be ignored. | 156 | // next tick of the last update would be ignored. |
138 | |||
139 | update.LastFullUpdateTime = part.TimeStampFull; | 157 | update.LastFullUpdateTime = part.TimeStampFull; |
140 | |||
141 | } | 158 | } |
142 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | 159 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) |
143 | { | 160 | { |
@@ -176,38 +193,46 @@ namespace OpenSim.Region.Framework.Scenes | |||
176 | } | 193 | } |
177 | } | 194 | } |
178 | 195 | ||
179 | public void Reset() | 196 | // public void Reset() |
180 | { | 197 | // { |
181 | if (m_pendingObjects == null) | 198 | // if (m_pendingObjects == null) |
182 | return; | 199 | // return; |
200 | // | ||
201 | // lock (m_pendingObjects) | ||
202 | // { | ||
203 | // if (m_pendingObjects != null) | ||
204 | // { | ||
205 | // m_pendingObjects.Clear(); | ||
206 | // m_pendingObjects = null; | ||
207 | // } | ||
208 | // } | ||
209 | // } | ||
183 | 210 | ||
211 | public void Close() | ||
212 | { | ||
184 | lock (m_pendingObjects) | 213 | lock (m_pendingObjects) |
185 | { | 214 | { |
186 | if (m_pendingObjects != null) | 215 | // We perform this under the m_pendingObjects lock in order to avoid a race condition with another |
216 | // thread on SendPrimUpdates() | ||
217 | IsEnabled = false; | ||
218 | |||
219 | lock (m_updateTimes) | ||
187 | { | 220 | { |
188 | m_pendingObjects.Clear(); | 221 | m_updateTimes.Clear(); |
189 | m_pendingObjects = null; | ||
190 | } | 222 | } |
191 | } | ||
192 | } | ||
193 | 223 | ||
194 | public void Close() | 224 | lock (m_partsUpdateQueue) |
195 | { | 225 | { |
196 | lock (m_updateTimes) | 226 | m_partsUpdateQueue.Clear(); |
197 | { | 227 | } |
198 | m_updateTimes.Clear(); | ||
199 | } | ||
200 | lock (m_partsUpdateQueue) | ||
201 | { | ||
202 | m_partsUpdateQueue.Clear(); | ||
203 | } | 228 | } |
204 | Reset(); | ||
205 | } | 229 | } |
206 | 230 | ||
207 | public int GetPendingObjectsCount() | 231 | public int GetPendingObjectsCount() |
208 | { | 232 | { |
209 | if (m_pendingObjects != null) | 233 | if (m_pendingObjects != null) |
210 | return m_pendingObjects.Count; | 234 | lock (m_pendingObjects) |
235 | return m_pendingObjects.Count; | ||
211 | 236 | ||
212 | return 0; | 237 | return 0; |
213 | } | 238 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 1ea2329..80f198d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs | |||
@@ -52,22 +52,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
52 | TestHelpers.InMethod(); | 52 | TestHelpers.InMethod(); |
53 | 53 | ||
54 | Scene scene = SceneHelpers.SetupScene(); | 54 | Scene scene = SceneHelpers.SetupScene(); |
55 | int partsToTestCount = 3; | ||
55 | 56 | ||
56 | string objName = "obj1"; | 57 | SceneObjectGroup so |
57 | UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); | 58 | = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10); |
58 | 59 | SceneObjectPart[] parts = so.Parts; | |
59 | SceneObjectPart part | ||
60 | = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) | ||
61 | { Name = objName, UUID = objUuid }; | ||
62 | 60 | ||
63 | Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True); | 61 | Assert.That(scene.AddNewSceneObject(so, false), Is.True); |
64 | 62 | SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID); | |
65 | SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid); | 63 | SceneObjectPart[] retrievedParts = retrievedSo.Parts; |
66 | 64 | ||
67 | //m_log.Debug("retrievedPart : {0}", retrievedPart); | 65 | //m_log.Debug("retrievedPart : {0}", retrievedPart); |
68 | // If the parts have the same UUID then we will consider them as one and the same | 66 | // If the parts have the same UUID then we will consider them as one and the same |
69 | Assert.That(retrievedPart.Name, Is.EqualTo(objName)); | 67 | Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount)); |
70 | Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); | 68 | |
69 | for (int i = 0; i < partsToTestCount; i++) | ||
70 | { | ||
71 | Assert.That(retrievedParts[i].Name, Is.EqualTo(parts[i].Name)); | ||
72 | Assert.That(retrievedParts[i].UUID, Is.EqualTo(parts[i].UUID)); | ||
73 | } | ||
71 | } | 74 | } |
72 | 75 | ||
73 | [Test] | 76 | [Test] |
@@ -103,6 +106,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
103 | Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); | 106 | Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); |
104 | Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); | 107 | Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); |
105 | } | 108 | } |
109 | |||
110 | /// <summary> | ||
111 | /// Test retrieving a scene object via the local id of one of its parts. | ||
112 | /// </summary> | ||
113 | [Test] | ||
114 | public void TestGetSceneObjectByPartLocalId() | ||
115 | { | ||
116 | TestHelpers.InMethod(); | ||
117 | |||
118 | Scene scene = SceneHelpers.SetupScene(); | ||
119 | int partsToTestCount = 3; | ||
120 | |||
121 | SceneObjectGroup so | ||
122 | = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10); | ||
123 | SceneObjectPart[] parts = so.Parts; | ||
124 | |||
125 | scene.AddNewSceneObject(so, false); | ||
126 | |||
127 | // Test getting via the root part's local id | ||
128 | Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Not.Null); | ||
129 | |||
130 | // Test getting via a non root part's local id | ||
131 | Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Not.Null); | ||
132 | |||
133 | // Test that we don't get back an object for a local id that doesn't exist | ||
134 | Assert.That(scene.GetGroupByPrim(999), Is.Null); | ||
135 | |||
136 | // Now delete the scene object and check again | ||
137 | scene.DeleteSceneObject(so, false); | ||
138 | |||
139 | Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Null); | ||
140 | Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Null); | ||
141 | } | ||
106 | 142 | ||
107 | /// <summary> | 143 | /// <summary> |
108 | /// Test deleting an object from a scene. | 144 | /// Test deleting an object from a scene. |
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index fdfbc78..8d41f00 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
43 | /// <summary> | 43 | /// <summary> |
44 | /// Gather uuids for a given entity. | 44 | /// Gather uuids for a given entity. |
45 | /// </summary> | 45 | /// </summary> |
46 | /// | 46 | /// <remarks> |
47 | /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts | 47 | /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts |
48 | /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets | 48 | /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets |
49 | /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be | 49 | /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be |
50 | /// retrieved to work out which assets it references). | 50 | /// retrieved to work out which assets it references). |
51 | /// </remarks> | ||
51 | public class UuidGatherer | 52 | public class UuidGatherer |
52 | { | 53 | { |
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
76 | /// <summary> | 77 | /// <summary> |
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | 78 | /// Gather all the asset uuids associated with the asset referenced by a given uuid |
78 | /// </summary> | 79 | /// </summary> |
79 | /// | 80 | /// <remarks> |
80 | /// This includes both those directly associated with | 81 | /// This includes both those directly associated with |
81 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | 82 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained |
82 | /// within this object). | 83 | /// within this object). |
83 | /// | 84 | /// </remarks> |
84 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> | 85 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> |
85 | /// <param name="assetType">The type of the asset for the uuid given</param> | 86 | /// <param name="assetType">The type of the asset for the uuid given</param> |
86 | /// <param name="assetUuids">The assets gathered</param> | 87 | /// <param name="assetUuids">The assets gathered</param> |
@@ -119,11 +120,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
119 | /// <summary> | 120 | /// <summary> |
120 | /// Gather all the asset uuids associated with a given object. | 121 | /// Gather all the asset uuids associated with a given object. |
121 | /// </summary> | 122 | /// </summary> |
122 | /// | 123 | /// <remarks> |
123 | /// This includes both those directly associated with | 124 | /// This includes both those directly associated with |
124 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | 125 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained |
125 | /// within this object). | 126 | /// within this object). |
126 | /// | 127 | /// </remarks> |
127 | /// <param name="sceneObject">The scene object for which to gather assets</param> | 128 | /// <param name="sceneObject">The scene object for which to gather assets</param> |
128 | /// <param name="assetUuids">The assets gathered</param> | 129 | /// <param name="assetUuids">The assets gathered</param> |
129 | public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) | 130 | public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 78296a4..246bc34 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using log4net; | 31 | using log4net; |
31 | using Nini.Config; | 32 | using Nini.Config; |
@@ -33,7 +34,9 @@ using NUnit.Framework; | |||
33 | using OpenMetaverse; | 34 | using OpenMetaverse; |
34 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 36 | using OpenSim.Framework.Communications; |
37 | using OpenSim.Region.CoreModules.Avatar.Attachments; | ||
36 | using OpenSim.Region.CoreModules.Avatar.AvatarFactory; | 38 | using OpenSim.Region.CoreModules.Avatar.AvatarFactory; |
39 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | ||
37 | using OpenSim.Region.CoreModules.Framework.UserManagement; | 40 | using OpenSim.Region.CoreModules.Framework.UserManagement; |
38 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; | 41 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; |
39 | using OpenSim.Region.Framework.Interfaces; | 42 | using OpenSim.Region.Framework.Interfaces; |
@@ -47,21 +50,49 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
47 | [TestFixture] | 50 | [TestFixture] |
48 | public class NPCModuleTests | 51 | public class NPCModuleTests |
49 | { | 52 | { |
50 | [Test] | 53 | private TestScene scene; |
51 | public void TestCreate() | 54 | private AvatarFactoryModule afm; |
55 | private UserManagementModule umm; | ||
56 | private AttachmentsModule am; | ||
57 | |||
58 | [TestFixtureSetUp] | ||
59 | public void FixtureInit() | ||
52 | { | 60 | { |
53 | TestHelpers.InMethod(); | 61 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. |
54 | // log4net.Config.XmlConfigurator.Configure(); | 62 | Util.FireAndForgetMethod = FireAndForgetMethod.None; |
63 | } | ||
55 | 64 | ||
65 | [TestFixtureTearDown] | ||
66 | public void TearDown() | ||
67 | { | ||
68 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
69 | // threads. Possibly, later tests should be rewritten not to worry about such things. | ||
70 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
71 | } | ||
72 | |||
73 | [SetUp] | ||
74 | public void Init() | ||
75 | { | ||
56 | IConfigSource config = new IniConfigSource(); | 76 | IConfigSource config = new IniConfigSource(); |
57 | config.AddConfig("NPC"); | 77 | config.AddConfig("NPC"); |
58 | config.Configs["NPC"].Set("Enabled", "true"); | 78 | config.Configs["NPC"].Set("Enabled", "true"); |
79 | config.AddConfig("Modules"); | ||
80 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | ||
59 | 81 | ||
60 | AvatarFactoryModule afm = new AvatarFactoryModule(); | 82 | afm = new AvatarFactoryModule(); |
61 | UserManagementModule umm = new UserManagementModule(); | 83 | umm = new UserManagementModule(); |
84 | am = new AttachmentsModule(); | ||
85 | |||
86 | scene = SceneHelpers.SetupScene(); | ||
87 | SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule()); | ||
88 | } | ||
89 | |||
90 | [Test] | ||
91 | public void TestCreate() | ||
92 | { | ||
93 | TestHelpers.InMethod(); | ||
94 | // log4net.Config.XmlConfigurator.Configure(); | ||
62 | 95 | ||
63 | TestScene scene = SceneHelpers.SetupScene(); | ||
64 | SceneHelpers.SetupSceneModules(scene, config, afm, umm, new NPCModule()); | ||
65 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); | 96 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); |
66 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); | 97 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); |
67 | 98 | ||
@@ -88,18 +119,53 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
88 | } | 119 | } |
89 | 120 | ||
90 | [Test] | 121 | [Test] |
91 | public void TestMove() | 122 | public void TestAttachments() |
92 | { | 123 | { |
93 | TestHelpers.InMethod(); | 124 | TestHelpers.InMethod(); |
94 | // log4net.Config.XmlConfigurator.Configure(); | 125 | // log4net.Config.XmlConfigurator.Configure(); |
95 | 126 | ||
96 | IConfigSource config = new IniConfigSource(); | 127 | UUID userId = TestHelpers.ParseTail(0x1); |
128 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | ||
129 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); | ||
97 | 130 | ||
98 | config.AddConfig("NPC"); | 131 | UUID attItemId = TestHelpers.ParseTail(0x2); |
99 | config.Configs["NPC"].Set("Enabled", "true"); | 132 | UUID attAssetId = TestHelpers.ParseTail(0x3); |
133 | string attName = "att"; | ||
134 | |||
135 | UserInventoryHelpers.CreateInventoryItem( | ||
136 | scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object); | ||
137 | |||
138 | am.RezSingleAttachmentFromInventory( | ||
139 | sp.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); | ||
140 | |||
141 | INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); | ||
142 | UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); | ||
143 | |||
144 | ScenePresence npc = scene.GetScenePresence(npcId); | ||
145 | |||
146 | // Check scene presence status | ||
147 | Assert.That(npc.HasAttachments(), Is.True); | ||
148 | List<SceneObjectGroup> attachments = npc.GetAttachments(); | ||
149 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
150 | SceneObjectGroup attSo = attachments[0]; | ||
151 | |||
152 | // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item | ||
153 | // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC. | ||
154 | // Assert.That(attSo.Name, Is.EqualTo(attName)); | ||
155 | |||
156 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | ||
157 | Assert.That(attSo.IsAttachment); | ||
158 | Assert.That(attSo.UsesPhysics, Is.False); | ||
159 | Assert.That(attSo.IsTemporary, Is.False); | ||
160 | Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID)); | ||
161 | } | ||
162 | |||
163 | [Test] | ||
164 | public void TestMove() | ||
165 | { | ||
166 | TestHelpers.InMethod(); | ||
167 | // log4net.Config.XmlConfigurator.Configure(); | ||
100 | 168 | ||
101 | TestScene scene = SceneHelpers.SetupScene(); | ||
102 | SceneHelpers.SetupSceneModules(scene, config, new NPCModule()); | ||
103 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); | 169 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); |
104 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); | 170 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); |
105 | 171 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6f34168..18c0dd2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -7040,6 +7040,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7040 | 7040 | ||
7041 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) | 7041 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) |
7042 | { | 7042 | { |
7043 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
7043 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | 7044 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); |
7044 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 7045 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
7045 | return shapeBlock; | 7046 | return shapeBlock; |
@@ -7123,8 +7124,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7123 | { | 7124 | { |
7124 | twist.y = 1.0f; | 7125 | twist.y = 1.0f; |
7125 | } | 7126 | } |
7126 | shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x); | 7127 | // A fairly large precision error occurs for some calculations, |
7127 | shapeBlock.PathTwist = (sbyte)(100 * twist.y); | 7128 | // if a float or double is directly cast to a byte or sbyte |
7129 | // variable, in both .Net and Mono. In .Net, coding | ||
7130 | // "(sbyte)(float)(some expression)" corrects the precision | ||
7131 | // errors. But this does not work for Mono. This longer coding | ||
7132 | // form of creating a tempoary float variable from the | ||
7133 | // expression first, then casting that variable to a byte or | ||
7134 | // sbyte, works for both .Net and Mono. These types of | ||
7135 | // assignments occur in SetPrimtiveBlockShapeParams and | ||
7136 | // SetPrimitiveShapeParams in support of llSetPrimitiveParams. | ||
7137 | tempFloat = (float)(100.0d * twist.x); | ||
7138 | shapeBlock.PathTwistBegin = (sbyte)tempFloat; | ||
7139 | tempFloat = (float)(100.0d * twist.y); | ||
7140 | shapeBlock.PathTwist = (sbyte)tempFloat; | ||
7128 | 7141 | ||
7129 | shapeBlock.ObjectLocalID = part.LocalId; | 7142 | shapeBlock.ObjectLocalID = part.LocalId; |
7130 | 7143 | ||
@@ -7138,6 +7151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7138 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 7151 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
7139 | return; | 7152 | return; |
7140 | 7153 | ||
7154 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
7141 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7155 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7142 | 7156 | ||
7143 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 7157 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -7158,8 +7172,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7158 | { | 7172 | { |
7159 | taper_b.y = 2f; | 7173 | taper_b.y = 2f; |
7160 | } | 7174 | } |
7161 | shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x)); | 7175 | tempFloat = (float)(100.0d * (2.0d - taper_b.x)); |
7162 | shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y)); | 7176 | shapeBlock.PathScaleX = (byte)tempFloat; |
7177 | tempFloat = (float)(100.0d * (2.0d - taper_b.y)); | ||
7178 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
7163 | if (topshear.x < -0.5f) | 7179 | if (topshear.x < -0.5f) |
7164 | { | 7180 | { |
7165 | topshear.x = -0.5f; | 7181 | topshear.x = -0.5f; |
@@ -7176,8 +7192,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7176 | { | 7192 | { |
7177 | topshear.y = 0.5f; | 7193 | topshear.y = 0.5f; |
7178 | } | 7194 | } |
7179 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 7195 | tempFloat = (float)(100.0d * topshear.x); |
7180 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 7196 | shapeBlock.PathShearX = (byte)tempFloat; |
7197 | tempFloat = (float)(100.0d * topshear.y); | ||
7198 | shapeBlock.PathShearY = (byte)tempFloat; | ||
7181 | 7199 | ||
7182 | part.Shape.SculptEntry = false; | 7200 | part.Shape.SculptEntry = false; |
7183 | part.UpdateShape(shapeBlock); | 7201 | part.UpdateShape(shapeBlock); |
@@ -7233,6 +7251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7233 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 7251 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
7234 | return; | 7252 | return; |
7235 | 7253 | ||
7254 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
7236 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7255 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7237 | 7256 | ||
7238 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 7257 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -7257,8 +7276,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7257 | { | 7276 | { |
7258 | holesize.y = 0.5f; | 7277 | holesize.y = 0.5f; |
7259 | } | 7278 | } |
7260 | shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x)); | 7279 | tempFloat = (float)(100.0d * (2.0d - holesize.x)); |
7261 | shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y)); | 7280 | shapeBlock.PathScaleX = (byte)tempFloat; |
7281 | tempFloat = (float)(100.0d * (2.0d - holesize.y)); | ||
7282 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
7262 | if (topshear.x < -0.5f) | 7283 | if (topshear.x < -0.5f) |
7263 | { | 7284 | { |
7264 | topshear.x = -0.5f; | 7285 | topshear.x = -0.5f; |
@@ -7275,8 +7296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7275 | { | 7296 | { |
7276 | topshear.y = 0.5f; | 7297 | topshear.y = 0.5f; |
7277 | } | 7298 | } |
7278 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 7299 | tempFloat = (float)(100.0d * topshear.x); |
7279 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 7300 | shapeBlock.PathShearX = (byte)tempFloat; |
7301 | tempFloat = (float)(100.0d * topshear.y); | ||
7302 | shapeBlock.PathShearY = (byte)tempFloat; | ||
7280 | if (profilecut.x < 0f) | 7303 | if (profilecut.x < 0f) |
7281 | { | 7304 | { |
7282 | profilecut.x = 0f; | 7305 | profilecut.x = 0f; |
@@ -7320,8 +7343,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7320 | { | 7343 | { |
7321 | taper_a.y = 1f; | 7344 | taper_a.y = 1f; |
7322 | } | 7345 | } |
7323 | shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x); | 7346 | tempFloat = (float)(100.0d * taper_a.x); |
7324 | shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y); | 7347 | shapeBlock.PathTaperX = (sbyte)tempFloat; |
7348 | tempFloat = (float)(100.0d * taper_a.y); | ||
7349 | shapeBlock.PathTaperY = (sbyte)tempFloat; | ||
7325 | if (revolutions < 1f) | 7350 | if (revolutions < 1f) |
7326 | { | 7351 | { |
7327 | revolutions = 1f; | 7352 | revolutions = 1f; |
@@ -7330,7 +7355,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7330 | { | 7355 | { |
7331 | revolutions = 4f; | 7356 | revolutions = 4f; |
7332 | } | 7357 | } |
7333 | shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0)); | 7358 | tempFloat = 66.66667f * (revolutions - 1.0f); |
7359 | shapeBlock.PathRevolutions = (byte)tempFloat; | ||
7334 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 | 7360 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 |
7335 | if (radiusoffset < 0f) | 7361 | if (radiusoffset < 0f) |
7336 | { | 7362 | { |
@@ -7340,7 +7366,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7340 | { | 7366 | { |
7341 | radiusoffset = 1f; | 7367 | radiusoffset = 1f; |
7342 | } | 7368 | } |
7343 | shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset); | 7369 | tempFloat = 100.0f * radiusoffset; |
7370 | shapeBlock.PathRadiusOffset = (sbyte)tempFloat; | ||
7344 | if (skew < -0.95f) | 7371 | if (skew < -0.95f) |
7345 | { | 7372 | { |
7346 | skew = -0.95f; | 7373 | skew = -0.95f; |
@@ -7349,7 +7376,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7349 | { | 7376 | { |
7350 | skew = 0.95f; | 7377 | skew = 0.95f; |
7351 | } | 7378 | } |
7352 | shapeBlock.PathSkew = (sbyte)(100 * skew); | 7379 | tempFloat = 100.0f * skew; |
7380 | shapeBlock.PathSkew = (sbyte)tempFloat; | ||
7353 | 7381 | ||
7354 | part.Shape.SculptEntry = false; | 7382 | part.Shape.SculptEntry = false; |
7355 | part.UpdateShape(shapeBlock); | 7383 | part.UpdateShape(shapeBlock); |
@@ -8268,10 +8296,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8268 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); | 8296 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); |
8269 | 8297 | ||
8270 | // float revolutions | 8298 | // float revolutions |
8271 | res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned | 8299 | res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); |
8272 | // byte is being used to represent the entire | 8300 | // Slightly inaccurate, because an unsigned byte is being used to represent |
8273 | // range of floating-point values from 1.0 | 8301 | // the entire range of floating-point values from 1.0 through 4.0 (which is how |
8274 | // through 4.0 (which is how SL does it). | 8302 | // SL does it). |
8303 | // | ||
8304 | // Using these formulas to store and retrieve PathRevolutions, it is not | ||
8305 | // possible to use all values between 1.00 and 4.00. For instance, you can't | ||
8306 | // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you | ||
8307 | // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them | ||
8308 | // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar | ||
8309 | // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. | ||
8310 | // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value | ||
8311 | // such as 1.10. So, SL must store and retreive the actual user input rather | ||
8312 | // than only storing the encoded value. | ||
8275 | 8313 | ||
8276 | // float radiusoffset | 8314 | // float radiusoffset |
8277 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); | 8315 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 0c1da47..8f450f8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -712,9 +712,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
712 | == World.LandChannel.GetLandObject( | 712 | == World.LandChannel.GetLandObject( |
713 | presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) | 713 | presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) |
714 | { | 714 | { |
715 | World.RequestTeleportLocation(presence.ControllingClient, regionName, | 715 | // We will launch the teleport on a new thread so that when the script threads are terminated |
716 | new Vector3((float)position.x, (float)position.y, (float)position.z), | 716 | // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. |
717 | new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation); | 717 | Util.FireAndForget( |
718 | o => World.RequestTeleportLocation(presence.ControllingClient, regionName, | ||
719 | new Vector3((float)position.x, (float)position.y, (float)position.z), | ||
720 | new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); | ||
718 | 721 | ||
719 | ScriptSleep(5000); | 722 | ScriptSleep(5000); |
720 | } | 723 | } |
@@ -750,9 +753,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
750 | == World.LandChannel.GetLandObject( | 753 | == World.LandChannel.GetLandObject( |
751 | presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) | 754 | presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) |
752 | { | 755 | { |
753 | World.RequestTeleportLocation(presence.ControllingClient, regionHandle, | 756 | // We will launch the teleport on a new thread so that when the script threads are terminated |
754 | new Vector3((float)position.x, (float)position.y, (float)position.z), | 757 | // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. |
755 | new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation); | 758 | Util.FireAndForget( |
759 | o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle, | ||
760 | new Vector3((float)position.x, (float)position.y, (float)position.z), | ||
761 | new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); | ||
762 | |||
756 | ScriptSleep(5000); | 763 | ScriptSleep(5000); |
757 | } | 764 | } |
758 | } | 765 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 8cd1e84..0cbad41 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs | |||
@@ -49,7 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
49 | 49 | ||
50 | private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; | 50 | private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; |
51 | private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; | 51 | private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; |
52 | private const double FLOAT_ACCURACY = 0.00005d; | 52 | private const float FLOAT_ACCURACY = 0.00005f; |
53 | private LSL_Api m_lslApi; | 53 | private LSL_Api m_lslApi; |
54 | 54 | ||
55 | [SetUp] | 55 | [SetUp] |
@@ -194,10 +194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
194 | ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type | 194 | ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type |
195 | ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type | 195 | ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type |
196 | new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut | 196 | new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut |
197 | 0.80d, // Prim hollow | 197 | 0.80f, // Prim hollow |
198 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist | 198 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist |
199 | new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple | 199 | new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple |
200 | 0.80d); // Prim hollow check | 200 | 0.80f); // Prim hollow check |
201 | 201 | ||
202 | // Test a prism. | 202 | // Test a prism. |
203 | CheckllSetPrimitiveParams( | 203 | CheckllSetPrimitiveParams( |
@@ -206,11 +206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
206 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type | 206 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type |
207 | ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type | 207 | ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type |
208 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 208 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
209 | 0.90d, // Prim hollow | 209 | 0.90f, // Prim hollow |
210 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist | 210 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist |
211 | new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper | 211 | new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper |
212 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 212 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear |
213 | 0.90d); // Prim hollow check | 213 | 0.90f); // Prim hollow check |
214 | 214 | ||
215 | // Test a box. | 215 | // Test a box. |
216 | CheckllSetPrimitiveParams( | 216 | CheckllSetPrimitiveParams( |
@@ -219,11 +219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
219 | ScriptBaseClass.PRIM_TYPE_BOX, // Prim type | 219 | ScriptBaseClass.PRIM_TYPE_BOX, // Prim type |
220 | ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type | 220 | ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type |
221 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 221 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
222 | 0.95d, // Prim hollow | 222 | 0.95f, // Prim hollow |
223 | new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist | 223 | new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist |
224 | new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper | 224 | new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper |
225 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 225 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear |
226 | 0.95d); // Prim hollow check | 226 | 0.95f); // Prim hollow check |
227 | 227 | ||
228 | // Test a tube. | 228 | // Test a tube. |
229 | CheckllSetPrimitiveParams( | 229 | CheckllSetPrimitiveParams( |
@@ -232,16 +232,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
232 | ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type | 232 | ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type |
233 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type | 233 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type |
234 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 234 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
235 | 0.00d, // Prim hollow | 235 | 0.00f, // Prim hollow |
236 | new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist | 236 | new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist |
237 | new LSL_Types.Vector3(1.0d, 0.5d, 0.0d), // Prim hole size | 237 | new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size |
238 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 238 | // Expression for y selected to test precision problems during byte |
239 | // cast in SetPrimitiveShapeParams. | ||
240 | new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear | ||
239 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut | 241 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut |
240 | new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper | 242 | // Expression for y selected to test precision problems during sbyte |
241 | 1.0d, // Prim revolutions | 243 | // cast in SetPrimitiveShapeParams. |
242 | 1.0d, // Prim radius | 244 | new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper |
243 | 0.0d, // Prim skew | 245 | 1.11f, // Prim revolutions |
244 | 0.00d); // Prim hollow check | 246 | 0.88f, // Prim radius |
247 | 0.95f, // Prim skew | ||
248 | 0.00f); // Prim hollow check | ||
245 | 249 | ||
246 | // Test a prism. | 250 | // Test a prism. |
247 | CheckllSetPrimitiveParams( | 251 | CheckllSetPrimitiveParams( |
@@ -250,11 +254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
250 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type | 254 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type |
251 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type | 255 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type |
252 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 256 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
253 | 0.95d, // Prim hollow | 257 | 0.95f, // Prim hollow |
254 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist | 258 | // Expression for x selected to test precision problems during sbyte |
255 | new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper | 259 | // cast in SetPrimitiveShapeBlockParams. |
260 | new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist | ||
261 | // Expression for y selected to test precision problems during sbyte | ||
262 | // cast in SetPrimitiveShapeParams. | ||
263 | new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper | ||
256 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 264 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear |
257 | 0.70d); // Prim hollow check | 265 | 0.70f); // Prim hollow check |
258 | 266 | ||
259 | // Test a sculpted prim. | 267 | // Test a sculpted prim. |
260 | CheckllSetPrimitiveParams( | 268 | CheckllSetPrimitiveParams( |
@@ -268,8 +276,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
268 | // Set prim params for a box, cylinder or prism and check results. | 276 | // Set prim params for a box, cylinder or prism and check results. |
269 | public void CheckllSetPrimitiveParams(string primTest, | 277 | public void CheckllSetPrimitiveParams(string primTest, |
270 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, | 278 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, |
271 | double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear, | 279 | float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear, |
272 | double primHollowCheck) | 280 | float primHollowCheck) |
273 | { | 281 | { |
274 | // Set the prim params. | 282 | // Set the prim params. |
275 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, | 283 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, |
@@ -297,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
297 | // Set prim params for a sphere and check results. | 305 | // Set prim params for a sphere and check results. |
298 | public void CheckllSetPrimitiveParams(string primTest, | 306 | public void CheckllSetPrimitiveParams(string primTest, |
299 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, | 307 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, |
300 | double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, double primHollowCheck) | 308 | float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck) |
301 | { | 309 | { |
302 | // Set the prim params. | 310 | // Set the prim params. |
303 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, | 311 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, |
@@ -324,9 +332,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
324 | // Set prim params for a torus, tube or ring and check results. | 332 | // Set prim params for a torus, tube or ring and check results. |
325 | public void CheckllSetPrimitiveParams(string primTest, | 333 | public void CheckllSetPrimitiveParams(string primTest, |
326 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, | 334 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, |
327 | double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize, | 335 | float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize, |
328 | LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper, | 336 | LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper, |
329 | double primRev, double primRadius, double primSkew, double primHollowCheck) | 337 | float primRev, float primRadius, float primSkew, float primHollowCheck) |
330 | { | 338 | { |
331 | // Set the prim params. | 339 | // Set the prim params. |
332 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, | 340 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, |
@@ -353,7 +361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
353 | CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut"); | 361 | CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut"); |
354 | CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper"); | 362 | CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper"); |
355 | Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY, | 363 | Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY, |
356 | "TestllSetPrimitiveParams " + primTest + " prim revolution fail"); | 364 | "TestllSetPrimitiveParams " + primTest + " prim revolutions fail"); |
357 | Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY, | 365 | Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY, |
358 | "TestllSetPrimitiveParams " + primTest + " prim radius fail"); | 366 | "TestllSetPrimitiveParams " + primTest + " prim radius fail"); |
359 | Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY, | 367 | Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY, |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 9cb074a..975e9cc 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -409,7 +409,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
409 | m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup), | 409 | m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup), |
410 | new Object[] { m_SaveTime }); | 410 | new Object[] { m_SaveTime }); |
411 | } | 411 | } |
412 | } | ||
412 | 413 | ||
414 | public void StartProcessing() | ||
415 | { | ||
413 | m_ThreadPool.Start(); | 416 | m_ThreadPool.Start(); |
414 | } | 417 | } |
415 | 418 | ||
@@ -659,7 +662,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
659 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 662 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
660 | if (part == null) | 663 | if (part == null) |
661 | { | 664 | { |
662 | m_log.Error("[Script] SceneObjectPart unavailable. Script NOT started."); | 665 | m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID); |
663 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; | 666 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; |
664 | m_ScriptFailCount++; | 667 | m_ScriptFailCount++; |
665 | return false; | 668 | return false; |