diff options
author | Melanie Thielker | 2009-04-30 11:58:23 +0000 |
---|---|---|
committer | Melanie Thielker | 2009-04-30 11:58:23 +0000 |
commit | 334738fca96498f31842f42db974bc46da35d94a (patch) | |
tree | 95c8cc63ca624989f0dcb9cb1cffc9907c6fd3a6 /OpenSim/Region/ClientStack | |
parent | Thank you kindly, MCortez for a patch that: (diff) | |
download | opensim-SC_OLD-334738fca96498f31842f42db974bc46da35d94a.zip opensim-SC_OLD-334738fca96498f31842f42db974bc46da35d94a.tar.gz opensim-SC_OLD-334738fca96498f31842f42db974bc46da35d94a.tar.bz2 opensim-SC_OLD-334738fca96498f31842f42db974bc46da35d94a.tar.xz |
Thank you, mpallari, for a patch that increses efficiency by combining
avatar updates into a single packet.
Applied with changes.
Fixes Mantis #3136
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 75 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using System.Net; | 31 | using System.Net; |
31 | using System.Reflection; | 32 | using 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) |