diff options
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 78 |
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) |