aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs75
1 files changed, 63 insertions, 12 deletions
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 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Net; 31using System.Net;
31using System.Reflection; 32using System.Reflection;
@@ -68,6 +69,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
68 private int m_cachedTextureSerial; 69 private int m_cachedTextureSerial;
69 private Timer m_clientPingTimer; 70 private Timer m_clientPingTimer;
70 71
72 private Timer m_terseUpdateTimer;
73 private Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_terseUpdates = new Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
74 private ushort m_terseTimeDilationLast = 0;
75
71 private bool m_clientBlocked; 76 private bool m_clientBlocked;
72 77
73 private int m_probesWithNoIngressPackets; 78 private int m_probesWithNoIngressPackets;
@@ -116,6 +121,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
116 protected string m_activeGroupName = String.Empty; 121 protected string m_activeGroupName = String.Empty;
117 protected ulong m_activeGroupPowers; 122 protected ulong m_activeGroupPowers;
118 protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>(); 123 protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>();
124 protected int m_terseUpdateRate = 50;
125 protected int m_terseUpdatesPerPacket = 5;
119 126
120 // LLClientView Only 127 // LLClientView Only
121 public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); 128 public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args);
@@ -521,7 +528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 528
522 // Shut down timers 529 // Shut down timers
523 m_clientPingTimer.Stop(); 530 m_clientPingTimer.Stop();
524 531 m_terseUpdateTimer.Stop();
525 532
526 // This is just to give the client a reasonable chance of 533 // This is just to give the client a reasonable chance of
527 // flushing out all it's packets. There should probably 534 // flushing out all it's packets. There should probably
@@ -602,6 +609,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
602 { 609 {
603 // Shut down timers 610 // Shut down timers
604 m_clientPingTimer.Stop(); 611 m_clientPingTimer.Stop();
612 m_terseUpdateTimer.Stop();
605 } 613 }
606 614
607 public void Restart() 615 public void Restart()
@@ -612,6 +620,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
612 m_clientPingTimer = new Timer(5000); 620 m_clientPingTimer = new Timer(5000);
613 m_clientPingTimer.Elapsed += CheckClientConnectivity; 621 m_clientPingTimer.Elapsed += CheckClientConnectivity;
614 m_clientPingTimer.Enabled = true; 622 m_clientPingTimer.Enabled = true;
623
624 m_terseUpdateTimer = new Timer(m_terseUpdateRate);
625 m_terseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates);
626 m_terseUpdateTimer.AutoReset = false;
615 } 627 }
616 628
617 public void Terminate() 629 public void Terminate()
@@ -833,6 +845,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
833 m_clientPingTimer.Elapsed += CheckClientConnectivity; 845 m_clientPingTimer.Elapsed += CheckClientConnectivity;
834 m_clientPingTimer.Enabled = true; 846 m_clientPingTimer.Enabled = true;
835 847
848 m_terseUpdateTimer = new Timer(m_terseUpdateRate);
849 m_terseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates);
850 m_terseUpdateTimer.AutoReset = false;
851
836 m_scene.AddNewClient(this); 852 m_scene.AddNewClient(this);
837 853
838 RefreshGroupMembership(); 854 RefreshGroupMembership();
@@ -2696,8 +2712,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2696 /// Send a terse positional/rotation/velocity update about an avatar to the client. This avatar can be that of 2712 /// Send a terse positional/rotation/velocity update about an avatar to the client. This avatar can be that of
2697 /// the client itself. 2713 /// the client itself.
2698 /// </summary> 2714 /// </summary>
2699 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 2715 public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
2700 Vector3 velocity, Quaternion rotation) 2716 Vector3 velocity, Quaternion rotation, UUID agentid)
2701 { 2717 {
2702 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) 2718 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
2703 rotation = Quaternion.Identity; 2719 rotation = Quaternion.Identity;
@@ -2706,17 +2722,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2706 2722
2707 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = 2723 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
2708 CreateAvatarImprovedBlock(localID, position, velocity, rotation); 2724 CreateAvatarImprovedBlock(localID, position, velocity, rotation);
2709 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 2725
2710 // TODO: don't create new blocks if recycling an old packet 2726 bool sendpacketnow = false;
2711 terse.RegionData.RegionHandle = regionHandle; 2727 lock (m_terseUpdates)
2712 terse.RegionData.TimeDilation = timeDilation; 2728 {
2713 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; 2729 // Only one update per avatar per packet. No need to send old ones so just overwrite them.
2714 terse.ObjectData[0] = terseBlock; 2730 m_terseUpdates[localID] = terseBlock;
2731 m_terseTimeDilationLast = timeDilation;
2715 2732
2716 terse.Header.Reliable = false; 2733 // If packet is full or own movement packet, send it.
2717 terse.Header.Zerocoded = true; 2734 if (agentid == m_agentId || m_terseUpdates.Count >= m_terseUpdatesPerPacket)
2735 {
2736 m_terseUpdateTimer.Stop();
2737 sendpacketnow = true;
2738 }
2739 else if (m_terseUpdates.Count == 1)
2740 m_terseUpdateTimer.Start();
2741 }
2742 // Call ProcessAvatarTerseUpdates outside the lock
2743 if (sendpacketnow)
2744 ProcessAvatarTerseUpdates(this, null);
2745 }
2746
2747 private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e)
2748 {
2749 Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> dataBlocks = null;
2750
2751 lock (m_terseUpdates)
2752 {
2753 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
2754 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
2755 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[dataBlocks.Count];
2718 2756
2719 OutPacket(terse, ThrottleOutPacketType.Task); 2757 int i = 0;
2758 foreach (KeyValuePair<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> dbe in m_terseUpdates)
2759 {
2760 terse.ObjectData[i] = dbe.Value;
2761 i++;
2762 }
2763 terse.RegionData.TimeDilation = m_terseTimeDilationLast;
2764
2765 terse.Header.Reliable = false;
2766 terse.Header.Zerocoded = true;
2767 OutPacket(terse, ThrottleOutPacketType.Task);
2768
2769 m_terseUpdates.Clear();
2770 }
2720 } 2771 }
2721 2772
2722 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 2773 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)