diff options
author | UbitUmarov | 2019-03-16 00:38:49 +0000 |
---|---|---|
committer | UbitUmarov | 2019-03-16 00:38:49 +0000 |
commit | 4a80802bec6574c54f534f83379a1b979dd9e20d (patch) | |
tree | 63a1512312c574712018c3934b7c73b91b1e771c /OpenSim | |
parent | minor cleanup (diff) | |
download | opensim-SC-4a80802bec6574c54f534f83379a1b979dd9e20d.zip opensim-SC-4a80802bec6574c54f534f83379a1b979dd9e20d.tar.gz opensim-SC-4a80802bec6574c54f534f83379a1b979dd9e20d.tar.bz2 opensim-SC-4a80802bec6574c54f534f83379a1b979dd9e20d.tar.xz |
lludp direct encode mapblockreply. Not bc its a high volume packet, but bc it needed work anyways
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 155 |
1 files changed, 117 insertions, 38 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 547c8a6..f2ebe2a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -1561,56 +1561,135 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1561 | OutPacket(newSimPack, ThrottleOutPacketType.Unknown); | 1561 | OutPacket(newSimPack, ThrottleOutPacketType.Unknown); |
1562 | } | 1562 | } |
1563 | 1563 | ||
1564 | internal void SendMapBlockSplit(List<MapBlockData> mapBlocks, uint flag) | 1564 | static private readonly byte[] MapBlockReplyHeader = new byte[] { |
1565 | Helpers.MSG_RELIABLE, | ||
1566 | 0, 0, 0, 0, // sequence number | ||
1567 | 0, // extra | ||
1568 | 0xff, 0xff, 1, 153 // ID 409 (bigendian low frequency) | ||
1569 | }; | ||
1570 | |||
1571 | public void SendMapBlock(List<MapBlockData> mapBlocks, uint flags) | ||
1565 | { | 1572 | { |
1566 | MapBlockReplyPacket mapReply = (MapBlockReplyPacket)PacketPool.Instance.GetPacket(PacketType.MapBlockReply); | 1573 | int blocks = mapBlocks.Count; |
1567 | // TODO: don't create new blocks if recycling an old packet | 1574 | ushort[] sizes = new ushort[2 * blocks]; |
1575 | bool needSizes = false; | ||
1576 | int sizesptr = 0; | ||
1568 | 1577 | ||
1569 | MapBlockData[] mapBlocks2 = mapBlocks.ToArray(); | 1578 | // check if we will need sizes block and get them aside |
1579 | int count = 0; | ||
1580 | ushort ut; | ||
1581 | foreach (MapBlockData md in mapBlocks) | ||
1582 | { | ||
1583 | ut = md.SizeX; | ||
1584 | sizes[count++] = ut; | ||
1585 | if (ut > 256) | ||
1586 | needSizes = true; | ||
1570 | 1587 | ||
1571 | mapReply.AgentData.AgentID = AgentId; | 1588 | ut = md.SizeY; |
1572 | mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks2.Length]; | 1589 | sizes[count++] = ut; |
1573 | mapReply.Size = new MapBlockReplyPacket.SizeBlock[mapBlocks2.Length]; | 1590 | if (ut > 256) |
1574 | mapReply.AgentData.Flags = flag; | 1591 | needSizes = true; |
1575 | |||
1576 | for (int i = 0; i < mapBlocks2.Length; i++) | ||
1577 | { | ||
1578 | mapReply.Data[i] = new MapBlockReplyPacket.DataBlock(); | ||
1579 | mapReply.Data[i].MapImageID = mapBlocks2[i].MapImageId; | ||
1580 | //m_log.Warn(mapBlocks2[i].MapImageId.ToString()); | ||
1581 | mapReply.Data[i].X = mapBlocks2[i].X; | ||
1582 | mapReply.Data[i].Y = mapBlocks2[i].Y; | ||
1583 | mapReply.Data[i].WaterHeight = mapBlocks2[i].WaterHeight; | ||
1584 | mapReply.Data[i].Name = Utils.StringToBytes(mapBlocks2[i].Name); | ||
1585 | mapReply.Data[i].RegionFlags = mapBlocks2[i].RegionFlags; | ||
1586 | mapReply.Data[i].Access = mapBlocks2[i].Access; | ||
1587 | mapReply.Data[i].Agents = mapBlocks2[i].Agents; | ||
1588 | |||
1589 | mapReply.Size[i] = new MapBlockReplyPacket.SizeBlock(); | ||
1590 | mapReply.Size[i].SizeX = mapBlocks2[i].SizeX; | ||
1591 | mapReply.Size[i].SizeY = mapBlocks2[i].SizeY; | ||
1592 | } | 1592 | } |
1593 | OutPacket(mapReply, ThrottleOutPacketType.Land); | ||
1594 | } | ||
1595 | 1593 | ||
1596 | public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag) | 1594 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
1597 | { | 1595 | byte[] data = buf.Data; |
1598 | MapBlockData[] mapBlocks2 = mapBlocks.ToArray(); | ||
1599 | 1596 | ||
1600 | int maxsend = 10; | 1597 | //setup header and agentinfo block |
1598 | Buffer.BlockCopy(MapBlockReplyHeader, 0, data, 0, 10); | ||
1599 | AgentId.ToBytes(data, 10); // 26 | ||
1600 | Utils.UIntToBytesSafepos(flags, data, 26); // 30 | ||
1601 | 1601 | ||
1602 | //int packets = Math.Ceiling(mapBlocks2.Length / maxsend); | 1602 | int countpos = 30; |
1603 | int pos = 31; | ||
1604 | int lastpos = 0; | ||
1603 | 1605 | ||
1604 | List<MapBlockData> sendingBlocks = new List<MapBlockData>(); | 1606 | int capacity = LLUDPServer.MAXPAYLOAD - pos; |
1605 | 1607 | ||
1606 | for (int i = 0; i < mapBlocks2.Length; i++) | 1608 | count = 0; |
1609 | byte[] regionName = null; | ||
1610 | |||
1611 | foreach (MapBlockData md in mapBlocks) | ||
1607 | { | 1612 | { |
1608 | sendingBlocks.Add(mapBlocks2[i]); | 1613 | lastpos = pos; |
1609 | if (((i + 1) == mapBlocks2.Length) || (((i + 1) % maxsend) == 0)) | 1614 | |
1615 | Utils.UInt16ToBytes(md.X, data, pos); pos += 2; | ||
1616 | Utils.UInt16ToBytes(md.Y, data, pos); pos += 2; | ||
1617 | regionName = Util.StringToBytes256(md.Name); | ||
1618 | data[pos++] = (byte)regionName.Length; | ||
1619 | if(regionName.Length > 0) | ||
1620 | Buffer.BlockCopy(regionName, 0, data, pos, regionName.Length); pos += regionName.Length; | ||
1621 | data[pos++] = md.Access; | ||
1622 | Utils.UIntToBytesSafepos(md.RegionFlags, data, pos); pos += 4; | ||
1623 | data[pos++] = md.WaterHeight; | ||
1624 | data[pos++] = md.Agents; | ||
1625 | md.MapImageId.ToBytes(data, pos); pos += 16; | ||
1626 | |||
1627 | if(needSizes) | ||
1628 | capacity -= 4; // 2 shorts per entry | ||
1629 | |||
1630 | if(pos < capacity) | ||
1610 | { | 1631 | { |
1611 | SendMapBlockSplit(sendingBlocks, flag); | 1632 | ++count; |
1612 | sendingBlocks = new List<MapBlockData>(); | 1633 | --blocks; |
1613 | } | 1634 | } |
1635 | else | ||
1636 | { | ||
1637 | // prepare next packet | ||
1638 | UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
1639 | Buffer.BlockCopy(MapBlockReplyHeader, 0, newbuf.Data, 0, 30); | ||
1640 | |||
1641 | // copy the block we already did | ||
1642 | int alreadyDone = pos - lastpos; | ||
1643 | Buffer.BlockCopy(data, lastpos, newbuf.Data, 31, alreadyDone); // 30 is datablock size | ||
1644 | |||
1645 | // finish current | ||
1646 | data[countpos] = (byte)count; | ||
1647 | if (needSizes) | ||
1648 | { | ||
1649 | data[lastpos++] = (byte)count; | ||
1650 | while (--count >= 0) | ||
1651 | { | ||
1652 | Utils.UInt16ToBytes(sizes[sizesptr++], data, lastpos); lastpos += 2; | ||
1653 | Utils.UInt16ToBytes(sizes[sizesptr++], data, lastpos); lastpos += 2; | ||
1654 | } | ||
1655 | } | ||
1656 | else | ||
1657 | data[lastpos++] = 0; | ||
1658 | |||
1659 | buf.DataLength = lastpos; | ||
1660 | // send it | ||
1661 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); | ||
1662 | |||
1663 | buf = newbuf; | ||
1664 | data = buf.Data; | ||
1665 | pos = alreadyDone + 31; | ||
1666 | capacity = LLUDPServer.MAXPAYLOAD - pos; | ||
1667 | if (needSizes) | ||
1668 | capacity -= 4; // 2 shorts per entry | ||
1669 | |||
1670 | count = 1; | ||
1671 | --blocks; | ||
1672 | } | ||
1673 | } | ||
1674 | regionName = null; | ||
1675 | |||
1676 | if (count > 0) | ||
1677 | { | ||
1678 | data[countpos] = (byte)count; | ||
1679 | if (needSizes) | ||
1680 | { | ||
1681 | data[pos++] = (byte)count; | ||
1682 | while (--count >= 0) | ||
1683 | { | ||
1684 | Utils.UInt16ToBytes(sizes[sizesptr++], data, pos); pos += 2; | ||
1685 | Utils.UInt16ToBytes(sizes[sizesptr++], data, pos); pos += 2; | ||
1686 | } | ||
1687 | } | ||
1688 | else | ||
1689 | data[pos++] = 0; | ||
1690 | |||
1691 | buf.DataLength = pos; | ||
1692 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); | ||
1614 | } | 1693 | } |
1615 | } | 1694 | } |
1616 | 1695 | ||