aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs78
1 files changed, 51 insertions, 27 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index ae93e11..b355c89 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -71,8 +71,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
71 private Timer m_clientPingTimer; 71 private Timer m_clientPingTimer;
72 72
73 private Timer m_avatarTerseUpdateTimer; 73 private Timer m_avatarTerseUpdateTimer;
74 private Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 74 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
75 private ushort m_terseTimeDilationLast = 0;
76 75
77 private Timer m_primTerseUpdateTimer; 76 private Timer m_primTerseUpdateTimer;
78 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 77 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
@@ -2770,39 +2769,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2770 } 2769 }
2771 2770
2772 /// <summary> 2771 /// <summary>
2773 /// Send a terse positional/rotation/velocity update about an avatar to the client. This avatar can be that of 2772 /// Send a terse positional/rotation/velocity update about an avatar
2774 /// the client itself. 2773 /// to the client. This avatar can be that of the client itself.
2775 /// </summary> 2774 /// </summary>
2776 public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 2775 public virtual void SendAvatarTerseUpdate(ulong regionHandle,
2777 Vector3 velocity, Quaternion rotation, UUID agentid) 2776 ushort timeDilation, uint localID, Vector3 position,
2777 Vector3 velocity, Quaternion rotation, UUID agentid)
2778 { 2778 {
2779 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) 2779 if (rotation.X == rotation.Y &&
2780 rotation.Y == rotation.Z &&
2781 rotation.Z == rotation.W && rotation.W == 0)
2780 rotation = Quaternion.Identity; 2782 rotation = Quaternion.Identity;
2781 2783
2782 //m_log.DebugFormat("[CLIENT]: Sending rotation {0} for {1} to {2}", rotation, localID, Name);
2783
2784 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = 2784 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
2785 CreateAvatarImprovedBlock(localID, position, velocity, rotation); 2785 CreateAvatarImprovedBlock(localID, position, velocity,rotation);
2786 2786
2787 bool sendpacketnow = false;
2788 lock (m_avatarTerseUpdates) 2787 lock (m_avatarTerseUpdates)
2789 { 2788 {
2790 // Only one update per avatar per packet. No need to send old ones so just overwrite them. 2789 m_avatarTerseUpdates.Add(terseBlock);
2791 m_avatarTerseUpdates[localID] = terseBlock;
2792 m_terseTimeDilationLast = timeDilation;
2793 2790
2794 // If packet is full or own movement packet, send it. 2791 // If packet is full or own movement packet, send it.
2795 if (agentid == m_agentId || m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket) 2792 if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket)
2796 { 2793 {
2797 m_avatarTerseUpdateTimer.Stop(); 2794 ProcessAvatarTerseUpdates(this, null);
2798 sendpacketnow = true;
2799 } 2795 }
2800 else if (m_avatarTerseUpdates.Count == 1) 2796 else if (m_avatarTerseUpdates.Count == 1)
2797 {
2801 m_avatarTerseUpdateTimer.Start(); 2798 m_avatarTerseUpdateTimer.Start();
2799 }
2802 } 2800 }
2803 // Call ProcessAvatarTerseUpdates outside the lock
2804 if (sendpacketnow)
2805 ProcessAvatarTerseUpdates(this, null);
2806 } 2801 }
2807 2802
2808 private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) 2803 private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e)
@@ -2810,22 +2805,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2810 lock (m_avatarTerseUpdates) 2805 lock (m_avatarTerseUpdates)
2811 { 2806 {
2812 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 2807 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
2808
2809 terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
2810
2813 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 2811 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
2814 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[m_avatarTerseUpdates.Count]; 2812 terse.RegionData.TimeDilation =
2813 (ushort)(Scene.TimeDilation * ushort.MaxValue);
2815 2814
2816 int i = 0; 2815 int max = m_avatarTerseUpdatesPerPacket;
2817 foreach (KeyValuePair<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> dbe in m_avatarTerseUpdates) 2816 if (max > m_avatarTerseUpdates.Count)
2817 max = m_avatarTerseUpdates.Count;
2818
2819 int count = 0;
2820 int size = 0;
2821
2822 byte[] zerobuffer = new byte[1024];
2823 byte[] blockbuffer = new byte[1024];
2824
2825 for (count = 0 ; count < max ; count++)
2818 { 2826 {
2819 terse.ObjectData[i] = dbe.Value; 2827 int length = 0;
2820 i++; 2828 m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length);
2829 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
2830 if (size + length > m_packetMTU)
2831 break;
2832 size += length;
2833 }
2834
2835 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
2836
2837 for (int i = 0 ; i < count ; i++)
2838 {
2839 terse.ObjectData[i] = m_avatarTerseUpdates[0];
2840 m_avatarTerseUpdates.RemoveAt(0);
2821 } 2841 }
2822 terse.RegionData.TimeDilation = m_terseTimeDilationLast;
2823 2842
2824 terse.Header.Reliable = false; 2843 terse.Header.Reliable = false;
2825 terse.Header.Zerocoded = true; 2844 terse.Header.Zerocoded = true;
2826 OutPacket(terse, ThrottleOutPacketType.Task); 2845 OutPacket(terse, ThrottleOutPacketType.Task);
2827 2846
2828 m_avatarTerseUpdates.Clear(); 2847 if (m_avatarTerseUpdates.Count == 0)
2848 m_avatarTerseUpdateTimer.Stop();
2829 } 2849 }
2830 } 2850 }
2831 2851
@@ -3151,6 +3171,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3151 { 3171 {
3152 ProcessPrimTerseUpdates(this, null); 3172 ProcessPrimTerseUpdates(this, null);
3153 } 3173 }
3174 while (m_avatarTerseUpdates.Count > 0)
3175 {
3176 ProcessAvatarTerseUpdates(this, null);
3177 }
3154 } 3178 }
3155 3179
3156 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 3180 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)