Merge branch 'ubitworkmaster'

avinationmerge
Melanie Thielker 2014-08-21 02:38:57 +02:00
commit f06f13b59d
9 changed files with 140 additions and 66 deletions

View File

@ -1116,6 +1116,8 @@ namespace OpenSim.Framework
/// <param name="localID"></param>
void SendKillObject(List<uint> localID);
void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);

View File

@ -62,7 +62,9 @@ namespace OpenSim.Framework
private uint m_nextQueue = 0;
private uint m_countFromQueue = 0;
// first queues are imediate, so no counts
private uint[] m_queueCounts = {0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1};
// private uint[] m_queueCounts = { 0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1 };
private uint[] m_queueCounts = {0, 0, 8, 8, 5, 4, 3, 2, 1, 1, 1, 1};
// this is ava, ava, attach, <10m, 20,40,80,160m,320,640,1280, +
// next request is a counter of the number of updates queued, it provides
// a total ordering on the updates coming through the queue and is more

View File

@ -3838,47 +3838,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
}
/// <summary>
/// Requeue an EntityUpdate when it was not acknowledged by the client.
/// We will update the priority and put it in the correct queue, merging update flags
/// with any other updates that may be queued for the same entity.
/// The original update time is used for the merged update.
/// </summary>
private void ResendPrimUpdate(EntityUpdate update)
{
// If the update exists in priority queue, it will be updated.
// If it does not exist then it will be added with the current (rather than its original) priority
uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
/* dont use this
udp packet resent must be done at udp level only
re map from a packet to original updates just doesnt work
lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Enqueue(priority, update);
}
/// <summary>
/// Requeue an EntityUpdate when it was not acknowledged by the client.
/// We will update the priority and put it in the correct queue, merging update flags
/// with any other updates that may be queued for the same entity.
/// The original update time is used for the merged update.
/// </summary>
private void ResendPrimUpdate(EntityUpdate update)
{
// If the update exists in priority queue, it will be updated.
// If it does not exist then it will be added with the current (rather than its original) priority
uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
/// <summary>
/// Requeue a list of EntityUpdates when they were not acknowledged by the client.
/// We will update the priority and put it in the correct queue, merging update flags
/// with any other updates that may be queued for the same entity.
/// The original update time is used for the merged update.
/// </summary>
private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
{
// m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Enqueue(priority, update);
}
// Remove the update packet from the list of packets waiting for acknowledgement
// because we are requeuing the list of updates. They will be resent in new packets
// with the most recent state and priority.
m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
// Count this as a resent packet since we are going to requeue all of the updates contained in it
Interlocked.Increment(ref m_udpClient.PacketsResent);
/// <summary>
/// Requeue a list of EntityUpdates when they were not acknowledged by the client.
/// We will update the priority and put it in the correct queue, merging update flags
/// with any other updates that may be queued for the same entity.
/// The original update time is used for the merged update.
/// </summary>
private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
{
// m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
// We're not going to worry about interlock yet since its not currently critical that this total count
// is 100% correct
m_udpServer.PacketsResentCount++;
// Remove the update packet from the list of packets waiting for acknowledgement
// because we are requeuing the list of updates. They will be resent in new packets
// with the most recent state and priority.
m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
foreach (EntityUpdate update in updates)
ResendPrimUpdate(update);
}
// Count this as a resent packet since we are going to requeue all of the updates contained in it
Interlocked.Increment(ref m_udpClient.PacketsResent);
// We're not going to worry about interlock yet since its not currently critical that this total count
// is 100% correct
m_udpServer.PacketsResentCount++;
foreach (EntityUpdate update in updates)
ResendPrimUpdate(update);
}
*/
// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
@ -4197,12 +4203,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < blocks.Count; i++)
packet.ObjectData[i] = blocks[i];
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
// OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
// use default udp retry
OutPacket(packet, ThrottleOutPacketType.Task, true);
}
#endregion Packet Sending
}
// hack.. dont use
public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
{
if (ent is SceneObjectPart)
{
SceneObjectPart part = (SceneObjectPart)ent;
ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = 1;
packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId);
if (parentID.HasValue)
{
blk.ParentID = parentID.Value;
}
packet.ObjectData[0] = blk;
OutPacket(packet, ThrottleOutPacketType.Task, true);
}
}
public void ReprioritizeUpdates()
{
lock (m_entityUpdates.SyncRoot)

View File

@ -175,7 +175,7 @@ namespace OpenSim.Region.Framework.Scenes
{
// Attachments are high priority,
if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
return 1;
return 2;
pqueue = ComputeDistancePriority(client, entity, false);
@ -233,16 +233,28 @@ namespace OpenSim.Region.Framework.Scenes
// And convert the distance to a priority queue, this computation gives queues
// at 10, 20, 40, 80, 160, 320, 640, and 1280m
uint pqueue = PriorityQueue.NumberOfImmediateQueues;
uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue
uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues;
/*
for (int i = 0; i < queues - 1; i++)
{
if (distance < 30 * Math.Pow(2.0,i))
break;
pqueue++;
}
*/
if (distance > 10f)
{
float tmp = (float)Math.Log((double)distance) * 1.4426950408889634073599246810019f - 3.3219280948873623478703194294894f;
// for a map identical to original:
// now
// 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
// 2st constant makes it be log2(distance/10)
pqueue += (uint)tmp;
if (pqueue > queues - 1)
pqueue = queues - 1;
}
// If this is a root agent, then determine front & back
// Bump up the priority queue (drop the priority) for any objects behind the avatar
if (useFrontBack && ! presence.IsChildAgent)

View File

@ -295,6 +295,18 @@ namespace OpenSim.Region.Framework.Scenes
return myID;
}
public uint AllocatePresenceLocalId()
{
uint myID;
_primAllocateMutex.WaitOne();
myID = ++m_lastAllocatedLocalId;
++m_lastAllocatedLocalId;
_primAllocateMutex.ReleaseMutex();
return myID;
}
#region Module Methods

View File

@ -969,7 +969,7 @@ namespace OpenSim.Region.Framework.Scenes
m_name = String.Format("{0} {1}", Firstname, Lastname);
m_scene = world;
m_uuid = client.AgentId;
LocalId = m_scene.AllocateLocalId();
LocalId = m_scene.AllocatePresenceLocalId();
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
if (account != null)
@ -1878,7 +1878,6 @@ namespace OpenSim.Region.Framework.Scenes
if (!IsChildAgent)
{
ValidateAndSendAppearanceAndAgentData();
m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts));
@ -1900,35 +1899,31 @@ namespace OpenSim.Region.Framework.Scenes
m_log.DebugFormat(
"[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
List<uint> kk = new List<uint>();
// Resume scripts this possible should also be moved down after sending the avatar to viewer ?
foreach (SceneObjectGroup sog in m_attachments)
{
foreach (SceneObjectPart part in sog.Parts)
kk.Add(part.LocalId);
sog.SendFullUpdateToClient(ControllingClient);
SendFullUpdateToClient(ControllingClient);
// sog.ScheduleGroupForFullUpdate();
m_scene.ForEachScenePresence(delegate(ScenePresence p)
if (!sog.HasPrivateAttachmentPoint)
{
if (p == this)
return;
if (sog.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
p.ControllingClient.SendKillObject(kk);
sog.SendFullUpdateToClient(p.ControllingClient);
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
});
// sog.ScheduleGroupForFullUpdate();
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p == this)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
p.ControllingClient.SendPartFullUpdate(sog.RootPart,LocalId + 1);
sog.SendFullUpdateToClient(p.ControllingClient);
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
});
}
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
kk.Clear();
}
}
}
@ -4752,12 +4747,18 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectGroup sog in m_attachments)
{
if (p == this || !sog.HasPrivateAttachmentPoint)
{
p.ControllingClient.SendPartFullUpdate(sog.RootPart, LocalId + 1);
sog.SendFullUpdateToClient(p.ControllingClient);
}
}
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
}
}
// send attachments to a client without filters except for huds
// for now they are checked in several places down the line...
// kills all parts before sending
public void SendAttachmentsToAgentNFPK(ScenePresence p)
{
lock (m_attachments)
@ -5680,7 +5681,7 @@ namespace OpenSim.Region.Framework.Scenes
p.SendAppearanceToAgent(this);
if (p.Animator != null)
p.Animator.SendAnimPackToClient(ControllingClient);
p.SendAttachmentsToAgentNFPK(this);
p.SendAttachmentsToAgentNF(this);
}
}
}
@ -5995,7 +5996,7 @@ namespace OpenSim.Region.Framework.Scenes
SendAppearanceToAgent(p);
if (Animator != null)
Animator.SendAnimPackToClient(p.ControllingClient);
SendAttachmentsToAgentNFPK(p);
SendAttachmentsToAgentNF(p);
}
}
@ -6011,7 +6012,7 @@ namespace OpenSim.Region.Framework.Scenes
p.SendAppearanceToAgent(this);
if (p.Animator != null)
p.Animator.SendAnimPackToClient(ControllingClient);
p.SendAttachmentsToAgentNFPK(this);
p.SendAttachmentsToAgentNF(this);
}
}
}

View File

@ -1702,5 +1702,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
{
}
public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
{
}
}
}

View File

@ -1272,5 +1272,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
{
}
}
}

View File

@ -536,6 +536,10 @@ namespace OpenSim.Tests.Common.Mock
ReceivedKills.AddRange(localID);
}
public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
{
}
public virtual void SetChildAgentThrottle(byte[] throttle)
{
}