lludp: direct encode AvatarAppearance

0.9.1.0-post-fixes
UbitUmarov 2019-03-17 02:02:40 +00:00
parent 2ff5b322be
commit ee8ad3e69d
1 changed files with 39 additions and 22 deletions

View File

@ -3995,36 +3995,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
} }
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) static private readonly byte[] AvatarAppearanceHeader = new byte[] {
{ Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
// m_log.DebugFormat( 0, 0, 0, 0, // sequence number
// "[LLCLIENTVIEW]: Sending avatar appearance for {0} with {1} bytes to {2} {3}", 0, // extra
// agentID, textureEntry.Length, Name, AgentId); 0xff, 0xff, 0, 158 // ID 158 (low frequency bigendian) not zeroencoded
//0xff, 0xff, 0, 1, 158 // ID 158 (low frequency bigendian) zeroencoded
};
AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); public void SendAppearance(UUID targetID, byte[] visualParams, byte[] textureEntry)
// TODO: don't create new blocks if recycling an old packet
avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
avp.ObjectData.TextureEntry = textureEntry;
AvatarAppearancePacket.VisualParamBlock avblock = null;
for (int i = 0; i < visualParams.Length; i++)
{ {
avblock = new AvatarAppearancePacket.VisualParamBlock(); // doing post zero encode, because odds of beeing bad are not that low
avblock.ParamValue = visualParams[i]; UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
avp.VisualParam[i] = avblock; Buffer.BlockCopy(AvatarAppearanceHeader, 0, buf.Data, 0, 10);
byte[] data = buf.Data;
int pos = 10;
//sender block
targetID.ToBytes(data, pos); pos += 16;
data[pos++] = 0;// is trial = false
// objectdata block ie texture
int len = textureEntry.Length;
if (len == 0)
{
data[pos++] = 0;
data[pos++] = 0;
}
else
{
data[pos++] = (byte)len;
data[pos++] = (byte)(len >> 8);
Buffer.BlockCopy(textureEntry, 0, data, pos, len); pos += len;
} }
avp.Sender.IsTrial = false; // visual parameters
avp.Sender.ID = agentID; len = visualParams.Length;
avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; data[pos++] = (byte)len;
avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0]; if(len > 0)
Buffer.BlockCopy(visualParams, 0, data, pos, len); pos += len;
// this need be use in future ? // no AppearanceData
// avp.AppearanceData[0].AppearanceVersion = 0; data[pos++] = 0;
// avp.AppearanceData[0].CofVersion = 0; // no AppearanceHover
data[pos++] = 0;
//m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); buf.DataLength = pos;
OutPacket(avp, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true);
} }
static private readonly byte[] AvatarAnimationHeader = new byte[] { static private readonly byte[] AvatarAnimationHeader = new byte[] {