From b21b6532b07a7a5b50e62de2f9b074c768a14e74 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Aug 2014 17:48:10 +0100 Subject: sending attachment kills before putting them back doesnt cover all cases and seems heavy for viewers --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 45 +++++++++++------------- 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a0c3ba9..864f54d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1878,7 +1878,6 @@ namespace OpenSim.Region.Framework.Scenes if (!IsChildAgent) { - ValidateAndSendAppearanceAndAgentData(); m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts)); @@ -1900,35 +1899,30 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat( "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); - List kk = new List(); - // Resume scripts this possible should also be moved down after sending the avatar to viewer ? foreach (SceneObjectGroup sog in m_attachments) { - foreach (SceneObjectPart part in sog.Parts) - kk.Add(part.LocalId); - sog.SendFullUpdateToClient(ControllingClient); SendFullUpdateToClient(ControllingClient); - // sog.ScheduleGroupForFullUpdate(); - m_scene.ForEachScenePresence(delegate(ScenePresence p) + if (!sog.HasPrivateAttachmentPoint) { - if (p == this) - return; - if (sog.HasPrivateAttachmentPoint) - return; - if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) - return; - - p.ControllingClient.SendKillObject(kk); - sog.SendFullUpdateToClient(p.ControllingClient); - SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path - }); - + // sog.ScheduleGroupForFullUpdate(); + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p == this) + return; + + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + sog.SendFullUpdateToClient(p.ControllingClient); + SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path + }); + } + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); sog.ResumeScripts(); - kk.Clear(); } } } @@ -4758,6 +4752,9 @@ namespace OpenSim.Region.Framework.Scenes } } + // send attachments to a client without filters except for huds + // for now they are checked in several places down the line... + // kills all parts before sending public void SendAttachmentsToAgentNFPK(ScenePresence p) { lock (m_attachments) @@ -5680,7 +5677,7 @@ namespace OpenSim.Region.Framework.Scenes p.SendAppearanceToAgent(this); if (p.Animator != null) p.Animator.SendAnimPackToClient(ControllingClient); - p.SendAttachmentsToAgentNFPK(this); + p.SendAttachmentsToAgentNF(this); } } } @@ -5995,7 +5992,7 @@ namespace OpenSim.Region.Framework.Scenes SendAppearanceToAgent(p); if (Animator != null) Animator.SendAnimPackToClient(p.ControllingClient); - SendAttachmentsToAgentNFPK(p); + SendAttachmentsToAgentNF(p); } } @@ -6011,7 +6008,7 @@ namespace OpenSim.Region.Framework.Scenes p.SendAppearanceToAgent(this); if (p.Animator != null) p.Animator.SendAnimPackToClient(ControllingClient); - p.SendAttachmentsToAgentNFPK(this); + p.SendAttachmentsToAgentNF(this); } } } -- cgit v1.1 From 16cf3967b4b2929e20f13a5d9ae91dc0e7ac03ef Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Aug 2014 17:54:23 +0100 Subject: Reserve a extra localID for a presence ( it will be localID + 1 ) --- OpenSim/Region/Framework/Scenes/SceneBase.cs | 12 ++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index dd0c828..f5be7a7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -295,6 +295,18 @@ namespace OpenSim.Region.Framework.Scenes return myID; } + + public uint AllocatePresenceLocalId() + { + uint myID; + + _primAllocateMutex.WaitOne(); + myID = ++m_lastAllocatedLocalId; + ++m_lastAllocatedLocalId; + _primAllocateMutex.ReleaseMutex(); + + return myID; + } #region Module Methods diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 864f54d..5ebf3db 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -969,7 +969,7 @@ namespace OpenSim.Region.Framework.Scenes m_name = String.Format("{0} {1}", Firstname, Lastname); m_scene = world; m_uuid = client.AgentId; - LocalId = m_scene.AllocateLocalId(); + LocalId = m_scene.AllocatePresenceLocalId(); UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); if (account != null) -- cgit v1.1 From 542118adf1791075bfb904d805a2c29cf303237e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Aug 2014 18:55:06 +0100 Subject: remove from use the UpdatesResend on resending udp packets. Just resend the UDP packet. Also just loose packets we tried to send 6 times already (ll says 3) A viewer may just beeing ignoring them, or then the link is just dead. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 80 ++++++++++++---------- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 10 +++ 2 files changed, 54 insertions(+), 36 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index b0cb4ea..475cfe2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3838,47 +3838,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); } - /// - /// Requeue an EntityUpdate when it was not acknowledged by the client. - /// We will update the priority and put it in the correct queue, merging update flags - /// with any other updates that may be queued for the same entity. - /// The original update time is used for the merged update. - /// - private void ResendPrimUpdate(EntityUpdate update) - { - // If the update exists in priority queue, it will be updated. - // If it does not exist then it will be added with the current (rather than its original) priority - uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity); + /* dont use this + udp packet resent must be done at udp level only + re map from a packet to original updates just doesnt work - lock (m_entityUpdates.SyncRoot) - m_entityUpdates.Enqueue(priority, update); - } + /// + /// Requeue an EntityUpdate when it was not acknowledged by the client. + /// We will update the priority and put it in the correct queue, merging update flags + /// with any other updates that may be queued for the same entity. + /// The original update time is used for the merged update. + /// + private void ResendPrimUpdate(EntityUpdate update) + { + // If the update exists in priority queue, it will be updated. + // If it does not exist then it will be added with the current (rather than its original) priority + uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity); - /// - /// Requeue a list of EntityUpdates when they were not acknowledged by the client. - /// We will update the priority and put it in the correct queue, merging update flags - /// with any other updates that may be queued for the same entity. - /// The original update time is used for the merged update. - /// - private void ResendPrimUpdates(List updates, OutgoingPacket oPacket) - { - // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber); + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Enqueue(priority, update); + } - // Remove the update packet from the list of packets waiting for acknowledgement - // because we are requeuing the list of updates. They will be resent in new packets - // with the most recent state and priority. - m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); - // Count this as a resent packet since we are going to requeue all of the updates contained in it - Interlocked.Increment(ref m_udpClient.PacketsResent); + /// + /// Requeue a list of EntityUpdates when they were not acknowledged by the client. + /// We will update the priority and put it in the correct queue, merging update flags + /// with any other updates that may be queued for the same entity. + /// The original update time is used for the merged update. + /// + private void ResendPrimUpdates(List updates, OutgoingPacket oPacket) + { + // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber); - // We're not going to worry about interlock yet since its not currently critical that this total count - // is 100% correct - m_udpServer.PacketsResentCount++; + // Remove the update packet from the list of packets waiting for acknowledgement + // because we are requeuing the list of updates. They will be resent in new packets + // with the most recent state and priority. + m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); - foreach (EntityUpdate update in updates) - ResendPrimUpdate(update); - } + // Count this as a resent packet since we are going to requeue all of the updates contained in it + Interlocked.Increment(ref m_udpClient.PacketsResent); + + // We're not going to worry about interlock yet since its not currently critical that this total count + // is 100% correct + m_udpServer.PacketsResentCount++; + + foreach (EntityUpdate update in updates) + ResendPrimUpdate(update); + } + */ // OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>(); // OpenSim.Framework.Lazy> compressedUpdateBlocks = new OpenSim.Framework.Lazy>(); @@ -4197,7 +4203,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; - OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); +// OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); + // use default udp retry + OutPacket(packet, ThrottleOutPacketType.Task, true); } #endregion Packet Sending diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 3b0312d..bf44152 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1207,6 +1207,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed", // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount); + // Bump up the resend count on this packet + Interlocked.Increment(ref outgoingPacket.ResendCount); + + // loose packets we retried more than 6 times + // sl says 3 so lets be more tolerant + // we can't not keep hammering with packets a viewer may just beeing ignoring + + if (outgoingPacket.ResendCount > 6) + return; + // Set the resent flag outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); outgoingPacket.Category = ThrottleOutPacketType.Resend; -- cgit v1.1 From 88587b4e73b240693bd03172d52c4f13b5f47868 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Aug 2014 21:41:16 +0100 Subject: reserve updates priority queue 2 for attachments, send them by it on BestAvatarResp scheme. Attachments cannot be sent on imediate queues, since they will block everything. Changed distance to priority math, keeping identical result, shifted to start at queue 3. --- OpenSim/Framework/PriorityQueue.cs | 4 +++- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs index e4f1111..d6c39a7 100644 --- a/OpenSim/Framework/PriorityQueue.cs +++ b/OpenSim/Framework/PriorityQueue.cs @@ -62,7 +62,9 @@ namespace OpenSim.Framework private uint m_nextQueue = 0; private uint m_countFromQueue = 0; // first queues are imediate, so no counts - private uint[] m_queueCounts = {0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1}; +// private uint[] m_queueCounts = { 0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1 }; + private uint[] m_queueCounts = {0, 0, 8, 8, 5, 4, 3, 2, 1, 1, 1, 1}; + // this is ava, ava, attach, <10m, 20,40,80,160m,320,640,1280, + // next request is a counter of the number of updates queued, it provides // a total ordering on the updates coming through the queue and is more diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 19d2689..c0405ad 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.Framework.Scenes { // Attachments are high priority, if (((SceneObjectPart)entity).ParentGroup.IsAttachment) - return 1; + return 2; pqueue = ComputeDistancePriority(client, entity, false); @@ -233,16 +233,28 @@ namespace OpenSim.Region.Framework.Scenes // And convert the distance to a priority queue, this computation gives queues // at 10, 20, 40, 80, 160, 320, 640, and 1280m - uint pqueue = PriorityQueue.NumberOfImmediateQueues; + uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; - +/* for (int i = 0; i < queues - 1; i++) { if (distance < 30 * Math.Pow(2.0,i)) break; pqueue++; } - +*/ + if (distance > 10f) + { + float tmp = (float)Math.Log((double)distance) * 1.4426950408889634073599246810019f - 3.3219280948873623478703194294894f; + // for a map identical to original: + // now + // 1st constant is 1/(log(2)) (natural log) so we get log2(distance) + // 2st constant makes it be log2(distance/10) + pqueue += (uint)tmp; + if (pqueue > queues - 1) + pqueue = queues - 1; + } + // If this is a root agent, then determine front & back // Bump up the priority queue (drop the priority) for any objects behind the avatar if (useFrontBack && ! presence.IsChildAgent) -- cgit v1.1 From ea1c232f92549d0282532779169ebf4b1811d0c4 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Aug 2014 00:08:43 +0100 Subject: revert droping udp packet resends after 6 retries, keep resending. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index bf44152..3b0312d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1207,16 +1207,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed", // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount); - // Bump up the resend count on this packet - Interlocked.Increment(ref outgoingPacket.ResendCount); - - // loose packets we retried more than 6 times - // sl says 3 so lets be more tolerant - // we can't not keep hammering with packets a viewer may just beeing ignoring - - if (outgoingPacket.ResendCount > 6) - return; - // Set the resent flag outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); outgoingPacket.Category = ThrottleOutPacketType.Resend; -- cgit v1.1 From 5bf145a3977a55c474106bbe2a6c107dd9457f0d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Aug 2014 00:49:10 +0100 Subject: add a direct sendpartfullUpdate to send a full object update to a part, optionally overriding its parentID. check what it does to attachments --- OpenSim/Framework/IClientAPI.cs | 2 ++ .../Region/ClientStack/Linden/UDP/LLClientView.cs | 26 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++++ .../Server/IRCClientView.cs | 3 +++ .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 ++++ OpenSim/Tests/Common/Mock/TestClient.cs | 4 ++++ 6 files changed, 43 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 3b0430b..d73802e 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1116,6 +1116,8 @@ namespace OpenSim.Framework /// void SendKillObject(List localID); + void SendPartFullUpdate(ISceneEntity ent, uint? parentID); + void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 475cfe2..06f1301 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4208,9 +4208,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task, true); } + + #endregion Packet Sending + } + // hack.. dont use + public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) + { + if (ent is SceneObjectPart) + { + SceneObjectPart part = (SceneObjectPart)ent; + ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + packet.RegionData.TimeDilation = 1; + packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; + + ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId); + if (parentID.HasValue) + { + blk.ParentID = parentID.Value; + } + + packet.ObjectData[0] = blk; + + OutPacket(packet, ThrottleOutPacketType.Task, true); + } + } + public void ReprioritizeUpdates() { lock (m_entityUpdates.SyncRoot) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5ebf3db..73283ed 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1916,6 +1916,7 @@ namespace OpenSim.Region.Framework.Scenes if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) return; + p.ControllingClient.SendPartFullUpdate(sog.RootPart,LocalId + 1); sog.SendFullUpdateToClient(p.ControllingClient); SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path }); @@ -4746,7 +4747,10 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectGroup sog in m_attachments) { if (p == this || !sog.HasPrivateAttachmentPoint) + { + p.ControllingClient.SendPartFullUpdate(sog.RootPart, LocalId + 1); sog.SendFullUpdateToClient(p.ControllingClient); + } } SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index f35ea92..2112b71 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1702,5 +1702,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server { } + public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) + { + } } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 7002d75..fa1d38a 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -1272,5 +1272,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) + { + } + } } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index f3eaed3..2758030 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -536,6 +536,10 @@ namespace OpenSim.Tests.Common.Mock ReceivedKills.AddRange(localID); } + public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) + { + } + public virtual void SetChildAgentThrottle(byte[] throttle) { } -- cgit v1.1