aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs682
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 414 insertions, 291 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index e9e2dca..9dd6663 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -202,6 +202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 m_stopPacket = TexturePacketCount(); 202 m_stopPacket = TexturePacketCount();
203 } 203 }
204 204
205 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
206 if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
207
205 m_currentPacket = StartPacket; 208 m_currentPacket = StartPacket;
206 } 209 }
207 } 210 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 133da0f..8fdbe7b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -157,6 +157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
157 public event RequestTaskInventory OnRequestTaskInventory; 157 public event RequestTaskInventory OnRequestTaskInventory;
158 public event UpdateInventoryItem OnUpdateInventoryItem; 158 public event UpdateInventoryItem OnUpdateInventoryItem;
159 public event CopyInventoryItem OnCopyInventoryItem; 159 public event CopyInventoryItem OnCopyInventoryItem;
160 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
160 public event MoveInventoryItem OnMoveInventoryItem; 161 public event MoveInventoryItem OnMoveInventoryItem;
161 public event RemoveInventoryItem OnRemoveInventoryItem; 162 public event RemoveInventoryItem OnRemoveInventoryItem;
162 public event RemoveInventoryFolder OnRemoveInventoryFolder; 163 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -254,7 +255,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
254 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 255 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
255 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 256 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
256 public event ClassifiedDelete OnClassifiedDelete; 257 public event ClassifiedDelete OnClassifiedDelete;
257 public event ClassifiedDelete OnClassifiedGodDelete; 258 public event ClassifiedGodDelete OnClassifiedGodDelete;
258 public event EventNotificationAddRequest OnEventNotificationAddRequest; 259 public event EventNotificationAddRequest OnEventNotificationAddRequest;
259 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 260 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
260 public event EventGodDelete OnEventGodDelete; 261 public event EventGodDelete OnEventGodDelete;
@@ -330,7 +331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
330 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 331 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
331 /// ownerless phantom. 332 /// ownerless phantom.
332 /// 333 ///
333 /// All manipulation of this set has to occur under a lock 334 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
334 /// 335 ///
335 /// </value> 336 /// </value>
336 protected HashSet<uint> m_killRecord; 337 protected HashSet<uint> m_killRecord;
@@ -338,6 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338// protected HashSet<uint> m_attachmentsSent; 339// protected HashSet<uint> m_attachmentsSent;
339 340
340 private int m_moneyBalance; 341 private int m_moneyBalance;
342 private bool m_deliverPackets = true;
341 private int m_animationSequenceNumber = 1; 343 private int m_animationSequenceNumber = 1;
342 private bool m_SendLogoutPacketWhenClosing = true; 344 private bool m_SendLogoutPacketWhenClosing = true;
343 private AgentUpdateArgs lastarg; 345 private AgentUpdateArgs lastarg;
@@ -378,6 +380,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
378 get { return m_startpos; } 380 get { return m_startpos; }
379 set { m_startpos = value; } 381 set { m_startpos = value; }
380 } 382 }
383 public bool DeliverPackets
384 {
385 get { return m_deliverPackets; }
386 set {
387 m_deliverPackets = value;
388 m_udpClient.m_deliverPackets = value;
389 }
390 }
381 public UUID AgentId { get { return m_agentId; } } 391 public UUID AgentId { get { return m_agentId; } }
382 public UUID ActiveGroupId { get { return m_activeGroupID; } } 392 public UUID ActiveGroupId { get { return m_activeGroupID; } }
383 public string ActiveGroupName { get { return m_activeGroupName; } } 393 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -479,18 +489,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
479 489
480 #region Client Methods 490 #region Client Methods
481 491
492
482 /// <summary> 493 /// <summary>
483 /// Shut down the client view 494 /// Shut down the client view
484 /// </summary> 495 /// </summary>
485 public void Close() 496 public void Close()
486 { 497 {
498 Close(true);
499 }
500
501 /// <summary>
502 /// Shut down the client view
503 /// </summary>
504 public void Close(bool sendStop)
505 {
487 m_log.DebugFormat( 506 m_log.DebugFormat(
488 "[CLIENT]: Close has been called for {0} attached to scene {1}", 507 "[CLIENT]: Close has been called for {0} attached to scene {1}",
489 Name, m_scene.RegionInfo.RegionName); 508 Name, m_scene.RegionInfo.RegionName);
490 509
491 // Send the STOP packet 510 if (sendStop)
492 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 511 {
493 OutPacket(disable, ThrottleOutPacketType.Unknown); 512 // Send the STOP packet
513 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
514 OutPacket(disable, ThrottleOutPacketType.Unknown);
515 }
494 516
495 IsActive = false; 517 IsActive = false;
496 518
@@ -791,7 +813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 reply.ChatData.OwnerID = fromAgentID; 813 reply.ChatData.OwnerID = fromAgentID;
792 reply.ChatData.SourceID = fromAgentID; 814 reply.ChatData.SourceID = fromAgentID;
793 815
794 OutPacket(reply, ThrottleOutPacketType.Task); 816 OutPacket(reply, ThrottleOutPacketType.Unknown);
795 } 817 }
796 818
797 /// <summary> 819 /// <summary>
@@ -1077,6 +1099,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1077 public virtual void SendLayerData(float[] map) 1099 public virtual void SendLayerData(float[] map)
1078 { 1100 {
1079 Util.FireAndForget(DoSendLayerData, map); 1101 Util.FireAndForget(DoSendLayerData, map);
1102
1103 // Send it sync, and async. It's not that much data
1104 // and it improves user experience just so much!
1105 DoSendLayerData(map);
1080 } 1106 }
1081 1107
1082 /// <summary> 1108 /// <summary>
@@ -1089,16 +1115,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1089 1115
1090 try 1116 try
1091 { 1117 {
1092 //for (int y = 0; y < 16; y++) 1118 for (int y = 0; y < 16; y++)
1093 //{ 1119 {
1094 // for (int x = 0; x < 16; x++) 1120 for (int x = 0; x < 16; x+=4)
1095 // { 1121 {
1096 // SendLayerData(x, y, map); 1122 SendLayerPacket(x, y, map);
1097 // } 1123 }
1098 //} 1124 }
1099
1100 // Send LayerData in a spiral pattern. Fun!
1101 SendLayerTopRight(map, 0, 0, 15, 15);
1102 } 1125 }
1103 catch (Exception e) 1126 catch (Exception e)
1104 { 1127 {
@@ -1106,51 +1129,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1106 } 1129 }
1107 } 1130 }
1108 1131
1109 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1110 {
1111 // Row
1112 for (int i = x1; i <= x2; i++)
1113 SendLayerData(i, y1, map);
1114
1115 // Column
1116 for (int j = y1 + 1; j <= y2; j++)
1117 SendLayerData(x2, j, map);
1118
1119 if (x2 - x1 > 0)
1120 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1121 }
1122
1123 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1124 {
1125 // Row in reverse
1126 for (int i = x2; i >= x1; i--)
1127 SendLayerData(i, y2, map);
1128
1129 // Column in reverse
1130 for (int j = y2 - 1; j >= y1; j--)
1131 SendLayerData(x1, j, map);
1132
1133 if (x2 - x1 > 0)
1134 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1135 }
1136
1137 /// <summary> 1132 /// <summary>
1138 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1133 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1139 /// </summary> 1134 /// </summary>
1140 /// <param name="map">heightmap</param> 1135 /// <param name="map">heightmap</param>
1141 /// <param name="px">X coordinate for patches 0..12</param> 1136 /// <param name="px">X coordinate for patches 0..12</param>
1142 /// <param name="py">Y coordinate for patches 0..15</param> 1137 /// <param name="py">Y coordinate for patches 0..15</param>
1143 // private void SendLayerPacket(float[] map, int y, int x) 1138 private void SendLayerPacket(int x, int y, float[] map)
1144 // { 1139 {
1145 // int[] patches = new int[4]; 1140 int[] patches = new int[4];
1146 // patches[0] = x + 0 + y * 16; 1141 patches[0] = x + 0 + y * 16;
1147 // patches[1] = x + 1 + y * 16; 1142 patches[1] = x + 1 + y * 16;
1148 // patches[2] = x + 2 + y * 16; 1143 patches[2] = x + 2 + y * 16;
1149 // patches[3] = x + 3 + y * 16; 1144 patches[3] = x + 3 + y * 16;
1150 1145
1151 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1146 float[] heightmap = (map.Length == 65536) ?
1152 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1147 map :
1153 // } 1148 LLHeightFieldMoronize(map);
1149
1150 try
1151 {
1152 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1153 OutPacket(layerpack, ThrottleOutPacketType.Land);
1154 }
1155 catch
1156 {
1157 for (int px = x ; px < x + 4 ; px++)
1158 SendLayerData(px, y, map);
1159 }
1160 }
1154 1161
1155 /// <summary> 1162 /// <summary>
1156 /// Sends a specified patch to a client 1163 /// Sends a specified patch to a client
@@ -1170,7 +1177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1170 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1177 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1171 layerpack.Header.Reliable = true; 1178 layerpack.Header.Reliable = true;
1172 1179
1173 OutPacket(layerpack, ThrottleOutPacketType.Land); 1180 OutPacket(layerpack, ThrottleOutPacketType.Task);
1174 } 1181 }
1175 catch (Exception e) 1182 catch (Exception e)
1176 { 1183 {
@@ -2294,6 +2301,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2294 OutPacket(sound, ThrottleOutPacketType.Task); 2301 OutPacket(sound, ThrottleOutPacketType.Task);
2295 } 2302 }
2296 2303
2304 public void SendTransferAbort(TransferRequestPacket transferRequest)
2305 {
2306 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2307 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2308 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2309 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2310 OutPacket(abort, ThrottleOutPacketType.Task);
2311 }
2312
2297 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2313 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2298 { 2314 {
2299 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2315 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3596,7 +3612,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3596 /// </summary> 3612 /// </summary>
3597 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3613 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3598 { 3614 {
3599 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3615 if (entity is SceneObjectPart)
3616 {
3617 SceneObjectPart e = (SceneObjectPart)entity;
3618 SceneObjectGroup g = e.ParentGroup;
3619 if (g.RootPart.Shape.State > 30) // HUD
3620 if (g.OwnerID != AgentId)
3621 return; // Don't send updates for other people's HUDs
3622 }
3623
3600 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3624 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3601 3625
3602 lock (m_entityUpdates.SyncRoot) 3626 lock (m_entityUpdates.SyncRoot)
@@ -3663,211 +3687,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3663 3687
3664 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3688 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3665 // condition where a kill can be processed before an out-of-date update for the same object. 3689 // condition where a kill can be processed before an out-of-date update for the same object.
3666 lock (m_killRecord) 3690 float avgTimeDilation = 1.0f;
3691 IEntityUpdate iupdate;
3692 Int32 timeinqueue; // this is just debugging code & can be dropped later
3693
3694 while (updatesThisCall < maxUpdates)
3667 { 3695 {
3668 float avgTimeDilation = 1.0f; 3696 lock (m_entityUpdates.SyncRoot)
3669 IEntityUpdate iupdate; 3697 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3670 Int32 timeinqueue; // this is just debugging code & can be dropped later 3698 break;
3671
3672 while (updatesThisCall < maxUpdates)
3673 {
3674 lock (m_entityUpdates.SyncRoot)
3675 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3676 break;
3677 3699
3678 EntityUpdate update = (EntityUpdate)iupdate; 3700 EntityUpdate update = (EntityUpdate)iupdate;
3679 3701
3680 avgTimeDilation += update.TimeDilation; 3702 avgTimeDilation += update.TimeDilation;
3681 avgTimeDilation *= 0.5f; 3703 avgTimeDilation *= 0.5f;
3682 3704
3683 if (update.Entity is SceneObjectPart) 3705 if (update.Entity is SceneObjectPart)
3706 {
3707 SceneObjectPart part = (SceneObjectPart)update.Entity;
3708
3709 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3710 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3711 // safety measure.
3712 //
3713 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3714 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3715 // updates and kills on different threads with different scheduling strategies, hence this protection.
3716 //
3717 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3718 // after the root prim has been deleted.
3719 lock (m_killRecord)
3684 { 3720 {
3685 SceneObjectPart part = (SceneObjectPart)update.Entity;
3686
3687 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3688 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3689 // safety measure.
3690 //
3691 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3692 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3693 // updates and kills on different threads with different scheduling strategies, hence this protection.
3694 //
3695 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3696 // after the root prim has been deleted.
3697 if (m_killRecord.Contains(part.LocalId)) 3721 if (m_killRecord.Contains(part.LocalId))
3698 {
3699 // m_log.WarnFormat(
3700 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3701 // part.LocalId, Name);
3702 continue; 3722 continue;
3703 } 3723 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3704 3724 continue;
3705 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3725 }
3726
3727 if (part.ParentGroup.IsDeleted)
3728 continue;
3729
3730 if (part.ParentGroup.IsAttachment)
3731 { // Someone else's HUD, why are we getting these?
3732 if (part.ParentGroup.OwnerID != AgentId &&
3733 part.ParentGroup.RootPart.Shape.State >= 30)
3734 continue;
3735 ScenePresence sp;
3736 // Owner is not in the sim, don't update it to
3737 // anyone
3738 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3739 continue;
3740
3741 List<SceneObjectGroup> atts = sp.GetAttachments();
3742 bool found = false;
3743 foreach (SceneObjectGroup att in atts)
3706 { 3744 {
3707 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3745 if (att == part.ParentGroup)
3708 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3709 { 3746 {
3710 part.Shape.LightEntry = false; 3747 found = true;
3748 break;
3711 } 3749 }
3712 } 3750 }
3751
3752 // It's an attachment of a valid avatar, but
3753 // doesn't seem to be attached, skip
3754 if (!found)
3755 continue;
3713 } 3756 }
3714 3757 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3715 ++updatesThisCall;
3716
3717 #region UpdateFlags to packet type conversion
3718
3719 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3720
3721 bool canUseCompressed = true;
3722 bool canUseImproved = true;
3723
3724 // Compressed object updates only make sense for LL primitives
3725 if (!(update.Entity is SceneObjectPart))
3726 {
3727 canUseCompressed = false;
3728 }
3729
3730 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3731 { 3758 {
3732 canUseCompressed = false; 3759 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3733 canUseImproved = false; 3760 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3734 }
3735 else
3736 {
3737 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3738 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3739 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3740 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3741 {
3742 canUseCompressed = false;
3743 }
3744
3745 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3746 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3747 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3748 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3751 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3759 { 3761 {
3760 canUseImproved = false; 3762 part.Shape.LightEntry = false;
3761 } 3763 }
3762 } 3764 }
3763 3765 }
3764 #endregion UpdateFlags to packet type conversion 3766
3765 3767 ++updatesThisCall;
3766 #region Block Construction 3768
3767 3769 #region UpdateFlags to packet type conversion
3768 // TODO: Remove this once we can build compressed updates 3770
3771 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3772
3773 bool canUseCompressed = true;
3774 bool canUseImproved = true;
3775
3776 // Compressed object updates only make sense for LL primitives
3777 if (!(update.Entity is SceneObjectPart))
3778 {
3769 canUseCompressed = false; 3779 canUseCompressed = false;
3770 3780 }
3771 if (!canUseImproved && !canUseCompressed) 3781
3772 { 3782 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3773 if (update.Entity is ScenePresence) 3783 {
3774 { 3784 canUseCompressed = false;
3775 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3785 canUseImproved = false;
3776 objectUpdates.Value.Add(update); 3786 }
3777 } 3787 else
3778 else 3788 {
3779 { 3789 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3780 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3790 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3781 objectUpdates.Value.Add(update); 3791 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3782 } 3792 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3783 }
3784 else if (!canUseImproved)
3785 { 3793 {
3786 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3794 canUseCompressed = false;
3787 compressedUpdates.Value.Add(update);
3788 } 3795 }
3789 else 3796
3797 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3798 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3790 { 3811 {
3791 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3812 canUseImproved = false;
3792 {
3793 // Self updates go into a special list
3794 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3795 terseAgentUpdates.Value.Add(update);
3796 }
3797 else
3798 {
3799 // Everything else goes here
3800 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3801 terseUpdates.Value.Add(update);
3802 }
3803 } 3813 }
3804
3805 #endregion Block Construction
3806 } 3814 }
3807
3808
3809 #region Packet Sending
3810 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3811 3815
3812 if (terseAgentUpdateBlocks.IsValueCreated) 3816 #endregion UpdateFlags to packet type conversion
3813 {
3814 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3815 3817
3816 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3818 #region Block Construction
3817 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3818 packet.RegionData.TimeDilation = timeDilation;
3819 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3820 3819
3821 for (int i = 0; i < blocks.Count; i++) 3820 // TODO: Remove this once we can build compressed updates
3822 packet.ObjectData[i] = blocks[i]; 3821 canUseCompressed = false;
3823 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3824 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3825 }
3826 3822
3827 if (objectUpdateBlocks.IsValueCreated) 3823 if (!canUseImproved && !canUseCompressed)
3828 { 3824 {
3829 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3825 if (update.Entity is ScenePresence)
3830 3826 {
3831 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3827 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3832 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3828 }
3833 packet.RegionData.TimeDilation = timeDilation; 3829 else
3834 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3830 {
3835 3831 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3836 for (int i = 0; i < blocks.Count; i++) 3832 }
3837 packet.ObjectData[i] = blocks[i];
3838 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3839 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3840 } 3833 }
3841 3834 else if (!canUseImproved)
3842 if (compressedUpdateBlocks.IsValueCreated)
3843 { 3835 {
3844 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3836 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3845
3846 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3847 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3848 packet.RegionData.TimeDilation = timeDilation;
3849 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3850
3851 for (int i = 0; i < blocks.Count; i++)
3852 packet.ObjectData[i] = blocks[i];
3853 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3854 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3855 } 3837 }
3856 3838 else
3857 if (terseUpdateBlocks.IsValueCreated)
3858 { 3839 {
3859 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3840 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3860 3841 // Self updates go into a special list
3861 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3842 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3862 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3843 else
3863 packet.RegionData.TimeDilation = timeDilation; 3844 // Everything else goes here
3864 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3845 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3865
3866 for (int i = 0; i < blocks.Count; i++)
3867 packet.ObjectData[i] = blocks[i];
3868 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3869 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3870 } 3846 }
3847
3848 #endregion Block Construction
3849 }
3850
3851 #region Packet Sending
3852
3853 const float TIME_DILATION = 1.0f;
3854 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3855
3856 if (terseAgentUpdateBlocks.IsValueCreated)
3857 {
3858 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3859
3860 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3861 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3862 packet.RegionData.TimeDilation = timeDilation;
3863 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3864
3865 for (int i = 0; i < blocks.Count; i++)
3866 packet.ObjectData[i] = blocks[i];
3867
3868 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3869 }
3870
3871 if (objectUpdateBlocks.IsValueCreated)
3872 {
3873 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3874
3875 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3876 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3877 packet.RegionData.TimeDilation = timeDilation;
3878 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3879
3880 for (int i = 0; i < blocks.Count; i++)
3881 packet.ObjectData[i] = blocks[i];
3882
3883 OutPacket(packet, ThrottleOutPacketType.Task, true);
3884 }
3885
3886 if (compressedUpdateBlocks.IsValueCreated)
3887 {
3888 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3889
3890 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3891 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3892 packet.RegionData.TimeDilation = timeDilation;
3893 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3894
3895 for (int i = 0; i < blocks.Count; i++)
3896 packet.ObjectData[i] = blocks[i];
3897
3898 OutPacket(packet, ThrottleOutPacketType.Task, true);
3899 }
3900
3901 if (terseUpdateBlocks.IsValueCreated)
3902 {
3903 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3904
3905 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3906 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3907 packet.RegionData.TimeDilation = timeDilation;
3908 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3909
3910 for (int i = 0; i < blocks.Count; i++)
3911 packet.ObjectData[i] = blocks[i];
3912
3913 OutPacket(packet, ThrottleOutPacketType.Task, true);
3871 } 3914 }
3872 3915
3873 #endregion Packet Sending 3916 #endregion Packet Sending
@@ -4168,11 +4211,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4168 4211
4169 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4212 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4170 // of the object rather than the properties when the packet was created 4213 // of the object rather than the properties when the packet was created
4171 OutPacket(packet, ThrottleOutPacketType.Task, true, 4214 // HACK : Remove intelligent resending until it's fixed in core
4172 delegate(OutgoingPacket oPacket) 4215 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4173 { 4216 // delegate(OutgoingPacket oPacket)
4174 ResendPropertyUpdates(updates, oPacket); 4217 // {
4175 }); 4218 // ResendPropertyUpdates(updates, oPacket);
4219 // });
4220 OutPacket(packet, ThrottleOutPacketType.Task, true);
4176 4221
4177 // pbcnt += blocks.Count; 4222 // pbcnt += blocks.Count;
4178 // ppcnt++; 4223 // ppcnt++;
@@ -4198,11 +4243,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4198 // of the object rather than the properties when the packet was created 4243 // of the object rather than the properties when the packet was created
4199 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4244 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4200 updates.Add(familyUpdates.Value[i]); 4245 updates.Add(familyUpdates.Value[i]);
4201 OutPacket(packet, ThrottleOutPacketType.Task, true, 4246 // HACK : Remove intelligent resending until it's fixed in core
4202 delegate(OutgoingPacket oPacket) 4247 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4203 { 4248 // delegate(OutgoingPacket oPacket)
4204 ResendPropertyUpdates(updates, oPacket); 4249 // {
4205 }); 4250 // ResendPropertyUpdates(updates, oPacket);
4251 // });
4252 OutPacket(packet, ThrottleOutPacketType.Task, true);
4206 4253
4207 // fpcnt++; 4254 // fpcnt++;
4208 // fbcnt++; 4255 // fbcnt++;
@@ -4351,37 +4398,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4351 if (bl[i].BannedUserID == UUID.Zero) 4398 if (bl[i].BannedUserID == UUID.Zero)
4352 continue; 4399 continue;
4353 BannedUsers.Add(bl[i].BannedUserID); 4400 BannedUsers.Add(bl[i].BannedUserID);
4354 }
4355 4401
4356 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4402 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4357 packet.AgentData.TransactionID = UUID.Random(); 4403 {
4358 packet.AgentData.AgentID = AgentId; 4404 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4359 packet.AgentData.SessionID = SessionId; 4405 packet.AgentData.TransactionID = UUID.Random();
4360 packet.MethodData.Invoice = invoice; 4406 packet.AgentData.AgentID = AgentId;
4361 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4407 packet.AgentData.SessionID = SessionId;
4408 packet.MethodData.Invoice = invoice;
4409 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4362 4410
4363 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4411 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4364 4412
4365 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4413 int j;
4366 { 4414 for (j = 0; j < (6 + BannedUsers.Count); j++)
4367 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4415 {
4368 } 4416 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4369 int j = 0; 4417 }
4418 j = 0;
4370 4419
4371 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4420 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4372 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4421 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4373 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4422 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4374 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4423 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4375 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4424 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4425 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4377 4426
4378 foreach (UUID banned in BannedUsers) 4427 foreach (UUID banned in BannedUsers)
4379 { 4428 {
4380 returnblock[j].Parameter = banned.GetBytes(); j++; 4429 returnblock[j].Parameter = banned.GetBytes(); j++;
4430 }
4431 packet.ParamList = returnblock;
4432 packet.Header.Reliable = true;
4433 OutPacket(packet, ThrottleOutPacketType.Task);
4434
4435 BannedUsers.Clear();
4436 }
4381 } 4437 }
4382 packet.ParamList = returnblock; 4438
4383 packet.Header.Reliable = false;
4384 OutPacket(packet, ThrottleOutPacketType.Task);
4385 } 4439 }
4386 4440
4387 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4441 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4550,7 +4604,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4550 4604
4551 if (landData.SimwideArea > 0) 4605 if (landData.SimwideArea > 0)
4552 { 4606 {
4553 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4607 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4608 // Never report more than sim total capacity
4609 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4610 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4554 updateMessage.SimWideMaxPrims = simulatorCapacity; 4611 updateMessage.SimWideMaxPrims = simulatorCapacity;
4555 } 4612 }
4556 else 4613 else
@@ -4679,14 +4736,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4679 4736
4680 if (notifyCount > 0) 4737 if (notifyCount > 0)
4681 { 4738 {
4682 if (notifyCount > 32) 4739// if (notifyCount > 32)
4683 { 4740// {
4684 m_log.InfoFormat( 4741// m_log.InfoFormat(
4685 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4742// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4686 + " - a developer might want to investigate whether this is a hard limit", 32); 4743// + " - a developer might want to investigate whether this is a hard limit", 32);
4687 4744//
4688 notifyCount = 32; 4745// notifyCount = 32;
4689 } 4746// }
4690 4747
4691 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4748 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4692 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4749 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5220,6 +5277,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5220 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5277 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5221 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5278 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5222 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5279 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5280 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5223 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5281 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5224 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5282 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5225 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5283 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5321,6 +5379,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5321 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5379 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5322 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5380 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5323 (x.ControlFlags != lastarg.ControlFlags) || 5381 (x.ControlFlags != lastarg.ControlFlags) ||
5382 (x.ControlFlags != 0) ||
5324 (x.Far != lastarg.Far) || 5383 (x.Far != lastarg.Far) ||
5325 (x.Flags != lastarg.Flags) || 5384 (x.Flags != lastarg.Flags) ||
5326 (x.State != lastarg.State) || 5385 (x.State != lastarg.State) ||
@@ -5698,7 +5757,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5698 args.Channel = ch; 5757 args.Channel = ch;
5699 args.From = String.Empty; 5758 args.From = String.Empty;
5700 args.Message = Utils.BytesToString(msg); 5759 args.Message = Utils.BytesToString(msg);
5701 args.Type = ChatTypeEnum.Shout; 5760 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5702 args.Position = new Vector3(); 5761 args.Position = new Vector3();
5703 args.Scene = Scene; 5762 args.Scene = Scene;
5704 args.Sender = this; 5763 args.Sender = this;
@@ -9704,7 +9763,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9704 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9763 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9705 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9764 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9706 UpdateMuteListEntry.MuteData.MuteType, 9765 UpdateMuteListEntry.MuteData.MuteType,
9707 UpdateMuteListEntry.AgentData.AgentID); 9766 UpdateMuteListEntry.MuteData.MuteFlags);
9708 return true; 9767 return true;
9709 } 9768 }
9710 return false; 9769 return false;
@@ -9719,8 +9778,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9719 { 9778 {
9720 handlerRemoveMuteListEntry(this, 9779 handlerRemoveMuteListEntry(this,
9721 RemoveMuteListEntry.MuteData.MuteID, 9780 RemoveMuteListEntry.MuteData.MuteID,
9722 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9781 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9723 RemoveMuteListEntry.AgentData.AgentID);
9724 return true; 9782 return true;
9725 } 9783 }
9726 return false; 9784 return false;
@@ -9768,6 +9826,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9768 { 9826 {
9769 return true; 9827 return true;
9770 } 9828 }
9829
9830 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9831 {
9832 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9833
9834 #region Packet Session and User Check
9835 if (m_checkPackets)
9836 {
9837 if (packet.AgentData.SessionID != SessionId ||
9838 packet.AgentData.AgentID != AgentId)
9839 return true;
9840 }
9841 #endregion
9842 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9843 List<InventoryItemBase> items = new List<InventoryItemBase>();
9844 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9845 {
9846 InventoryItemBase b = new InventoryItemBase();
9847 b.ID = n.OldItemID;
9848 b.Folder = n.OldFolderID;
9849 items.Add(b);
9850 }
9851
9852 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9853 if (handlerMoveItemsAndLeaveCopy != null)
9854 {
9855 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9856 }
9857
9858 return true;
9859 }
9771 9860
9772 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9861 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9773 { 9862 {
@@ -10194,6 +10283,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10194 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10283 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10195 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10284 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10196 10285
10286 Scene scene = (Scene)m_scene;
10287 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10288 {
10289 ScenePresence p;
10290 if (scene.TryGetScenePresence(sender.AgentId, out p))
10291 {
10292 if (p.GodLevel >= 200)
10293 {
10294 groupProfileReply.GroupData.OpenEnrollment = true;
10295 groupProfileReply.GroupData.MembershipFee = 0;
10296 }
10297 }
10298 }
10299
10197 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10300 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10198 } 10301 }
10199 return true; 10302 return true;
@@ -10766,11 +10869,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10766 10869
10767 StartLure handlerStartLure = OnStartLure; 10870 StartLure handlerStartLure = OnStartLure;
10768 if (handlerStartLure != null) 10871 if (handlerStartLure != null)
10769 handlerStartLure(startLureRequest.Info.LureType, 10872 {
10770 Utils.BytesToString( 10873 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10771 startLureRequest.Info.Message), 10874 {
10772 startLureRequest.TargetData[0].TargetID, 10875 handlerStartLure(startLureRequest.Info.LureType,
10773 this); 10876 Utils.BytesToString(
10877 startLureRequest.Info.Message),
10878 startLureRequest.TargetData[i].TargetID,
10879 this);
10880 }
10881 }
10774 return true; 10882 return true;
10775 } 10883 }
10776 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10884 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10884,10 +10992,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10884 } 10992 }
10885 #endregion 10993 #endregion
10886 10994
10887 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10995 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10888 if (handlerClassifiedGodDelete != null) 10996 if (handlerClassifiedGodDelete != null)
10889 handlerClassifiedGodDelete( 10997 handlerClassifiedGodDelete(
10890 classifiedGodDelete.Data.ClassifiedID, 10998 classifiedGodDelete.Data.ClassifiedID,
10999 classifiedGodDelete.Data.QueryID,
10891 this); 11000 this);
10892 return true; 11001 return true;
10893 } 11002 }
@@ -11919,7 +12028,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11919 12028
11920// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12029// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11921 12030
12031
12032 //Note, the bool returned from the below function is useless since it is always false.
11922 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12033 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12034
11923 } 12035 }
11924 12036
11925 /// <summary> 12037 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..c951071 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -439,6 +440,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
439 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
440 { 441 {
441 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
443
444 if (m_deliverPackets == false)
445 {
446 queue.Enqueue(packet);
447 return true;
448 }
449
442 TokenBucket bucket = m_throttleCategories[category]; 450 TokenBucket bucket = m_throttleCategories[category];
443 451
444 // Don't send this packet if there is already a packet waiting in the queue 452 // Don't send this packet if there is already a packet waiting in the queue
@@ -488,6 +496,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 /// <returns>True if any packets were sent, otherwise false</returns> 496 /// <returns>True if any packets were sent, otherwise false</returns>
489 public bool DequeueOutgoing() 497 public bool DequeueOutgoing()
490 { 498 {
499 if (m_deliverPackets == false) return false;
500
491 OutgoingPacket packet; 501 OutgoingPacket packet;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
@@ -520,7 +530,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 // No dequeued packet waiting to be sent, try to pull one off 530 // No dequeued packet waiting to be sent, try to pull one off
521 // this queue 531 // this queue
522 queue = m_packetOutboxes[i]; 532 queue = m_packetOutboxes[i];
523 if (queue.Dequeue(out packet)) 533 if (queue != null && queue.Dequeue(out packet))
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 // A packet was pulled off the queue. See if we have
526 // enough tokens in the bucket to send it out 536 // enough tokens in the bucket to send it out
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ccad241..ae8251a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -991,7 +991,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
991 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 991 if (m_scene.TryGetClient(udpClient.AgentID, out client))
992 { 992 {
993 client.IsLoggingOut = true; 993 client.IsLoggingOut = true;
994 client.Close(); 994 client.Close(false);
995 } 995 }
996 } 996 }
997 997
@@ -1003,6 +1003,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1003 1003
1004 while (base.IsRunning) 1004 while (base.IsRunning)
1005 { 1005 {
1006 m_scene.ThreadAlive(1);
1006 try 1007 try
1007 { 1008 {
1008 IncomingPacket incomingPacket = null; 1009 IncomingPacket incomingPacket = null;
@@ -1045,6 +1046,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1045 1046
1046 while (base.IsRunning) 1047 while (base.IsRunning)
1047 { 1048 {
1049 m_scene.ThreadAlive(2);
1048 try 1050 try
1049 { 1051 {
1050 m_packetSent = false; 1052 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6eebd9d..d2779ba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,