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.cs93
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs27
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs107
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs4
4 files changed, 170 insertions, 61 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 4780701..e7ce2e0 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -792,16 +792,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
792 } 792 }
793 } 793 }
794 794
795 public void SendGenericMessage(string method, List<string> message) 795 public void SendGenericMessage(string method, List<byte[]> message)
796 { 796 {
797 GenericMessagePacket gmp = new GenericMessagePacket(); 797 GenericMessagePacket gmp = new GenericMessagePacket();
798 gmp.MethodData.Method = Util.StringToBytes256(method); 798 gmp.MethodData.Method = Util.StringToBytes256(method);
799 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 799 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
800 int i = 0; 800 int i = 0;
801 foreach (string val in message) 801 foreach (byte[] val in message)
802 { 802 {
803 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); 803 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
804 gmp.ParamList[i++].Parameter = Util.StringToBytes256(val); 804 gmp.ParamList[i++].Parameter = val;
805 } 805 }
806 OutPacket(gmp, ThrottleOutPacketType.Task); 806 OutPacket(gmp, ThrottleOutPacketType.Task);
807 } 807 }
@@ -813,6 +813,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
813 public virtual void SendLayerData(float[] map) 813 public virtual void SendLayerData(float[] map)
814 { 814 {
815 Util.FireAndForget(DoSendLayerData, map); 815 Util.FireAndForget(DoSendLayerData, map);
816
817 // Send it sync, and async. It's not that much data
818 // and it improves user experience just so much!
819 DoSendLayerData(map);
816 } 820 }
817 821
818 /// <summary> 822 /// <summary>
@@ -825,16 +829,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
825 829
826 try 830 try
827 { 831 {
828 //for (int y = 0; y < 16; y++) 832 for (int y = 0; y < 16; y++)
829 //{ 833 {
830 // for (int x = 0; x < 16; x++) 834 for (int x = 0; x < 16; x+=4)
831 // { 835 {
832 // SendLayerData(x, y, map); 836 SendLayerPacket(x, y, map);
833 // } 837 }
834 //} 838 }
835
836 // Send LayerData in a spiral pattern. Fun!
837 SendLayerTopRight(map, 0, 0, 15, 15);
838 } 839 }
839 catch (Exception e) 840 catch (Exception e)
840 { 841 {
@@ -842,51 +843,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
842 } 843 }
843 } 844 }
844 845
845 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
846 {
847 // Row
848 for (int i = x1; i <= x2; i++)
849 SendLayerData(i, y1, map);
850
851 // Column
852 for (int j = y1 + 1; j <= y2; j++)
853 SendLayerData(x2, j, map);
854
855 if (x2 - x1 > 0)
856 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
857 }
858
859 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
860 {
861 // Row in reverse
862 for (int i = x2; i >= x1; i--)
863 SendLayerData(i, y2, map);
864
865 // Column in reverse
866 for (int j = y2 - 1; j >= y1; j--)
867 SendLayerData(x1, j, map);
868
869 if (x2 - x1 > 0)
870 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
871 }
872
873 /// <summary> 846 /// <summary>
874 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 847 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
875 /// </summary> 848 /// </summary>
876 /// <param name="map">heightmap</param> 849 /// <param name="map">heightmap</param>
877 /// <param name="px">X coordinate for patches 0..12</param> 850 /// <param name="px">X coordinate for patches 0..12</param>
878 /// <param name="py">Y coordinate for patches 0..15</param> 851 /// <param name="py">Y coordinate for patches 0..15</param>
879 // private void SendLayerPacket(float[] map, int y, int x) 852 private void SendLayerPacket(int x, int y, float[] map)
880 // { 853 {
881 // int[] patches = new int[4]; 854 int[] patches = new int[4];
882 // patches[0] = x + 0 + y * 16; 855 patches[0] = x + 0 + y * 16;
883 // patches[1] = x + 1 + y * 16; 856 patches[1] = x + 1 + y * 16;
884 // patches[2] = x + 2 + y * 16; 857 patches[2] = x + 2 + y * 16;
885 // patches[3] = x + 3 + y * 16; 858 patches[3] = x + 3 + y * 16;
886 859
887 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 860 float[] heightmap = (map.Length == 65536) ?
888 // OutPacket(layerpack, ThrottleOutPacketType.Land); 861 map :
889 // } 862 LLHeightFieldMoronize(map);
863
864 try
865 {
866 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
867 OutPacket(layerpack, ThrottleOutPacketType.Land);
868 }
869 catch
870 {
871 for (int px = x ; px < x + 4 ; px++)
872 SendLayerData(px, y, map);
873 }
874 }
890 875
891 /// <summary> 876 /// <summary>
892 /// Sends a specified patch to a client 877 /// Sends a specified patch to a client
@@ -3164,7 +3149,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3164 3149
3165 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3150 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3166 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3151 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3167
3168 OutPacket(objupdate, ThrottleOutPacketType.Task); 3152 OutPacket(objupdate, ThrottleOutPacketType.Task);
3169 } 3153 }
3170 3154
@@ -3215,8 +3199,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3215 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3199 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3216 } 3200 }
3217 3201
3218 // HACK: Using the task category until the tiered reprioritization code is in 3202 OutPacket(terse, ThrottleOutPacketType.State);
3219 OutPacket(terse, ThrottleOutPacketType.Task);
3220 } 3203 }
3221 3204
3222 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3205 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 3c4fa72..4d9f58f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -402,6 +402,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
402 #region Queue or Send 402 #region Queue or Send
403 403
404 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); 404 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
405 outgoingPacket.Type = type;
405 406
406 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 407 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
407 SendPacketFinal(outgoingPacket); 408 SendPacketFinal(outgoingPacket);
@@ -513,6 +514,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 byte flags = buffer.Data[0]; 514 byte flags = buffer.Data[0];
514 bool isResend = (flags & Helpers.MSG_RESENT) != 0; 515 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
515 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 516 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
517 bool sendSynchronous = false;
516 LLUDPClient udpClient = outgoingPacket.Client; 518 LLUDPClient udpClient = outgoingPacket.Client;
517 519
518 if (!udpClient.IsConnected) 520 if (!udpClient.IsConnected)
@@ -568,9 +570,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
568 if (isReliable) 570 if (isReliable)
569 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); 571 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength);
570 572
571 // Put the UDP payload on the wire 573 //Some packet types need to be sent synchonously.
572 AsyncBeginSend(buffer); 574 //Sorry, i know it's not optimal, but until the LL client
575 //manages packets correctly and re-orders them as required, this is necessary.
573 576
577
578 // Put the UDP payload on the wire
579 if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate)
580 {
581 SyncBeginPrioritySend(buffer, 2); // highest priority
582 }
583 else if (outgoingPacket.Type == PacketType.ObjectUpdate
584 || outgoingPacket.Type == PacketType.LayerData)
585 {
586 SyncBeginPrioritySend(buffer, 1); // medium priority
587 }
588 else
589 {
590 SyncBeginPrioritySend(buffer, 0); // normal priority
591 }
592
593 //AsyncBeginSend(buffer);
594
574 // Keep track of when this packet was sent out (right now) 595 // Keep track of when this packet was sent out (right now)
575 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 596 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
576 } 597 }
@@ -851,7 +872,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
851 872
852 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); 873 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
853 874
854 AsyncBeginSend(buffer); 875 SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends
855 } 876 }
856 877
857 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) 878 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index d2779ba..de2cd24 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -29,6 +29,7 @@ using System;
29using System.Net; 29using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using System.Collections.Generic;
32using log4net; 33using log4net;
33 34
34namespace OpenMetaverse 35namespace OpenMetaverse
@@ -52,12 +53,30 @@ namespace OpenMetaverse
52 /// <summary>Local IP address to bind to in server mode</summary> 53 /// <summary>Local IP address to bind to in server mode</summary>
53 protected IPAddress m_localBindAddress; 54 protected IPAddress m_localBindAddress;
54 55
56 /// <summary>
57 /// Standard queue for our outgoing SyncBeginPrioritySend
58 /// </summary>
59 private List<UDPPacketBuffer> m_standardQueue = new List<UDPPacketBuffer>();
60
61 /// <summary>
62 /// Medium priority queue for our outgoing SyncBeginPrioritySend
63 /// </summary>
64 private List<UDPPacketBuffer> m_mediumPriorityQueue = new List<UDPPacketBuffer>();
65
66 /// <summary>
67 /// Prioritised queue for our outgoing SyncBeginPrioritySend
68 /// </summary>
69 private List<UDPPacketBuffer> m_priorityQueue = new List<UDPPacketBuffer>();
70
55 /// <summary>UDP socket, used in either client or server mode</summary> 71 /// <summary>UDP socket, used in either client or server mode</summary>
56 private Socket m_udpSocket; 72 private Socket m_udpSocket;
57 73
58 /// <summary>Flag to process packets asynchronously or synchronously</summary> 74 /// <summary>Flag to process packets asynchronously or synchronously</summary>
59 private bool m_asyncPacketHandling; 75 private bool m_asyncPacketHandling;
60 76
77 /// <summary>Are we currently sending data asynchronously?</summary>
78 private volatile bool m_sendingData = false;
79
61 /// <summary>The all important shutdown flag</summary> 80 /// <summary>The all important shutdown flag</summary>
62 private volatile bool m_shutdownFlag = true; 81 private volatile bool m_shutdownFlag = true;
63 82
@@ -246,7 +265,51 @@ namespace OpenMetaverse
246 } 265 }
247 } 266 }
248 267
249 public void AsyncBeginSend(UDPPacketBuffer buf) 268 public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority)
269 {
270 if (!m_shutdownFlag)
271 {
272 if (!m_sendingData)
273 {
274 m_sendingData = true;
275 try
276 {
277 AsyncBeginSend(buf);
278 }
279 catch (SocketException) { }
280 catch (ObjectDisposedException) { }
281 }
282 else
283 {
284 if (Priority == 2)
285 {
286 lock (m_priorityQueue)
287 {
288 m_priorityQueue.Add(buf);
289 }
290 }
291 else
292 {
293 if (Priority != 0)
294 {
295 lock (m_mediumPriorityQueue)
296 {
297 m_mediumPriorityQueue.Add(buf);
298 }
299 }
300 else
301 {
302 lock (m_standardQueue)
303 {
304 m_standardQueue.Add(buf);
305 }
306 }
307 }
308 }
309 }
310 }
311
312 private void AsyncBeginSend(UDPPacketBuffer buf)
250 { 313 {
251 if (!m_shutdownFlag) 314 if (!m_shutdownFlag)
252 { 315 {
@@ -270,8 +333,48 @@ namespace OpenMetaverse
270 { 333 {
271 try 334 try
272 { 335 {
273// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
274 m_udpSocket.EndSendTo(result); 336 m_udpSocket.EndSendTo(result);
337
338 if (m_sendingData)
339 {
340 lock (m_priorityQueue)
341 {
342 if (m_priorityQueue.Count > 0)
343 {
344 UDPPacketBuffer buf = m_priorityQueue[0];
345 m_priorityQueue.RemoveAt(0);
346 AsyncBeginSend(buf);
347 }
348 else
349 {
350 lock (m_mediumPriorityQueue)
351 {
352 if (m_mediumPriorityQueue.Count > 0)
353 {
354 UDPPacketBuffer buf = m_mediumPriorityQueue[0];
355 m_mediumPriorityQueue.RemoveAt(0);
356 AsyncBeginSend(buf);
357 }
358 else
359 {
360 lock (m_standardQueue)
361 {
362 if (m_standardQueue.Count > 0)
363 {
364 UDPPacketBuffer buf = m_standardQueue[0];
365 m_standardQueue.RemoveAt(0);
366 AsyncBeginSend(buf);
367 }
368 else
369 {
370 m_sendingData = false;
371 }
372 }
373 }
374 }
375 }
376 }
377 }
275 } 378 }
276 catch (SocketException) { } 379 catch (SocketException) { }
277 catch (ObjectDisposedException) { } 380 catch (ObjectDisposedException) { }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
index 1a1a1cb..7dc42d3 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenMetaverse.Packets;
31 32
32namespace OpenSim.Region.ClientStack.LindenUDP 33namespace OpenSim.Region.ClientStack.LindenUDP
33{ 34{
@@ -52,7 +53,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
52 public int TickCount; 53 public int TickCount;
53 /// <summary>Category this packet belongs to</summary> 54 /// <summary>Category this packet belongs to</summary>
54 public ThrottleOutPacketType Category; 55 public ThrottleOutPacketType Category;
55 56 /// <summary>The type of packet so its delivery method can be determined</summary>
57 public PacketType Type;
56 /// <summary> 58 /// <summary>
57 /// Default constructor 59 /// Default constructor
58 /// </summary> 60 /// </summary>