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.cs698
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 465 insertions, 309 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 7223438..11d3e36 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 158 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 159 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 160 public event CopyInventoryItem OnCopyInventoryItem;
161 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 162 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 163 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 164 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -255,7 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
255 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 256 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
256 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
257 public event ClassifiedDelete OnClassifiedDelete; 258 public event ClassifiedDelete OnClassifiedDelete;
258 public event ClassifiedDelete OnClassifiedGodDelete; 259 public event ClassifiedGodDelete OnClassifiedGodDelete;
259 public event EventNotificationAddRequest OnEventNotificationAddRequest; 260 public event EventNotificationAddRequest OnEventNotificationAddRequest;
260 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
261 public event EventGodDelete OnEventGodDelete; 262 public event EventGodDelete OnEventGodDelete;
@@ -286,6 +287,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
286 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
287 public event SimWideDeletesDelegate OnSimWideDeletes; 288 public event SimWideDeletesDelegate OnSimWideDeletes;
288 public event SendPostcard OnSendPostcard; 289 public event SendPostcard OnSendPostcard;
290 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
289 public event MuteListEntryUpdate OnUpdateMuteListEntry; 291 public event MuteListEntryUpdate OnUpdateMuteListEntry;
290 public event MuteListEntryRemove OnRemoveMuteListEntry; 292 public event MuteListEntryRemove OnRemoveMuteListEntry;
291 public event GodlikeMessage onGodlikeMessage; 293 public event GodlikeMessage onGodlikeMessage;
@@ -331,7 +333,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
331 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 333 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
332 /// ownerless phantom. 334 /// ownerless phantom.
333 /// 335 ///
334 /// All manipulation of this set has to occur under a lock 336 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
335 /// 337 ///
336 /// </value> 338 /// </value>
337 protected HashSet<uint> m_killRecord; 339 protected HashSet<uint> m_killRecord;
@@ -339,6 +341,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339// protected HashSet<uint> m_attachmentsSent; 341// protected HashSet<uint> m_attachmentsSent;
340 342
341 private int m_moneyBalance; 343 private int m_moneyBalance;
344 private bool m_deliverPackets = true;
342 private int m_animationSequenceNumber = 1; 345 private int m_animationSequenceNumber = 1;
343 private bool m_SendLogoutPacketWhenClosing = true; 346 private bool m_SendLogoutPacketWhenClosing = true;
344 private AgentUpdateArgs lastarg; 347 private AgentUpdateArgs lastarg;
@@ -379,6 +382,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
379 get { return m_startpos; } 382 get { return m_startpos; }
380 set { m_startpos = value; } 383 set { m_startpos = value; }
381 } 384 }
385 public bool DeliverPackets
386 {
387 get { return m_deliverPackets; }
388 set {
389 m_deliverPackets = value;
390 m_udpClient.m_deliverPackets = value;
391 }
392 }
382 public UUID AgentId { get { return m_agentId; } } 393 public UUID AgentId { get { return m_agentId; } }
383 public ISceneAgent SceneAgent { get; private set; } 394 public ISceneAgent SceneAgent { get; private set; }
384 public UUID ActiveGroupId { get { return m_activeGroupID; } } 395 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -481,18 +492,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
481 492
482 #region Client Methods 493 #region Client Methods
483 494
495
484 /// <summary> 496 /// <summary>
485 /// Shut down the client view 497 /// Shut down the client view
486 /// </summary> 498 /// </summary>
487 public void Close() 499 public void Close()
488 { 500 {
501 Close(true);
502 }
503
504 /// <summary>
505 /// Shut down the client view
506 /// </summary>
507 public void Close(bool sendStop)
508 {
489 m_log.DebugFormat( 509 m_log.DebugFormat(
490 "[CLIENT]: Close has been called for {0} attached to scene {1}", 510 "[CLIENT]: Close has been called for {0} attached to scene {1}",
491 Name, m_scene.RegionInfo.RegionName); 511 Name, m_scene.RegionInfo.RegionName);
492 512
493 // Send the STOP packet 513 if (sendStop)
494 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 514 {
495 OutPacket(disable, ThrottleOutPacketType.Unknown); 515 // Send the STOP packet
516 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
517 OutPacket(disable, ThrottleOutPacketType.Unknown);
518 }
496 519
497 IsActive = false; 520 IsActive = false;
498 521
@@ -794,7 +817,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
794 reply.ChatData.OwnerID = fromAgentID; 817 reply.ChatData.OwnerID = fromAgentID;
795 reply.ChatData.SourceID = fromAgentID; 818 reply.ChatData.SourceID = fromAgentID;
796 819
797 OutPacket(reply, ThrottleOutPacketType.Task); 820 OutPacket(reply, ThrottleOutPacketType.Unknown);
798 } 821 }
799 822
800 /// <summary> 823 /// <summary>
@@ -1080,6 +1103,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1080 public virtual void SendLayerData(float[] map) 1103 public virtual void SendLayerData(float[] map)
1081 { 1104 {
1082 Util.FireAndForget(DoSendLayerData, map); 1105 Util.FireAndForget(DoSendLayerData, map);
1106
1107 // Send it sync, and async. It's not that much data
1108 // and it improves user experience just so much!
1109 DoSendLayerData(map);
1083 } 1110 }
1084 1111
1085 /// <summary> 1112 /// <summary>
@@ -1092,16 +1119,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1092 1119
1093 try 1120 try
1094 { 1121 {
1095 //for (int y = 0; y < 16; y++) 1122 for (int y = 0; y < 16; y++)
1096 //{ 1123 {
1097 // for (int x = 0; x < 16; x++) 1124 for (int x = 0; x < 16; x+=4)
1098 // { 1125 {
1099 // SendLayerData(x, y, map); 1126 SendLayerPacket(x, y, map);
1100 // } 1127 }
1101 //} 1128 }
1102
1103 // Send LayerData in a spiral pattern. Fun!
1104 SendLayerTopRight(map, 0, 0, 15, 15);
1105 } 1129 }
1106 catch (Exception e) 1130 catch (Exception e)
1107 { 1131 {
@@ -1109,51 +1133,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1109 } 1133 }
1110 } 1134 }
1111 1135
1112 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1113 {
1114 // Row
1115 for (int i = x1; i <= x2; i++)
1116 SendLayerData(i, y1, map);
1117
1118 // Column
1119 for (int j = y1 + 1; j <= y2; j++)
1120 SendLayerData(x2, j, map);
1121
1122 if (x2 - x1 > 0)
1123 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1124 }
1125
1126 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1127 {
1128 // Row in reverse
1129 for (int i = x2; i >= x1; i--)
1130 SendLayerData(i, y2, map);
1131
1132 // Column in reverse
1133 for (int j = y2 - 1; j >= y1; j--)
1134 SendLayerData(x1, j, map);
1135
1136 if (x2 - x1 > 0)
1137 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1138 }
1139
1140 /// <summary> 1136 /// <summary>
1141 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1137 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1142 /// </summary> 1138 /// </summary>
1143 /// <param name="map">heightmap</param> 1139 /// <param name="map">heightmap</param>
1144 /// <param name="px">X coordinate for patches 0..12</param> 1140 /// <param name="px">X coordinate for patches 0..12</param>
1145 /// <param name="py">Y coordinate for patches 0..15</param> 1141 /// <param name="py">Y coordinate for patches 0..15</param>
1146 // private void SendLayerPacket(float[] map, int y, int x) 1142 private void SendLayerPacket(int x, int y, float[] map)
1147 // { 1143 {
1148 // int[] patches = new int[4]; 1144 int[] patches = new int[4];
1149 // patches[0] = x + 0 + y * 16; 1145 patches[0] = x + 0 + y * 16;
1150 // patches[1] = x + 1 + y * 16; 1146 patches[1] = x + 1 + y * 16;
1151 // patches[2] = x + 2 + y * 16; 1147 patches[2] = x + 2 + y * 16;
1152 // patches[3] = x + 3 + y * 16; 1148 patches[3] = x + 3 + y * 16;
1153 1149
1154 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1150 float[] heightmap = (map.Length == 65536) ?
1155 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1151 map :
1156 // } 1152 LLHeightFieldMoronize(map);
1153
1154 try
1155 {
1156 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1157 OutPacket(layerpack, ThrottleOutPacketType.Land);
1158 }
1159 catch
1160 {
1161 for (int px = x ; px < x + 4 ; px++)
1162 SendLayerData(px, y, map);
1163 }
1164 }
1157 1165
1158 /// <summary> 1166 /// <summary>
1159 /// Sends a specified patch to a client 1167 /// Sends a specified patch to a client
@@ -1173,7 +1181,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1173 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1181 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1174 layerpack.Header.Reliable = true; 1182 layerpack.Header.Reliable = true;
1175 1183
1176 OutPacket(layerpack, ThrottleOutPacketType.Land); 1184 OutPacket(layerpack, ThrottleOutPacketType.Task);
1177 } 1185 }
1178 catch (Exception e) 1186 catch (Exception e)
1179 { 1187 {
@@ -2297,6 +2305,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2297 OutPacket(sound, ThrottleOutPacketType.Task); 2305 OutPacket(sound, ThrottleOutPacketType.Task);
2298 } 2306 }
2299 2307
2308 public void SendTransferAbort(TransferRequestPacket transferRequest)
2309 {
2310 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2311 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2312 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2313 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2314 OutPacket(abort, ThrottleOutPacketType.Task);
2315 }
2316
2300 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2317 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2301 { 2318 {
2302 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2319 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3599,7 +3616,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3599 /// </summary> 3616 /// </summary>
3600 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3617 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3601 { 3618 {
3602 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3619 if (entity is SceneObjectPart)
3620 {
3621 SceneObjectPart e = (SceneObjectPart)entity;
3622 SceneObjectGroup g = e.ParentGroup;
3623 if (g.RootPart.Shape.State > 30) // HUD
3624 if (g.OwnerID != AgentId)
3625 return; // Don't send updates for other people's HUDs
3626 }
3627
3603 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3628 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3604 3629
3605 lock (m_entityUpdates.SyncRoot) 3630 lock (m_entityUpdates.SyncRoot)
@@ -3666,211 +3691,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3666 3691
3667 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3692 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3668 // condition where a kill can be processed before an out-of-date update for the same object. 3693 // condition where a kill can be processed before an out-of-date update for the same object.
3669 lock (m_killRecord) 3694 float avgTimeDilation = 1.0f;
3695 IEntityUpdate iupdate;
3696 Int32 timeinqueue; // this is just debugging code & can be dropped later
3697
3698 while (updatesThisCall < maxUpdates)
3670 { 3699 {
3671 float avgTimeDilation = 1.0f; 3700 lock (m_entityUpdates.SyncRoot)
3672 IEntityUpdate iupdate; 3701 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3673 Int32 timeinqueue; // this is just debugging code & can be dropped later 3702 break;
3674
3675 while (updatesThisCall < maxUpdates)
3676 {
3677 lock (m_entityUpdates.SyncRoot)
3678 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3679 break;
3680 3703
3681 EntityUpdate update = (EntityUpdate)iupdate; 3704 EntityUpdate update = (EntityUpdate)iupdate;
3682 3705
3683 avgTimeDilation += update.TimeDilation; 3706 avgTimeDilation += update.TimeDilation;
3684 avgTimeDilation *= 0.5f; 3707 avgTimeDilation *= 0.5f;
3685 3708
3686 if (update.Entity is SceneObjectPart) 3709 if (update.Entity is SceneObjectPart)
3710 {
3711 SceneObjectPart part = (SceneObjectPart)update.Entity;
3712
3713 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3714 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3715 // safety measure.
3716 //
3717 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3718 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3719 // updates and kills on different threads with different scheduling strategies, hence this protection.
3720 //
3721 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3722 // after the root prim has been deleted.
3723 lock (m_killRecord)
3687 { 3724 {
3688 SceneObjectPart part = (SceneObjectPart)update.Entity;
3689
3690 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3691 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3692 // safety measure.
3693 //
3694 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3695 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3696 // updates and kills on different threads with different scheduling strategies, hence this protection.
3697 //
3698 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3699 // after the root prim has been deleted.
3700 if (m_killRecord.Contains(part.LocalId)) 3725 if (m_killRecord.Contains(part.LocalId))
3701 {
3702 // m_log.WarnFormat(
3703 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3704 // part.LocalId, Name);
3705 continue; 3726 continue;
3706 } 3727 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3707 3728 continue;
3708 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3729 }
3730
3731 if (part.ParentGroup.IsDeleted)
3732 continue;
3733
3734 if (part.ParentGroup.IsAttachment)
3735 { // Someone else's HUD, why are we getting these?
3736 if (part.ParentGroup.OwnerID != AgentId &&
3737 part.ParentGroup.RootPart.Shape.State >= 30)
3738 continue;
3739 ScenePresence sp;
3740 // Owner is not in the sim, don't update it to
3741 // anyone
3742 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3743 continue;
3744
3745 List<SceneObjectGroup> atts = sp.GetAttachments();
3746 bool found = false;
3747 foreach (SceneObjectGroup att in atts)
3709 { 3748 {
3710 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3749 if (att == part.ParentGroup)
3711 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3712 { 3750 {
3713 part.Shape.LightEntry = false; 3751 found = true;
3752 break;
3714 } 3753 }
3715 } 3754 }
3755
3756 // It's an attachment of a valid avatar, but
3757 // doesn't seem to be attached, skip
3758 if (!found)
3759 continue;
3716 } 3760 }
3717 3761 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3718 ++updatesThisCall;
3719
3720 #region UpdateFlags to packet type conversion
3721
3722 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3723
3724 bool canUseCompressed = true;
3725 bool canUseImproved = true;
3726
3727 // Compressed object updates only make sense for LL primitives
3728 if (!(update.Entity is SceneObjectPart))
3729 {
3730 canUseCompressed = false;
3731 }
3732
3733 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3734 {
3735 canUseCompressed = false;
3736 canUseImproved = false;
3737 }
3738 else
3739 { 3762 {
3740 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3763 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3741 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3764 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3742 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3743 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3744 {
3745 canUseCompressed = false;
3746 }
3747
3748 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3751 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3762 { 3765 {
3763 canUseImproved = false; 3766 part.Shape.LightEntry = false;
3764 } 3767 }
3765 } 3768 }
3766 3769 }
3767 #endregion UpdateFlags to packet type conversion 3770
3768 3771 ++updatesThisCall;
3769 #region Block Construction 3772
3770 3773 #region UpdateFlags to packet type conversion
3771 // TODO: Remove this once we can build compressed updates 3774
3775 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3776
3777 bool canUseCompressed = true;
3778 bool canUseImproved = true;
3779
3780 // Compressed object updates only make sense for LL primitives
3781 if (!(update.Entity is SceneObjectPart))
3782 {
3772 canUseCompressed = false; 3783 canUseCompressed = false;
3773 3784 }
3774 if (!canUseImproved && !canUseCompressed) 3785
3775 { 3786 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3776 if (update.Entity is ScenePresence) 3787 {
3777 { 3788 canUseCompressed = false;
3778 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3789 canUseImproved = false;
3779 objectUpdates.Value.Add(update); 3790 }
3780 } 3791 else
3781 else 3792 {
3782 { 3793 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3783 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3794 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3784 objectUpdates.Value.Add(update); 3795 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3785 } 3796 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3786 }
3787 else if (!canUseImproved)
3788 { 3797 {
3789 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3798 canUseCompressed = false;
3790 compressedUpdates.Value.Add(update);
3791 } 3799 }
3792 else 3800
3801 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3793 { 3815 {
3794 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3816 canUseImproved = false;
3795 {
3796 // Self updates go into a special list
3797 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3798 terseAgentUpdates.Value.Add(update);
3799 }
3800 else
3801 {
3802 // Everything else goes here
3803 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3804 terseUpdates.Value.Add(update);
3805 }
3806 } 3817 }
3807
3808 #endregion Block Construction
3809 } 3818 }
3810
3811
3812 #region Packet Sending
3813 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3814 3819
3815 if (terseAgentUpdateBlocks.IsValueCreated) 3820 #endregion UpdateFlags to packet type conversion
3816 {
3817 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3818 3821
3819 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3822 #region Block Construction
3820 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3821 packet.RegionData.TimeDilation = timeDilation;
3822 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3823 3823
3824 for (int i = 0; i < blocks.Count; i++) 3824 // TODO: Remove this once we can build compressed updates
3825 packet.ObjectData[i] = blocks[i]; 3825 canUseCompressed = false;
3826 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3827 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3828 }
3829 3826
3830 if (objectUpdateBlocks.IsValueCreated) 3827 if (!canUseImproved && !canUseCompressed)
3831 { 3828 {
3832 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3829 if (update.Entity is ScenePresence)
3833 3830 {
3834 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3831 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3835 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3832 }
3836 packet.RegionData.TimeDilation = timeDilation; 3833 else
3837 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3834 {
3838 3835 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3839 for (int i = 0; i < blocks.Count; i++) 3836 }
3840 packet.ObjectData[i] = blocks[i];
3841 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3842 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3843 } 3837 }
3844 3838 else if (!canUseImproved)
3845 if (compressedUpdateBlocks.IsValueCreated)
3846 { 3839 {
3847 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3840 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3848
3849 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3850 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3851 packet.RegionData.TimeDilation = timeDilation;
3852 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3853
3854 for (int i = 0; i < blocks.Count; i++)
3855 packet.ObjectData[i] = blocks[i];
3856 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3857 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3858 } 3841 }
3859 3842 else
3860 if (terseUpdateBlocks.IsValueCreated)
3861 { 3843 {
3862 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3844 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3863 3845 // Self updates go into a special list
3864 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3846 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3865 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3847 else
3866 packet.RegionData.TimeDilation = timeDilation; 3848 // Everything else goes here
3867 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3849 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3868
3869 for (int i = 0; i < blocks.Count; i++)
3870 packet.ObjectData[i] = blocks[i];
3871 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3872 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3873 } 3850 }
3851
3852 #endregion Block Construction
3853 }
3854
3855 #region Packet Sending
3856
3857 const float TIME_DILATION = 1.0f;
3858 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3859
3860 if (terseAgentUpdateBlocks.IsValueCreated)
3861 {
3862 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3863
3864 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3865 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3866 packet.RegionData.TimeDilation = timeDilation;
3867 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3868
3869 for (int i = 0; i < blocks.Count; i++)
3870 packet.ObjectData[i] = blocks[i];
3871
3872 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3873 }
3874
3875 if (objectUpdateBlocks.IsValueCreated)
3876 {
3877 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3878
3879 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3880 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3881 packet.RegionData.TimeDilation = timeDilation;
3882 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3883
3884 for (int i = 0; i < blocks.Count; i++)
3885 packet.ObjectData[i] = blocks[i];
3886
3887 OutPacket(packet, ThrottleOutPacketType.Task, true);
3888 }
3889
3890 if (compressedUpdateBlocks.IsValueCreated)
3891 {
3892 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3893
3894 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3895 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3896 packet.RegionData.TimeDilation = timeDilation;
3897 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3898
3899 for (int i = 0; i < blocks.Count; i++)
3900 packet.ObjectData[i] = blocks[i];
3901
3902 OutPacket(packet, ThrottleOutPacketType.Task, true);
3903 }
3904
3905 if (terseUpdateBlocks.IsValueCreated)
3906 {
3907 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3908
3909 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3910 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3911 packet.RegionData.TimeDilation = timeDilation;
3912 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3913
3914 for (int i = 0; i < blocks.Count; i++)
3915 packet.ObjectData[i] = blocks[i];
3916
3917 OutPacket(packet, ThrottleOutPacketType.Task, true);
3874 } 3918 }
3875 3919
3876 #endregion Packet Sending 3920 #endregion Packet Sending
@@ -4171,11 +4215,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4171 4215
4172 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4216 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4173 // of the object rather than the properties when the packet was created 4217 // of the object rather than the properties when the packet was created
4174 OutPacket(packet, ThrottleOutPacketType.Task, true, 4218 // HACK : Remove intelligent resending until it's fixed in core
4175 delegate(OutgoingPacket oPacket) 4219 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4176 { 4220 // delegate(OutgoingPacket oPacket)
4177 ResendPropertyUpdates(updates, oPacket); 4221 // {
4178 }); 4222 // ResendPropertyUpdates(updates, oPacket);
4223 // });
4224 OutPacket(packet, ThrottleOutPacketType.Task, true);
4179 4225
4180 // pbcnt += blocks.Count; 4226 // pbcnt += blocks.Count;
4181 // ppcnt++; 4227 // ppcnt++;
@@ -4201,11 +4247,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4201 // of the object rather than the properties when the packet was created 4247 // of the object rather than the properties when the packet was created
4202 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4248 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4203 updates.Add(familyUpdates.Value[i]); 4249 updates.Add(familyUpdates.Value[i]);
4204 OutPacket(packet, ThrottleOutPacketType.Task, true, 4250 // HACK : Remove intelligent resending until it's fixed in core
4205 delegate(OutgoingPacket oPacket) 4251 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4206 { 4252 // delegate(OutgoingPacket oPacket)
4207 ResendPropertyUpdates(updates, oPacket); 4253 // {
4208 }); 4254 // ResendPropertyUpdates(updates, oPacket);
4255 // });
4256 OutPacket(packet, ThrottleOutPacketType.Task, true);
4209 4257
4210 // fpcnt++; 4258 // fpcnt++;
4211 // fbcnt++; 4259 // fbcnt++;
@@ -4354,37 +4402,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4354 if (bl[i].BannedUserID == UUID.Zero) 4402 if (bl[i].BannedUserID == UUID.Zero)
4355 continue; 4403 continue;
4356 BannedUsers.Add(bl[i].BannedUserID); 4404 BannedUsers.Add(bl[i].BannedUserID);
4357 }
4358 4405
4359 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4406 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4360 packet.AgentData.TransactionID = UUID.Random(); 4407 {
4361 packet.AgentData.AgentID = AgentId; 4408 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4362 packet.AgentData.SessionID = SessionId; 4409 packet.AgentData.TransactionID = UUID.Random();
4363 packet.MethodData.Invoice = invoice; 4410 packet.AgentData.AgentID = AgentId;
4364 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4411 packet.AgentData.SessionID = SessionId;
4412 packet.MethodData.Invoice = invoice;
4413 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4365 4414
4366 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4415 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4367 4416
4368 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4417 int j;
4369 { 4418 for (j = 0; j < (6 + BannedUsers.Count); j++)
4370 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4419 {
4371 } 4420 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4372 int j = 0; 4421 }
4422 j = 0;
4373 4423
4374 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4424 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4375 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4425 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4426 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4427 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4428 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4429 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4380 4430
4381 foreach (UUID banned in BannedUsers) 4431 foreach (UUID banned in BannedUsers)
4382 { 4432 {
4383 returnblock[j].Parameter = banned.GetBytes(); j++; 4433 returnblock[j].Parameter = banned.GetBytes(); j++;
4434 }
4435 packet.ParamList = returnblock;
4436 packet.Header.Reliable = true;
4437 OutPacket(packet, ThrottleOutPacketType.Task);
4438
4439 BannedUsers.Clear();
4440 }
4384 } 4441 }
4385 packet.ParamList = returnblock; 4442
4386 packet.Header.Reliable = false;
4387 OutPacket(packet, ThrottleOutPacketType.Task);
4388 } 4443 }
4389 4444
4390 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4445 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4553,7 +4608,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4553 4608
4554 if (landData.SimwideArea > 0) 4609 if (landData.SimwideArea > 0)
4555 { 4610 {
4556 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4611 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4612 // Never report more than sim total capacity
4613 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4614 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4557 updateMessage.SimWideMaxPrims = simulatorCapacity; 4615 updateMessage.SimWideMaxPrims = simulatorCapacity;
4558 } 4616 }
4559 else 4617 else
@@ -4682,14 +4740,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4682 4740
4683 if (notifyCount > 0) 4741 if (notifyCount > 0)
4684 { 4742 {
4685 if (notifyCount > 32) 4743// if (notifyCount > 32)
4686 { 4744// {
4687 m_log.InfoFormat( 4745// m_log.InfoFormat(
4688 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4746// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4689 + " - a developer might want to investigate whether this is a hard limit", 32); 4747// + " - a developer might want to investigate whether this is a hard limit", 32);
4690 4748//
4691 notifyCount = 32; 4749// notifyCount = 32;
4692 } 4750// }
4693 4751
4694 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4752 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4695 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4753 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5216,6 +5274,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5216 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5274 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5217 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5275 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5218 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5276 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5277 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5219 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5278 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5220 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5279 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5221 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5280 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5282,6 +5341,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5282 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5341 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5283 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5342 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5284 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5343 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5344 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5285 5345
5286 AddGenericPacketHandler("autopilot", HandleAutopilot); 5346 AddGenericPacketHandler("autopilot", HandleAutopilot);
5287 } 5347 }
@@ -5317,6 +5377,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5317 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5377 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5318 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5378 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5319 (x.ControlFlags != lastarg.ControlFlags) || 5379 (x.ControlFlags != lastarg.ControlFlags) ||
5380 (x.ControlFlags != 0) ||
5320 (x.Far != lastarg.Far) || 5381 (x.Far != lastarg.Far) ||
5321 (x.Flags != lastarg.Flags) || 5382 (x.Flags != lastarg.Flags) ||
5322 (x.State != lastarg.State) || 5383 (x.State != lastarg.State) ||
@@ -5694,7 +5755,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5694 args.Channel = ch; 5755 args.Channel = ch;
5695 args.From = String.Empty; 5756 args.From = String.Empty;
5696 args.Message = Utils.BytesToString(msg); 5757 args.Message = Utils.BytesToString(msg);
5697 args.Type = ChatTypeEnum.Shout; 5758 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5698 args.Position = new Vector3(); 5759 args.Position = new Vector3();
5699 args.Scene = Scene; 5760 args.Scene = Scene;
5700 args.Sender = this; 5761 args.Sender = this;
@@ -9710,7 +9771,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9710 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9771 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9711 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9772 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9712 UpdateMuteListEntry.MuteData.MuteType, 9773 UpdateMuteListEntry.MuteData.MuteType,
9713 UpdateMuteListEntry.AgentData.AgentID); 9774 UpdateMuteListEntry.MuteData.MuteFlags);
9714 return true; 9775 return true;
9715 } 9776 }
9716 return false; 9777 return false;
@@ -9725,8 +9786,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9725 { 9786 {
9726 handlerRemoveMuteListEntry(this, 9787 handlerRemoveMuteListEntry(this,
9727 RemoveMuteListEntry.MuteData.MuteID, 9788 RemoveMuteListEntry.MuteData.MuteID,
9728 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9789 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9729 RemoveMuteListEntry.AgentData.AgentID);
9730 return true; 9790 return true;
9731 } 9791 }
9732 return false; 9792 return false;
@@ -9770,10 +9830,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9770 return false; 9830 return false;
9771 } 9831 }
9772 9832
9833 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9834 {
9835 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9836 (ChangeInventoryItemFlagsPacket)packet;
9837 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9838 if (handlerChangeInventoryItemFlags != null)
9839 {
9840 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9841 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9842 return true;
9843 }
9844 return false;
9845 }
9846
9773 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9847 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9774 { 9848 {
9775 return true; 9849 return true;
9776 } 9850 }
9851
9852 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9853 {
9854 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9855
9856 #region Packet Session and User Check
9857 if (m_checkPackets)
9858 {
9859 if (packet.AgentData.SessionID != SessionId ||
9860 packet.AgentData.AgentID != AgentId)
9861 return true;
9862 }
9863 #endregion
9864 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9865 List<InventoryItemBase> items = new List<InventoryItemBase>();
9866 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9867 {
9868 InventoryItemBase b = new InventoryItemBase();
9869 b.ID = n.OldItemID;
9870 b.Folder = n.OldFolderID;
9871 items.Add(b);
9872 }
9873
9874 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9875 if (handlerMoveItemsAndLeaveCopy != null)
9876 {
9877 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9878 }
9879
9880 return true;
9881 }
9777 9882
9778 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9883 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9779 { 9884 {
@@ -10200,6 +10305,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10200 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10305 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10201 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10306 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10202 10307
10308 Scene scene = (Scene)m_scene;
10309 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10310 {
10311 ScenePresence p;
10312 if (scene.TryGetScenePresence(sender.AgentId, out p))
10313 {
10314 if (p.GodLevel >= 200)
10315 {
10316 groupProfileReply.GroupData.OpenEnrollment = true;
10317 groupProfileReply.GroupData.MembershipFee = 0;
10318 }
10319 }
10320 }
10321
10203 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10322 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10204 } 10323 }
10205 return true; 10324 return true;
@@ -10772,11 +10891,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10772 10891
10773 StartLure handlerStartLure = OnStartLure; 10892 StartLure handlerStartLure = OnStartLure;
10774 if (handlerStartLure != null) 10893 if (handlerStartLure != null)
10775 handlerStartLure(startLureRequest.Info.LureType, 10894 {
10776 Utils.BytesToString( 10895 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10777 startLureRequest.Info.Message), 10896 {
10778 startLureRequest.TargetData[0].TargetID, 10897 handlerStartLure(startLureRequest.Info.LureType,
10779 this); 10898 Utils.BytesToString(
10899 startLureRequest.Info.Message),
10900 startLureRequest.TargetData[i].TargetID,
10901 this);
10902 }
10903 }
10780 return true; 10904 return true;
10781 } 10905 }
10782 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10906 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10890,10 +11014,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10890 } 11014 }
10891 #endregion 11015 #endregion
10892 11016
10893 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11017 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10894 if (handlerClassifiedGodDelete != null) 11018 if (handlerClassifiedGodDelete != null)
10895 handlerClassifiedGodDelete( 11019 handlerClassifiedGodDelete(
10896 classifiedGodDelete.Data.ClassifiedID, 11020 classifiedGodDelete.Data.ClassifiedID,
11021 classifiedGodDelete.Data.QueryID,
10897 this); 11022 this);
10898 return true; 11023 return true;
10899 } 11024 }
@@ -11929,7 +12054,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11929 12054
11930// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12055// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11931 12056
12057
12058 //Note, the bool returned from the below function is useless since it is always false.
11932 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12059 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12060
11933 } 12061 }
11934 12062
11935 /// <summary> 12063 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..ae72175 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,7 +496,9 @@ 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 {
491 OutgoingPacket packet; 499 if (m_deliverPackets == false) return false;
500
501 OutgoingPacket packet = null;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
494 bool packetSent = false; 504 bool packetSent = false;
@@ -520,32 +530,49 @@ 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)
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 bool success = false;
526 // enough tokens in the bucket to send it out 536 try
527 if (bucket.RemoveTokens(packet.Buffer.DataLength))
528 { 537 {
529 // Send the packet 538 success = queue.Dequeue(out packet);
530 m_udpServer.SendPacketFinal(packet);
531 packetSent = true;
532 } 539 }
533 else 540 catch
534 { 541 {
535 // Save the dequeued packet for the next iteration 542 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
536 m_nextPackets[i] = packet;
537 } 543 }
538 544 if (success)
539 // If the queue is empty after this dequeue, fire the queue 545 {
540 // empty callback now so it has a chance to fill before we 546 // A packet was pulled off the queue. See if we have
541 // get back here 547 // enough tokens in the bucket to send it out
542 if (queue.Count == 0) 548 if (bucket.RemoveTokens(packet.Buffer.DataLength))
549 {
550 // Send the packet
551 m_udpServer.SendPacketFinal(packet);
552 packetSent = true;
553 }
554 else
555 {
556 // Save the dequeued packet for the next iteration
557 m_nextPackets[i] = packet;
558 }
559
560 // If the queue is empty after this dequeue, fire the queue
561 // empty callback now so it has a chance to fill before we
562 // get back here
563 if (queue.Count == 0)
564 emptyCategories |= CategoryToFlag(i);
565 }
566 else
567 {
568 // No packets in this queue. Fire the queue empty callback
569 // if it has not been called recently
543 emptyCategories |= CategoryToFlag(i); 570 emptyCategories |= CategoryToFlag(i);
571 }
544 } 572 }
545 else 573 else
546 { 574 {
547 // No packets in this queue. Fire the queue empty callback 575 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
548 // if it has not been called recently
549 emptyCategories |= CategoryToFlag(i); 576 emptyCategories |= CategoryToFlag(i);
550 } 577 }
551 } 578 }
@@ -703,4 +730,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
703 } 730 }
704 } 731 }
705 } 732 }
706} \ No newline at end of file 733}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 5610c09..bf5b85a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1030,7 +1030,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1030 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1030 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1031 { 1031 {
1032 client.IsLoggingOut = true; 1032 client.IsLoggingOut = true;
1033 client.Close(); 1033 client.Close(false);
1034 } 1034 }
1035 } 1035 }
1036 1036
@@ -1042,6 +1042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1042 1042
1043 while (base.IsRunning) 1043 while (base.IsRunning)
1044 { 1044 {
1045 m_scene.ThreadAlive(1);
1045 try 1046 try
1046 { 1047 {
1047 IncomingPacket incomingPacket = null; 1048 IncomingPacket incomingPacket = null;
@@ -1084,6 +1085,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1084 1085
1085 while (base.IsRunning) 1086 while (base.IsRunning)
1086 { 1087 {
1088 m_scene.ThreadAlive(2);
1087 try 1089 try
1088 { 1090 {
1089 m_packetSent = false; 1091 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..cfe7c9d 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,