diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 170 |
1 files changed, 109 insertions, 61 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 55c5422..c78f5b3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -48,6 +48,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
48 | { | 48 | { |
49 | #region INonSharedRegionModule | 49 | #region INonSharedRegionModule |
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | |||
52 | public int DebugLevel { get; set; } | ||
51 | 53 | ||
52 | private Scene m_scene; | 54 | private Scene m_scene; |
53 | private IInventoryAccessModule m_invAccessModule; | 55 | private IInventoryAccessModule m_invAccessModule; |
@@ -79,11 +81,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
79 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 81 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
80 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); | 82 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); |
81 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); | 83 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); |
84 | |||
85 | MainConsole.Instance.Commands.AddCommand( | ||
86 | "Debug", | ||
87 | false, | ||
88 | "debug attachments", | ||
89 | "debug attachments [0|1]", | ||
90 | "Turn on attachments debugging\n" | ||
91 | + " <= 0 - turns off debugging\n" | ||
92 | + " >= 1 - turns on attachment message logging\n", | ||
93 | HandleDebugAttachments); | ||
82 | } | 94 | } |
83 | 95 | ||
84 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI | 96 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI |
85 | } | 97 | } |
86 | 98 | ||
99 | private void HandleDebugAttachments(string module, string[] args) | ||
100 | { | ||
101 | int debugLevel; | ||
102 | |||
103 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) | ||
104 | { | ||
105 | MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]"); | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | DebugLevel = debugLevel; | ||
110 | MainConsole.Instance.OutputFormat( | ||
111 | "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name); | ||
112 | } | ||
113 | } | ||
114 | |||
87 | /// <summary> | 115 | /// <summary> |
88 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. | 116 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. |
89 | /// </summary> | 117 | /// </summary> |
@@ -196,14 +224,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
196 | 224 | ||
197 | if (sp.GetAttachments().Count > 0) | 225 | if (sp.GetAttachments().Count > 0) |
198 | { | 226 | { |
199 | // m_log.DebugFormat( | 227 | if (DebugLevel > 0) |
200 | // "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", | 228 | m_log.DebugFormat( |
201 | // m_scene.Name, sp.Name); | 229 | "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", |
230 | m_scene.Name, sp.Name); | ||
202 | 231 | ||
203 | return; | 232 | return; |
204 | } | 233 | } |
205 | 234 | ||
206 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); | 235 | if (DebugLevel > 0) |
236 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); | ||
207 | 237 | ||
208 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | 238 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); |
209 | foreach (AvatarAttachment attach in attachments) | 239 | foreach (AvatarAttachment attach in attachments) |
@@ -245,7 +275,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
245 | if (!Enabled) | 275 | if (!Enabled) |
246 | return; | 276 | return; |
247 | 277 | ||
248 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | 278 | if (DebugLevel > 0) |
279 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
249 | 280 | ||
250 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 281 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
251 | 282 | ||
@@ -278,9 +309,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
278 | if (!Enabled) | 309 | if (!Enabled) |
279 | return; | 310 | return; |
280 | 311 | ||
281 | // m_log.DebugFormat( | 312 | if (DebugLevel > 0) |
282 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | 313 | m_log.DebugFormat( |
283 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | 314 | "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", |
315 | m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
284 | 316 | ||
285 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 317 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
286 | { | 318 | { |
@@ -313,9 +345,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
313 | { | 345 | { |
314 | if (group.GetSittingAvatarsCount() != 0) | 346 | if (group.GetSittingAvatarsCount() != 0) |
315 | { | 347 | { |
316 | // m_log.WarnFormat( | 348 | if (DebugLevel > 0) |
317 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | 349 | m_log.WarnFormat( |
318 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | 350 | "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", |
351 | group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | ||
319 | 352 | ||
320 | return false; | 353 | return false; |
321 | } | 354 | } |
@@ -351,9 +384,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
351 | 384 | ||
352 | if (attachments.Contains(group)) | 385 | if (attachments.Contains(group)) |
353 | { | 386 | { |
354 | // m_log.WarnFormat( | 387 | if (DebugLevel > 0) |
355 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | 388 | m_log.WarnFormat( |
356 | // group.Name, group.LocalId, sp.Name, AttachmentPt); | 389 | "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", |
390 | group.Name, group.LocalId, sp.Name, attachmentPt); | ||
357 | 391 | ||
358 | return false; | 392 | return false; |
359 | } | 393 | } |
@@ -418,9 +452,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
418 | if (!Enabled) | 452 | if (!Enabled) |
419 | return null; | 453 | return null; |
420 | 454 | ||
421 | // m_log.DebugFormat( | 455 | if (DebugLevel > 0) |
422 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", | 456 | m_log.DebugFormat( |
423 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); | 457 | "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", |
458 | (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); | ||
424 | 459 | ||
425 | bool append = (AttachmentPt & 0x80) != 0; | 460 | bool append = (AttachmentPt & 0x80) != 0; |
426 | AttachmentPt &= 0x7f; | 461 | AttachmentPt &= 0x7f; |
@@ -444,9 +479,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
444 | // if (sp.Appearance.GetAttachmentForItem(itemID) != null) | 479 | // if (sp.Appearance.GetAttachmentForItem(itemID) != null) |
445 | if (alreadyOn) | 480 | if (alreadyOn) |
446 | { | 481 | { |
447 | // m_log.WarnFormat( | 482 | if (DebugLevel > 0) |
448 | // "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", | 483 | m_log.DebugFormat( |
449 | // sp.Name, itemID, AttachmentPt); | 484 | "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", |
485 | sp.Name, itemID, AttachmentPt); | ||
450 | 486 | ||
451 | return null; | 487 | return null; |
452 | } | 488 | } |
@@ -459,7 +495,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
459 | if (!Enabled) | 495 | if (!Enabled) |
460 | return; | 496 | return; |
461 | 497 | ||
462 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | 498 | if (DebugLevel > 0) |
499 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | ||
463 | 500 | ||
464 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | 501 | foreach (KeyValuePair<UUID, uint> rez in rezlist) |
465 | { | 502 | { |
@@ -477,9 +514,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
477 | if (!Enabled) | 514 | if (!Enabled) |
478 | return; | 515 | return; |
479 | 516 | ||
480 | // m_log.DebugFormat( | 517 | if (DebugLevel > 0) |
481 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", | 518 | m_log.DebugFormat( |
482 | // sp.UUID, soLocalId); | 519 | "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", |
520 | sp.UUID, soLocalId); | ||
483 | 521 | ||
484 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); | 522 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); |
485 | 523 | ||
@@ -495,9 +533,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
495 | if (inventoryID == UUID.Zero) | 533 | if (inventoryID == UUID.Zero) |
496 | return; | 534 | return; |
497 | 535 | ||
498 | // m_log.DebugFormat( | 536 | if (DebugLevel > 0) |
499 | // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", | 537 | m_log.DebugFormat( |
500 | // so.Name, so.LocalId, inventoryID); | 538 | "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", |
539 | so.Name, so.LocalId, inventoryID); | ||
501 | 540 | ||
502 | lock (sp.AttachmentsSyncLock) | 541 | lock (sp.AttachmentsSyncLock) |
503 | { | 542 | { |
@@ -552,9 +591,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
552 | return; | 591 | return; |
553 | } | 592 | } |
554 | 593 | ||
555 | // m_log.DebugFormat( | 594 | if (DebugLevel > 0) |
556 | // "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", | 595 | m_log.DebugFormat( |
557 | // so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); | 596 | "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", |
597 | so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); | ||
558 | 598 | ||
559 | // Scripts MUST be snapshotted before the object is | 599 | // Scripts MUST be snapshotted before the object is |
560 | // removed from the scene because doing otherwise will | 600 | // removed from the scene because doing otherwise will |
@@ -680,12 +720,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
680 | 720 | ||
681 | grp.HasGroupChanged = false; // Prevent it being saved over and over | 721 | grp.HasGroupChanged = false; // Prevent it being saved over and over |
682 | } | 722 | } |
683 | // else | 723 | else if (DebugLevel > 0) |
684 | // { | 724 | { |
685 | // m_log.DebugFormat( | 725 | m_log.DebugFormat( |
686 | // "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | 726 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", |
687 | // grp.UUID, grp.AttachmentPoint); | 727 | grp.UUID, grp.AttachmentPoint); |
688 | // } | 728 | } |
689 | } | 729 | } |
690 | 730 | ||
691 | /// <summary> | 731 | /// <summary> |
@@ -703,9 +743,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
703 | private void AttachToAgent( | 743 | private void AttachToAgent( |
704 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 744 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
705 | { | 745 | { |
706 | // m_log.DebugFormat( | 746 | if (DebugLevel > 0) |
707 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 747 | m_log.DebugFormat( |
708 | // so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 748 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", |
749 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | ||
709 | 750 | ||
710 | so.DetachFromBackup(); | 751 | so.DetachFromBackup(); |
711 | 752 | ||
@@ -730,9 +771,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
730 | { | 771 | { |
731 | if (so.HasPrivateAttachmentPoint) | 772 | if (so.HasPrivateAttachmentPoint) |
732 | { | 773 | { |
733 | // m_log.DebugFormat( | 774 | if (DebugLevel > 0) |
734 | // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", | 775 | m_log.DebugFormat( |
735 | // so.Name, sp.Name, so.AttachmentPoint); | 776 | "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", |
777 | so.Name, sp.Name, so.AttachmentPoint); | ||
736 | 778 | ||
737 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the | 779 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the |
738 | // scene that it's no longer in their awareness. | 780 | // scene that it's no longer in their awareness. |
@@ -766,9 +808,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
766 | if (m_invAccessModule == null) | 808 | if (m_invAccessModule == null) |
767 | return null; | 809 | return null; |
768 | 810 | ||
769 | // m_log.DebugFormat( | 811 | if (DebugLevel > 0) |
770 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | 812 | m_log.DebugFormat( |
771 | // grp.Name, grp.LocalId, remoteClient.Name); | 813 | "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", |
814 | grp.Name, grp.LocalId, sp.Name); | ||
772 | 815 | ||
773 | InventoryItemBase newItem | 816 | InventoryItemBase newItem |
774 | = m_invAccessModule.CopyToInventory( | 817 | = m_invAccessModule.CopyToInventory( |
@@ -877,9 +920,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
877 | return null; | 920 | return null; |
878 | } | 921 | } |
879 | 922 | ||
880 | // m_log.DebugFormat( | 923 | if (DebugLevel > 0) |
881 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | 924 | m_log.DebugFormat( |
882 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); | 925 | "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", |
926 | objatt.Name, sp.Name, attachmentPt, m_scene.Name); | ||
883 | 927 | ||
884 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 928 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
885 | objatt.HasGroupChanged = false; | 929 | objatt.HasGroupChanged = false; |
@@ -949,9 +993,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
949 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); | 993 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); |
950 | if (changed && m_scene.AvatarFactory != null) | 994 | if (changed && m_scene.AvatarFactory != null) |
951 | { | 995 | { |
952 | // m_log.DebugFormat( | 996 | if (DebugLevel > 0) |
953 | // "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", | 997 | m_log.DebugFormat( |
954 | // sp.Name, att.Name, AttachmentPt); | 998 | "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", |
999 | sp.Name, att.Name, AttachmentPt); | ||
955 | 1000 | ||
956 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 1001 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
957 | } | 1002 | } |
@@ -966,9 +1011,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
966 | if (!Enabled) | 1011 | if (!Enabled) |
967 | return null; | 1012 | return null; |
968 | 1013 | ||
969 | // m_log.DebugFormat( | 1014 | if (DebugLevel > 0) |
970 | // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", | 1015 | m_log.DebugFormat( |
971 | // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | 1016 | "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", |
1017 | (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | ||
972 | 1018 | ||
973 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1019 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
974 | 1020 | ||
@@ -999,9 +1045,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
999 | 1045 | ||
1000 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 1046 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
1001 | { | 1047 | { |
1002 | // m_log.DebugFormat( | 1048 | if (DebugLevel > 0) |
1003 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", | 1049 | m_log.DebugFormat( |
1004 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); | 1050 | "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", |
1051 | objectLocalID, remoteClient.Name, AttachmentPt, silent); | ||
1005 | 1052 | ||
1006 | if (!Enabled) | 1053 | if (!Enabled) |
1007 | return; | 1054 | return; |
@@ -1036,9 +1083,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1036 | // Calls attach with a Zero position | 1083 | // Calls attach with a Zero position |
1037 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append)) | 1084 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append)) |
1038 | { | 1085 | { |
1039 | // m_log.Debug( | 1086 | if (DebugLevel > 0) |
1040 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | 1087 | m_log.Debug( |
1041 | // + ", AttachmentPoint: " + AttachmentPt); | 1088 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
1089 | + ", AttachmentPoint: " + AttachmentPt); | ||
1042 | 1090 | ||
1043 | // Save avatar attachment information | 1091 | // Save avatar attachment information |
1044 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | 1092 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); |
@@ -1095,4 +1143,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1095 | 1143 | ||
1096 | #endregion | 1144 | #endregion |
1097 | } | 1145 | } |
1098 | } | 1146 | } \ No newline at end of file |