From ff0ccf9c67e3840c39729e1ce9677b96e0cfd472 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 7 Aug 2016 14:30:27 +0100 Subject: several changes related to culling option --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 188 ++++++++++----------- 1 file changed, 90 insertions(+), 98 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index e3b2fd1..b823abe 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3937,7 +3937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP uint priority = m_prioritizer.GetUpdatePriority(this, entity); lock (m_entityUpdates.SyncRoot) - m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); + m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags)); } /// @@ -4006,12 +4006,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race // condition where a kill can be processed before an out-of-date update for the same object. // float avgTimeDilation = 0.0f; - IEntityUpdate iupdate; + EntityUpdate update; Int32 timeinqueue; // this is just debugging code & can be dropped later bool doCulling = m_scene.ObjectsCullingByDistance; float cullingrange = 64.0f; HashSet GroupsNeedFullUpdate = new HashSet(); + List kills = new List(); // Vector3 mycamera = Vector3.Zero; Vector3 mypos = Vector3.Zero; ScenePresence mysp = (ScenePresence)SceneAgent; @@ -4027,12 +4028,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP while (updatesThisCall < maxUpdates) { lock (m_entityUpdates.SyncRoot) - if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue)) + if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) break; - - EntityUpdate update = (EntityUpdate)iupdate; - + // avgTimeDilation += update.TimeDilation; + PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; + + if(updateFlags.HasFlag(PrimUpdateFlags.Kill)) + { + m_killRecord.Add(update.Entity.LocalId); + continue; + } if (update.Entity is SceneObjectPart) { @@ -4156,11 +4162,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region UpdateFlags to packet type conversion - PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; - bool canUseCompressed = true; bool canUseImproved = true; + // Compressed object updates only make sense for LL primitives if (!(update.Entity is SceneObjectPart)) { @@ -4319,17 +4324,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_killRecord.Clear(); } + if (kills.Count > 0) + { + foreach(SceneObjectGroup grp in kills) + { + foreach(SceneObjectPart p in grp.Parts) + SendEntityUpdate(p,PrimUpdateFlags.Kill); + } + kills.Clear(); + } + if(GroupsNeedFullUpdate.Count > 0) { foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) { - grp.ScheduleGroupForFullUpdate(); + foreach(SceneObjectPart p in grp.Parts) + SendEntityUpdate(p,PrimUpdateFlags.CancelKill); lock(GroupsInView) GroupsInView.Add(grp); } } #endregion - } // hack.. dont use @@ -4368,7 +4383,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } private bool CheckGroupsInViewBusy = false; - private bool CheckGroupsInViewOverRun = false; public void CheckGroupsInView() { @@ -4377,112 +4391,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; if(CheckGroupsInViewBusy) - { - CheckGroupsInViewOverRun = true; return; - } + CheckGroupsInViewBusy = true; - do - { - CheckGroupsInViewOverRun = false; - float cullingrange = 64.0f; + float cullingrange = 64.0f; // Vector3 mycamera = Vector3.Zero; - Vector3 mypos = Vector3.Zero; - ScenePresence mysp = (ScenePresence)SceneAgent; - if(mysp != null && !mysp.IsDeleted) - { - cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; + Vector3 mypos = Vector3.Zero; + ScenePresence mysp = (ScenePresence)SceneAgent; + if(mysp != null && !mysp.IsDeleted) + { + cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; // mycamera = mysp.CameraPosition; - mypos = mysp.AbsolutePosition; - } - else - { - CheckGroupsInViewBusy= false; - return; - } + mypos = mysp.AbsolutePosition; + } + else + { + CheckGroupsInViewBusy= false; + return; + } - HashSet NewGroupsInView = new HashSet(); - HashSet GroupsNeedFullUpdate = new HashSet(); - List kills = new List(); - int killedParst = 0; + HashSet NewGroupsInView = new HashSet(); + HashSet GroupsNeedFullUpdate = new HashSet(); + List kills = new List(); - EntityBase[] entities = m_scene.Entities.GetEntities(); - foreach (EntityBase e in entities) - { - if(!IsActive) - return; + EntityBase[] entities = m_scene.Entities.GetEntities(); + foreach (EntityBase e in entities) + { + if(!IsActive) + return; - if (e != null && e is SceneObjectGroup) - { - SceneObjectGroup grp = (SceneObjectGroup)e; - if(grp.IsDeleted || grp.IsAttachment) - continue; + if (e != null && e is SceneObjectGroup) + { + SceneObjectGroup grp = (SceneObjectGroup)e; + if(grp.IsDeleted || grp.IsAttachment) + continue; - float bradius = grp.GetBoundsRadius(); - Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter(); + float bradius = grp.GetBoundsRadius(); + Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter(); // float dcam = (grppos - mycamera).LengthSquared(); - float dpos = (grppos - mypos).LengthSquared(); + float dpos = (grppos - mypos).LengthSquared(); // if(dcam < dpos) // dpos = dcam; - dpos = (float)Math.Sqrt(dpos) - bradius; + dpos = (float)Math.Sqrt(dpos) - bradius; - bool inview; - lock(GroupsInView) - inview = GroupsInView.Contains(grp); - - if(dpos > cullingrange) - { - if(inview) - { - kills.Add(grp.LocalId); - killedParst += grp.PrimCount; + bool inview; + lock(GroupsInView) + inview = GroupsInView.Contains(grp); - if (killedParst > 199 ) - { - SendKillObject(kills); - kills.Clear(); - killedParst = 0; - Thread.Sleep(50); - if(mysp != null && !mysp.IsDeleted) - { - cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; -// mycamera = mysp.CameraPosition; - mypos = mysp.AbsolutePosition; - } - else - { - CheckGroupsInViewBusy= false; - return; - } - } - } - } - else - { - if(!inview) - GroupsNeedFullUpdate.Add(grp); - NewGroupsInView.Add(grp); - } + if(dpos > cullingrange) + { + if(inview) + kills.Add(grp); + } + else + { + if(!inview) + GroupsNeedFullUpdate.Add(grp); + NewGroupsInView.Add(grp); } } + } - lock(GroupsInView) - GroupsInView = NewGroupsInView; + lock(GroupsInView) + GroupsInView = NewGroupsInView; - if (kills.Count > 0) + if (kills.Count > 0) + { + foreach(SceneObjectGroup grp in kills) { - SendKillObject(kills); - kills.Clear(); + foreach(SceneObjectPart p in grp.Parts) + SendEntityUpdate(p,PrimUpdateFlags.Kill); } + kills.Clear(); + } - if(GroupsNeedFullUpdate.Count > 0) + if(GroupsNeedFullUpdate.Count > 0) + { + foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) { - foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) - grp.ScheduleGroupForFullUpdate(); + foreach(SceneObjectPart p in grp.Parts) + SendEntityUpdate(p,PrimUpdateFlags.CancelKill); } - } while(CheckGroupsInViewOverRun); + } CheckGroupsInViewBusy = false; } @@ -4670,13 +4662,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(pack, ThrottleOutPacketType.Task); } - private class ObjectPropertyUpdate : IEntityUpdate + private class ObjectPropertyUpdate : EntityUpdate { internal bool SendFamilyProps; internal bool SendObjectProps; public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj) - : base(entity,flags) + : base(entity,(PrimUpdateFlags)flags) { SendFamilyProps = sendfam; SendObjectProps = sendobj; @@ -4745,7 +4737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OpenSim.Framework.Lazy> propertyUpdates = new OpenSim.Framework.Lazy>(); - IEntityUpdate iupdate; + EntityUpdate iupdate; Int32 timeinqueue; // this is just debugging code & can be dropped later int updatesThisCall = 0; @@ -4849,11 +4841,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt); } - private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags) + private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, PrimUpdateFlags requestFlags) { ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); - block.RequestFlags = requestFlags; + block.RequestFlags = (uint)requestFlags; block.ObjectID = sop.UUID; if (sop.OwnerID == sop.GroupID) block.OwnerID = UUID.Zero; -- cgit v1.1 From c255c23981a3023e3587a71872bbaeb6fcd62093 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 7 Aug 2016 17:07:09 +0100 Subject: move updates from updates queues into udp queues acording to their payload estimated size and udp sending capability on a time slice, instead always moving a arbitrary number of updates. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 81 ++++++++++++---------- 1 file changed, 45 insertions(+), 36 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index b823abe..6beb9b4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3982,7 +3982,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ResendPrimUpdate(update); } - private void ProcessEntityUpdates(int maxUpdates) + private void ProcessEntityUpdates(int maxUpdatesBytes) { OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>(); OpenSim.Framework.Lazy> compressedUpdateBlocks = new OpenSim.Framework.Lazy>(); @@ -3996,16 +3996,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Check to see if this is a flush - if (maxUpdates <= 0) + if (maxUpdatesBytes <= 0) { - maxUpdates = Int32.MaxValue; + maxUpdatesBytes = Int32.MaxValue; } - int updatesThisCall = 0; - - // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race - // condition where a kill can be processed before an out-of-date update for the same object. -// float avgTimeDilation = 0.0f; EntityUpdate update; Int32 timeinqueue; // this is just debugging code & can be dropped later @@ -4018,25 +4013,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP ScenePresence mysp = (ScenePresence)SceneAgent; if(mysp != null && !mysp.IsDeleted) { - cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance +16f; + cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; // mycamera = mysp.CameraPosition; mypos = mysp.AbsolutePosition; } else doCulling = false; - while (updatesThisCall < maxUpdates) + while (maxUpdatesBytes > 0) { lock (m_entityUpdates.SyncRoot) if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) break; -// avgTimeDilation += update.TimeDilation; PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; if(updateFlags.HasFlag(PrimUpdateFlags.Kill)) { m_killRecord.Add(update.Entity.LocalId); + maxUpdatesBytes -= 30; continue; } @@ -4158,8 +4153,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP continue; } - ++updatesThisCall; - #region UpdateFlags to packet type conversion bool canUseCompressed = true; @@ -4212,30 +4205,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP // TODO: Remove this once we can build compressed updates canUseCompressed = false; - + if (!canUseImproved && !canUseCompressed) { if (update.Entity is ScenePresence) { - objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); + ObjectUpdatePacket.ObjectDataBlock ablock = + CreateAvatarUpdateBlock((ScenePresence)update.Entity); + objectUpdateBlocks.Value.Add(ablock); + maxUpdatesBytes -= ablock.Length; } else { - objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); + ObjectUpdatePacket.ObjectDataBlock ablock = + CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); + objectUpdateBlocks.Value.Add(ablock); + maxUpdatesBytes -= ablock.Length; } } else if (!canUseImproved) { - compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); + ObjectUpdateCompressedPacket.ObjectDataBlock ablock = + CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags); + compressedUpdateBlocks.Value.Add(ablock); + maxUpdatesBytes -= ablock.Length; } else { if (update.Entity is ScenePresence) + { // ALL presence updates go into a special list - terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); + ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock = + CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); + terseAgentUpdateBlocks.Value.Add(ablock); + maxUpdatesBytes -= ablock.Length; + } else + { // Everything else goes here - terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); + ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock = + CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); + terseUpdateBlocks.Value.Add(ablock); + maxUpdatesBytes -= ablock.Length; + } } #endregion Block Construction @@ -4504,8 +4516,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // of updates converted to packets. Since we don't want packets // to sit in the queue with old data, only convert enough updates // to packets that can be sent in 200ms. - private Int32 m_LastQueueFill = 0; - private Int32 m_maxUpdates = 0; +// private Int32 m_LastQueueFill = 0; +// private Int32 m_maxUpdates = 0; void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) { @@ -4516,7 +4528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // if (!m_udpServer.IsRunningOutbound) // return; - +/* if (m_maxUpdates == 0 || m_LastQueueFill == 0) { m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; @@ -4530,17 +4542,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP } m_maxUpdates = Util.Clamp(m_maxUpdates,10,500); m_LastQueueFill = Util.EnvironmentTickCount(); - +*/ + int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30); + if (m_entityUpdates.Count > 0) - ProcessEntityUpdates(m_maxUpdates); + ProcessEntityUpdates(maxUpdateBytes); if (m_entityProps.Count > 0) - ProcessEntityPropertyRequests(m_maxUpdates); + ProcessEntityPropertyRequests(maxUpdateBytes); } if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); - } + } internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories) { @@ -4723,7 +4737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); } - private void ProcessEntityPropertyRequests(int maxUpdates) + private void ProcessEntityPropertyRequests(int maxUpdateBytes) { OpenSim.Framework.Lazy> objectFamilyBlocks = new OpenSim.Framework.Lazy>(); @@ -4740,8 +4754,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP EntityUpdate iupdate; Int32 timeinqueue; // this is just debugging code & can be dropped later - int updatesThisCall = 0; - while (updatesThisCall < m_maxUpdates) + while (maxUpdateBytes > 0) { lock (m_entityProps.SyncRoot) if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) @@ -4756,6 +4769,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); objectFamilyBlocks.Value.Add(objPropDB); familyUpdates.Value.Add(update); + maxUpdateBytes -= objPropDB.Length; } } @@ -4767,16 +4781,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); objectPropertiesBlocks.Value.Add(objPropDB); propertyUpdates.Value.Add(update); + maxUpdateBytes -= objPropDB.Length; } } - - updatesThisCall++; } - - - // Int32 ppcnt = 0; - // Int32 pbcnt = 0; - + if (objectPropertiesBlocks.IsValueCreated) { List blocks = objectPropertiesBlocks.Value; -- cgit v1.1 From c04792142f332b7d1e892eb739b7e0b70b3bd0e7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 12 Aug 2016 03:58:04 +0100 Subject: partially revert commit 42a9afdc43cc.. of 06-12 not allowing more updates to be enqueued on deleted objects. Keep the catch up on deenqueue, so preserving the race condition safe guard. Let Scene sendkillObject work even if object is flaged as deleted. Still not clear how this are related to mantis 7858 or even less to 7990. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6beb9b4..24d92f2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4007,7 +4007,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP bool doCulling = m_scene.ObjectsCullingByDistance; float cullingrange = 64.0f; HashSet GroupsNeedFullUpdate = new HashSet(); - List kills = new List(); // Vector3 mycamera = Vector3.Zero; Vector3 mypos = Vector3.Zero; ScenePresence mysp = (ScenePresence)SceneAgent; @@ -4048,7 +4047,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Instead send another kill object, because the first one may have gotten // into a race condition if (!m_killRecord.Contains(grp.LocalId)) + { m_killRecord.Add(grp.LocalId); + maxUpdatesBytes -= 30; + } continue; } @@ -4336,16 +4338,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_killRecord.Clear(); } - if (kills.Count > 0) - { - foreach(SceneObjectGroup grp in kills) - { - foreach(SceneObjectPart p in grp.Parts) - SendEntityUpdate(p,PrimUpdateFlags.Kill); - } - kills.Clear(); - } - if(GroupsNeedFullUpdate.Count > 0) { foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) -- cgit v1.1 From 9080aaf9eba71293929627659b83ee77ee4f5d26 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 12 Aug 2016 04:08:19 +0100 Subject: only reissue a kill if a update is for a deleted sog root part. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 24d92f2..2c2bcea 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1711,11 +1711,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendKillObject(List localIDs) { - // think we do need this // foreach (uint id in localIDs) // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); - // remove pending entities + // remove pending entities to reduce looping chances. lock (m_entityProps.SyncRoot) m_entityProps.Remove(localIDs); lock (m_entityUpdates.SyncRoot) @@ -4046,7 +4045,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Don't send updates for objects that have been marked deleted. // Instead send another kill object, because the first one may have gotten // into a race condition - if (!m_killRecord.Contains(grp.LocalId)) + if (part == grp.RootPart && !m_killRecord.Contains(grp.LocalId)) { m_killRecord.Add(grp.LocalId); maxUpdatesBytes -= 30; -- cgit v1.1 From 09832edadf91e02edbc3e5238aad12ec10998391 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 12 Aug 2016 18:47:01 +0100 Subject: avoid automatic packet spliting in GroupMembersReply --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 2c2bcea..6275f19 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4462,12 +4462,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (kills.Count > 0) { + List partIDs = new List(); foreach(SceneObjectGroup grp in kills) { + SendEntityUpdate(grp.RootPart,PrimUpdateFlags.Kill); foreach(SceneObjectPart p in grp.Parts) - SendEntityUpdate(p,PrimUpdateFlags.Kill); + { + if(p != grp.RootPart) + partIDs.Add(p.LocalId); + } } kills.Clear(); + if(partIDs.Count > 0) + { + lock (m_entityProps.SyncRoot) + m_entityProps.Remove(partIDs); + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Remove(partIDs); + } } if(GroupsNeedFullUpdate.Count > 0) @@ -11409,12 +11421,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_GroupsModule.GroupMembersRequest(this, groupMembersRequestPacket.GroupData.GroupID); int memberCount = members.Count; - - while (true) + int indx = 0; + while (indx < memberCount) { - int blockCount = members.Count; - if (blockCount > 40) - blockCount = 40; + int blockCount = memberCount - indx; + if (blockCount > 25) + blockCount = 25; GroupMembersReplyPacket groupMembersReply = (GroupMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupMembersReply); @@ -11435,8 +11447,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < blockCount; i++) { - GroupMembersData m = members[0]; - members.RemoveAt(0); + GroupMembersData m = members[indx++]; groupMembersReply.MemberData[i] = new GroupMembersReplyPacket.MemberDataBlock(); @@ -11454,8 +11465,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m.IsOwner; } OutPacket(groupMembersReply, ThrottleOutPacketType.Task); - if (members.Count == 0) - return true; } } return true; -- cgit v1.1 From ac542715f1712eaba298a0a8e42c3ce9b0c7f24a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 18 Aug 2016 12:45:11 +0100 Subject: add caps HomeLocation ; add client SendAlertMessage(string message, string info), where info in info message field. only minimal testing done --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6275f19..f580e5a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2411,6 +2411,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(alertPack, ThrottleOutPacketType.Task); } + public void SendAlertMessage(string message, string info) + { + AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); + alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); + alertPack.AlertData.Message = Util.StringToBytes256(message); + alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[1]; + alertPack.AlertInfo[0] = new AlertMessagePacket.AlertInfoBlock(); + alertPack.AlertInfo[0].Message = Util.StringToBytes256(info); + alertPack.AlertInfo[0].ExtraParams = new Byte[0]; + OutPacket(alertPack, ThrottleOutPacketType.Task); + } + /// /// Send an agent alert message to the client. /// -- cgit v1.1