Change avatar updates to be processed the same way object updates are, e.g.

packet length check. More changes to come
0.6.5-rc1
Melanie Thielker 2009-05-07 12:06:07 +00:00
parent 3312938f6b
commit aa4e42069b
1 changed files with 52 additions and 28 deletions

View File

@ -71,8 +71,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Timer m_clientPingTimer; private Timer m_clientPingTimer;
private Timer m_avatarTerseUpdateTimer; private Timer m_avatarTerseUpdateTimer;
private Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
private ushort m_terseTimeDilationLast = 0;
private Timer m_primTerseUpdateTimer; private Timer m_primTerseUpdateTimer;
private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
@ -2770,39 +2769,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
/// <summary> /// <summary>
/// Send a terse positional/rotation/velocity update about an avatar to the client. This avatar can be that of /// Send a terse positional/rotation/velocity update about an avatar
/// the client itself. /// to the client. This avatar can be that of the client itself.
/// </summary> /// </summary>
public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, public virtual void SendAvatarTerseUpdate(ulong regionHandle,
ushort timeDilation, uint localID, Vector3 position,
Vector3 velocity, Quaternion rotation, UUID agentid) Vector3 velocity, Quaternion rotation, UUID agentid)
{ {
if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) if (rotation.X == rotation.Y &&
rotation.Y == rotation.Z &&
rotation.Z == rotation.W && rotation.W == 0)
rotation = Quaternion.Identity; rotation = Quaternion.Identity;
//m_log.DebugFormat("[CLIENT]: Sending rotation {0} for {1} to {2}", rotation, localID, Name);
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
CreateAvatarImprovedBlock(localID, position, velocity, rotation); CreateAvatarImprovedBlock(localID, position, velocity,rotation);
bool sendpacketnow = false;
lock (m_avatarTerseUpdates) lock (m_avatarTerseUpdates)
{ {
// Only one update per avatar per packet. No need to send old ones so just overwrite them. m_avatarTerseUpdates.Add(terseBlock);
m_avatarTerseUpdates[localID] = terseBlock;
m_terseTimeDilationLast = timeDilation;
// If packet is full or own movement packet, send it. // If packet is full or own movement packet, send it.
if (agentid == m_agentId || m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket) if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket)
{ {
m_avatarTerseUpdateTimer.Stop(); ProcessAvatarTerseUpdates(this, null);
sendpacketnow = true;
} }
else if (m_avatarTerseUpdates.Count == 1) else if (m_avatarTerseUpdates.Count == 1)
{
m_avatarTerseUpdateTimer.Start(); m_avatarTerseUpdateTimer.Start();
} }
// Call ProcessAvatarTerseUpdates outside the lock }
if (sendpacketnow)
ProcessAvatarTerseUpdates(this, null);
} }
private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e)
@ -2810,22 +2805,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_avatarTerseUpdates) lock (m_avatarTerseUpdates)
{ {
ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[m_avatarTerseUpdates.Count];
int i = 0; terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
foreach (KeyValuePair<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> dbe in m_avatarTerseUpdates)
terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
terse.RegionData.TimeDilation =
(ushort)(Scene.TimeDilation * ushort.MaxValue);
int max = m_avatarTerseUpdatesPerPacket;
if (max > m_avatarTerseUpdates.Count)
max = m_avatarTerseUpdates.Count;
int count = 0;
int size = 0;
byte[] zerobuffer = new byte[1024];
byte[] blockbuffer = new byte[1024];
for (count = 0 ; count < max ; count++)
{ {
terse.ObjectData[i] = dbe.Value; int length = 0;
i++; m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length);
length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
if (size + length > m_packetMTU)
break;
size += length;
}
terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
for (int i = 0 ; i < count ; i++)
{
terse.ObjectData[i] = m_avatarTerseUpdates[0];
m_avatarTerseUpdates.RemoveAt(0);
} }
terse.RegionData.TimeDilation = m_terseTimeDilationLast;
terse.Header.Reliable = false; terse.Header.Reliable = false;
terse.Header.Zerocoded = true; terse.Header.Zerocoded = true;
OutPacket(terse, ThrottleOutPacketType.Task); OutPacket(terse, ThrottleOutPacketType.Task);
m_avatarTerseUpdates.Clear(); if (m_avatarTerseUpdates.Count == 0)
m_avatarTerseUpdateTimer.Stop();
} }
} }
@ -3151,6 +3171,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
ProcessPrimTerseUpdates(this, null); ProcessPrimTerseUpdates(this, null);
} }
while (m_avatarTerseUpdates.Count > 0)
{
ProcessAvatarTerseUpdates(this, null);
}
} }
public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)