aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorUbitUmarov2019-02-27 10:07:25 +0000
committerUbitUmarov2019-02-27 10:07:25 +0000
commitbcf05afd64d3b38c66d6d117a51e336a7e98dfc3 (patch)
tree86e40c3780aa30a1bb2559a30ff4f48d38d02fd3 /OpenSim
parentavoid packet split on terseupdates (diff)
downloadopensim-SC-bcf05afd64d3b38c66d6d117a51e336a7e98dfc3.zip
opensim-SC-bcf05afd64d3b38c66d6d117a51e336a7e98dfc3.tar.gz
opensim-SC-bcf05afd64d3b38c66d6d117a51e336a7e98dfc3.tar.bz2
opensim-SC-bcf05afd64d3b38c66d6d117a51e336a7e98dfc3.tar.xz
direct encode terseupdates
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs210
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs11
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs21
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs2
4 files changed, 207 insertions, 37 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index f28534b..a9edf08 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4084,6 +4084,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4084 ResendPrimUpdate(update); 4084 ResendPrimUpdate(update);
4085 } 4085 }
4086 4086
4087 static private readonly byte[] terseUpdateHeader = new byte[] {
4088 Helpers.MSG_RELIABLE,
4089 0, 0, 0, 0, // sequence number
4090 0, // extra
4091 15 // ID (high frequency)
4092 };
4093
4087 private void ProcessEntityUpdates(int maxUpdatesBytes) 4094 private void ProcessEntityUpdates(int maxUpdatesBytes)
4088 { 4095 {
4089 if (!IsActive) 4096 if (!IsActive)
@@ -4377,38 +4384,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4377 { 4384 {
4378 const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry 4385 const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry
4379 int blocks = terseAgentUpdates.Count; 4386 int blocks = terseAgentUpdates.Count;
4380
4381 ImprovedTerseObjectUpdatePacket packet
4382 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4383 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4384 packet.RegionData.TimeDilation = timeDilation;
4385
4386 int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; 4387 int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks;
4387 List<EntityUpdate> tau = new List<EntityUpdate>(curNBlocks); 4388 List<EntityUpdate> tau = new List<EntityUpdate>(curNBlocks);
4388 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; 4389
4390 UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
4391
4392 //setup header and regioninfo block
4393 Array.Copy(terseUpdateHeader, buf.Data, 7);
4394 Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7);
4395 Utils.UInt16ToBytes(timeDilation, buf.Data, 15);
4396 buf.Data[17] = (byte)curNBlocks;
4397 int pos = 18;
4389 4398
4390 int count = 0; 4399 int count = 0;
4391 foreach (EntityUpdate eu in terseAgentUpdates) 4400 foreach (EntityUpdate eu in terseAgentUpdates)
4392 { 4401 {
4393 packet.ObjectData[count++] = CreateImprovedTerseBlock(eu.Entity); 4402 CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos);
4394 tau.Add(eu); 4403 tau.Add(eu);
4404 ++count;
4395 --blocks; 4405 --blocks;
4396 if (count == curNBlocks && blocks > 0) 4406 if (count == curNBlocks && blocks > 0)
4397 { 4407 {
4398 OutPacket(packet, ThrottleOutPacketType.Unknown, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); 4408 // we need more packets
4399 packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4409 UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
4400 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4410 Array.Copy(buf.Data, newbuf.Data, 17); // start is the same
4401 packet.RegionData.TimeDilation = timeDilation; 4411
4412 buf.DataLength = pos;
4413 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown,
4414 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
4402 4415
4403 curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; 4416 curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks;
4404 tau = new List<EntityUpdate>(curNBlocks); 4417 tau = new List<EntityUpdate>(curNBlocks);
4405 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks];
4406 count = 0; 4418 count = 0;
4419
4420 buf = newbuf;
4421 buf.Data[17] = (byte)curNBlocks;
4422 pos = 18;
4407 } 4423 }
4408 } 4424 }
4409 4425
4410 if (tau.Count > 0) 4426 if (count > 0)
4411 OutPacket(packet, ThrottleOutPacketType.Unknown, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); 4427 {
4428 buf.DataLength = pos;
4429 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown,
4430 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
4431 }
4412 } 4432 }
4413 4433
4414 if (objectUpdateBlocks != null) 4434 if (objectUpdateBlocks != null)
@@ -4437,38 +4457,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4437 { 4457 {
4438 const int maxNBlocks = (LLUDPServer.MTU - 18) / 47; // no texture entry 4458 const int maxNBlocks = (LLUDPServer.MTU - 18) / 47; // no texture entry
4439 int blocks = terseUpdates.Count; 4459 int blocks = terseUpdates.Count;
4440
4441 ImprovedTerseObjectUpdatePacket packet =
4442 (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4443 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4444 packet.RegionData.TimeDilation = timeDilation;
4445
4446 int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; 4460 int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks;
4447 List<EntityUpdate> tau = new List<EntityUpdate>(curNBlocks); 4461 List<EntityUpdate> tau = new List<EntityUpdate>(curNBlocks);
4448 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; 4462
4463 UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
4464
4465 //setup header and regioninfo block
4466 Array.Copy(terseUpdateHeader, buf.Data, 7);
4467 Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7);
4468 Utils.UInt16ToBytes(timeDilation, buf.Data, 15);
4469 buf.Data[17] = (byte)curNBlocks;
4470 int pos = 18;
4449 4471
4450 int count = 0; 4472 int count = 0;
4451 foreach (EntityUpdate eu in terseUpdates) 4473 foreach (EntityUpdate eu in terseUpdates)
4452 { 4474 {
4453 packet.ObjectData[count++] = CreateImprovedTerseBlock(eu.Entity); 4475 CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos);
4454 tau.Add(eu); 4476 tau.Add(eu);
4477 ++count;
4455 --blocks; 4478 --blocks;
4456 if (count == curNBlocks && blocks > 0) 4479 if (count == curNBlocks && blocks > 0)
4457 { 4480 {
4458 OutPacket(packet, ThrottleOutPacketType.Task, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); 4481 // we need more packets
4459 packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4482 UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
4460 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4483 Array.Copy(buf.Data, newbuf.Data, 17); // start is the same
4461 packet.RegionData.TimeDilation = timeDilation; 4484
4485 buf.DataLength = pos;
4486 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
4487 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
4462 4488
4463 curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; 4489 curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks;
4464 tau = new List<EntityUpdate>(curNBlocks); 4490 tau = new List<EntityUpdate>(curNBlocks);
4465 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks];
4466 count = 0; 4491 count = 0;
4492
4493 buf = newbuf;
4494 buf.Data[17] = (byte)curNBlocks;
4495 pos = 18;
4467 } 4496 }
4468 } 4497 }
4469 4498
4470 if (tau.Count > 0) 4499 if (count > 0)
4471 OutPacket(packet, ThrottleOutPacketType.Task, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); 4500 {
4501 buf.DataLength = pos;
4502 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
4503 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false);
4504 }
4472 } 4505 }
4473 4506
4474 if (ObjectAnimationUpdates != null) 4507 if (ObjectAnimationUpdates != null)
@@ -5686,6 +5719,123 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5686 return block; 5719 return block;
5687 } 5720 }
5688 5721
5722
5723 protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos)
5724 {
5725 #region ScenePresence/SOP Handling
5726
5727 bool avatar = (entity is ScenePresence);
5728 uint localID = entity.LocalId;
5729 uint attachPoint;
5730 Vector4 collisionPlane;
5731 Vector3 position, velocity, acceleration, angularVelocity;
5732 Quaternion rotation;
5733 byte datasize;
5734
5735 if (avatar)
5736 {
5737 ScenePresence presence = (ScenePresence)entity;
5738
5739 position = presence.OffsetPosition;
5740 velocity = presence.Velocity;
5741 acceleration = Vector3.Zero;
5742 rotation = presence.Rotation;
5743 // tpvs can only see rotations around Z in some cases
5744 if (!presence.Flying && !presence.IsSatOnObject)
5745 {
5746 rotation.X = 0f;
5747 rotation.Y = 0f;
5748 }
5749 rotation.Normalize();
5750 angularVelocity = presence.AngularVelocity;
5751
5752 // m_log.DebugFormat(
5753 // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name);
5754
5755 attachPoint = presence.State;
5756 collisionPlane = presence.CollisionPlane;
5757
5758 datasize = 60;
5759 }
5760 else
5761 {
5762 SceneObjectPart part = (SceneObjectPart)entity;
5763
5764 attachPoint = part.ParentGroup.AttachmentPoint;
5765 attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
5766 // m_log.DebugFormat(
5767 // "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
5768 // attachPoint, part.Name, part.LocalId, Name);
5769
5770 collisionPlane = Vector4.Zero;
5771 position = part.RelativePosition;
5772 velocity = part.Velocity;
5773 acceleration = part.Acceleration;
5774 angularVelocity = part.AngularVelocity;
5775 rotation = part.RotationOffset;
5776
5777 datasize = 44;
5778 }
5779
5780 #endregion ScenePresence/SOP Handling
5781 //object block size
5782 data[pos++] = datasize;
5783
5784 // LocalID
5785 Utils.UIntToBytes(localID, data, pos);
5786 pos += 4;
5787
5788 // Avatar/CollisionPlane
5789 data[pos++] = (byte)attachPoint;
5790 if (avatar)
5791 {
5792 data[pos++] = 1;
5793
5794 if (collisionPlane == Vector4.Zero)
5795 collisionPlane = Vector4.UnitW;
5796 //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane);
5797 collisionPlane.ToBytes(data, pos);
5798 pos += 16;
5799 }
5800 else
5801 {
5802 data[pos++] = 0;
5803 }
5804
5805 // Position
5806 position.ToBytes(data, pos);
5807 pos += 12;
5808
5809 // Velocity
5810 ClampVectorForUint(ref velocity, 128f);
5811 Utils.FloatToUInt16Bytes(velocity.X, 128.0f, data, pos); pos += 2;
5812 Utils.FloatToUInt16Bytes(velocity.Y, 128.0f, data, pos); pos += 2;
5813 Utils.FloatToUInt16Bytes(velocity.Z, 128.0f, data, pos); pos += 2;
5814
5815 // Acceleration
5816 ClampVectorForUint(ref acceleration, 64f);
5817 Utils.FloatToUInt16Bytes(acceleration.X, 64.0f, data, pos); pos += 2;
5818 Utils.FloatToUInt16Bytes(acceleration.Y, 64.0f, data, pos); pos += 2;
5819 Utils.FloatToUInt16Bytes(acceleration.Z, 64.0f, data, pos); pos += 2;
5820
5821 // Rotation
5822 Utils.FloatToUInt16Bytes(rotation.X, 1.0f, data, pos); pos += 2;
5823 Utils.FloatToUInt16Bytes(rotation.Y, 1.0f, data, pos); pos += 2;
5824 Utils.FloatToUInt16Bytes(rotation.Z, 1.0f, data, pos); pos += 2;
5825 Utils.FloatToUInt16Bytes(rotation.W, 1.0f, data, pos); pos += 2;
5826
5827 // Angular Velocity
5828 ClampVectorForUint(ref angularVelocity, 64f);
5829 Utils.FloatToUInt16Bytes(angularVelocity.X, 64.0f, data, pos); pos += 2;
5830 Utils.FloatToUInt16Bytes(angularVelocity.Y, 64.0f, data, pos); pos += 2;
5831 Utils.FloatToUInt16Bytes(angularVelocity.Z, 64.0f, data, pos); pos += 2;
5832
5833 // texture entry block size
5834 data[pos++] = 0;
5835 data[pos++] = 0;
5836 // total size 63 or 47
5837 }
5838
5689 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5839 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5690 { 5840 {
5691 Vector3 offsetPosition = data.OffsetPosition; 5841 Vector3 offsetPosition = data.OffsetPosition;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index fca7943..d0d2152 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -575,22 +575,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
575 { 575 {
576 DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 576 DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
577 577
578 if (m_deliverPackets == false) 578 if (forceQueue || m_deliverPackets == false)
579 { 579 {
580 queue.Enqueue(packet, highPriority); 580 queue.Enqueue(packet, highPriority);
581 return true; 581 return true;
582 } 582 }
583 583
584 TokenBucket bucket = m_throttleCategories[category]; 584 // need to enqueue if queue is not empty
585
586 // Don't send this packet if queue is not empty
587 if (queue.Count > 0 || m_nextPackets[category] != null) 585 if (queue.Count > 0 || m_nextPackets[category] != null)
588 { 586 {
589 queue.Enqueue(packet, highPriority); 587 queue.Enqueue(packet, highPriority);
590 return true; 588 return true;
591 } 589 }
592 590
593 if (!forceQueue && bucket.CheckTokens(packet.Buffer.DataLength)) 591 // check bandwidth
592 TokenBucket bucket = m_throttleCategories[category];
593 if (bucket.CheckTokens(packet.Buffer.DataLength))
594 { 594 {
595 // enough tokens so it can be sent imediatly by caller 595 // enough tokens so it can be sent imediatly by caller
596 bucket.RemoveTokens(packet.Buffer.DataLength); 596 bucket.RemoveTokens(packet.Buffer.DataLength);
@@ -608,7 +608,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
608 // We don't have a token bucket for this category, so it will not be queued 608 // We don't have a token bucket for this category, so it will not be queued
609 return false; 609 return false;
610 } 610 }
611
612 } 611 }
613 612
614 /// <summary> 613 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d324623..f12b3b9 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -934,6 +934,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
934 #endregion Queue or Send 934 #endregion Queue or Send
935 } 935 }
936 936
937 public void SendUDPPacket(
938 LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue)
939 {
940 bool highPriority = false;
941
942 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
943 {
944 category = (ThrottleOutPacketType)((int)category & 127);
945 highPriority = true;
946 }
947
948 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
949
950 // If we were not provided a method for handling unacked, use the UDPServer default method
951 if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
952 outgoingPacket.UnackedMethod = ((method == null) ? delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
953
954 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forcequeue, highPriority))
955 SendPacketFinal(outgoingPacket);
956 }
957
937 public void SendAcks(LLUDPClient udpClient) 958 public void SendAcks(LLUDPClient udpClient)
938 { 959 {
939 uint ack; 960 uint ack;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6f346d3..49aca3c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -489,7 +489,7 @@ namespace OpenMetaverse
489 public void SyncSend(UDPPacketBuffer buf) 489 public void SyncSend(UDPPacketBuffer buf)
490 { 490 {
491 if(buf.RemoteEndPoint == null) 491 if(buf.RemoteEndPoint == null)
492 return; // was already expired 492 return; // already expired
493 try 493 try
494 { 494 {
495 m_udpSocket.SendTo( 495 m_udpSocket.SendTo(