aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-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 fba5090..2b5e632 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -770,16 +770,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
770 } 770 }
771 } 771 }
772 772
773 public void SendGenericMessage(string method, List<string> message) 773 public void SendGenericMessage(string method, List<byte[]> message)
774 { 774 {
775 GenericMessagePacket gmp = new GenericMessagePacket(); 775 GenericMessagePacket gmp = new GenericMessagePacket();
776 gmp.MethodData.Method = Util.StringToBytes256(method); 776 gmp.MethodData.Method = Util.StringToBytes256(method);
777 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 777 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
778 int i = 0; 778 int i = 0;
779 foreach (string val in message) 779 foreach (byte[] val in message)
780 { 780 {
781 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); 781 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
782 gmp.ParamList[i++].Parameter = Util.StringToBytes256(val); 782 gmp.ParamList[i++].Parameter = val;
783 } 783 }
784 OutPacket(gmp, ThrottleOutPacketType.Task); 784 OutPacket(gmp, ThrottleOutPacketType.Task);
785 } 785 }
@@ -791,6 +791,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 public virtual void SendLayerData(float[] map) 791 public virtual void SendLayerData(float[] map)
792 { 792 {
793 Util.FireAndForget(DoSendLayerData, map); 793 Util.FireAndForget(DoSendLayerData, map);
794
795 // Send it sync, and async. It's not that much data
796 // and it improves user experience just so much!
797 DoSendLayerData(map);
794 } 798 }
795 799
796 /// <summary> 800 /// <summary>
@@ -803,16 +807,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
803 807
804 try 808 try
805 { 809 {
806 //for (int y = 0; y < 16; y++) 810 for (int y = 0; y < 16; y++)
807 //{ 811 {
808 // for (int x = 0; x < 16; x++) 812 for (int x = 0; x < 16; x+=4)
809 // { 813 {
810 // SendLayerData(x, y, map); 814 SendLayerPacket(x, y, map);
811 // } 815 }
812 //} 816 }
813
814 // Send LayerData in a spiral pattern. Fun!
815 SendLayerTopRight(map, 0, 0, 15, 15);
816 } 817 }
817 catch (Exception e) 818 catch (Exception e)
818 { 819 {
@@ -820,51 +821,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
820 } 821 }
821 } 822 }
822 823
823 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
824 {
825 // Row
826 for (int i = x1; i <= x2; i++)
827 SendLayerData(i, y1, map);
828
829 // Column
830 for (int j = y1 + 1; j <= y2; j++)
831 SendLayerData(x2, j, map);
832
833 if (x2 - x1 > 0)
834 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
835 }
836
837 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
838 {
839 // Row in reverse
840 for (int i = x2; i >= x1; i--)
841 SendLayerData(i, y2, map);
842
843 // Column in reverse
844 for (int j = y2 - 1; j >= y1; j--)
845 SendLayerData(x1, j, map);
846
847 if (x2 - x1 > 0)
848 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
849 }
850
851 /// <summary> 824 /// <summary>
852 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 825 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
853 /// </summary> 826 /// </summary>
854 /// <param name="map">heightmap</param> 827 /// <param name="map">heightmap</param>
855 /// <param name="px">X coordinate for patches 0..12</param> 828 /// <param name="px">X coordinate for patches 0..12</param>
856 /// <param name="py">Y coordinate for patches 0..15</param> 829 /// <param name="py">Y coordinate for patches 0..15</param>
857 // private void SendLayerPacket(float[] map, int y, int x) 830 private void SendLayerPacket(int x, int y, float[] map)
858 // { 831 {
859 // int[] patches = new int[4]; 832 int[] patches = new int[4];
860 // patches[0] = x + 0 + y * 16; 833 patches[0] = x + 0 + y * 16;
861 // patches[1] = x + 1 + y * 16; 834 patches[1] = x + 1 + y * 16;
862 // patches[2] = x + 2 + y * 16; 835 patches[2] = x + 2 + y * 16;
863 // patches[3] = x + 3 + y * 16; 836 patches[3] = x + 3 + y * 16;
864 837
865 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 838 float[] heightmap = (map.Length == 65536) ?
866 // OutPacket(layerpack, ThrottleOutPacketType.Land); 839 map :
867 // } 840 LLHeightFieldMoronize(map);
841
842 try
843 {
844 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
845 OutPacket(layerpack, ThrottleOutPacketType.Land);
846 }
847 catch
848 {
849 for (int px = x ; px < x + 4 ; px++)
850 SendLayerData(px, y, map);
851 }
852 }
868 853
869 /// <summary> 854 /// <summary>
870 /// Sends a specified patch to a client 855 /// Sends a specified patch to a client
@@ -3142,7 +3127,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3142 3127
3143 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3128 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3144 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3129 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3145
3146 OutPacket(objupdate, ThrottleOutPacketType.Task); 3130 OutPacket(objupdate, ThrottleOutPacketType.Task);
3147 } 3131 }
3148 3132
@@ -3193,8 +3177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3193 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3177 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3194 } 3178 }
3195 3179
3196 // HACK: Using the task category until the tiered reprioritization code is in 3180 OutPacket(terse, ThrottleOutPacketType.State);
3197 OutPacket(terse, ThrottleOutPacketType.Task);
3198 } 3181 }
3199 3182
3200 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3183 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 338f2bb..85961b9 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>