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 1d4be8a..ace4444 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;
@@ -285,6 +286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 286 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
286 public event SimWideDeletesDelegate OnSimWideDeletes; 287 public event SimWideDeletesDelegate OnSimWideDeletes;
287 public event SendPostcard OnSendPostcard; 288 public event SendPostcard OnSendPostcard;
289 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
288 public event MuteListEntryUpdate OnUpdateMuteListEntry; 290 public event MuteListEntryUpdate OnUpdateMuteListEntry;
289 public event MuteListEntryRemove OnRemoveMuteListEntry; 291 public event MuteListEntryRemove OnRemoveMuteListEntry;
290 public event GodlikeMessage onGodlikeMessage; 292 public event GodlikeMessage onGodlikeMessage;
@@ -330,7 +332,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
330 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 332 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
331 /// ownerless phantom. 333 /// ownerless phantom.
332 /// 334 ///
333 /// All manipulation of this set has to occur under a lock 335 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
334 /// 336 ///
335 /// </value> 337 /// </value>
336 protected HashSet<uint> m_killRecord; 338 protected HashSet<uint> m_killRecord;
@@ -338,6 +340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338// protected HashSet<uint> m_attachmentsSent; 340// protected HashSet<uint> m_attachmentsSent;
339 341
340 private int m_moneyBalance; 342 private int m_moneyBalance;
343 private bool m_deliverPackets = true;
341 private int m_animationSequenceNumber = 1; 344 private int m_animationSequenceNumber = 1;
342 private bool m_SendLogoutPacketWhenClosing = true; 345 private bool m_SendLogoutPacketWhenClosing = true;
343 private AgentUpdateArgs lastarg; 346 private AgentUpdateArgs lastarg;
@@ -378,6 +381,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
378 get { return m_startpos; } 381 get { return m_startpos; }
379 set { m_startpos = value; } 382 set { m_startpos = value; }
380 } 383 }
384 public bool DeliverPackets
385 {
386 get { return m_deliverPackets; }
387 set {
388 m_deliverPackets = value;
389 m_udpClient.m_deliverPackets = value;
390 }
391 }
381 public UUID AgentId { get { return m_agentId; } } 392 public UUID AgentId { get { return m_agentId; } }
382 public ISceneAgent SceneAgent { get; private set; } 393 public ISceneAgent SceneAgent { get; private set; }
383 public UUID ActiveGroupId { get { return m_activeGroupID; } } 394 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -480,18 +491,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
480 491
481 #region Client Methods 492 #region Client Methods
482 493
494
483 /// <summary> 495 /// <summary>
484 /// Shut down the client view 496 /// Shut down the client view
485 /// </summary> 497 /// </summary>
486 public void Close() 498 public void Close()
487 { 499 {
500 Close(true);
501 }
502
503 /// <summary>
504 /// Shut down the client view
505 /// </summary>
506 public void Close(bool sendStop)
507 {
488 m_log.DebugFormat( 508 m_log.DebugFormat(
489 "[CLIENT]: Close has been called for {0} attached to scene {1}", 509 "[CLIENT]: Close has been called for {0} attached to scene {1}",
490 Name, m_scene.RegionInfo.RegionName); 510 Name, m_scene.RegionInfo.RegionName);
491 511
492 // Send the STOP packet 512 if (sendStop)
493 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 513 {
494 OutPacket(disable, ThrottleOutPacketType.Unknown); 514 // Send the STOP packet
515 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
516 OutPacket(disable, ThrottleOutPacketType.Unknown);
517 }
495 518
496 IsActive = false; 519 IsActive = false;
497 520
@@ -793,7 +816,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
793 reply.ChatData.OwnerID = fromAgentID; 816 reply.ChatData.OwnerID = fromAgentID;
794 reply.ChatData.SourceID = fromAgentID; 817 reply.ChatData.SourceID = fromAgentID;
795 818
796 OutPacket(reply, ThrottleOutPacketType.Task); 819 OutPacket(reply, ThrottleOutPacketType.Unknown);
797 } 820 }
798 821
799 /// <summary> 822 /// <summary>
@@ -1079,6 +1102,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1079 public virtual void SendLayerData(float[] map) 1102 public virtual void SendLayerData(float[] map)
1080 { 1103 {
1081 Util.FireAndForget(DoSendLayerData, map); 1104 Util.FireAndForget(DoSendLayerData, map);
1105
1106 // Send it sync, and async. It's not that much data
1107 // and it improves user experience just so much!
1108 DoSendLayerData(map);
1082 } 1109 }
1083 1110
1084 /// <summary> 1111 /// <summary>
@@ -1091,16 +1118,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1091 1118
1092 try 1119 try
1093 { 1120 {
1094 //for (int y = 0; y < 16; y++) 1121 for (int y = 0; y < 16; y++)
1095 //{ 1122 {
1096 // for (int x = 0; x < 16; x++) 1123 for (int x = 0; x < 16; x+=4)
1097 // { 1124 {
1098 // SendLayerData(x, y, map); 1125 SendLayerPacket(x, y, map);
1099 // } 1126 }
1100 //} 1127 }
1101
1102 // Send LayerData in a spiral pattern. Fun!
1103 SendLayerTopRight(map, 0, 0, 15, 15);
1104 } 1128 }
1105 catch (Exception e) 1129 catch (Exception e)
1106 { 1130 {
@@ -1108,51 +1132,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1108 } 1132 }
1109 } 1133 }
1110 1134
1111 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1112 {
1113 // Row
1114 for (int i = x1; i <= x2; i++)
1115 SendLayerData(i, y1, map);
1116
1117 // Column
1118 for (int j = y1 + 1; j <= y2; j++)
1119 SendLayerData(x2, j, map);
1120
1121 if (x2 - x1 > 0)
1122 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1123 }
1124
1125 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1126 {
1127 // Row in reverse
1128 for (int i = x2; i >= x1; i--)
1129 SendLayerData(i, y2, map);
1130
1131 // Column in reverse
1132 for (int j = y2 - 1; j >= y1; j--)
1133 SendLayerData(x1, j, map);
1134
1135 if (x2 - x1 > 0)
1136 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1137 }
1138
1139 /// <summary> 1135 /// <summary>
1140 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1136 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1141 /// </summary> 1137 /// </summary>
1142 /// <param name="map">heightmap</param> 1138 /// <param name="map">heightmap</param>
1143 /// <param name="px">X coordinate for patches 0..12</param> 1139 /// <param name="px">X coordinate for patches 0..12</param>
1144 /// <param name="py">Y coordinate for patches 0..15</param> 1140 /// <param name="py">Y coordinate for patches 0..15</param>
1145 // private void SendLayerPacket(float[] map, int y, int x) 1141 private void SendLayerPacket(int x, int y, float[] map)
1146 // { 1142 {
1147 // int[] patches = new int[4]; 1143 int[] patches = new int[4];
1148 // patches[0] = x + 0 + y * 16; 1144 patches[0] = x + 0 + y * 16;
1149 // patches[1] = x + 1 + y * 16; 1145 patches[1] = x + 1 + y * 16;
1150 // patches[2] = x + 2 + y * 16; 1146 patches[2] = x + 2 + y * 16;
1151 // patches[3] = x + 3 + y * 16; 1147 patches[3] = x + 3 + y * 16;
1152 1148
1153 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1149 float[] heightmap = (map.Length == 65536) ?
1154 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1150 map :
1155 // } 1151 LLHeightFieldMoronize(map);
1152
1153 try
1154 {
1155 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1156 OutPacket(layerpack, ThrottleOutPacketType.Land);
1157 }
1158 catch
1159 {
1160 for (int px = x ; px < x + 4 ; px++)
1161 SendLayerData(px, y, map);
1162 }
1163 }
1156 1164
1157 /// <summary> 1165 /// <summary>
1158 /// Sends a specified patch to a client 1166 /// Sends a specified patch to a client
@@ -1172,7 +1180,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1172 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1180 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1173 layerpack.Header.Reliable = true; 1181 layerpack.Header.Reliable = true;
1174 1182
1175 OutPacket(layerpack, ThrottleOutPacketType.Land); 1183 OutPacket(layerpack, ThrottleOutPacketType.Task);
1176 } 1184 }
1177 catch (Exception e) 1185 catch (Exception e)
1178 { 1186 {
@@ -2296,6 +2304,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2296 OutPacket(sound, ThrottleOutPacketType.Task); 2304 OutPacket(sound, ThrottleOutPacketType.Task);
2297 } 2305 }
2298 2306
2307 public void SendTransferAbort(TransferRequestPacket transferRequest)
2308 {
2309 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2310 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2311 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2312 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2313 OutPacket(abort, ThrottleOutPacketType.Task);
2314 }
2315
2299 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2316 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2300 { 2317 {
2301 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2318 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3598,7 +3615,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3598 /// </summary> 3615 /// </summary>
3599 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3616 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3600 { 3617 {
3601 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3618 if (entity is SceneObjectPart)
3619 {
3620 SceneObjectPart e = (SceneObjectPart)entity;
3621 SceneObjectGroup g = e.ParentGroup;
3622 if (g.RootPart.Shape.State > 30) // HUD
3623 if (g.OwnerID != AgentId)
3624 return; // Don't send updates for other people's HUDs
3625 }
3626
3602 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3627 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3603 3628
3604 lock (m_entityUpdates.SyncRoot) 3629 lock (m_entityUpdates.SyncRoot)
@@ -3665,211 +3690,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3665 3690
3666 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3691 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3667 // condition where a kill can be processed before an out-of-date update for the same object. 3692 // condition where a kill can be processed before an out-of-date update for the same object.
3668 lock (m_killRecord) 3693 float avgTimeDilation = 1.0f;
3694 IEntityUpdate iupdate;
3695 Int32 timeinqueue; // this is just debugging code & can be dropped later
3696
3697 while (updatesThisCall < maxUpdates)
3669 { 3698 {
3670 float avgTimeDilation = 1.0f; 3699 lock (m_entityUpdates.SyncRoot)
3671 IEntityUpdate iupdate; 3700 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3672 Int32 timeinqueue; // this is just debugging code & can be dropped later 3701 break;
3673
3674 while (updatesThisCall < maxUpdates)
3675 {
3676 lock (m_entityUpdates.SyncRoot)
3677 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3678 break;
3679 3702
3680 EntityUpdate update = (EntityUpdate)iupdate; 3703 EntityUpdate update = (EntityUpdate)iupdate;
3681 3704
3682 avgTimeDilation += update.TimeDilation; 3705 avgTimeDilation += update.TimeDilation;
3683 avgTimeDilation *= 0.5f; 3706 avgTimeDilation *= 0.5f;
3684 3707
3685 if (update.Entity is SceneObjectPart) 3708 if (update.Entity is SceneObjectPart)
3709 {
3710 SceneObjectPart part = (SceneObjectPart)update.Entity;
3711
3712 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3713 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3714 // safety measure.
3715 //
3716 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3717 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3718 // updates and kills on different threads with different scheduling strategies, hence this protection.
3719 //
3720 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3721 // after the root prim has been deleted.
3722 lock (m_killRecord)
3686 { 3723 {
3687 SceneObjectPart part = (SceneObjectPart)update.Entity;
3688
3689 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3690 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3691 // safety measure.
3692 //
3693 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3694 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3695 // updates and kills on different threads with different scheduling strategies, hence this protection.
3696 //
3697 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3698 // after the root prim has been deleted.
3699 if (m_killRecord.Contains(part.LocalId)) 3724 if (m_killRecord.Contains(part.LocalId))
3700 {
3701 // m_log.WarnFormat(
3702 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3703 // part.LocalId, Name);
3704 continue; 3725 continue;
3705 } 3726 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3706 3727 continue;
3707 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3728 }
3729
3730 if (part.ParentGroup.IsDeleted)
3731 continue;
3732
3733 if (part.ParentGroup.IsAttachment)
3734 { // Someone else's HUD, why are we getting these?
3735 if (part.ParentGroup.OwnerID != AgentId &&
3736 part.ParentGroup.RootPart.Shape.State >= 30)
3737 continue;
3738 ScenePresence sp;
3739 // Owner is not in the sim, don't update it to
3740 // anyone
3741 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3742 continue;
3743
3744 List<SceneObjectGroup> atts = sp.GetAttachments();
3745 bool found = false;
3746 foreach (SceneObjectGroup att in atts)
3708 { 3747 {
3709 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3748 if (att == part.ParentGroup)
3710 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3711 { 3749 {
3712 part.Shape.LightEntry = false; 3750 found = true;
3751 break;
3713 } 3752 }
3714 } 3753 }
3754
3755 // It's an attachment of a valid avatar, but
3756 // doesn't seem to be attached, skip
3757 if (!found)
3758 continue;
3715 } 3759 }
3716 3760 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3717 ++updatesThisCall;
3718
3719 #region UpdateFlags to packet type conversion
3720
3721 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3722
3723 bool canUseCompressed = true;
3724 bool canUseImproved = true;
3725
3726 // Compressed object updates only make sense for LL primitives
3727 if (!(update.Entity is SceneObjectPart))
3728 {
3729 canUseCompressed = false;
3730 }
3731
3732 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3733 {
3734 canUseCompressed = false;
3735 canUseImproved = false;
3736 }
3737 else
3738 { 3761 {
3739 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3762 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3740 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3763 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3741 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3742 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3743 {
3744 canUseCompressed = false;
3745 }
3746
3747 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3748 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3751 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3761 { 3764 {
3762 canUseImproved = false; 3765 part.Shape.LightEntry = false;
3763 } 3766 }
3764 } 3767 }
3765 3768 }
3766 #endregion UpdateFlags to packet type conversion 3769
3767 3770 ++updatesThisCall;
3768 #region Block Construction 3771
3769 3772 #region UpdateFlags to packet type conversion
3770 // TODO: Remove this once we can build compressed updates 3773
3774 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3775
3776 bool canUseCompressed = true;
3777 bool canUseImproved = true;
3778
3779 // Compressed object updates only make sense for LL primitives
3780 if (!(update.Entity is SceneObjectPart))
3781 {
3771 canUseCompressed = false; 3782 canUseCompressed = false;
3772 3783 }
3773 if (!canUseImproved && !canUseCompressed) 3784
3774 { 3785 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3775 if (update.Entity is ScenePresence) 3786 {
3776 { 3787 canUseCompressed = false;
3777 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3788 canUseImproved = false;
3778 objectUpdates.Value.Add(update); 3789 }
3779 } 3790 else
3780 else 3791 {
3781 { 3792 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3782 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3793 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3783 objectUpdates.Value.Add(update); 3794 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3784 } 3795 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3785 }
3786 else if (!canUseImproved)
3787 { 3796 {
3788 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3797 canUseCompressed = false;
3789 compressedUpdates.Value.Add(update);
3790 } 3798 }
3791 else 3799
3800 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3792 { 3814 {
3793 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3815 canUseImproved = false;
3794 {
3795 // Self updates go into a special list
3796 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3797 terseAgentUpdates.Value.Add(update);
3798 }
3799 else
3800 {
3801 // Everything else goes here
3802 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3803 terseUpdates.Value.Add(update);
3804 }
3805 } 3816 }
3806
3807 #endregion Block Construction
3808 } 3817 }
3809
3810
3811 #region Packet Sending
3812 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3813 3818
3814 if (terseAgentUpdateBlocks.IsValueCreated) 3819 #endregion UpdateFlags to packet type conversion
3815 {
3816 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3817 3820
3818 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3821 #region Block Construction
3819 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3820 packet.RegionData.TimeDilation = timeDilation;
3821 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3822 3822
3823 for (int i = 0; i < blocks.Count; i++) 3823 // TODO: Remove this once we can build compressed updates
3824 packet.ObjectData[i] = blocks[i]; 3824 canUseCompressed = false;
3825 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3826 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3827 }
3828 3825
3829 if (objectUpdateBlocks.IsValueCreated) 3826 if (!canUseImproved && !canUseCompressed)
3830 { 3827 {
3831 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3828 if (update.Entity is ScenePresence)
3832 3829 {
3833 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3830 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3834 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3831 }
3835 packet.RegionData.TimeDilation = timeDilation; 3832 else
3836 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3833 {
3837 3834 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3838 for (int i = 0; i < blocks.Count; i++) 3835 }
3839 packet.ObjectData[i] = blocks[i];
3840 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3841 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3842 } 3836 }
3843 3837 else if (!canUseImproved)
3844 if (compressedUpdateBlocks.IsValueCreated)
3845 { 3838 {
3846 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3839 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3847
3848 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3849 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3850 packet.RegionData.TimeDilation = timeDilation;
3851 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3852
3853 for (int i = 0; i < blocks.Count; i++)
3854 packet.ObjectData[i] = blocks[i];
3855 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3856 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3857 } 3840 }
3858 3841 else
3859 if (terseUpdateBlocks.IsValueCreated)
3860 { 3842 {
3861 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3843 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3862 3844 // Self updates go into a special list
3863 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3845 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3864 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3846 else
3865 packet.RegionData.TimeDilation = timeDilation; 3847 // Everything else goes here
3866 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3848 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3867
3868 for (int i = 0; i < blocks.Count; i++)
3869 packet.ObjectData[i] = blocks[i];
3870 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3871 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3872 } 3849 }
3850
3851 #endregion Block Construction
3852 }
3853
3854 #region Packet Sending
3855
3856 const float TIME_DILATION = 1.0f;
3857 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3858
3859 if (terseAgentUpdateBlocks.IsValueCreated)
3860 {
3861 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3862
3863 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3864 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3865 packet.RegionData.TimeDilation = timeDilation;
3866 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3867
3868 for (int i = 0; i < blocks.Count; i++)
3869 packet.ObjectData[i] = blocks[i];
3870
3871 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3872 }
3873
3874 if (objectUpdateBlocks.IsValueCreated)
3875 {
3876 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3877
3878 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3879 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3880 packet.RegionData.TimeDilation = timeDilation;
3881 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3882
3883 for (int i = 0; i < blocks.Count; i++)
3884 packet.ObjectData[i] = blocks[i];
3885
3886 OutPacket(packet, ThrottleOutPacketType.Task, true);
3887 }
3888
3889 if (compressedUpdateBlocks.IsValueCreated)
3890 {
3891 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3892
3893 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3894 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3895 packet.RegionData.TimeDilation = timeDilation;
3896 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3897
3898 for (int i = 0; i < blocks.Count; i++)
3899 packet.ObjectData[i] = blocks[i];
3900
3901 OutPacket(packet, ThrottleOutPacketType.Task, true);
3902 }
3903
3904 if (terseUpdateBlocks.IsValueCreated)
3905 {
3906 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3907
3908 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3909 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3910 packet.RegionData.TimeDilation = timeDilation;
3911 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3912
3913 for (int i = 0; i < blocks.Count; i++)
3914 packet.ObjectData[i] = blocks[i];
3915
3916 OutPacket(packet, ThrottleOutPacketType.Task, true);
3873 } 3917 }
3874 3918
3875 #endregion Packet Sending 3919 #endregion Packet Sending
@@ -4170,11 +4214,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4170 4214
4171 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4215 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4172 // of the object rather than the properties when the packet was created 4216 // of the object rather than the properties when the packet was created
4173 OutPacket(packet, ThrottleOutPacketType.Task, true, 4217 // HACK : Remove intelligent resending until it's fixed in core
4174 delegate(OutgoingPacket oPacket) 4218 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4175 { 4219 // delegate(OutgoingPacket oPacket)
4176 ResendPropertyUpdates(updates, oPacket); 4220 // {
4177 }); 4221 // ResendPropertyUpdates(updates, oPacket);
4222 // });
4223 OutPacket(packet, ThrottleOutPacketType.Task, true);
4178 4224
4179 // pbcnt += blocks.Count; 4225 // pbcnt += blocks.Count;
4180 // ppcnt++; 4226 // ppcnt++;
@@ -4200,11 +4246,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4200 // of the object rather than the properties when the packet was created 4246 // of the object rather than the properties when the packet was created
4201 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4247 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4202 updates.Add(familyUpdates.Value[i]); 4248 updates.Add(familyUpdates.Value[i]);
4203 OutPacket(packet, ThrottleOutPacketType.Task, true, 4249 // HACK : Remove intelligent resending until it's fixed in core
4204 delegate(OutgoingPacket oPacket) 4250 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4205 { 4251 // delegate(OutgoingPacket oPacket)
4206 ResendPropertyUpdates(updates, oPacket); 4252 // {
4207 }); 4253 // ResendPropertyUpdates(updates, oPacket);
4254 // });
4255 OutPacket(packet, ThrottleOutPacketType.Task, true);
4208 4256
4209 // fpcnt++; 4257 // fpcnt++;
4210 // fbcnt++; 4258 // fbcnt++;
@@ -4353,37 +4401,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4353 if (bl[i].BannedUserID == UUID.Zero) 4401 if (bl[i].BannedUserID == UUID.Zero)
4354 continue; 4402 continue;
4355 BannedUsers.Add(bl[i].BannedUserID); 4403 BannedUsers.Add(bl[i].BannedUserID);
4356 }
4357 4404
4358 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4405 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4359 packet.AgentData.TransactionID = UUID.Random(); 4406 {
4360 packet.AgentData.AgentID = AgentId; 4407 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4361 packet.AgentData.SessionID = SessionId; 4408 packet.AgentData.TransactionID = UUID.Random();
4362 packet.MethodData.Invoice = invoice; 4409 packet.AgentData.AgentID = AgentId;
4363 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4410 packet.AgentData.SessionID = SessionId;
4411 packet.MethodData.Invoice = invoice;
4412 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4364 4413
4365 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4414 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4366 4415
4367 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4416 int j;
4368 { 4417 for (j = 0; j < (6 + BannedUsers.Count); j++)
4369 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4418 {
4370 } 4419 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4371 int j = 0; 4420 }
4421 j = 0;
4372 4422
4373 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4423 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4374 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4424 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4375 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4425 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4426 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4427 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4428 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4379 4429
4380 foreach (UUID banned in BannedUsers) 4430 foreach (UUID banned in BannedUsers)
4381 { 4431 {
4382 returnblock[j].Parameter = banned.GetBytes(); j++; 4432 returnblock[j].Parameter = banned.GetBytes(); j++;
4433 }
4434 packet.ParamList = returnblock;
4435 packet.Header.Reliable = true;
4436 OutPacket(packet, ThrottleOutPacketType.Task);
4437
4438 BannedUsers.Clear();
4439 }
4383 } 4440 }
4384 packet.ParamList = returnblock; 4441
4385 packet.Header.Reliable = false;
4386 OutPacket(packet, ThrottleOutPacketType.Task);
4387 } 4442 }
4388 4443
4389 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4444 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4552,7 +4607,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4552 4607
4553 if (landData.SimwideArea > 0) 4608 if (landData.SimwideArea > 0)
4554 { 4609 {
4555 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4610 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4611 // Never report more than sim total capacity
4612 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4613 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4556 updateMessage.SimWideMaxPrims = simulatorCapacity; 4614 updateMessage.SimWideMaxPrims = simulatorCapacity;
4557 } 4615 }
4558 else 4616 else
@@ -4681,14 +4739,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4681 4739
4682 if (notifyCount > 0) 4740 if (notifyCount > 0)
4683 { 4741 {
4684 if (notifyCount > 32) 4742// if (notifyCount > 32)
4685 { 4743// {
4686 m_log.InfoFormat( 4744// m_log.InfoFormat(
4687 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4745// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4688 + " - a developer might want to investigate whether this is a hard limit", 32); 4746// + " - a developer might want to investigate whether this is a hard limit", 32);
4689 4747//
4690 notifyCount = 32; 4748// notifyCount = 32;
4691 } 4749// }
4692 4750
4693 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4751 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4694 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4752 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5214,6 +5272,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5214 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5272 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5215 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5273 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5216 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5274 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5275 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5217 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5276 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5218 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5277 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5219 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5278 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5280,6 +5339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5280 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5339 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5281 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5340 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5282 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5341 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5342 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5283 5343
5284 AddGenericPacketHandler("autopilot", HandleAutopilot); 5344 AddGenericPacketHandler("autopilot", HandleAutopilot);
5285 } 5345 }
@@ -5315,6 +5375,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5315 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5375 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5316 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5376 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5317 (x.ControlFlags != lastarg.ControlFlags) || 5377 (x.ControlFlags != lastarg.ControlFlags) ||
5378 (x.ControlFlags != 0) ||
5318 (x.Far != lastarg.Far) || 5379 (x.Far != lastarg.Far) ||
5319 (x.Flags != lastarg.Flags) || 5380 (x.Flags != lastarg.Flags) ||
5320 (x.State != lastarg.State) || 5381 (x.State != lastarg.State) ||
@@ -5692,7 +5753,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5692 args.Channel = ch; 5753 args.Channel = ch;
5693 args.From = String.Empty; 5754 args.From = String.Empty;
5694 args.Message = Utils.BytesToString(msg); 5755 args.Message = Utils.BytesToString(msg);
5695 args.Type = ChatTypeEnum.Shout; 5756 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5696 args.Position = new Vector3(); 5757 args.Position = new Vector3();
5697 args.Scene = Scene; 5758 args.Scene = Scene;
5698 args.Sender = this; 5759 args.Sender = this;
@@ -9698,7 +9759,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9698 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9759 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9699 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9760 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9700 UpdateMuteListEntry.MuteData.MuteType, 9761 UpdateMuteListEntry.MuteData.MuteType,
9701 UpdateMuteListEntry.AgentData.AgentID); 9762 UpdateMuteListEntry.MuteData.MuteFlags);
9702 return true; 9763 return true;
9703 } 9764 }
9704 return false; 9765 return false;
@@ -9713,8 +9774,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9713 { 9774 {
9714 handlerRemoveMuteListEntry(this, 9775 handlerRemoveMuteListEntry(this,
9715 RemoveMuteListEntry.MuteData.MuteID, 9776 RemoveMuteListEntry.MuteData.MuteID,
9716 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9777 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9717 RemoveMuteListEntry.AgentData.AgentID);
9718 return true; 9778 return true;
9719 } 9779 }
9720 return false; 9780 return false;
@@ -9758,10 +9818,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9758 return false; 9818 return false;
9759 } 9819 }
9760 9820
9821 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9822 {
9823 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9824 (ChangeInventoryItemFlagsPacket)packet;
9825 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9826 if (handlerChangeInventoryItemFlags != null)
9827 {
9828 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9829 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9830 return true;
9831 }
9832 return false;
9833 }
9834
9761 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9835 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9762 { 9836 {
9763 return true; 9837 return true;
9764 } 9838 }
9839
9840 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9841 {
9842 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9843
9844 #region Packet Session and User Check
9845 if (m_checkPackets)
9846 {
9847 if (packet.AgentData.SessionID != SessionId ||
9848 packet.AgentData.AgentID != AgentId)
9849 return true;
9850 }
9851 #endregion
9852 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9853 List<InventoryItemBase> items = new List<InventoryItemBase>();
9854 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9855 {
9856 InventoryItemBase b = new InventoryItemBase();
9857 b.ID = n.OldItemID;
9858 b.Folder = n.OldFolderID;
9859 items.Add(b);
9860 }
9861
9862 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9863 if (handlerMoveItemsAndLeaveCopy != null)
9864 {
9865 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9866 }
9867
9868 return true;
9869 }
9765 9870
9766 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9871 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9767 { 9872 {
@@ -10188,6 +10293,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10188 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10293 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10189 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10294 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10190 10295
10296 Scene scene = (Scene)m_scene;
10297 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10298 {
10299 ScenePresence p;
10300 if (scene.TryGetScenePresence(sender.AgentId, out p))
10301 {
10302 if (p.GodLevel >= 200)
10303 {
10304 groupProfileReply.GroupData.OpenEnrollment = true;
10305 groupProfileReply.GroupData.MembershipFee = 0;
10306 }
10307 }
10308 }
10309
10191 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10310 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10192 } 10311 }
10193 return true; 10312 return true;
@@ -10760,11 +10879,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10760 10879
10761 StartLure handlerStartLure = OnStartLure; 10880 StartLure handlerStartLure = OnStartLure;
10762 if (handlerStartLure != null) 10881 if (handlerStartLure != null)
10763 handlerStartLure(startLureRequest.Info.LureType, 10882 {
10764 Utils.BytesToString( 10883 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10765 startLureRequest.Info.Message), 10884 {
10766 startLureRequest.TargetData[0].TargetID, 10885 handlerStartLure(startLureRequest.Info.LureType,
10767 this); 10886 Utils.BytesToString(
10887 startLureRequest.Info.Message),
10888 startLureRequest.TargetData[i].TargetID,
10889 this);
10890 }
10891 }
10768 return true; 10892 return true;
10769 } 10893 }
10770 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10894 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10878,10 +11002,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10878 } 11002 }
10879 #endregion 11003 #endregion
10880 11004
10881 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11005 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10882 if (handlerClassifiedGodDelete != null) 11006 if (handlerClassifiedGodDelete != null)
10883 handlerClassifiedGodDelete( 11007 handlerClassifiedGodDelete(
10884 classifiedGodDelete.Data.ClassifiedID, 11008 classifiedGodDelete.Data.ClassifiedID,
11009 classifiedGodDelete.Data.QueryID,
10885 this); 11010 this);
10886 return true; 11011 return true;
10887 } 11012 }
@@ -11917,7 +12042,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11917 12042
11918// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12043// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11919 12044
12045
12046 //Note, the bool returned from the below function is useless since it is always false.
11920 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12047 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12048
11921 } 12049 }
11922 12050
11923 /// <summary> 12051 /// <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,