From 334738fca96498f31842f42db974bc46da35d94a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 30 Apr 2009 11:58:23 +0000 Subject: Thank you, mpallari, for a patch that increses efficiency by combining avatar updates into a single packet. Applied with changes. Fixes Mantis #3136 --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 2 +- .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 2 +- OpenSim/Framework/IClientAPI.cs | 2 +- .../Region/ClientStack/LindenUDP/LLClientView.cs | 75 ++++++++++++++++++---- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- OpenSim/Tests/Common/Mock/TestClient.cs | 2 +- 8 files changed, 70 insertions(+), 19 deletions(-) diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 52c8072..d8e2711 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -1001,7 +1001,7 @@ namespace OpenSim.Client.MXP.ClientStack MXPSendAvatarData(firstName + " " + lastName, ownerID, UUID.Zero, avatarID, avatarLocalID, position, rotation); } - public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation) + public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID uuid) { MovementEventMessage me = new MovementEventMessage(); me.ObjectIndex = localID; diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 314bbe4..c37bc06 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -558,7 +558,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation) + public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID uuid) { throw new System.NotImplementedException(); } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 2f9f594..32544b9 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -871,7 +871,7 @@ namespace OpenSim.Framework Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation); void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, - Vector3 velocity, Quaternion rotation); + Vector3 velocity, Quaternion rotation, UUID agentid); void SendCoarseLocationUpdate(List users, List CoarseLocations); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 48612ab..ada5d10 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Net; using System.Reflection; @@ -68,6 +69,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_cachedTextureSerial; private Timer m_clientPingTimer; + private Timer m_terseUpdateTimer; + private Dictionary m_terseUpdates = new Dictionary(); + private ushort m_terseTimeDilationLast = 0; + private bool m_clientBlocked; private int m_probesWithNoIngressPackets; @@ -116,6 +121,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected string m_activeGroupName = String.Empty; protected ulong m_activeGroupPowers; protected Dictionary m_groupPowers = new Dictionary(); + protected int m_terseUpdateRate = 50; + protected int m_terseUpdatesPerPacket = 5; // LLClientView Only public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); @@ -521,7 +528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Shut down timers m_clientPingTimer.Stop(); - + m_terseUpdateTimer.Stop(); // This is just to give the client a reasonable chance of // flushing out all it's packets. There should probably @@ -602,6 +609,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // Shut down timers m_clientPingTimer.Stop(); + m_terseUpdateTimer.Stop(); } public void Restart() @@ -612,6 +620,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_clientPingTimer = new Timer(5000); m_clientPingTimer.Elapsed += CheckClientConnectivity; m_clientPingTimer.Enabled = true; + + m_terseUpdateTimer = new Timer(m_terseUpdateRate); + m_terseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); + m_terseUpdateTimer.AutoReset = false; } public void Terminate() @@ -833,6 +845,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_clientPingTimer.Elapsed += CheckClientConnectivity; m_clientPingTimer.Enabled = true; + m_terseUpdateTimer = new Timer(m_terseUpdateRate); + m_terseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); + m_terseUpdateTimer.AutoReset = false; + m_scene.AddNewClient(this); RefreshGroupMembership(); @@ -2696,8 +2712,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Send a terse positional/rotation/velocity update about an avatar to the client. This avatar can be that of /// the client itself. /// - public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, - Vector3 velocity, Quaternion rotation) + public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, + Vector3 velocity, Quaternion rotation, UUID agentid) { if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) rotation = Quaternion.Identity; @@ -2706,17 +2722,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateAvatarImprovedBlock(localID, position, velocity, rotation); - ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - // TODO: don't create new blocks if recycling an old packet - terse.RegionData.RegionHandle = regionHandle; - terse.RegionData.TimeDilation = timeDilation; - terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; - terse.ObjectData[0] = terseBlock; + + bool sendpacketnow = false; + lock (m_terseUpdates) + { + // Only one update per avatar per packet. No need to send old ones so just overwrite them. + m_terseUpdates[localID] = terseBlock; + m_terseTimeDilationLast = timeDilation; - terse.Header.Reliable = false; - terse.Header.Zerocoded = true; + // If packet is full or own movement packet, send it. + if (agentid == m_agentId || m_terseUpdates.Count >= m_terseUpdatesPerPacket) + { + m_terseUpdateTimer.Stop(); + sendpacketnow = true; + } + else if (m_terseUpdates.Count == 1) + m_terseUpdateTimer.Start(); + } + // Call ProcessAvatarTerseUpdates outside the lock + if (sendpacketnow) + ProcessAvatarTerseUpdates(this, null); + } + + private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) + { + Dictionary dataBlocks = null; + + lock (m_terseUpdates) + { + ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; + terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[dataBlocks.Count]; - OutPacket(terse, ThrottleOutPacketType.Task); + int i = 0; + foreach (KeyValuePair dbe in m_terseUpdates) + { + terse.ObjectData[i] = dbe.Value; + i++; + } + terse.RegionData.TimeDilation = m_terseTimeDilationLast; + + terse.Header.Reliable = false; + terse.Header.Zerocoded = true; + OutPacket(terse, ThrottleOutPacketType.Task); + + m_terseUpdates.Clear(); + } } public void SendCoarseLocationUpdate(List users, List CoarseLocations) diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 579f09f..036c9a4 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -503,7 +503,7 @@ namespace OpenSim.Region.Examples.SimpleModule } public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, - Vector3 position, Vector3 velocity, Quaternion rotation) + Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) { } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d8ce080..5bfd947 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2367,7 +2367,7 @@ namespace OpenSim.Region.Framework.Scenes Quaternion rot = m_bodyRot; pos.Z -= m_appearance.HipOffset; remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), - new Vector3(vel.X, vel.Y, vel.Z), rot); + new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); m_scene.StatsReporter.AddAgentUpdates(1); diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index abe915c..b20b15b 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -592,7 +592,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC } public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, - Vector3 position, Vector3 velocity, Quaternion rotation) + Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentId) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index a593fe4..39520e7 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -590,7 +590,7 @@ namespace OpenSim.Tests.Common.Mock } public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, - Vector3 position, Vector3 velocity, Quaternion rotation) + Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) { } -- cgit v1.1