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_avatarTerseUpdateTimer;
private Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new Dictionary<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
private ushort m_terseTimeDilationLast = 0;
private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
private Timer m_primTerseUpdateTimer;
private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
@ -2770,39 +2769,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
/// <summary>
/// Send a terse positional/rotation/velocity update about an avatar to the client. This avatar can be that of
/// the client itself.
/// Send a terse positional/rotation/velocity update about an avatar
/// to the client. This avatar can be that of the client itself.
/// </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)
{
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;
//m_log.DebugFormat("[CLIENT]: Sending rotation {0} for {1} to {2}", rotation, localID, Name);
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
CreateAvatarImprovedBlock(localID, position, velocity, rotation);
CreateAvatarImprovedBlock(localID, position, velocity,rotation);
bool sendpacketnow = false;
lock (m_avatarTerseUpdates)
{
// Only one update per avatar per packet. No need to send old ones so just overwrite them.
m_avatarTerseUpdates[localID] = terseBlock;
m_terseTimeDilationLast = timeDilation;
m_avatarTerseUpdates.Add(terseBlock);
// 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();
sendpacketnow = true;
ProcessAvatarTerseUpdates(this, null);
}
else if (m_avatarTerseUpdates.Count == 1)
{
m_avatarTerseUpdateTimer.Start();
}
// Call ProcessAvatarTerseUpdates outside the lock
if (sendpacketnow)
ProcessAvatarTerseUpdates(this, null);
}
}
private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e)
@ -2810,22 +2805,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_avatarTerseUpdates)
{
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;
foreach (KeyValuePair<uint, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> dbe in m_avatarTerseUpdates)
terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
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;
i++;
int length = 0;
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.Zerocoded = true;
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);
}
while (m_avatarTerseUpdates.Count > 0)
{
ProcessAvatarTerseUpdates(this, null);
}
}
public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)