aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
diff options
context:
space:
mode:
authorUbitUmarov2019-11-13 18:44:58 +0000
committerUbitUmarov2019-11-13 18:44:58 +0000
commit5d2ffdc35bf17188443e930f4dec8222e6b1430c (patch)
tree8c5e51907ce52c61cb218895c4dc8a4a524cc8e6 /OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
parentReduce Max region size to 4096m (diff)
downloadopensim-SC-5d2ffdc35bf17188443e930f4dec8222e6b1430c.zip
opensim-SC-5d2ffdc35bf17188443e930f4dec8222e6b1430c.tar.gz
opensim-SC-5d2ffdc35bf17188443e930f4dec8222e6b1430c.tar.bz2
opensim-SC-5d2ffdc35bf17188443e930f4dec8222e6b1430c.tar.xz
limit max number of attachments to 38. All can be on same point
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rwxr-xr-xOpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs168
1 files changed, 92 insertions, 76 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index e342897..e82dc7f 100755
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -59,6 +59,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
59 private Scene m_scene; 59 private Scene m_scene;
60 private IRegionConsole m_regionConsole; 60 private IRegionConsole m_regionConsole;
61 private IInventoryAccessModule m_invAccessModule; 61 private IInventoryAccessModule m_invAccessModule;
62 private bool m_wearReplacesAllOption = true;
62 63
63 /// <summary> 64 /// <summary>
64 /// Are attachments enabled? 65 /// Are attachments enabled?
@@ -74,6 +75,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
74 if (config != null) 75 if (config != null)
75 { 76 {
76 Enabled = config.GetBoolean("Enabled", true); 77 Enabled = config.GetBoolean("Enabled", true);
78 m_wearReplacesAllOption = config.GetBoolean("WearReplacesAll", true);
77 } 79 }
78 else 80 else
79 { 81 {
@@ -101,10 +103,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
101 103
102 public void RemoveRegion(Scene scene) 104 public void RemoveRegion(Scene scene)
103 { 105 {
104 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this); 106 if (!Enabled)
107 return;
105 108
106 if (Enabled) 109 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
107 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; 110 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
108 } 111 }
109 112
110 public void RegionLoaded(Scene scene) 113 public void RegionLoaded(Scene scene)
@@ -225,8 +228,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
225 ConsoleDisplayList ct = new ConsoleDisplayList(); 228 ConsoleDisplayList ct = new ConsoleDisplayList();
226 229
227 List<SceneObjectGroup> attachmentObjects = sp.GetAttachments(); 230 List<SceneObjectGroup> attachmentObjects = sp.GetAttachments();
228 foreach (SceneObjectGroup attachmentObject in attachmentObjects) 231 for (int i = 0; i < attachmentObjects.Count; ++i)
229 { 232 {
233 SceneObjectGroup attachmentObject = attachmentObjects[i];
230 ct.Indent = 2; 234 ct.Indent = 2;
231 ct.AddRow("Attachment Name", attachmentObject.Name); 235 ct.AddRow("Attachment Name", attachmentObject.Name);
232 ct.AddRow("Local ID", attachmentObject.LocalId); 236 ct.AddRow("Local ID", attachmentObject.LocalId);
@@ -308,13 +312,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
308 List<SceneObjectGroup> attachments = sp.GetAttachments(); 312 List<SceneObjectGroup> attachments = sp.GetAttachments();
309 if (attachments.Count > 0) 313 if (attachments.Count > 0)
310 { 314 {
311 ad.AttachmentObjects = new List<ISceneObject>(); 315 ad.AttachmentObjects = new List<ISceneObject>(attachments.Count);
312 ad.AttachmentObjectStates = new List<string>(); 316 ad.AttachmentObjectStates = new List<string>(attachments.Count);
313 // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
314 sp.InTransitScriptStates.Clear(); 317 sp.InTransitScriptStates.Clear();
315 318
316 foreach (SceneObjectGroup sog in attachments) 319 for (int indx = 0; indx < attachments.Count; ++indx)
317 { 320 {
321 SceneObjectGroup sog = attachments[indx];
318 // We need to make a copy and pass that copy 322 // We need to make a copy and pass that copy
319 // because of transfers withn the same sim 323 // because of transfers withn the same sim
320 ISceneObject clone = sog.CloneForNewScene(); 324 ISceneObject clone = sog.CloneForNewScene();
@@ -343,17 +347,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
343 sp.ClearAttachments(); 347 sp.ClearAttachments();
344 348
345 int i = 0; 349 int i = 0;
346 foreach (ISceneObject so in ad.AttachmentObjects) 350 for (int indx = 0; indx < ad.AttachmentObjects.Count; ++indx)
347 { 351 {
348 ((SceneObjectGroup)so).LocalId = 0; 352 SceneObjectGroup sog = (SceneObjectGroup)ad.AttachmentObjects[indx];
349 ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); 353 sog.LocalId = 0;
354 sog.RootPart.ClearUpdateSchedule();
350 355
351// m_log.DebugFormat( 356// m_log.DebugFormat(
352// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}", 357// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}",
353// ad.AttachmentObjectStates[i].Length, so.Name, sp.Name, m_scene.Name); 358// ad.AttachmentObjectStates[i].Length, sog.Name, sp.Name, m_scene.Name);
354 359
355 so.SetState(ad.AttachmentObjectStates[i++], m_scene); 360 sog.SetState(ad.AttachmentObjectStates[i++], m_scene);
356 m_scene.IncomingCreateObject(Vector3.Zero, so); 361 m_scene.IncomingCreateObject(Vector3.Zero, sog);
357 } 362 }
358 } 363 }
359 } 364 }
@@ -363,14 +368,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
363 if (!Enabled) 368 if (!Enabled)
364 return; 369 return;
365 370
366 if (null == sp.Appearance) 371 if (sp.Appearance == null)
367 { 372 {
368 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); 373 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
369
370 return; 374 return;
371 } 375 }
372 376
373 if (sp.GetAttachments().Count > 0) 377 if (sp.GetAttachmentsCount() > 0)
374 { 378 {
375 if (DebugLevel > 0) 379 if (DebugLevel > 0)
376 m_log.DebugFormat( 380 m_log.DebugFormat(
@@ -420,27 +424,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
420 424
421 // Let's get all items at once, so they get cached 425 // Let's get all items at once, so they get cached
422 UUID[] items = new UUID[attachments.Count]; 426 UUID[] items = new UUID[attachments.Count];
423 int i = 0; 427 for (int i = 0; i < attachments.Count; ++i)
424 foreach (AvatarAttachment attach in attachments) 428 items[i] = attachments[i].ItemID;
425 items[i++] = attach.ItemID; 429
426 m_scene.InventoryService.GetMultipleItems(sp.UUID, items); 430 m_scene.InventoryService.GetMultipleItems(sp.UUID, items);
427 431
428 foreach (AvatarAttachment attach in attachments) 432 for (int indx = 0; indx < attachments.Count; ++indx)
429 { 433 {
434 AvatarAttachment attach = attachments[indx];
430 uint attachmentPt = (uint)attach.AttachPoint; 435 uint attachmentPt = (uint)attach.AttachPoint;
431 436
432// m_log.DebugFormat( 437// m_log.DebugFormat(
433// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}", 438// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
434// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName); 439// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName);
435 440
436 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
437 // But they're not used anyway, the item is being looked up for now, so let's proceed.
438 //if (UUID.Zero == assetID)
439 //{
440 // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
441 // continue;
442 //}
443
444 try 441 try
445 { 442 {
446 string xmlData; 443 string xmlData;
@@ -482,24 +479,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
482 if (attachments.Count <= 0) 479 if (attachments.Count <= 0)
483 return; 480 return;
484 481
485 Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>();
486
487 if (sp.PresenceType != PresenceType.Npc) 482 if (sp.PresenceType != PresenceType.Npc)
488 { 483 {
489 foreach (SceneObjectGroup so in attachments)
490 {
491 // Scripts MUST be snapshotted before the object is
492 // removed from the scene because doing otherwise will
493 // clobber the run flag
494 // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
495 // scripts performing attachment operations at the same time. Getting object states stops the scripts.
496 scriptStates[so] = PrepareScriptInstanceForSave(so, false);
497 }
498
499 lock (sp.AttachmentsSyncLock) 484 lock (sp.AttachmentsSyncLock)
500 { 485 {
501 foreach (SceneObjectGroup so in attachments) 486 for (int i = 0; i < attachments.Count; ++i)
502 UpdateDetachedObject(sp, so, scriptStates[so]); 487 {
488 SceneObjectGroup sog = attachments[i];
489 UpdateDetachedObject(sp, sog, PrepareScriptInstanceForSave(sog, false));
490 }
503 sp.ClearAttachments(); 491 sp.ClearAttachments();
504 } 492 }
505 } 493 }
@@ -507,8 +495,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
507 { 495 {
508 lock (sp.AttachmentsSyncLock) 496 lock (sp.AttachmentsSyncLock)
509 { 497 {
510 foreach (SceneObjectGroup so in attachments) 498 for (int i = 0; i < attachments.Count; ++i)
511 UpdateDetachedObject(sp, so, String.Empty); 499 UpdateDetachedObject(sp, attachments[i], String.Empty);
512 sp.ClearAttachments(); 500 sp.ClearAttachments();
513 } 501 }
514 } 502 }
@@ -524,9 +512,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
524 "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", 512 "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
525 m_scene.RegionInfo.RegionName, sp.Name, silent); 513 m_scene.RegionInfo.RegionName, sp.Name, silent);
526 514
527 foreach (SceneObjectGroup sop in sp.GetAttachments()) 515 List<SceneObjectGroup> attachments = sp.GetAttachments();
516
517 for(int i = 0; i < attachments.Count; ++i)
528 { 518 {
529 sop.Scene.DeleteSceneObject(sop, silent); 519 SceneObjectGroup sog = attachments[i];
520 sog.Scene.DeleteSceneObject(sog, silent);
530 } 521 }
531 522
532 sp.ClearAttachments(); 523 sp.ClearAttachments();
@@ -612,41 +603,61 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
612 attachPos = Vector3.Zero; 603 attachPos = Vector3.Zero;
613 } 604 }
614 605
615 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 606 if(attachmentPt > (uint)AttachmentPoint.LastValid)
616 if (attachments.Contains(group))
617 { 607 {
618// if (DebugLevel > 0) 608 m_log.WarnFormat("[ATTACHMENTS MODULE]: Invalid attachment point {0} SP {1}", attachmentPt, sp.Name);
619// m_log.WarnFormat(
620// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
621// group.Name, group.LocalId, sp.Name, attachmentPt);
622
623 return false; 609 return false;
624 } 610 }
625 611
626 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones 612 List<SceneObjectGroup> attachments = sp.GetAttachments();
627 while (attachments.Count >= 5) 613 List<SceneObjectGroup> toRemove = new List<SceneObjectGroup>(attachments.Count);
628 { 614 bool doRemCheck = !append;
629 if (attachments[0].FromItemID != UUID.Zero)
630 DetachSingleAttachmentToInv(sp, attachments[0]);
631 attachments.RemoveAt(0);
632 }
633 615
634 // If we're not appending, remove the rest as well 616 for(int i = 0; i < attachments.Count; ++i)
635 if (attachments.Count != 0 && !append)
636 { 617 {
637 foreach (SceneObjectGroup g in attachments) 618 SceneObjectGroup sog = attachments[i];
619 // duplications ?
620 if (group.UUID == sog.UUID)
638 { 621 {
639 if (g.FromItemID != UUID.Zero) 622 // if (DebugLevel > 0)
640 DetachSingleAttachmentToInv(sp, g); 623 // m_log.WarnFormat(
624 // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
625 // group.Name, group.LocalId, sp.Name, attachmentPt);
626 return false;
641 } 627 }
628 if(doRemCheck)
629 {
630 if(sog.AttachmentPoint == attachmentPt)
631 {
632 toRemove.Add(sog);
633 if(!m_wearReplacesAllOption)
634 doRemCheck = false;
635 }
636 }
637 }
638
639 if(attachments.Count - toRemove.Count >= Constants.MaxAgentAttachments)
640 {
641 m_log.WarnFormat("[ATTACHMENTS MODULE]: Max attachments exceded {0}",sp.Name);
642 return false;
642 } 643 }
643 644
644 group.DetachFromBackup(); 645 group.DetachFromBackup();
646 group.AttachmentPoint = attachmentPt;
647 group.RootPart.AttachedPos = attachPos;
645 648
649 // If we're not appending, remove the rest as well
646 lock (sp.AttachmentsSyncLock) 650 lock (sp.AttachmentsSyncLock)
647 { 651 {
648 group.AttachmentPoint = attachmentPt; 652 if (toRemove.Count > 0)
649 group.RootPart.AttachedPos = attachPos; 653 {
654 for (int i = 0; i< toRemove.Count; ++i)
655 {
656 SceneObjectGroup g = toRemove[i];
657 if (g.FromItemID != UUID.Zero)
658 DetachSingleAttachmentToInv(sp, g);
659 }
660 }
650 661
651 if (addToInventory && sp.PresenceType != PresenceType.Npc) 662 if (addToInventory && sp.PresenceType != PresenceType.Npc)
652 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); 663 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
@@ -668,7 +679,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
668 // and not all scripts are loaded at this point 679 // and not all scripts are loaded at this point
669 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); 680 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
670 } 681 }
671
672 return true; 682 return true;
673 } 683 }
674 684
@@ -1255,10 +1265,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1255 1265
1256 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. 1266 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
1257 objatt.HasGroupChanged = false; 1267 objatt.HasGroupChanged = false;
1258 bool tainted = false;
1259 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
1260 tainted = true;
1261 1268
1269 Vector3 lastPos = objatt.RootPart.OffsetPosition;
1270 Vector3 lastAttPos = objatt.RootPart.AttachedPos;
1271 bool doneAttach = false;
1262 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal 1272 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
1263 // course of events. If not, then it's probably not worth trying to recover the situation 1273 // course of events. If not, then it's probably not worth trying to recover the situation
1264 // since this is more likely to trigger further exceptions and confuse later debugging. If 1274 // since this is more likely to trigger further exceptions and confuse later debugging. If
@@ -1273,21 +1283,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1273 objatt.ResetOwnerChangeFlag(); 1283 objatt.ResetOwnerChangeFlag();
1274 } 1284 }
1275 1285
1276 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); 1286 doneAttach = AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append);
1277 } 1287 }
1278 catch (Exception e) 1288 catch (Exception e)
1279 { 1289 {
1280 m_log.ErrorFormat( 1290 m_log.ErrorFormat(
1281 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", 1291 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
1282 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); 1292 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
1293 doneAttach = false;
1294 }
1283 1295
1296 if(!doneAttach)
1297 {
1284 // Make sure the object doesn't stick around and bail 1298 // Make sure the object doesn't stick around and bail
1285 sp.RemoveAttachment(objatt); 1299 sp.RemoveAttachment(objatt);
1286 m_scene.DeleteSceneObject(objatt, false); 1300 m_scene.DeleteSceneObject(objatt, false);
1287 return null; 1301 return null;
1288 } 1302 }
1289 1303
1290 if (tainted) 1304 if ((attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) ||
1305 lastPos != objatt.RootPart.OffsetPosition ||
1306 lastAttPos != objatt.RootPart.AttachedPos)
1291 objatt.HasGroupChanged = true; 1307 objatt.HasGroupChanged = true;
1292 1308
1293 return objatt; 1309 return objatt;