llupd direct encode object updates for agents; let terse updates be zeroencoded. This is not as spec but does work
parent
b5ad1b7dcc
commit
0944a96517
|
@ -3891,29 +3891,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (ent == null)
|
||||
return;
|
||||
|
||||
ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
||||
objupdate.Header.Zerocoded = true;
|
||||
|
||||
objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
|
||||
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||
|
||||
if(ent is ScenePresence)
|
||||
if (ent is ScenePresence)
|
||||
{
|
||||
ScenePresence presence = ent as ScenePresence;
|
||||
objupdate.RegionData.RegionHandle = presence.RegionHandle;
|
||||
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
|
||||
|
||||
UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
|
||||
|
||||
//setup header and regioninfo block
|
||||
Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7);
|
||||
Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7);
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f), buf.Data, 15);
|
||||
|
||||
buf.Data[17] = 1;
|
||||
int pos = 18;
|
||||
CreateAvatarUpdateBlock(presence, buf.Data, ref pos);
|
||||
|
||||
buf.DataLength = pos;
|
||||
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true);
|
||||
}
|
||||
|
||||
else if(ent is SceneObjectPart)
|
||||
{
|
||||
ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
||||
objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
|
||||
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||
|
||||
SceneObjectPart part = ent as SceneObjectPart;
|
||||
objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||
objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent);
|
||||
objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent);
|
||||
|
||||
OutPacket(objupdate, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
|
||||
|
||||
// We need to record the avatar local id since the root prim of an attachment points to this.
|
||||
// m_attachmentsSent.Add(avatar.LocalId);
|
||||
// m_attachmentsSent.Add(avatar.LocalId);
|
||||
}
|
||||
|
||||
public void SendEntityTerseUpdateImmediate(ISceneEntity ent)
|
||||
|
@ -4084,8 +4095,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
ResendPrimUpdate(update);
|
||||
}
|
||||
|
||||
static private readonly byte[] objectUpdateHeader = new byte[] {
|
||||
Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
|
||||
0, 0, 0, 0, // sequence number
|
||||
0, // extra
|
||||
12 // ID (high frequency)
|
||||
};
|
||||
|
||||
static private readonly byte[] terseUpdateHeader = new byte[] {
|
||||
Helpers.MSG_RELIABLE,
|
||||
Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec
|
||||
0, 0, 0, 0, // sequence number
|
||||
0, // extra
|
||||
15 // ID (high frequency)
|
||||
|
@ -4105,7 +4123,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
List<EntityUpdate> objectUpdates = null;
|
||||
// List<EntityUpdate> compressedUpdates = null;
|
||||
List<EntityUpdate> terseUpdates = null;
|
||||
List<EntityUpdate> terseAgentUpdates = null;
|
||||
List<SceneObjectPart> ObjectAnimationUpdates = null;
|
||||
|
||||
// Check to see if this is a flush
|
||||
|
@ -4275,7 +4292,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if(ObjectAnimationUpdates == null)
|
||||
ObjectAnimationUpdates = new List<SceneObjectPart>();
|
||||
ObjectAnimationUpdates.Add(sop);
|
||||
maxUpdatesBytes -= 32 * sop.Animations.Count + 16;
|
||||
maxUpdatesBytes -= 20 * sop.Animations.Count + 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4329,37 +4346,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
if ((updateFlags & canNotUseImprovedMask) == 0)
|
||||
{
|
||||
if (terseUpdates == null)
|
||||
{
|
||||
terseUpdates = new List<EntityUpdate>();
|
||||
maxUpdatesBytes -= 18;
|
||||
}
|
||||
terseUpdates.Add(update);
|
||||
|
||||
if (update.Entity is ScenePresence)
|
||||
{
|
||||
// ALL presence updates go into a special list
|
||||
if (terseAgentUpdates == null)
|
||||
{
|
||||
terseAgentUpdates = new List<EntityUpdate>();
|
||||
maxUpdatesBytes -= 18;
|
||||
}
|
||||
terseAgentUpdates.Add(update);
|
||||
maxUpdatesBytes -= 63; // no texture entry
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything else goes here
|
||||
if (terseUpdates == null)
|
||||
{
|
||||
terseUpdates = new List<EntityUpdate>();
|
||||
maxUpdatesBytes -= 18;
|
||||
}
|
||||
terseUpdates.Add(update);
|
||||
maxUpdatesBytes -= 47;
|
||||
if ((updateFlags & PrimUpdateFlags.Textures) != 0)
|
||||
maxUpdatesBytes -= 100; // aprox
|
||||
if ((updateFlags & PrimUpdateFlags.Textures) == 0)
|
||||
maxUpdatesBytes -= 47;
|
||||
else
|
||||
maxUpdatesBytes -= 150; // aprox
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectUpdatePacket.ObjectDataBlock ablock;
|
||||
if (update.Entity is ScenePresence)
|
||||
{
|
||||
ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
|
||||
}
|
||||
else
|
||||
ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp);
|
||||
if(objectUpdateBlocks == null)
|
||||
|
@ -4385,57 +4395,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
|
||||
|
||||
if (terseAgentUpdates != null)
|
||||
{
|
||||
const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry
|
||||
int blocks = terseAgentUpdates.Count;
|
||||
int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks;
|
||||
List<EntityUpdate> tau = new List<EntityUpdate>(curNBlocks);
|
||||
|
||||
UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
|
||||
|
||||
//setup header and regioninfo block
|
||||
Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7);
|
||||
Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7);
|
||||
Utils.UInt16ToBytes(timeDilation, buf.Data, 15);
|
||||
buf.Data[17] = (byte)curNBlocks;
|
||||
int pos = 18;
|
||||
|
||||
int count = 0;
|
||||
foreach (EntityUpdate eu in terseAgentUpdates)
|
||||
{
|
||||
CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, false);
|
||||
tau.Add(eu);
|
||||
++count;
|
||||
--blocks;
|
||||
if (count == curNBlocks && blocks > 0)
|
||||
{
|
||||
// we need more packets
|
||||
UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
|
||||
Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, 17); // start is the same
|
||||
|
||||
buf.DataLength = pos;
|
||||
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown,
|
||||
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
|
||||
|
||||
curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks;
|
||||
tau = new List<EntityUpdate>(curNBlocks);
|
||||
count = 0;
|
||||
|
||||
buf = newbuf;
|
||||
buf.Data[17] = (byte)curNBlocks;
|
||||
pos = 18;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
buf.DataLength = pos;
|
||||
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown,
|
||||
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (objectUpdateBlocks != null)
|
||||
{
|
||||
ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
||||
|
@ -4497,8 +4456,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
buf.Data[17] = (byte)count;
|
||||
buf.DataLength = lastpos;
|
||||
// zero encode is not as spec
|
||||
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
|
||||
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
|
||||
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true);
|
||||
|
||||
tau = new List<EntityUpdate>(30);
|
||||
tau.Add(eu);
|
||||
|
@ -4513,7 +4473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
buf.Data[17] = (byte)count;
|
||||
buf.DataLength = pos;
|
||||
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
|
||||
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
|
||||
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4534,13 +4494,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
UUID[] ids = null;
|
||||
int[] seqs = null;
|
||||
int count = sop.GetAnimations(out ids, out seqs);
|
||||
if(count < 0)
|
||||
continue;
|
||||
|
||||
ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation);
|
||||
ani.Sender = new ObjectAnimationPacket.SenderBlock();
|
||||
ani.Sender.ID = sop.UUID;
|
||||
ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[sop.Animations.Count];
|
||||
ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[count];
|
||||
|
||||
for(int i = 0; i< count; i++)
|
||||
{
|
||||
|
@ -5732,7 +5690,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
return block;
|
||||
}
|
||||
|
||||
|
||||
protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture)
|
||||
{
|
||||
#region ScenePresence/SOP Handling
|
||||
|
@ -5871,7 +5828,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
|
||||
{
|
||||
Vector3 offsetPosition = data.OffsetPosition;
|
||||
Quaternion rotation = data.Rotation;
|
||||
// tpvs can only see rotations around Z in some cases
|
||||
if(!data.Flying && !data.IsSatOnObject)
|
||||
|
@ -5881,27 +5837,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
rotation.Normalize();
|
||||
|
||||
uint parentID = data.ParentID;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name);
|
||||
|
||||
byte[] objectData = new byte[76];
|
||||
|
||||
Vector3 velocity = new Vector3(0, 0, 0);
|
||||
Vector3 acceleration = new Vector3(0, 0, 0);
|
||||
//Vector3 velocity = Vector3.Zero;
|
||||
Vector3 acceleration = Vector3.Zero;
|
||||
Vector3 angularvelocity = Vector3.Zero;
|
||||
|
||||
data.CollisionPlane.ToBytes(objectData, 0);
|
||||
offsetPosition.ToBytes(objectData, 16);
|
||||
velocity.ToBytes(objectData, 28);
|
||||
data.OffsetPosition.ToBytes(objectData, 16);
|
||||
data.Velocity.ToBytes(objectData, 28);
|
||||
acceleration.ToBytes(objectData, 40);
|
||||
rotation.ToBytes(objectData, 52);
|
||||
data.AngularVelocity.ToBytes(objectData, 64);
|
||||
angularvelocity.ToBytes(objectData, 64);
|
||||
|
||||
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
|
||||
|
||||
update.Data = Utils.EmptyBytes;
|
||||
update.ExtraParams = new byte[1];
|
||||
update.ExtraParams = Utils.EmptyBytes;
|
||||
update.FullID = data.UUID;
|
||||
update.ID = data.LocalId;
|
||||
update.Material = (byte)Material.Flesh;
|
||||
|
@ -5938,7 +5893,99 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
return update;
|
||||
}
|
||||
|
||||
// protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
|
||||
protected void CreateAvatarUpdateBlock(ScenePresence data, byte[] dest, ref int pos)
|
||||
{
|
||||
Quaternion rotation = data.Rotation;
|
||||
// tpvs can only see rotations around Z in some cases
|
||||
if (!data.Flying && !data.IsSatOnObject)
|
||||
{
|
||||
rotation.X = 0f;
|
||||
rotation.Y = 0f;
|
||||
}
|
||||
rotation.Normalize();
|
||||
|
||||
//Vector3 velocity = Vector3.Zero;
|
||||
//Vector3 acceleration = Vector3.Zero;
|
||||
//Vector3 angularvelocity = Vector3.Zero;
|
||||
|
||||
Utils.UIntToBytesSafepos(data.LocalId, dest, pos); pos += 4;
|
||||
dest[pos++] = 0; // state
|
||||
data.UUID.ToBytes(dest, pos); pos += 16;
|
||||
Utils.UIntToBytesSafepos(0 , dest, pos); pos += 4; // crc
|
||||
dest[pos++] = (byte)PCode.Avatar;
|
||||
dest[pos++] = (byte)Material.Flesh;
|
||||
dest[pos++] = 0; // clickaction
|
||||
data.Appearance.AvatarSize.ToBytes(dest, pos); pos += 12;
|
||||
|
||||
// objectdata block
|
||||
dest[pos++] = 76;
|
||||
data.CollisionPlane.ToBytes(dest, pos); pos += 16;
|
||||
data.OffsetPosition.ToBytes(dest, pos); pos += 12;
|
||||
data.Velocity.ToBytes(dest, pos); pos += 12;
|
||||
|
||||
//acceleration.ToBytes(dest, pos); pos += 12;
|
||||
Array.Clear(dest, pos, 12); pos += 12;
|
||||
|
||||
rotation.ToBytes(dest, pos); pos += 12;
|
||||
|
||||
//angularvelocity.ToBytes(dest, pos); pos += 12;
|
||||
Array.Clear(dest, pos, 12); pos += 12;
|
||||
|
||||
SceneObjectPart parentPart = data.ParentPart;
|
||||
if (parentPart != null)
|
||||
{
|
||||
Utils.UIntToBytesSafepos(parentPart.ParentGroup.LocalId, dest, pos);
|
||||
pos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Utils.UIntToBytesSafepos(0, dest, pos);
|
||||
// pos += 4;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
}
|
||||
|
||||
//Utils.UIntToBytesSafepos(0, dest, pos); pos += 4; //update flags
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
|
||||
//pbs
|
||||
dest[pos++] = 16;
|
||||
dest[pos++] = 1;
|
||||
//Utils.UInt16ToBytes(0, dest, pos); pos += 2;
|
||||
//Utils.UInt16ToBytes(0, dest, pos); pos += 2;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
dest[pos++] = 0;
|
||||
|
||||
dest[pos++] = 100;
|
||||
dest[pos++] = 100;
|
||||
|
||||
// rest of pbs is 0 (15), texture entry (2) and texture anim (1)
|
||||
const int pbszeros = 15 + 2 + 1;
|
||||
Array.Clear(dest, pos, pbszeros); pos += pbszeros;
|
||||
|
||||
//NameValue
|
||||
byte[] nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
|
||||
data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
|
||||
int len = nv.Length;
|
||||
dest[pos++] = (byte)len;
|
||||
dest[pos++] = (byte)(len >> 8);
|
||||
Buffer.BlockCopy(nv, 0, dest, pos, len); pos += len;
|
||||
|
||||
// data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1),
|
||||
// sound id(16), sound owner(16) gain (4), flags (1), radius (4)
|
||||
// jointtype(1) joint pivot(12) joint offset(12)
|
||||
const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12;
|
||||
Array.Clear(dest, pos, lastzeros); pos += lastzeros;
|
||||
}
|
||||
|
||||
// protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
|
||||
protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp)
|
||||
{
|
||||
byte[] objectData = new byte[60];
|
||||
|
|
|
@ -274,10 +274,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||
public readonly float TickCountResolution;
|
||||
|
||||
/// <summary>Number of prim updates to put on the queue each time the
|
||||
/// OnQueueEmpty event is triggered for updates</summary>
|
||||
public readonly int PrimUpdatesPerCallback;
|
||||
|
||||
/// <summary>Number of texture packets to put on the queue each time the
|
||||
/// OnQueueEmpty event is triggered for textures</summary>
|
||||
public readonly int TextureSendLimit;
|
||||
|
@ -440,7 +436,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
||||
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
||||
|
||||
PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
|
||||
TextureSendLimit = config.GetInt("TextureSendLimit", 20);
|
||||
|
||||
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
||||
|
@ -451,7 +446,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
else
|
||||
{
|
||||
PrimUpdatesPerCallback = 100;
|
||||
TextureSendLimit = 20;
|
||||
m_ackTimeout = 1000 * 60; // 1 minute
|
||||
m_pausedAckTimeout = 1000 * 300; // 5 minutes
|
||||
|
@ -934,11 +928,73 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
#endregion Queue or Send
|
||||
}
|
||||
|
||||
public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input)
|
||||
{
|
||||
UDPPacketBuffer zb = GetNewUDPBuffer(null);
|
||||
int srclen = input.DataLength;
|
||||
byte[] src = input.Data;
|
||||
byte[] dest = zb.Data;
|
||||
|
||||
int zerolen = 6;
|
||||
byte zerocount = 0;
|
||||
|
||||
for (int i = zerolen; i < srclen; i++)
|
||||
{
|
||||
if (src[i] == 0x00)
|
||||
{
|
||||
zerocount++;
|
||||
if (zerocount == 0)
|
||||
{
|
||||
dest[zerolen++] = 0x00;
|
||||
dest[zerolen++] = 0xff;
|
||||
zerocount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zerocount != 0)
|
||||
{
|
||||
dest[zerolen++] = 0x00;
|
||||
dest[zerolen++] = zerocount;
|
||||
zerocount = 0;
|
||||
}
|
||||
|
||||
dest[zerolen++] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (zerocount != 0)
|
||||
{
|
||||
dest[zerolen++] = 0x00;
|
||||
dest[zerolen++] = zerocount;
|
||||
}
|
||||
|
||||
if(zerolen >= srclen)
|
||||
{
|
||||
FreeUDPBuffer(zb);
|
||||
|
||||
src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED);
|
||||
return input;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(src, 0, dest, 0, 6);
|
||||
|
||||
zb.RemoteEndPoint = input.RemoteEndPoint;
|
||||
zb.DataLength = zerolen;
|
||||
|
||||
FreeUDPBuffer(input);
|
||||
|
||||
return zb;
|
||||
}
|
||||
|
||||
public void SendUDPPacket(
|
||||
LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue)
|
||||
LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode)
|
||||
{
|
||||
bool highPriority = false;
|
||||
|
||||
if(zerocode)
|
||||
buffer = ZeroEncode(buffer);
|
||||
|
||||
if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
|
||||
{
|
||||
category = (ThrottleOutPacketType)((int)category & 127);
|
||||
|
|
|
@ -747,17 +747,6 @@
|
|||
;texture_default = 18500
|
||||
;asset_default = 10500
|
||||
|
||||
; Configures how ObjectUpdates are aggregated. These numbers
|
||||
; do not literally mean how many updates will be put in each
|
||||
; packet that goes over the wire, as packets are
|
||||
; automatically split on a 1400 byte boundary. These control
|
||||
; the balance between responsiveness of interest list updates
|
||||
; and total throughput. Higher numbers will ensure more full-
|
||||
; sized packets and faster sending of data, but more delay in
|
||||
; updating interest lists
|
||||
;
|
||||
;PrimUpdatesPerCallback = 100
|
||||
|
||||
; TextureSendLimit determines how many packets will be put on
|
||||
; the outgoing queue each cycle. Like the settings above, this
|
||||
; is a balance between responsiveness to priority updates and
|
||||
|
@ -767,16 +756,6 @@
|
|||
;
|
||||
;TextureSendLimit = 20
|
||||
|
||||
; CannibalizeTextureRate allows bandwidth to be moved from the
|
||||
; UDP texture throttle to the task throttle. Since most viewers
|
||||
; use HTTP textures, this provides a means of using what is largely
|
||||
; unused bandwidth in the total throttle. The value is the proportion
|
||||
; of the texture rate to move to the task queue. It must be between
|
||||
; 0.0 (none of the bandwidth is cannibalized) and 0.9 (90% of the
|
||||
; bandwidth is grabbed)
|
||||
;
|
||||
; CannibalizeTextureRate = 0.5
|
||||
|
||||
; Quash and remove any light properties from attachments not on the
|
||||
; hands. This allows flashlights and lanterns to function, but kills
|
||||
; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps
|
||||
|
|
Loading…
Reference in New Issue