diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ecae8c8c58..ac041f500b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1257,6 +1257,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendLayerTopRight(x1 + 1, y1, x2, y2 - 1); } + static private readonly byte[] TerrainPacketHeader = new byte[] { + Helpers.MSG_RELIABLE, // zero code is not as spec + 0, 0, 0, 0, // sequence number + 0, // extra + 11, // ID (high frequency) + }; + + private const int END_OF_PATCHES = 97; + private const int STRIDE = 264; + public void SendLayerData(int[] map) { if(map == null) @@ -1264,9 +1274,75 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - List packets = OpenSimTerrainCompressor.CreateLayerDataPackets(m_scene.Heightmap.GetTerrainData(), map); - foreach (LayerDataPacket pkt in packets) - OutPacket(pkt, ThrottleOutPacketType.Land); + TerrainData terrData = m_scene.Heightmap.GetTerrainData(); + byte landPacketType = (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) ? + (byte)TerrainPatch.LayerType.LandExtended : (byte)TerrainPatch.LayerType.Land; + + int numberPatchs = map.Length / 2; + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + byte[] data = buf.Data; + + Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7); + + data[7] = landPacketType; + //data[8] and data[9] == datablock size to fill later + + data[10] = 0; // BitPack needs this on reused packets + + // start data + BitPack bitpack = new BitPack(data, 10); + bitpack.PackBits(STRIDE, 16); + bitpack.PackBitsFromByte(16); + bitpack.PackBitsFromByte(landPacketType); + + int s; + int datasize = 0; + for (int i = 0; i < numberPatchs; i++) + { + s = 2 * i; + OpenSimTerrainCompressor.CreatePatchFromTerrainData(bitpack, terrData, map[s], map[s + 1]); + if (bitpack.BytePos > 950 && i != numberPatchs - 1) + { + //finish this packet + bitpack.PackBitsFromByte(END_OF_PATCHES); + + // fix the datablock lenght + datasize = bitpack.BytePos - 9; + data[8] = (byte)datasize; + data[9] = (byte)(datasize >> 8); + + buf.DataLength = bitpack.BytePos + 1; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); + + // start another + buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + data = buf.Data; + + Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7); + + data[7] = landPacketType; + //data[8] and data[9] == datablock size to fill later + + data[10] = 0; // BitPack needs this + // start data + bitpack = new BitPack(data, 10); + + bitpack.PackBits(STRIDE, 16); + bitpack.PackBitsFromByte(16); + bitpack.PackBitsFromByte(landPacketType); + } + } + + bitpack.PackBitsFromByte(END_OF_PATCHES); + + datasize = bitpack.BytePos - 9; + data[8] = (byte)datasize; + data[9] = (byte)(datasize >> 8); + + buf.DataLength = bitpack.BytePos + 1; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); + } catch (Exception e) { @@ -4512,7 +4588,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc); else CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc); - if (zc.Position < LLUDPServer.MTU - 5) + if (zc.Position < LLUDPServer.MAXPAYLOAD) { tau.Add(eu); ++count; @@ -4593,7 +4669,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lastpos = pos; CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, (eu.Flags & PrimUpdateFlags.Textures) != 0); - if (pos < LLUDPServer.MTU) + if (pos < LLUDPServer.MAXPAYLOAD) { tau.Add(eu); ++count; diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs index a60381afb7..020c7bed99 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs @@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return iout; } +/* // new using terrain data and patchs indexes public static List CreateLayerDataPackets(TerrainData terrData, int[] map) { @@ -213,6 +214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return ret; } +*/ public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY) {