aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-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 afbe56b..3995620 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -234,6 +234,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_stopPacket = TexturePacketCount(); 234 m_stopPacket = TexturePacketCount();
235 } 235 }
236 236
237 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
238 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
239
237 m_currentPacket = StartPacket; 240 m_currentPacket = StartPacket;
238 } 241 }
239 } 242 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 29ad966..bbaa08e 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;
@@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 257 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 258 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 259 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 260 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 261 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 262 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 263 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +288,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 288 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 289 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 290 public event SendPostcard OnSendPostcard;
291 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 292 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 293 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 294 public event GodlikeMessage onGodlikeMessage;
@@ -337,7 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 339 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 340 /// ownerless phantom.
339 /// 341 ///
340 /// All manipulation of this set has to occur under a lock 342 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 343 ///
342 /// </value> 344 /// </value>
343 protected HashSet<uint> m_killRecord; 345 protected HashSet<uint> m_killRecord;
@@ -345,6 +347,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
345// protected HashSet<uint> m_attachmentsSent; 347// protected HashSet<uint> m_attachmentsSent;
346 348
347 private int m_moneyBalance; 349 private int m_moneyBalance;
350 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 351 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 352 private bool m_SendLogoutPacketWhenClosing = true;
350 private AgentUpdateArgs lastarg; 353 private AgentUpdateArgs lastarg;
@@ -384,6 +387,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
384 get { return m_startpos; } 387 get { return m_startpos; }
385 set { m_startpos = value; } 388 set { m_startpos = value; }
386 } 389 }
390 public bool DeliverPackets
391 {
392 get { return m_deliverPackets; }
393 set {
394 m_deliverPackets = value;
395 m_udpClient.m_deliverPackets = value;
396 }
397 }
387 public UUID AgentId { get { return m_agentId; } } 398 public UUID AgentId { get { return m_agentId; } }
388 public ISceneAgent SceneAgent { get; private set; } 399 public ISceneAgent SceneAgent { get; private set; }
389 public UUID ActiveGroupId { get { return m_activeGroupID; } } 400 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -488,18 +499,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 499
489 #region Client Methods 500 #region Client Methods
490 501
502
491 /// <summary> 503 /// <summary>
492 /// Shut down the client view 504 /// Shut down the client view
493 /// </summary> 505 /// </summary>
494 public void Close() 506 public void Close()
495 { 507 {
508 Close(true);
509 }
510
511 /// <summary>
512 /// Shut down the client view
513 /// </summary>
514 public void Close(bool sendStop)
515 {
496 m_log.DebugFormat( 516 m_log.DebugFormat(
497 "[CLIENT]: Close has been called for {0} attached to scene {1}", 517 "[CLIENT]: Close has been called for {0} attached to scene {1}",
498 Name, m_scene.RegionInfo.RegionName); 518 Name, m_scene.RegionInfo.RegionName);
499 519
500 // Send the STOP packet 520 if (sendStop)
501 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 521 {
502 OutPacket(disable, ThrottleOutPacketType.Unknown); 522 // Send the STOP packet
523 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
524 OutPacket(disable, ThrottleOutPacketType.Unknown);
525 }
503 526
504 IsActive = false; 527 IsActive = false;
505 528
@@ -799,7 +822,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
799 reply.ChatData.OwnerID = fromAgentID; 822 reply.ChatData.OwnerID = fromAgentID;
800 reply.ChatData.SourceID = fromAgentID; 823 reply.ChatData.SourceID = fromAgentID;
801 824
802 OutPacket(reply, ThrottleOutPacketType.Task); 825 OutPacket(reply, ThrottleOutPacketType.Unknown);
803 } 826 }
804 827
805 /// <summary> 828 /// <summary>
@@ -1085,6 +1108,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1085 public virtual void SendLayerData(float[] map) 1108 public virtual void SendLayerData(float[] map)
1086 { 1109 {
1087 Util.FireAndForget(DoSendLayerData, map); 1110 Util.FireAndForget(DoSendLayerData, map);
1111
1112 // Send it sync, and async. It's not that much data
1113 // and it improves user experience just so much!
1114 DoSendLayerData(map);
1088 } 1115 }
1089 1116
1090 /// <summary> 1117 /// <summary>
@@ -1097,16 +1124,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1097 1124
1098 try 1125 try
1099 { 1126 {
1100 //for (int y = 0; y < 16; y++) 1127 for (int y = 0; y < 16; y++)
1101 //{ 1128 {
1102 // for (int x = 0; x < 16; x++) 1129 for (int x = 0; x < 16; x+=4)
1103 // { 1130 {
1104 // SendLayerData(x, y, map); 1131 SendLayerPacket(x, y, map);
1105 // } 1132 }
1106 //} 1133 }
1107
1108 // Send LayerData in a spiral pattern. Fun!
1109 SendLayerTopRight(map, 0, 0, 15, 15);
1110 } 1134 }
1111 catch (Exception e) 1135 catch (Exception e)
1112 { 1136 {
@@ -1114,51 +1138,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1114 } 1138 }
1115 } 1139 }
1116 1140
1117 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1118 {
1119 // Row
1120 for (int i = x1; i <= x2; i++)
1121 SendLayerData(i, y1, map);
1122
1123 // Column
1124 for (int j = y1 + 1; j <= y2; j++)
1125 SendLayerData(x2, j, map);
1126
1127 if (x2 - x1 > 0)
1128 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1129 }
1130
1131 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1132 {
1133 // Row in reverse
1134 for (int i = x2; i >= x1; i--)
1135 SendLayerData(i, y2, map);
1136
1137 // Column in reverse
1138 for (int j = y2 - 1; j >= y1; j--)
1139 SendLayerData(x1, j, map);
1140
1141 if (x2 - x1 > 0)
1142 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1143 }
1144
1145 /// <summary> 1141 /// <summary>
1146 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1142 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1147 /// </summary> 1143 /// </summary>
1148 /// <param name="map">heightmap</param> 1144 /// <param name="map">heightmap</param>
1149 /// <param name="px">X coordinate for patches 0..12</param> 1145 /// <param name="px">X coordinate for patches 0..12</param>
1150 /// <param name="py">Y coordinate for patches 0..15</param> 1146 /// <param name="py">Y coordinate for patches 0..15</param>
1151 // private void SendLayerPacket(float[] map, int y, int x) 1147 private void SendLayerPacket(int x, int y, float[] map)
1152 // { 1148 {
1153 // int[] patches = new int[4]; 1149 int[] patches = new int[4];
1154 // patches[0] = x + 0 + y * 16; 1150 patches[0] = x + 0 + y * 16;
1155 // patches[1] = x + 1 + y * 16; 1151 patches[1] = x + 1 + y * 16;
1156 // patches[2] = x + 2 + y * 16; 1152 patches[2] = x + 2 + y * 16;
1157 // patches[3] = x + 3 + y * 16; 1153 patches[3] = x + 3 + y * 16;
1158 1154
1159 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1155 float[] heightmap = (map.Length == 65536) ?
1160 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1156 map :
1161 // } 1157 LLHeightFieldMoronize(map);
1158
1159 try
1160 {
1161 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1162 OutPacket(layerpack, ThrottleOutPacketType.Land);
1163 }
1164 catch
1165 {
1166 for (int px = x ; px < x + 4 ; px++)
1167 SendLayerData(px, y, map);
1168 }
1169 }
1162 1170
1163 /// <summary> 1171 /// <summary>
1164 /// Sends a specified patch to a client 1172 /// Sends a specified patch to a client
@@ -1178,7 +1186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1178 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1186 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1179 layerpack.Header.Reliable = true; 1187 layerpack.Header.Reliable = true;
1180 1188
1181 OutPacket(layerpack, ThrottleOutPacketType.Land); 1189 OutPacket(layerpack, ThrottleOutPacketType.Task);
1182 } 1190 }
1183 catch (Exception e) 1191 catch (Exception e)
1184 { 1192 {
@@ -2302,6 +2310,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2302 OutPacket(sound, ThrottleOutPacketType.Task); 2310 OutPacket(sound, ThrottleOutPacketType.Task);
2303 } 2311 }
2304 2312
2313 public void SendTransferAbort(TransferRequestPacket transferRequest)
2314 {
2315 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2316 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2317 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2318 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2319 OutPacket(abort, ThrottleOutPacketType.Task);
2320 }
2321
2305 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2322 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2306 { 2323 {
2307 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2324 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3612,7 +3629,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3612 /// </summary> 3629 /// </summary>
3613 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3630 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3614 { 3631 {
3615 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3632 if (entity is SceneObjectPart)
3633 {
3634 SceneObjectPart e = (SceneObjectPart)entity;
3635 SceneObjectGroup g = e.ParentGroup;
3636 if (g.RootPart.Shape.State > 30) // HUD
3637 if (g.OwnerID != AgentId)
3638 return; // Don't send updates for other people's HUDs
3639 }
3640
3616 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3641 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3617 3642
3618 lock (m_entityUpdates.SyncRoot) 3643 lock (m_entityUpdates.SyncRoot)
@@ -3679,211 +3704,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3679 3704
3680 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3705 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3681 // condition where a kill can be processed before an out-of-date update for the same object. 3706 // condition where a kill can be processed before an out-of-date update for the same object.
3682 lock (m_killRecord) 3707 float avgTimeDilation = 1.0f;
3708 IEntityUpdate iupdate;
3709 Int32 timeinqueue; // this is just debugging code & can be dropped later
3710
3711 while (updatesThisCall < maxUpdates)
3683 { 3712 {
3684 float avgTimeDilation = 1.0f; 3713 lock (m_entityUpdates.SyncRoot)
3685 IEntityUpdate iupdate; 3714 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3686 Int32 timeinqueue; // this is just debugging code & can be dropped later 3715 break;
3687
3688 while (updatesThisCall < maxUpdates)
3689 {
3690 lock (m_entityUpdates.SyncRoot)
3691 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3692 break;
3693 3716
3694 EntityUpdate update = (EntityUpdate)iupdate; 3717 EntityUpdate update = (EntityUpdate)iupdate;
3695 3718
3696 avgTimeDilation += update.TimeDilation; 3719 avgTimeDilation += update.TimeDilation;
3697 avgTimeDilation *= 0.5f; 3720 avgTimeDilation *= 0.5f;
3698 3721
3699 if (update.Entity is SceneObjectPart) 3722 if (update.Entity is SceneObjectPart)
3723 {
3724 SceneObjectPart part = (SceneObjectPart)update.Entity;
3725
3726 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3727 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3728 // safety measure.
3729 //
3730 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3731 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3732 // updates and kills on different threads with different scheduling strategies, hence this protection.
3733 //
3734 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3735 // after the root prim has been deleted.
3736 lock (m_killRecord)
3700 { 3737 {
3701 SceneObjectPart part = (SceneObjectPart)update.Entity;
3702
3703 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3704 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3705 // safety measure.
3706 //
3707 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3708 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3709 // updates and kills on different threads with different scheduling strategies, hence this protection.
3710 //
3711 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3712 // after the root prim has been deleted.
3713 if (m_killRecord.Contains(part.LocalId)) 3738 if (m_killRecord.Contains(part.LocalId))
3714 {
3715 // m_log.WarnFormat(
3716 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3717 // part.LocalId, Name);
3718 continue; 3739 continue;
3719 } 3740 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3720 3741 continue;
3721 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3742 }
3743
3744 if (part.ParentGroup.IsDeleted)
3745 continue;
3746
3747 if (part.ParentGroup.IsAttachment)
3748 { // Someone else's HUD, why are we getting these?
3749 if (part.ParentGroup.OwnerID != AgentId &&
3750 part.ParentGroup.RootPart.Shape.State >= 30)
3751 continue;
3752 ScenePresence sp;
3753 // Owner is not in the sim, don't update it to
3754 // anyone
3755 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3756 continue;
3757
3758 List<SceneObjectGroup> atts = sp.GetAttachments();
3759 bool found = false;
3760 foreach (SceneObjectGroup att in atts)
3722 { 3761 {
3723 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3762 if (att == part.ParentGroup)
3724 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3725 { 3763 {
3726 part.Shape.LightEntry = false; 3764 found = true;
3765 break;
3727 } 3766 }
3728 } 3767 }
3768
3769 // It's an attachment of a valid avatar, but
3770 // doesn't seem to be attached, skip
3771 if (!found)
3772 continue;
3729 } 3773 }
3730 3774 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3731 ++updatesThisCall;
3732
3733 #region UpdateFlags to packet type conversion
3734
3735 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3736
3737 bool canUseCompressed = true;
3738 bool canUseImproved = true;
3739
3740 // Compressed object updates only make sense for LL primitives
3741 if (!(update.Entity is SceneObjectPart))
3742 {
3743 canUseCompressed = false;
3744 }
3745
3746 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3747 {
3748 canUseCompressed = false;
3749 canUseImproved = false;
3750 }
3751 else
3752 { 3775 {
3753 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3776 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3754 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3777 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3755 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3757 {
3758 canUseCompressed = false;
3759 }
3760
3761 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3775 { 3778 {
3776 canUseImproved = false; 3779 part.Shape.LightEntry = false;
3777 } 3780 }
3778 } 3781 }
3779 3782 }
3780 #endregion UpdateFlags to packet type conversion 3783
3781 3784 ++updatesThisCall;
3782 #region Block Construction 3785
3783 3786 #region UpdateFlags to packet type conversion
3784 // TODO: Remove this once we can build compressed updates 3787
3788 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3789
3790 bool canUseCompressed = true;
3791 bool canUseImproved = true;
3792
3793 // Compressed object updates only make sense for LL primitives
3794 if (!(update.Entity is SceneObjectPart))
3795 {
3785 canUseCompressed = false; 3796 canUseCompressed = false;
3786 3797 }
3787 if (!canUseImproved && !canUseCompressed) 3798
3788 { 3799 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3789 if (update.Entity is ScenePresence) 3800 {
3790 { 3801 canUseCompressed = false;
3791 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3802 canUseImproved = false;
3792 objectUpdates.Value.Add(update); 3803 }
3793 } 3804 else
3794 else 3805 {
3795 { 3806 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3796 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3807 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3797 objectUpdates.Value.Add(update); 3808 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3798 } 3809 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3799 }
3800 else if (!canUseImproved)
3801 { 3810 {
3802 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3811 canUseCompressed = false;
3803 compressedUpdates.Value.Add(update);
3804 } 3812 }
3805 else 3813
3814 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3821 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3822 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3823 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3824 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3825 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3826 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3827 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3806 { 3828 {
3807 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3829 canUseImproved = false;
3808 {
3809 // Self updates go into a special list
3810 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3811 terseAgentUpdates.Value.Add(update);
3812 }
3813 else
3814 {
3815 // Everything else goes here
3816 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3817 terseUpdates.Value.Add(update);
3818 }
3819 } 3830 }
3820
3821 #endregion Block Construction
3822 } 3831 }
3823
3824
3825 #region Packet Sending
3826 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3827 3832
3828 if (terseAgentUpdateBlocks.IsValueCreated) 3833 #endregion UpdateFlags to packet type conversion
3829 {
3830 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3831 3834
3832 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3835 #region Block Construction
3833 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3834 packet.RegionData.TimeDilation = timeDilation;
3835 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3836 3836
3837 for (int i = 0; i < blocks.Count; i++) 3837 // TODO: Remove this once we can build compressed updates
3838 packet.ObjectData[i] = blocks[i]; 3838 canUseCompressed = false;
3839 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3840 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3841 }
3842 3839
3843 if (objectUpdateBlocks.IsValueCreated) 3840 if (!canUseImproved && !canUseCompressed)
3844 { 3841 {
3845 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3842 if (update.Entity is ScenePresence)
3846 3843 {
3847 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3844 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3848 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3845 }
3849 packet.RegionData.TimeDilation = timeDilation; 3846 else
3850 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3847 {
3851 3848 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3852 for (int i = 0; i < blocks.Count; i++) 3849 }
3853 packet.ObjectData[i] = blocks[i];
3854 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3855 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3856 } 3850 }
3857 3851 else if (!canUseImproved)
3858 if (compressedUpdateBlocks.IsValueCreated)
3859 { 3852 {
3860 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3853 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3861
3862 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3863 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3864 packet.RegionData.TimeDilation = timeDilation;
3865 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3866
3867 for (int i = 0; i < blocks.Count; i++)
3868 packet.ObjectData[i] = blocks[i];
3869 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3870 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3871 } 3854 }
3872 3855 else
3873 if (terseUpdateBlocks.IsValueCreated)
3874 { 3856 {
3875 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3857 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3876 3858 // Self updates go into a special list
3877 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3859 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3860 else
3879 packet.RegionData.TimeDilation = timeDilation; 3861 // Everything else goes here
3880 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3862 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3881
3882 for (int i = 0; i < blocks.Count; i++)
3883 packet.ObjectData[i] = blocks[i];
3884 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3885 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3886 } 3863 }
3864
3865 #endregion Block Construction
3866 }
3867
3868 #region Packet Sending
3869
3870 const float TIME_DILATION = 1.0f;
3871 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3872
3873 if (terseAgentUpdateBlocks.IsValueCreated)
3874 {
3875 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3876
3877 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3878 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3879 packet.RegionData.TimeDilation = timeDilation;
3880 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3881
3882 for (int i = 0; i < blocks.Count; i++)
3883 packet.ObjectData[i] = blocks[i];
3884
3885 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3886 }
3887
3888 if (objectUpdateBlocks.IsValueCreated)
3889 {
3890 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3891
3892 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3893 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3894 packet.RegionData.TimeDilation = timeDilation;
3895 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3896
3897 for (int i = 0; i < blocks.Count; i++)
3898 packet.ObjectData[i] = blocks[i];
3899
3900 OutPacket(packet, ThrottleOutPacketType.Task, true);
3901 }
3902
3903 if (compressedUpdateBlocks.IsValueCreated)
3904 {
3905 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3906
3907 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3908 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3909 packet.RegionData.TimeDilation = timeDilation;
3910 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3911
3912 for (int i = 0; i < blocks.Count; i++)
3913 packet.ObjectData[i] = blocks[i];
3914
3915 OutPacket(packet, ThrottleOutPacketType.Task, true);
3916 }
3917
3918 if (terseUpdateBlocks.IsValueCreated)
3919 {
3920 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3921
3922 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3923 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3924 packet.RegionData.TimeDilation = timeDilation;
3925 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3926
3927 for (int i = 0; i < blocks.Count; i++)
3928 packet.ObjectData[i] = blocks[i];
3929
3930 OutPacket(packet, ThrottleOutPacketType.Task, true);
3887 } 3931 }
3888 3932
3889 #endregion Packet Sending 3933 #endregion Packet Sending
@@ -4176,11 +4220,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4176 4220
4177 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4221 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4178 // of the object rather than the properties when the packet was created 4222 // of the object rather than the properties when the packet was created
4179 OutPacket(packet, ThrottleOutPacketType.Task, true, 4223 // HACK : Remove intelligent resending until it's fixed in core
4180 delegate(OutgoingPacket oPacket) 4224 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4181 { 4225 // delegate(OutgoingPacket oPacket)
4182 ResendPropertyUpdates(updates, oPacket); 4226 // {
4183 }); 4227 // ResendPropertyUpdates(updates, oPacket);
4228 // });
4229 OutPacket(packet, ThrottleOutPacketType.Task, true);
4184 4230
4185 // pbcnt += blocks.Count; 4231 // pbcnt += blocks.Count;
4186 // ppcnt++; 4232 // ppcnt++;
@@ -4206,11 +4252,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4206 // of the object rather than the properties when the packet was created 4252 // of the object rather than the properties when the packet was created
4207 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4253 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4208 updates.Add(familyUpdates.Value[i]); 4254 updates.Add(familyUpdates.Value[i]);
4209 OutPacket(packet, ThrottleOutPacketType.Task, true, 4255 // HACK : Remove intelligent resending until it's fixed in core
4210 delegate(OutgoingPacket oPacket) 4256 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4211 { 4257 // delegate(OutgoingPacket oPacket)
4212 ResendPropertyUpdates(updates, oPacket); 4258 // {
4213 }); 4259 // ResendPropertyUpdates(updates, oPacket);
4260 // });
4261 OutPacket(packet, ThrottleOutPacketType.Task, true);
4214 4262
4215 // fpcnt++; 4263 // fpcnt++;
4216 // fbcnt++; 4264 // fbcnt++;
@@ -4359,37 +4407,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4359 if (bl[i].BannedUserID == UUID.Zero) 4407 if (bl[i].BannedUserID == UUID.Zero)
4360 continue; 4408 continue;
4361 BannedUsers.Add(bl[i].BannedUserID); 4409 BannedUsers.Add(bl[i].BannedUserID);
4362 }
4363 4410
4364 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4411 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4365 packet.AgentData.TransactionID = UUID.Random(); 4412 {
4366 packet.AgentData.AgentID = AgentId; 4413 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4367 packet.AgentData.SessionID = SessionId; 4414 packet.AgentData.TransactionID = UUID.Random();
4368 packet.MethodData.Invoice = invoice; 4415 packet.AgentData.AgentID = AgentId;
4369 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4416 packet.AgentData.SessionID = SessionId;
4417 packet.MethodData.Invoice = invoice;
4418 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4370 4419
4371 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4420 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4372 4421
4373 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4422 int j;
4374 { 4423 for (j = 0; j < (6 + BannedUsers.Count); j++)
4375 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4424 {
4376 } 4425 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4377 int j = 0; 4426 }
4427 j = 0;
4378 4428
4379 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4429 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4430 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4431 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4432 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4383 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4433 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4384 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4434 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4385 4435
4386 foreach (UUID banned in BannedUsers) 4436 foreach (UUID banned in BannedUsers)
4387 { 4437 {
4388 returnblock[j].Parameter = banned.GetBytes(); j++; 4438 returnblock[j].Parameter = banned.GetBytes(); j++;
4439 }
4440 packet.ParamList = returnblock;
4441 packet.Header.Reliable = true;
4442 OutPacket(packet, ThrottleOutPacketType.Task);
4443
4444 BannedUsers.Clear();
4445 }
4389 } 4446 }
4390 packet.ParamList = returnblock; 4447
4391 packet.Header.Reliable = false;
4392 OutPacket(packet, ThrottleOutPacketType.Task);
4393 } 4448 }
4394 4449
4395 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4450 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4575,7 +4630,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4575 4630
4576 if (landData.SimwideArea > 0) 4631 if (landData.SimwideArea > 0)
4577 { 4632 {
4578 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4633 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4634 // Never report more than sim total capacity
4635 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4636 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4579 updateMessage.SimWideMaxPrims = simulatorCapacity; 4637 updateMessage.SimWideMaxPrims = simulatorCapacity;
4580 } 4638 }
4581 else 4639 else
@@ -4704,14 +4762,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4704 4762
4705 if (notifyCount > 0) 4763 if (notifyCount > 0)
4706 { 4764 {
4707 if (notifyCount > 32) 4765// if (notifyCount > 32)
4708 { 4766// {
4709 m_log.InfoFormat( 4767// m_log.InfoFormat(
4710 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4768// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4711 + " - a developer might want to investigate whether this is a hard limit", 32); 4769// + " - a developer might want to investigate whether this is a hard limit", 32);
4712 4770//
4713 notifyCount = 32; 4771// notifyCount = 32;
4714 } 4772// }
4715 4773
4716 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4774 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4717 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4775 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5244,6 +5302,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5244 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5302 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5245 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5303 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5246 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5304 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5305 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5247 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5306 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5248 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5307 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5249 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5308 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5310,6 +5369,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5310 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5369 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5311 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5370 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5312 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5371 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5372 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5313 5373
5314 AddGenericPacketHandler("autopilot", HandleAutopilot); 5374 AddGenericPacketHandler("autopilot", HandleAutopilot);
5315 } 5375 }
@@ -5345,6 +5405,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5345 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5405 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5346 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5406 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5347 (x.ControlFlags != lastarg.ControlFlags) || 5407 (x.ControlFlags != lastarg.ControlFlags) ||
5408 (x.ControlFlags != 0) ||
5348 (x.Far != lastarg.Far) || 5409 (x.Far != lastarg.Far) ||
5349 (x.Flags != lastarg.Flags) || 5410 (x.Flags != lastarg.Flags) ||
5350 (x.State != lastarg.State) || 5411 (x.State != lastarg.State) ||
@@ -5722,7 +5783,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5722 args.Channel = ch; 5783 args.Channel = ch;
5723 args.From = String.Empty; 5784 args.From = String.Empty;
5724 args.Message = Utils.BytesToString(msg); 5785 args.Message = Utils.BytesToString(msg);
5725 args.Type = ChatTypeEnum.Shout; 5786 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5726 args.Position = new Vector3(); 5787 args.Position = new Vector3();
5727 args.Scene = Scene; 5788 args.Scene = Scene;
5728 args.Sender = this; 5789 args.Sender = this;
@@ -9761,7 +9822,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9761 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9822 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9762 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9823 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9763 UpdateMuteListEntry.MuteData.MuteType, 9824 UpdateMuteListEntry.MuteData.MuteType,
9764 UpdateMuteListEntry.AgentData.AgentID); 9825 UpdateMuteListEntry.MuteData.MuteFlags);
9765 return true; 9826 return true;
9766 } 9827 }
9767 return false; 9828 return false;
@@ -9776,8 +9837,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9776 { 9837 {
9777 handlerRemoveMuteListEntry(this, 9838 handlerRemoveMuteListEntry(this,
9778 RemoveMuteListEntry.MuteData.MuteID, 9839 RemoveMuteListEntry.MuteData.MuteID,
9779 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9840 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9780 RemoveMuteListEntry.AgentData.AgentID);
9781 return true; 9841 return true;
9782 } 9842 }
9783 return false; 9843 return false;
@@ -9821,10 +9881,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9821 return false; 9881 return false;
9822 } 9882 }
9823 9883
9884 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9885 {
9886 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9887 (ChangeInventoryItemFlagsPacket)packet;
9888 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9889 if (handlerChangeInventoryItemFlags != null)
9890 {
9891 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9892 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9893 return true;
9894 }
9895 return false;
9896 }
9897
9824 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9898 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9825 { 9899 {
9826 return true; 9900 return true;
9827 } 9901 }
9902
9903 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9904 {
9905 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9906
9907 #region Packet Session and User Check
9908 if (m_checkPackets)
9909 {
9910 if (packet.AgentData.SessionID != SessionId ||
9911 packet.AgentData.AgentID != AgentId)
9912 return true;
9913 }
9914 #endregion
9915 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9916 List<InventoryItemBase> items = new List<InventoryItemBase>();
9917 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9918 {
9919 InventoryItemBase b = new InventoryItemBase();
9920 b.ID = n.OldItemID;
9921 b.Folder = n.OldFolderID;
9922 items.Add(b);
9923 }
9924
9925 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9926 if (handlerMoveItemsAndLeaveCopy != null)
9927 {
9928 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9929 }
9930
9931 return true;
9932 }
9828 9933
9829 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9934 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9830 { 9935 {
@@ -10251,6 +10356,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10251 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10356 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10252 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10357 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10253 10358
10359 Scene scene = (Scene)m_scene;
10360 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10361 {
10362 ScenePresence p;
10363 if (scene.TryGetScenePresence(sender.AgentId, out p))
10364 {
10365 if (p.GodLevel >= 200)
10366 {
10367 groupProfileReply.GroupData.OpenEnrollment = true;
10368 groupProfileReply.GroupData.MembershipFee = 0;
10369 }
10370 }
10371 }
10372
10254 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10373 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10255 } 10374 }
10256 return true; 10375 return true;
@@ -10824,11 +10943,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10824 10943
10825 StartLure handlerStartLure = OnStartLure; 10944 StartLure handlerStartLure = OnStartLure;
10826 if (handlerStartLure != null) 10945 if (handlerStartLure != null)
10827 handlerStartLure(startLureRequest.Info.LureType, 10946 {
10828 Utils.BytesToString( 10947 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10829 startLureRequest.Info.Message), 10948 {
10830 startLureRequest.TargetData[0].TargetID, 10949 handlerStartLure(startLureRequest.Info.LureType,
10831 this); 10950 Utils.BytesToString(
10951 startLureRequest.Info.Message),
10952 startLureRequest.TargetData[i].TargetID,
10953 this);
10954 }
10955 }
10832 return true; 10956 return true;
10833 } 10957 }
10834 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10958 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10942,10 +11066,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10942 } 11066 }
10943 #endregion 11067 #endregion
10944 11068
10945 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11069 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10946 if (handlerClassifiedGodDelete != null) 11070 if (handlerClassifiedGodDelete != null)
10947 handlerClassifiedGodDelete( 11071 handlerClassifiedGodDelete(
10948 classifiedGodDelete.Data.ClassifiedID, 11072 classifiedGodDelete.Data.ClassifiedID,
11073 classifiedGodDelete.Data.QueryID,
10949 this); 11074 this);
10950 return true; 11075 return true;
10951 } 11076 }
@@ -11989,7 +12114,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11989 12114
11990// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12115// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11991 12116
12117
12118 //Note, the bool returned from the below function is useless since it is always false.
11992 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12119 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12120
11993 } 12121 }
11994 12122
11995 /// <summary> 12123 /// <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 7b1aa2c..3139112 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1031,7 +1031,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1031 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1031 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1032 { 1032 {
1033 client.IsLoggingOut = true; 1033 client.IsLoggingOut = true;
1034 client.Close(); 1034 client.Close(false);
1035 } 1035 }
1036 } 1036 }
1037 1037
@@ -1043,6 +1043,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1043 1043
1044 while (base.IsRunning) 1044 while (base.IsRunning)
1045 { 1045 {
1046 m_scene.ThreadAlive(1);
1046 try 1047 try
1047 { 1048 {
1048 IncomingPacket incomingPacket = null; 1049 IncomingPacket incomingPacket = null;
@@ -1085,6 +1086,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1085 1086
1086 while (base.IsRunning) 1087 while (base.IsRunning)
1087 { 1088 {
1089 m_scene.ThreadAlive(2);
1088 try 1090 try
1089 { 1091 {
1090 m_packetSent = false; 1092 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,