aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
authorUbitUmarov2015-09-02 19:54:53 +0100
committerUbitUmarov2015-09-02 19:54:53 +0100
commita11edceb00b5b86f825bd957bdac9edb91f893dd (patch)
treec192eae26f3aadf365a66f32fc6d9ade2f0a0c61 /OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
parentbad merge? (diff)
downloadopensim-SC_OLD-a11edceb00b5b86f825bd957bdac9edb91f893dd.zip
opensim-SC_OLD-a11edceb00b5b86f825bd957bdac9edb91f893dd.tar.gz
opensim-SC_OLD-a11edceb00b5b86f825bd957bdac9edb91f893dd.tar.bz2
opensim-SC_OLD-a11edceb00b5b86f825bd957bdac9edb91f893dd.tar.xz
seems to compile ( tests comented out)
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs242
1 files changed, 7 insertions, 235 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index a703377..5e1801a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -122,17 +122,12 @@ namespace OpenSim.Region.Framework.Scenes
122 /// since the group's last persistent backup 122 /// since the group's last persistent backup
123 /// </summary> 123 /// </summary>
124 private bool m_hasGroupChanged = false; 124 private bool m_hasGroupChanged = false;
125<<<<<<< HEAD
126 private long timeFirstChanged;
127 private long timeLastChanged;
128=======
129 private long timeFirstChanged = 0; 125 private long timeFirstChanged = 0;
130 private long timeLastChanged = 0; 126 private long timeLastChanged = 0;
131 private long m_maxPersistTime = 0; 127 private long m_maxPersistTime = 0;
132 private long m_minPersistTime = 0; 128 private long m_minPersistTime = 0;
133// private Random m_rand; 129// private Random m_rand;
134 private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>(); 130 private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
135>>>>>>> avn/ubitvar
136 131
137 /// <summary> 132 /// <summary>
138 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage 133 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
@@ -205,7 +200,6 @@ namespace OpenSim.Region.Framework.Scenes
205 /// the prims in the database still use the old SceneGroupID. That's a problem if the group 200 /// the prims in the database still use the old SceneGroupID. That's a problem if the group
206 /// is deleted, because we delete groups by searching for prims by their SceneGroupID. 201 /// is deleted, because we delete groups by searching for prims by their SceneGroupID.
207 /// </summary> 202 /// </summary>
208<<<<<<< HEAD
209 public bool GroupContainsForeignPrims 203 public bool GroupContainsForeignPrims
210 { 204 {
211 private set 205 private set
@@ -218,9 +212,7 @@ namespace OpenSim.Region.Framework.Scenes
218 get { return m_groupContainsForeignPrims; } 212 get { return m_groupContainsForeignPrims; }
219 } 213 }
220 214
221=======
222 public bool HasGroupChangedDueToDelink { get; set; } 215 public bool HasGroupChangedDueToDelink { get; set; }
223>>>>>>> avn/ubitvar
224 216
225 private bool isTimeToPersist() 217 private bool isTimeToPersist()
226 { 218 {
@@ -350,7 +342,6 @@ namespace OpenSim.Region.Framework.Scenes
350 get { return RootPart.VolumeDetectActive; } 342 get { return RootPart.VolumeDetectActive; }
351 } 343 }
352 344
353<<<<<<< HEAD
354 private Vector3 lastPhysGroupPos; 345 private Vector3 lastPhysGroupPos;
355 private Quaternion lastPhysGroupRot; 346 private Quaternion lastPhysGroupRot;
356 347
@@ -358,9 +349,8 @@ namespace OpenSim.Region.Framework.Scenes
358 /// Is this entity set to be saved in persistent storage? 349 /// Is this entity set to be saved in persistent storage?
359 /// </summary> 350 /// </summary>
360 public bool Backup { get; private set; } 351 public bool Backup { get; private set; }
361======= 352
362 private bool m_isBackedUp; 353 private bool m_isBackedUp;
363>>>>>>> avn/ubitvar
364 354
365 public bool IsBackedUp 355 public bool IsBackedUp
366 { 356 {
@@ -570,146 +560,11 @@ namespace OpenSim.Region.Framework.Scenes
570 && !Scene.LoadingPrims 560 && !Scene.LoadingPrims
571 ) 561 )
572 { 562 {
573<<<<<<< HEAD
574 if (
575 !Scene.PositionIsInCurrentRegion(val)
576 && !IsAttachmentCheckFull()
577 && (!Scene.LoadingPrims)
578 )
579 {
580 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
581 string version = String.Empty;
582 Vector3 newpos = Vector3.Zero;
583 string failureReason = String.Empty;
584 OpenSim.Services.Interfaces.GridRegion destination = null;
585
586 if (m_rootPart.KeyframeMotion != null)
587 m_rootPart.KeyframeMotion.StartCrossingCheck();
588
589 bool canCross = true;
590 foreach (ScenePresence av in GetSittingAvatars())
591 {
592 // We need to cross these agents. First, let's find
593 // out if any of them can't cross for some reason.
594 // We have to deny the crossing entirely if any
595 // of them are banned. Alternatively, we could
596 // unsit banned agents....
597
598
599 // We set the avatar position as being the object
600 // position to get the region to send to
601 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos, out failureReason)) == null)
602 {
603 canCross = false;
604 break;
605 }
606
607 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
608 }
609
610 if (canCross)
611 {
612 // We unparent the SP quietly so that it won't
613 // be made to stand up
614
615 List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
616
617 foreach (ScenePresence av in GetSittingAvatars())
618 {
619 avtocrossInfo avinfo = new avtocrossInfo();
620 SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
621 if (parentPart != null)
622 av.ParentUUID = parentPart.UUID;
623
624 avinfo.av = av;
625 avinfo.ParentID = av.ParentID;
626 avsToCross.Add(avinfo);
627
628 av.PrevSitOffset = av.OffsetPosition;
629 av.ParentID = 0;
630 }
631
632 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
633
634 // Normalize
635 if (val.X >= m_scene.RegionInfo.RegionSizeX)
636 val.X -= m_scene.RegionInfo.RegionSizeX;
637 if (val.Y >= m_scene.RegionInfo.RegionSizeY)
638 val.Y -= m_scene.RegionInfo.RegionSizeY;
639 if (val.X < 0)
640 val.X += m_scene.RegionInfo.RegionSizeX;
641 if (val.Y < 0)
642 val.Y += m_scene.RegionInfo.RegionSizeY;
643
644 // If it's deleted, crossing was successful
645 if (IsDeleted)
646 {
647 foreach (avtocrossInfo avinfo in avsToCross)
648 {
649 ScenePresence av = avinfo.av;
650 if (!av.IsInTransit) // just in case...
651 {
652 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
653
654 av.IsInTransit = true;
655
656 // A temporary measure to allow regression tests to work.
657 // Quite possibly, all BeginInvoke() calls should be replaced by Util.FireAndForget
658 // or similar since BeginInvoke() always uses the system threadpool to launch
659 // threads rather than any replace threadpool that we might be using.
660 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
661 {
662 entityTransfer.CrossAgentToNewRegionAsync(av, val, destination, av.Flying, version);
663 CrossAgentToNewRegionCompleted(av);
664 }
665 else
666 {
667 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
668 d.BeginInvoke(
669 av, val, destination, av.Flying, version,
670 ar => CrossAgentToNewRegionCompleted(d.EndInvoke(ar)), null);
671 }
672 }
673 else
674 {
675 m_log.DebugFormat("[SCENE OBJECT]: Not crossing avatar {0} to {1} because it's already in transit", av.Name, val);
676 }
677 }
678
679 return;
680 }
681 else // cross failed, put avas back ??
682 {
683 foreach (avtocrossInfo avinfo in avsToCross)
684 {
685 ScenePresence av = avinfo.av;
686 av.ParentUUID = UUID.Zero;
687 av.ParentID = avinfo.ParentID;
688 }
689 }
690 }
691 else
692 {
693 if (m_rootPart.KeyframeMotion != null)
694 m_rootPart.KeyframeMotion.CrossingFailure();
695
696 if (RootPart.PhysActor != null)
697 {
698 RootPart.PhysActor.CrossingFailure();
699 }
700 }
701
702 Vector3 oldp = AbsolutePosition;
703 val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)m_scene.RegionInfo.RegionSizeX - 0.5f);
704 val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)m_scene.RegionInfo.RegionSizeY - 0.5f);
705 val.Z = Util.Clamp<float>(oldp.Z, 0.5f, Constants.RegionHeight);
706=======
707 if (!inTransit) 563 if (!inTransit)
708 { 564 {
709 inTransit = true; 565 inTransit = true;
710 SOGCrossDelegate d = CrossAsync; 566 SOGCrossDelegate d = CrossAsync;
711 d.BeginInvoke(this, val, CrossAsyncCompleted, d); 567 d.BeginInvoke(this, val, CrossAsyncCompleted, d);
712>>>>>>> avn/ubitvar
713 } 568 }
714 return; 569 return;
715 } 570 }
@@ -1200,7 +1055,7 @@ namespace OpenSim.Region.Framework.Scenes
1200 /// No avatar should appear more than once in this list. 1055 /// No avatar should appear more than once in this list.
1201 /// Do not manipulate this list directly - use the Add/Remove sitting avatar methods on SceneObjectPart. 1056 /// Do not manipulate this list directly - use the Add/Remove sitting avatar methods on SceneObjectPart.
1202 /// </remarks> 1057 /// </remarks>
1203 protected internal List<ScenePresence> m_sittingAvatars = new List<ScenePresence>(); 1058 protected internal List<UUID> m_sittingAvatars = new List<UUID>();
1204 1059
1205 #endregion 1060 #endregion
1206 1061
@@ -1311,14 +1166,10 @@ namespace OpenSim.Region.Framework.Scenes
1311 /// </summary> 1166 /// </summary>
1312 public virtual void AttachToBackup() 1167 public virtual void AttachToBackup()
1313 { 1168 {
1314<<<<<<< HEAD
1315 if (CanBeBackedUp)
1316=======
1317 if (IsAttachment) return; 1169 if (IsAttachment) return;
1318 m_scene.SceneGraph.FireAttachToBackup(this); 1170 m_scene.SceneGraph.FireAttachToBackup(this);
1319 1171
1320 if (InSceneBackup) 1172// if (InSceneBackup)
1321>>>>>>> avn/ubitvar
1322 { 1173 {
1323// m_log.DebugFormat( 1174// m_log.DebugFormat(
1324// "[SCENE OBJECT GROUP]: Attaching object {0} {1} to scene presistence sweep", Name, UUID); 1175// "[SCENE OBJECT GROUP]: Attaching object {0} {1} to scene presistence sweep", Name, UUID);
@@ -1431,21 +1282,12 @@ namespace OpenSim.Region.Framework.Scenes
1431 /// <returns></returns> 1282 /// <returns></returns>
1432 public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) 1283 public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
1433 { 1284 {
1434<<<<<<< HEAD
1435 maxX = -256f;
1436 maxY = -256f;
1437 maxZ = -256f;
1438 minX = 10000f;
1439 minY = 10000f;
1440 minZ = 10000f;
1441=======
1442 maxX = float.MinValue; 1285 maxX = float.MinValue;
1443 maxY = float.MinValue; 1286 maxY = float.MinValue;
1444 maxZ = float.MinValue; 1287 maxZ = float.MinValue;
1445 minX = float.MaxValue; 1288 minX = float.MaxValue;
1446 minY = float.MaxValue; 1289 minY = float.MaxValue;
1447 minZ = float.MaxValue; 1290 minZ = float.MaxValue;
1448>>>>>>> avn/ubitvar
1449 1291
1450 SceneObjectPart[] parts = m_parts.GetArray(); 1292 SceneObjectPart[] parts = m_parts.GetArray();
1451 foreach (SceneObjectPart part in parts) 1293 foreach (SceneObjectPart part in parts)
@@ -1843,17 +1685,6 @@ namespace OpenSim.Region.Framework.Scenes
1843 } 1685 }
1844 } 1686 }
1845 1687
1846<<<<<<< HEAD
1847
1848 /// <summary>
1849 ///
1850 /// </summary>
1851 /// <param name="part"></param>
1852 private void SetPartAsNonRoot(SceneObjectPart part)
1853 {
1854 part.ParentID = m_rootPart.LocalId;
1855 part.ClearUndoState();
1856=======
1857 /// <summary> 1688 /// <summary>
1858 /// Add the avatar to this linkset (avatar is sat). 1689 /// Add the avatar to this linkset (avatar is sat).
1859 /// </summary> 1690 /// </summary>
@@ -1893,7 +1724,6 @@ namespace OpenSim.Region.Framework.Scenes
1893 public List<ScenePresence> GetLinkedAvatars() 1724 public List<ScenePresence> GetLinkedAvatars()
1894 { 1725 {
1895 return m_linkedAvatars; 1726 return m_linkedAvatars;
1896>>>>>>> avn/ubitvar
1897 } 1727 }
1898 1728
1899 /// <summary> 1729 /// <summary>
@@ -2197,14 +2027,7 @@ namespace OpenSim.Region.Framework.Scenes
2197 2027
2198 if (Scene != null) 2028 if (Scene != null)
2199 { 2029 {
2200<<<<<<< HEAD
2201 if (!sp.IsChildAgent && sp.ParentID == part.LocalId)
2202 sp.StandUp();
2203
2204 if (!silent)
2205=======
2206 Scene.ForEachRootScenePresence(delegate(ScenePresence avatar) 2030 Scene.ForEachRootScenePresence(delegate(ScenePresence avatar)
2207>>>>>>> avn/ubitvar
2208 { 2031 {
2209 if (avatar.ParentID == LocalId) 2032 if (avatar.ParentID == LocalId)
2210 avatar.StandUp(); 2033 avatar.StandUp();
@@ -2504,16 +2327,6 @@ namespace OpenSim.Region.Framework.Scenes
2504 /// <returns></returns> 2327 /// <returns></returns>
2505 public SceneObjectGroup Copy(bool userExposed) 2328 public SceneObjectGroup Copy(bool userExposed)
2506 { 2329 {
2507<<<<<<< HEAD
2508 // FIXME: This is dangerous since it's easy to forget to reset some references when necessary and end up
2509 // with bugs that only occur in some circumstances (e.g. crossing between regions on the same simulator
2510 // but not between regions on different simulators). Really, all copying should be done explicitly.
2511 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
2512
2513 dupe.Backup = false;
2514 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
2515 dupe.m_sittingAvatars = new List<ScenePresence>();
2516=======
2517 m_dupeInProgress = true; 2330 m_dupeInProgress = true;
2518 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); 2331 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
2519 dupe.m_isBackedUp = false; 2332 dupe.m_isBackedUp = false;
@@ -2525,7 +2338,6 @@ namespace OpenSim.Region.Framework.Scenes
2525 dupe.m_linkedAvatars = new List<ScenePresence>(); 2338 dupe.m_linkedAvatars = new List<ScenePresence>();
2526 dupe.m_sittingAvatars = new List<UUID>(); 2339 dupe.m_sittingAvatars = new List<UUID>();
2527 2340
2528>>>>>>> avn/ubitvar
2529 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); 2341 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
2530 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; 2342 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
2531 2343
@@ -2700,12 +2512,8 @@ namespace OpenSim.Region.Framework.Scenes
2700 return RootPart.Torque; 2512 return RootPart.Torque;
2701 } 2513 }
2702 2514
2703<<<<<<< HEAD
2704 public void MoveToTarget(Vector3 target, float tau)
2705=======
2706 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object 2515 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
2707 public void moveToTarget(Vector3 target, float tau) 2516 public void MoveToTarget(Vector3 target, float tau)
2708>>>>>>> avn/ubitvar
2709 { 2517 {
2710 if (IsAttachment) 2518 if (IsAttachment)
2711 { 2519 {
@@ -2732,21 +2540,7 @@ namespace OpenSim.Region.Framework.Scenes
2732 if (IsAttachment) 2540 if (IsAttachment)
2733 { 2541 {
2734 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); 2542 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
2735<<<<<<< HEAD
2736
2737 if (avatar != null)
2738 avatar.ResetMoveToTarget();
2739 }
2740 else
2741 {
2742 PhysicsActor pa = RootPart.PhysActor;
2743 2543
2744 if (pa != null && pa.PIDActive)
2745 {
2746 pa.PIDActive = false;
2747
2748 ScheduleGroupForTerseUpdate();
2749=======
2750 if (avatar != null) 2544 if (avatar != null)
2751 { 2545 {
2752 avatar.ResetMoveToTarget(); 2546 avatar.ResetMoveToTarget();
@@ -2786,7 +2580,6 @@ namespace OpenSim.Region.Framework.Scenes
2786 rootpart.PhysActor.APIDDamping = damping; 2580 rootpart.PhysActor.APIDDamping = damping;
2787 rootpart.PhysActor.APIDActive = true; 2581 rootpart.PhysActor.APIDActive = true;
2788 } 2582 }
2789>>>>>>> avn/ubitvar
2790 } 2583 }
2791 } 2584 }
2792 } 2585 }
@@ -3484,18 +3277,6 @@ namespace OpenSim.Region.Framework.Scenes
3484 3277
3485 linkPart.Rezzed = RootPart.Rezzed; 3278 linkPart.Rezzed = RootPart.Rezzed;
3486 3279
3487<<<<<<< HEAD
3488 // We must persist the delinked group to the database immediately, for safety. The problem
3489 // is that although in memory the new group has a new SceneGroupID, in the database it
3490 // still has the parent group's SceneGroupID (until the next backup). This means that if the
3491 // parent group is deleted then the delinked group will also be deleted from the database.
3492 // This problem will disappear if the region remains alive long enough for another backup,
3493 // since at that time the delinked group's new SceneGroupID will be written to the database.
3494 // But if the region crashes before that then the prims will be permanently gone, and this must
3495 // not happen. (We can't use a just-in-time trick like GroupContainsForeignPrims in this case
3496 // because the delinked group doesn't know when the source group is deleted.)
3497 m_scene.ForceSceneObjectBackup(objectGroup);
3498=======
3499 // When we delete a group, we currently have to force persist to the database if the object id has changed 3280 // When we delete a group, we currently have to force persist to the database if the object id has changed
3500 // (since delete works by deleting all rows which have a given object id) 3281 // (since delete works by deleting all rows which have a given object id)
3501 3282
@@ -3507,7 +3288,6 @@ namespace OpenSim.Region.Framework.Scenes
3507 m_rootPart.PhysActor.Building = false; 3288 m_rootPart.PhysActor.Building = false;
3508 3289
3509 objectGroup.HasGroupChangedDueToDelink = true; 3290 objectGroup.HasGroupChangedDueToDelink = true;
3510>>>>>>> avn/ubitvar
3511 3291
3512 if (sendEvents) 3292 if (sendEvents)
3513 linkPart.TriggerScriptChangedEvent(Changed.LINK); 3293 linkPart.TriggerScriptChangedEvent(Changed.LINK);
@@ -3521,13 +3301,9 @@ namespace OpenSim.Region.Framework.Scenes
3521 /// <param name="objectGroup"></param> 3301 /// <param name="objectGroup"></param>
3522 public virtual void DetachFromBackup() 3302 public virtual void DetachFromBackup()
3523 { 3303 {
3524<<<<<<< HEAD
3525 if (Backup && Scene != null)
3526=======
3527 if (m_scene != null) 3304 if (m_scene != null)
3528 m_scene.SceneGraph.FireDetachFromBackup(this); 3305 m_scene.SceneGraph.FireDetachFromBackup(this);
3529 if (m_isBackedUp && Scene != null) 3306 if (m_isBackedUp && Scene != null)
3530>>>>>>> avn/ubitvar
3531 m_scene.EventManager.OnBackup -= ProcessBackup; 3307 m_scene.EventManager.OnBackup -= ProcessBackup;
3532 3308
3533 Backup = false; 3309 Backup = false;
@@ -3973,9 +3749,6 @@ namespace OpenSim.Region.Framework.Scenes
3973 { 3749 {
3974 RootPart.UpdatePermissions(AgentID, field, localID, mask, addRemTF); 3750 RootPart.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
3975 3751
3976<<<<<<< HEAD
3977 AdjustChildPrimPermissions(Scene.Permissions.IsGod(AgentID));
3978=======
3979 bool god = Scene.Permissions.IsGod(AgentID); 3752 bool god = Scene.Permissions.IsGod(AgentID);
3980 3753
3981 if (field == 1 && god) 3754 if (field == 1 && god)
@@ -3986,8 +3759,7 @@ namespace OpenSim.Region.Framework.Scenes
3986 }); 3759 });
3987 } 3760 }
3988 3761
3989 AdjustChildPrimPermissions(); 3762 AdjustChildPrimPermissions(false);
3990>>>>>>> avn/ubitvar
3991 3763
3992 if (field == 1 && god) // Base mask was set. Update all child part inventories 3764 if (field == 1 && god) // Base mask was set. Update all child part inventories
3993 { 3765 {
@@ -5037,10 +4809,10 @@ namespace OpenSim.Region.Framework.Scenes
5037 /// down after it move one place down the list. 4809 /// down after it move one place down the list.
5038 /// </remarks> 4810 /// </remarks>
5039 /// <returns>A list of the sitting avatars. Returns an empty list if there are no sitting avatars.</returns> 4811 /// <returns>A list of the sitting avatars. Returns an empty list if there are no sitting avatars.</returns>
5040 public List<ScenePresence> GetSittingAvatars() 4812 public List<UUID> GetSittingAvatars()
5041 { 4813 {
5042 lock (m_sittingAvatars) 4814 lock (m_sittingAvatars)
5043 return new List<ScenePresence>(m_sittingAvatars); 4815 return new List<UUID>(m_sittingAvatars);
5044 } 4816 }
5045 4817
5046 /// <summary> 4818 /// <summary>