Merge branch 'master' of /var/git/opensim/
commit
3da12c2d3f
|
@ -3562,24 +3562,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
EntityUpdate update;
|
EntityUpdate update;
|
||||||
while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
|
while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
|
||||||
{
|
{
|
||||||
|
if (update.Entity is SceneObjectPart)
|
||||||
|
{
|
||||||
|
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||||
|
|
||||||
// Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
|
// Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
|
||||||
// will never receive an update after a prim kill. Even then, keeping the kill record may be a good
|
// will never receive an update after a prim kill. Even then, keeping the kill record may be a good
|
||||||
// safety measure.
|
// safety measure.
|
||||||
//
|
//
|
||||||
// Receiving updates after kills results in undeleteable prims that persist until relog and
|
// If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
|
||||||
// currently occurs because prims can be deleted before all queued updates are sent.
|
// after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
|
||||||
if (m_killRecord.Contains(update.Entity.LocalId))
|
// updates and kills on different threads with different scheduling strategies, hence this protection.
|
||||||
|
//
|
||||||
|
// This doesn't appear to apply to child prims - a client will happily ignore these updates
|
||||||
|
// after the root prim has been deleted.
|
||||||
|
if (m_killRecord.Contains(part.LocalId))
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat(
|
// m_log.WarnFormat(
|
||||||
// "[CLIENT]: Preventing full update for prim with local id {0} after client for user {1} told it was deleted",
|
// "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
|
||||||
// update.Entity.LocalId, Name);
|
// part.LocalId, Name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update.Entity is SceneObjectPart)
|
|
||||||
{
|
|
||||||
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
|
||||||
|
|
||||||
if (part.ParentGroup.IsAttachment && m_disableFacelights)
|
if (part.ParentGroup.IsAttachment && m_disableFacelights)
|
||||||
{
|
{
|
||||||
if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
|
if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
|
||||||
|
|
|
@ -399,7 +399,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool EnqueueOutgoing(OutgoingPacket packet)
|
/// <summary>
|
||||||
|
/// Queue an outgoing packet if appropriate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packet"></param>
|
||||||
|
/// <param name="forceQueue">Always queue the packet if at all possible.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the packet has been queued,
|
||||||
|
/// false if the packet has not been queued and should be sent immediately.
|
||||||
|
/// </returns>
|
||||||
|
public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
|
||||||
{
|
{
|
||||||
int category = (int)packet.Category;
|
int category = (int)packet.Category;
|
||||||
|
|
||||||
|
@ -408,14 +417,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
|
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
|
||||||
TokenBucket bucket = m_throttleCategories[category];
|
TokenBucket bucket = m_throttleCategories[category];
|
||||||
|
|
||||||
if (bucket.RemoveTokens(packet.Buffer.DataLength))
|
if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength))
|
||||||
{
|
{
|
||||||
// Enough tokens were removed from the bucket, the packet will not be queued
|
// Enough tokens were removed from the bucket, the packet will not be queued
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Not enough tokens in the bucket, queue this packet
|
// Force queue specified or not enough tokens in the bucket, queue this packet
|
||||||
queue.Enqueue(packet);
|
queue.Enqueue(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,6 +312,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the process of sending a packet to the client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="udpClient"></param>
|
||||||
|
/// <param name="packet"></param>
|
||||||
|
/// <param name="category"></param>
|
||||||
|
/// <param name="allowSplitting"></param>
|
||||||
public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting)
|
public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting)
|
||||||
{
|
{
|
||||||
// CoarseLocationUpdate packets cannot be split in an automated way
|
// CoarseLocationUpdate packets cannot be split in an automated way
|
||||||
|
@ -339,6 +346,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the process of sending a packet to the client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="udpClient"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="category"></param>
|
||||||
public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category)
|
public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category)
|
||||||
{
|
{
|
||||||
int dataLength = data.Length;
|
int dataLength = data.Length;
|
||||||
|
@ -396,7 +410,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
|
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
|
||||||
|
|
||||||
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
|
// If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
|
||||||
|
// continue to display the deleted object until relog. Therefore, we need to always queue a kill object
|
||||||
|
// packet so that it isn't sent before a queued update packet.
|
||||||
|
bool requestQueue = type == PacketType.KillObject;
|
||||||
|
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
|
||||||
SendPacketFinal(outgoingPacket);
|
SendPacketFinal(outgoingPacket);
|
||||||
|
|
||||||
#endregion Queue or Send
|
#endregion Queue or Send
|
||||||
|
@ -489,7 +507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
//Interlocked.Increment(ref Stats.ResentPackets);
|
//Interlocked.Increment(ref Stats.ResentPackets);
|
||||||
|
|
||||||
// Requeue or resend the packet
|
// Requeue or resend the packet
|
||||||
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
|
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
|
||||||
SendPacketFinal(outgoingPacket);
|
SendPacketFinal(outgoingPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue