diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 251 | ||||
-rwxr-xr-x | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 70 |
2 files changed, 212 insertions, 109 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index e039fbf..f8ff3c4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -3891,29 +3891,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3891 | if (ent == null) | 3891 | if (ent == null) |
3892 | return; | 3892 | return; |
3893 | 3893 | ||
3894 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3894 | if (ent is ScenePresence) |
3895 | objupdate.Header.Zerocoded = true; | ||
3896 | |||
3897 | objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | ||
3898 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3899 | |||
3900 | if(ent is ScenePresence) | ||
3901 | { | 3895 | { |
3902 | ScenePresence presence = ent as ScenePresence; | 3896 | ScenePresence presence = ent as ScenePresence; |
3903 | objupdate.RegionData.RegionHandle = presence.RegionHandle; | 3897 | |
3904 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); | 3898 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
3899 | |||
3900 | //setup header and regioninfo block | ||
3901 | Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); | ||
3902 | Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); | ||
3903 | Utils.UInt16ToBytes(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f), buf.Data, 15); | ||
3904 | |||
3905 | buf.Data[17] = 1; | ||
3906 | int pos = 18; | ||
3907 | CreateAvatarUpdateBlock(presence, buf.Data, ref pos); | ||
3908 | |||
3909 | buf.DataLength = pos; | ||
3910 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true); | ||
3905 | } | 3911 | } |
3912 | |||
3906 | else if(ent is SceneObjectPart) | 3913 | else if(ent is SceneObjectPart) |
3907 | { | 3914 | { |
3915 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||
3916 | objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | ||
3917 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3918 | |||
3908 | SceneObjectPart part = ent as SceneObjectPart; | 3919 | SceneObjectPart part = ent as SceneObjectPart; |
3909 | objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 3920 | objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; |
3910 | objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); | 3921 | objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); |
3911 | } | ||
3912 | 3922 | ||
3913 | OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); | 3923 | OutPacket(objupdate, ThrottleOutPacketType.Task); |
3924 | } | ||
3914 | 3925 | ||
3915 | // We need to record the avatar local id since the root prim of an attachment points to this. | 3926 | // We need to record the avatar local id since the root prim of an attachment points to this. |
3916 | // m_attachmentsSent.Add(avatar.LocalId); | 3927 | // m_attachmentsSent.Add(avatar.LocalId); |
3917 | } | 3928 | } |
3918 | 3929 | ||
3919 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) | 3930 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) |
@@ -4084,8 +4095,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4084 | ResendPrimUpdate(update); | 4095 | ResendPrimUpdate(update); |
4085 | } | 4096 | } |
4086 | 4097 | ||
4098 | static private readonly byte[] objectUpdateHeader = new byte[] { | ||
4099 | Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, | ||
4100 | 0, 0, 0, 0, // sequence number | ||
4101 | 0, // extra | ||
4102 | 12 // ID (high frequency) | ||
4103 | }; | ||
4104 | |||
4087 | static private readonly byte[] terseUpdateHeader = new byte[] { | 4105 | static private readonly byte[] terseUpdateHeader = new byte[] { |
4088 | Helpers.MSG_RELIABLE, | 4106 | Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec |
4089 | 0, 0, 0, 0, // sequence number | 4107 | 0, 0, 0, 0, // sequence number |
4090 | 0, // extra | 4108 | 0, // extra |
4091 | 15 // ID (high frequency) | 4109 | 15 // ID (high frequency) |
@@ -4105,7 +4123,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4105 | List<EntityUpdate> objectUpdates = null; | 4123 | List<EntityUpdate> objectUpdates = null; |
4106 | // List<EntityUpdate> compressedUpdates = null; | 4124 | // List<EntityUpdate> compressedUpdates = null; |
4107 | List<EntityUpdate> terseUpdates = null; | 4125 | List<EntityUpdate> terseUpdates = null; |
4108 | List<EntityUpdate> terseAgentUpdates = null; | ||
4109 | List<SceneObjectPart> ObjectAnimationUpdates = null; | 4126 | List<SceneObjectPart> ObjectAnimationUpdates = null; |
4110 | 4127 | ||
4111 | // Check to see if this is a flush | 4128 | // Check to see if this is a flush |
@@ -4275,7 +4292,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4275 | if(ObjectAnimationUpdates == null) | 4292 | if(ObjectAnimationUpdates == null) |
4276 | ObjectAnimationUpdates = new List<SceneObjectPart>(); | 4293 | ObjectAnimationUpdates = new List<SceneObjectPart>(); |
4277 | ObjectAnimationUpdates.Add(sop); | 4294 | ObjectAnimationUpdates.Add(sop); |
4278 | maxUpdatesBytes -= 32 * sop.Animations.Count + 16; | 4295 | maxUpdatesBytes -= 20 * sop.Animations.Count + 24; |
4279 | } | 4296 | } |
4280 | } | 4297 | } |
4281 | } | 4298 | } |
@@ -4329,37 +4346,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4329 | 4346 | ||
4330 | if ((updateFlags & canNotUseImprovedMask) == 0) | 4347 | if ((updateFlags & canNotUseImprovedMask) == 0) |
4331 | { | 4348 | { |
4349 | if (terseUpdates == null) | ||
4350 | { | ||
4351 | terseUpdates = new List<EntityUpdate>(); | ||
4352 | maxUpdatesBytes -= 18; | ||
4353 | } | ||
4354 | terseUpdates.Add(update); | ||
4332 | 4355 | ||
4333 | if (update.Entity is ScenePresence) | 4356 | if (update.Entity is ScenePresence) |
4334 | { | ||
4335 | // ALL presence updates go into a special list | ||
4336 | if (terseAgentUpdates == null) | ||
4337 | { | ||
4338 | terseAgentUpdates = new List<EntityUpdate>(); | ||
4339 | maxUpdatesBytes -= 18; | ||
4340 | } | ||
4341 | terseAgentUpdates.Add(update); | ||
4342 | maxUpdatesBytes -= 63; // no texture entry | 4357 | maxUpdatesBytes -= 63; // no texture entry |
4343 | } | ||
4344 | else | 4358 | else |
4345 | { | 4359 | { |
4346 | // Everything else goes here | 4360 | if ((updateFlags & PrimUpdateFlags.Textures) == 0) |
4347 | if (terseUpdates == null) | 4361 | maxUpdatesBytes -= 47; |
4348 | { | 4362 | else |
4349 | terseUpdates = new List<EntityUpdate>(); | 4363 | maxUpdatesBytes -= 150; // aprox |
4350 | maxUpdatesBytes -= 18; | ||
4351 | } | ||
4352 | terseUpdates.Add(update); | ||
4353 | maxUpdatesBytes -= 47; | ||
4354 | if ((updateFlags & PrimUpdateFlags.Textures) != 0) | ||
4355 | maxUpdatesBytes -= 100; // aprox | ||
4356 | } | 4364 | } |
4357 | } | 4365 | } |
4358 | else | 4366 | else |
4359 | { | 4367 | { |
4360 | ObjectUpdatePacket.ObjectDataBlock ablock; | 4368 | ObjectUpdatePacket.ObjectDataBlock ablock; |
4361 | if (update.Entity is ScenePresence) | 4369 | if (update.Entity is ScenePresence) |
4370 | { | ||
4362 | ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); | 4371 | ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); |
4372 | } | ||
4363 | else | 4373 | else |
4364 | ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); | 4374 | ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); |
4365 | if(objectUpdateBlocks == null) | 4375 | if(objectUpdateBlocks == null) |
@@ -4385,57 +4395,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4385 | 4395 | ||
4386 | timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | 4396 | timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); |
4387 | 4397 | ||
4388 | if (terseAgentUpdates != null) | ||
4389 | { | ||
4390 | const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry | ||
4391 | int blocks = terseAgentUpdates.Count; | ||
4392 | int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; | ||
4393 | List<EntityUpdate> tau = new List<EntityUpdate>(curNBlocks); | ||
4394 | |||
4395 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
4396 | |||
4397 | //setup header and regioninfo block | ||
4398 | Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7); | ||
4399 | Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); | ||
4400 | Utils.UInt16ToBytes(timeDilation, buf.Data, 15); | ||
4401 | buf.Data[17] = (byte)curNBlocks; | ||
4402 | int pos = 18; | ||
4403 | |||
4404 | int count = 0; | ||
4405 | foreach (EntityUpdate eu in terseAgentUpdates) | ||
4406 | { | ||
4407 | CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, false); | ||
4408 | tau.Add(eu); | ||
4409 | ++count; | ||
4410 | --blocks; | ||
4411 | if (count == curNBlocks && blocks > 0) | ||
4412 | { | ||
4413 | // we need more packets | ||
4414 | UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
4415 | Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, 17); // start is the same | ||
4416 | |||
4417 | buf.DataLength = pos; | ||
4418 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, | ||
4419 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); | ||
4420 | |||
4421 | curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; | ||
4422 | tau = new List<EntityUpdate>(curNBlocks); | ||
4423 | count = 0; | ||
4424 | |||
4425 | buf = newbuf; | ||
4426 | buf.Data[17] = (byte)curNBlocks; | ||
4427 | pos = 18; | ||
4428 | } | ||
4429 | } | ||
4430 | |||
4431 | if (count > 0) | ||
4432 | { | ||
4433 | buf.DataLength = pos; | ||
4434 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, | ||
4435 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); | ||
4436 | } | ||
4437 | } | ||
4438 | |||
4439 | if (objectUpdateBlocks != null) | 4398 | if (objectUpdateBlocks != null) |
4440 | { | 4399 | { |
4441 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 4400 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
@@ -4497,8 +4456,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4497 | 4456 | ||
4498 | buf.Data[17] = (byte)count; | 4457 | buf.Data[17] = (byte)count; |
4499 | buf.DataLength = lastpos; | 4458 | buf.DataLength = lastpos; |
4459 | // zero encode is not as spec | ||
4500 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, | 4460 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, |
4501 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); | 4461 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true); |
4502 | 4462 | ||
4503 | tau = new List<EntityUpdate>(30); | 4463 | tau = new List<EntityUpdate>(30); |
4504 | tau.Add(eu); | 4464 | tau.Add(eu); |
@@ -4513,7 +4473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4513 | buf.Data[17] = (byte)count; | 4473 | buf.Data[17] = (byte)count; |
4514 | buf.DataLength = pos; | 4474 | buf.DataLength = pos; |
4515 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, | 4475 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, |
4516 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); | 4476 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true); |
4517 | } | 4477 | } |
4518 | } | 4478 | } |
4519 | 4479 | ||
@@ -4534,13 +4494,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4534 | UUID[] ids = null; | 4494 | UUID[] ids = null; |
4535 | int[] seqs = null; | 4495 | int[] seqs = null; |
4536 | int count = sop.GetAnimations(out ids, out seqs); | 4496 | int count = sop.GetAnimations(out ids, out seqs); |
4537 | if(count < 0) | ||
4538 | continue; | ||
4539 | 4497 | ||
4540 | ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation); | 4498 | ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation); |
4541 | ani.Sender = new ObjectAnimationPacket.SenderBlock(); | 4499 | ani.Sender = new ObjectAnimationPacket.SenderBlock(); |
4542 | ani.Sender.ID = sop.UUID; | 4500 | ani.Sender.ID = sop.UUID; |
4543 | ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[sop.Animations.Count]; | 4501 | ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[count]; |
4544 | 4502 | ||
4545 | for(int i = 0; i< count; i++) | 4503 | for(int i = 0; i< count; i++) |
4546 | { | 4504 | { |
@@ -5732,7 +5690,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5732 | return block; | 5690 | return block; |
5733 | } | 5691 | } |
5734 | 5692 | ||
5735 | |||
5736 | protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture) | 5693 | protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture) |
5737 | { | 5694 | { |
5738 | #region ScenePresence/SOP Handling | 5695 | #region ScenePresence/SOP Handling |
@@ -5871,7 +5828,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5871 | 5828 | ||
5872 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) | 5829 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) |
5873 | { | 5830 | { |
5874 | Vector3 offsetPosition = data.OffsetPosition; | ||
5875 | Quaternion rotation = data.Rotation; | 5831 | Quaternion rotation = data.Rotation; |
5876 | // tpvs can only see rotations around Z in some cases | 5832 | // tpvs can only see rotations around Z in some cases |
5877 | if(!data.Flying && !data.IsSatOnObject) | 5833 | if(!data.Flying && !data.IsSatOnObject) |
@@ -5881,27 +5837,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5881 | } | 5837 | } |
5882 | rotation.Normalize(); | 5838 | rotation.Normalize(); |
5883 | 5839 | ||
5884 | uint parentID = data.ParentID; | ||
5885 | |||
5886 | // m_log.DebugFormat( | 5840 | // m_log.DebugFormat( |
5887 | // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); | 5841 | // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); |
5888 | 5842 | ||
5889 | byte[] objectData = new byte[76]; | 5843 | byte[] objectData = new byte[76]; |
5890 | 5844 | ||
5891 | Vector3 velocity = new Vector3(0, 0, 0); | 5845 | //Vector3 velocity = Vector3.Zero; |
5892 | Vector3 acceleration = new Vector3(0, 0, 0); | 5846 | Vector3 acceleration = Vector3.Zero; |
5847 | Vector3 angularvelocity = Vector3.Zero; | ||
5893 | 5848 | ||
5894 | data.CollisionPlane.ToBytes(objectData, 0); | 5849 | data.CollisionPlane.ToBytes(objectData, 0); |
5895 | offsetPosition.ToBytes(objectData, 16); | 5850 | data.OffsetPosition.ToBytes(objectData, 16); |
5896 | velocity.ToBytes(objectData, 28); | 5851 | data.Velocity.ToBytes(objectData, 28); |
5897 | acceleration.ToBytes(objectData, 40); | 5852 | acceleration.ToBytes(objectData, 40); |
5898 | rotation.ToBytes(objectData, 52); | 5853 | rotation.ToBytes(objectData, 52); |
5899 | data.AngularVelocity.ToBytes(objectData, 64); | 5854 | angularvelocity.ToBytes(objectData, 64); |
5900 | 5855 | ||
5901 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | 5856 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); |
5902 | 5857 | ||
5903 | update.Data = Utils.EmptyBytes; | 5858 | update.Data = Utils.EmptyBytes; |
5904 | update.ExtraParams = new byte[1]; | 5859 | update.ExtraParams = Utils.EmptyBytes; |
5905 | update.FullID = data.UUID; | 5860 | update.FullID = data.UUID; |
5906 | update.ID = data.LocalId; | 5861 | update.ID = data.LocalId; |
5907 | update.Material = (byte)Material.Flesh; | 5862 | update.Material = (byte)Material.Flesh; |
@@ -5938,7 +5893,99 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5938 | return update; | 5893 | return update; |
5939 | } | 5894 | } |
5940 | 5895 | ||
5941 | // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) | 5896 | protected void CreateAvatarUpdateBlock(ScenePresence data, byte[] dest, ref int pos) |
5897 | { | ||
5898 | Quaternion rotation = data.Rotation; | ||
5899 | // tpvs can only see rotations around Z in some cases | ||
5900 | if (!data.Flying && !data.IsSatOnObject) | ||
5901 | { | ||
5902 | rotation.X = 0f; | ||
5903 | rotation.Y = 0f; | ||
5904 | } | ||
5905 | rotation.Normalize(); | ||
5906 | |||
5907 | //Vector3 velocity = Vector3.Zero; | ||
5908 | //Vector3 acceleration = Vector3.Zero; | ||
5909 | //Vector3 angularvelocity = Vector3.Zero; | ||
5910 | |||
5911 | Utils.UIntToBytesSafepos(data.LocalId, dest, pos); pos += 4; | ||
5912 | dest[pos++] = 0; // state | ||
5913 | data.UUID.ToBytes(dest, pos); pos += 16; | ||
5914 | Utils.UIntToBytesSafepos(0 , dest, pos); pos += 4; // crc | ||
5915 | dest[pos++] = (byte)PCode.Avatar; | ||
5916 | dest[pos++] = (byte)Material.Flesh; | ||
5917 | dest[pos++] = 0; // clickaction | ||
5918 | data.Appearance.AvatarSize.ToBytes(dest, pos); pos += 12; | ||
5919 | |||
5920 | // objectdata block | ||
5921 | dest[pos++] = 76; | ||
5922 | data.CollisionPlane.ToBytes(dest, pos); pos += 16; | ||
5923 | data.OffsetPosition.ToBytes(dest, pos); pos += 12; | ||
5924 | data.Velocity.ToBytes(dest, pos); pos += 12; | ||
5925 | |||
5926 | //acceleration.ToBytes(dest, pos); pos += 12; | ||
5927 | Array.Clear(dest, pos, 12); pos += 12; | ||
5928 | |||
5929 | rotation.ToBytes(dest, pos); pos += 12; | ||
5930 | |||
5931 | //angularvelocity.ToBytes(dest, pos); pos += 12; | ||
5932 | Array.Clear(dest, pos, 12); pos += 12; | ||
5933 | |||
5934 | SceneObjectPart parentPart = data.ParentPart; | ||
5935 | if (parentPart != null) | ||
5936 | { | ||
5937 | Utils.UIntToBytesSafepos(parentPart.ParentGroup.LocalId, dest, pos); | ||
5938 | pos += 4; | ||
5939 | } | ||
5940 | else | ||
5941 | { | ||
5942 | // Utils.UIntToBytesSafepos(0, dest, pos); | ||
5943 | // pos += 4; | ||
5944 | dest[pos++] = 0; | ||
5945 | dest[pos++] = 0; | ||
5946 | dest[pos++] = 0; | ||
5947 | dest[pos++] = 0; | ||
5948 | } | ||
5949 | |||
5950 | //Utils.UIntToBytesSafepos(0, dest, pos); pos += 4; //update flags | ||
5951 | dest[pos++] = 0; | ||
5952 | dest[pos++] = 0; | ||
5953 | dest[pos++] = 0; | ||
5954 | dest[pos++] = 0; | ||
5955 | |||
5956 | //pbs | ||
5957 | dest[pos++] = 16; | ||
5958 | dest[pos++] = 1; | ||
5959 | //Utils.UInt16ToBytes(0, dest, pos); pos += 2; | ||
5960 | //Utils.UInt16ToBytes(0, dest, pos); pos += 2; | ||
5961 | dest[pos++] = 0; | ||
5962 | dest[pos++] = 0; | ||
5963 | dest[pos++] = 0; | ||
5964 | dest[pos++] = 0; | ||
5965 | |||
5966 | dest[pos++] = 100; | ||
5967 | dest[pos++] = 100; | ||
5968 | |||
5969 | // rest of pbs is 0 (15), texture entry (2) and texture anim (1) | ||
5970 | const int pbszeros = 15 + 2 + 1; | ||
5971 | Array.Clear(dest, pos, pbszeros); pos += pbszeros; | ||
5972 | |||
5973 | //NameValue | ||
5974 | byte[] nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + | ||
5975 | data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); | ||
5976 | int len = nv.Length; | ||
5977 | dest[pos++] = (byte)len; | ||
5978 | dest[pos++] = (byte)(len >> 8); | ||
5979 | Buffer.BlockCopy(nv, 0, dest, pos, len); pos += len; | ||
5980 | |||
5981 | // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1), | ||
5982 | // sound id(16), sound owner(16) gain (4), flags (1), radius (4) | ||
5983 | // jointtype(1) joint pivot(12) joint offset(12) | ||
5984 | const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12; | ||
5985 | Array.Clear(dest, pos, lastzeros); pos += lastzeros; | ||
5986 | } | ||
5987 | |||
5988 | // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) | ||
5942 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) | 5989 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) |
5943 | { | 5990 | { |
5944 | byte[] objectData = new byte[60]; | 5991 | byte[] objectData = new byte[60]; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 653f648..6fd782a 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -274,10 +274,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
274 | /// <summary>The measured resolution of Environment.TickCount</summary> | 274 | /// <summary>The measured resolution of Environment.TickCount</summary> |
275 | public readonly float TickCountResolution; | 275 | public readonly float TickCountResolution; |
276 | 276 | ||
277 | /// <summary>Number of prim updates to put on the queue each time the | ||
278 | /// OnQueueEmpty event is triggered for updates</summary> | ||
279 | public readonly int PrimUpdatesPerCallback; | ||
280 | |||
281 | /// <summary>Number of texture packets to put on the queue each time the | 277 | /// <summary>Number of texture packets to put on the queue each time the |
282 | /// OnQueueEmpty event is triggered for textures</summary> | 278 | /// OnQueueEmpty event is triggered for textures</summary> |
283 | public readonly int TextureSendLimit; | 279 | public readonly int TextureSendLimit; |
@@ -440,7 +436,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
440 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); | 436 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); |
441 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); | 437 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); |
442 | 438 | ||
443 | PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100); | ||
444 | TextureSendLimit = config.GetInt("TextureSendLimit", 20); | 439 | TextureSendLimit = config.GetInt("TextureSendLimit", 20); |
445 | 440 | ||
446 | m_defaultRTO = config.GetInt("DefaultRTO", 0); | 441 | m_defaultRTO = config.GetInt("DefaultRTO", 0); |
@@ -451,7 +446,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
451 | } | 446 | } |
452 | else | 447 | else |
453 | { | 448 | { |
454 | PrimUpdatesPerCallback = 100; | ||
455 | TextureSendLimit = 20; | 449 | TextureSendLimit = 20; |
456 | m_ackTimeout = 1000 * 60; // 1 minute | 450 | m_ackTimeout = 1000 * 60; // 1 minute |
457 | m_pausedAckTimeout = 1000 * 300; // 5 minutes | 451 | m_pausedAckTimeout = 1000 * 300; // 5 minutes |
@@ -934,11 +928,73 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
934 | #endregion Queue or Send | 928 | #endregion Queue or Send |
935 | } | 929 | } |
936 | 930 | ||
931 | public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input) | ||
932 | { | ||
933 | UDPPacketBuffer zb = GetNewUDPBuffer(null); | ||
934 | int srclen = input.DataLength; | ||
935 | byte[] src = input.Data; | ||
936 | byte[] dest = zb.Data; | ||
937 | |||
938 | int zerolen = 6; | ||
939 | byte zerocount = 0; | ||
940 | |||
941 | for (int i = zerolen; i < srclen; i++) | ||
942 | { | ||
943 | if (src[i] == 0x00) | ||
944 | { | ||
945 | zerocount++; | ||
946 | if (zerocount == 0) | ||
947 | { | ||
948 | dest[zerolen++] = 0x00; | ||
949 | dest[zerolen++] = 0xff; | ||
950 | zerocount++; | ||
951 | } | ||
952 | } | ||
953 | else | ||
954 | { | ||
955 | if (zerocount != 0) | ||
956 | { | ||
957 | dest[zerolen++] = 0x00; | ||
958 | dest[zerolen++] = zerocount; | ||
959 | zerocount = 0; | ||
960 | } | ||
961 | |||
962 | dest[zerolen++] = src[i]; | ||
963 | } | ||
964 | } | ||
965 | |||
966 | if (zerocount != 0) | ||
967 | { | ||
968 | dest[zerolen++] = 0x00; | ||
969 | dest[zerolen++] = zerocount; | ||
970 | } | ||
971 | |||
972 | if(zerolen >= srclen) | ||
973 | { | ||
974 | FreeUDPBuffer(zb); | ||
975 | |||
976 | src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED); | ||
977 | return input; | ||
978 | } | ||
979 | |||
980 | Buffer.BlockCopy(src, 0, dest, 0, 6); | ||
981 | |||
982 | zb.RemoteEndPoint = input.RemoteEndPoint; | ||
983 | zb.DataLength = zerolen; | ||
984 | |||
985 | FreeUDPBuffer(input); | ||
986 | |||
987 | return zb; | ||
988 | } | ||
989 | |||
937 | public void SendUDPPacket( | 990 | public void SendUDPPacket( |
938 | LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue) | 991 | LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode) |
939 | { | 992 | { |
940 | bool highPriority = false; | 993 | bool highPriority = false; |
941 | 994 | ||
995 | if(zerocode) | ||
996 | buffer = ZeroEncode(buffer); | ||
997 | |||
942 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) | 998 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) |
943 | { | 999 | { |
944 | category = (ThrottleOutPacketType)((int)category & 127); | 1000 | category = (ThrottleOutPacketType)((int)category & 127); |