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 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 7d39ddc..effa8d0 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 UUID ActiveGroupId { get { return m_activeGroupID; } } 393 public UUID ActiveGroupId { get { return m_activeGroupID; } }
383 public string ActiveGroupName { get { return m_activeGroupName; } } 394 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -479,18 +490,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
479 490
480 #region Client Methods 491 #region Client Methods
481 492
493
482 /// <summary> 494 /// <summary>
483 /// Shut down the client view 495 /// Shut down the client view
484 /// </summary> 496 /// </summary>
485 public void Close() 497 public void Close()
486 { 498 {
499 Close(true);
500 }
501
502 /// <summary>
503 /// Shut down the client view
504 /// </summary>
505 public void Close(bool sendStop)
506 {
487 m_log.DebugFormat( 507 m_log.DebugFormat(
488 "[CLIENT]: Close has been called for {0} attached to scene {1}", 508 "[CLIENT]: Close has been called for {0} attached to scene {1}",
489 Name, m_scene.RegionInfo.RegionName); 509 Name, m_scene.RegionInfo.RegionName);
490 510
491 // Send the STOP packet 511 if (sendStop)
492 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 512 {
493 OutPacket(disable, ThrottleOutPacketType.Unknown); 513 // Send the STOP packet
514 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
515 OutPacket(disable, ThrottleOutPacketType.Unknown);
516 }
494 517
495 IsActive = false; 518 IsActive = false;
496 519
@@ -791,7 +814,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 reply.ChatData.OwnerID = fromAgentID; 814 reply.ChatData.OwnerID = fromAgentID;
792 reply.ChatData.SourceID = fromAgentID; 815 reply.ChatData.SourceID = fromAgentID;
793 816
794 OutPacket(reply, ThrottleOutPacketType.Task); 817 OutPacket(reply, ThrottleOutPacketType.Unknown);
795 } 818 }
796 819
797 /// <summary> 820 /// <summary>
@@ -1077,6 +1100,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1077 public virtual void SendLayerData(float[] map) 1100 public virtual void SendLayerData(float[] map)
1078 { 1101 {
1079 Util.FireAndForget(DoSendLayerData, map); 1102 Util.FireAndForget(DoSendLayerData, map);
1103
1104 // Send it sync, and async. It's not that much data
1105 // and it improves user experience just so much!
1106 DoSendLayerData(map);
1080 } 1107 }
1081 1108
1082 /// <summary> 1109 /// <summary>
@@ -1089,16 +1116,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1089 1116
1090 try 1117 try
1091 { 1118 {
1092 //for (int y = 0; y < 16; y++) 1119 for (int y = 0; y < 16; y++)
1093 //{ 1120 {
1094 // for (int x = 0; x < 16; x++) 1121 for (int x = 0; x < 16; x+=4)
1095 // { 1122 {
1096 // SendLayerData(x, y, map); 1123 SendLayerPacket(x, y, map);
1097 // } 1124 }
1098 //} 1125 }
1099
1100 // Send LayerData in a spiral pattern. Fun!
1101 SendLayerTopRight(map, 0, 0, 15, 15);
1102 } 1126 }
1103 catch (Exception e) 1127 catch (Exception e)
1104 { 1128 {
@@ -1106,51 +1130,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1106 } 1130 }
1107 } 1131 }
1108 1132
1109 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1110 {
1111 // Row
1112 for (int i = x1; i <= x2; i++)
1113 SendLayerData(i, y1, map);
1114
1115 // Column
1116 for (int j = y1 + 1; j <= y2; j++)
1117 SendLayerData(x2, j, map);
1118
1119 if (x2 - x1 > 0)
1120 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1121 }
1122
1123 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1124 {
1125 // Row in reverse
1126 for (int i = x2; i >= x1; i--)
1127 SendLayerData(i, y2, map);
1128
1129 // Column in reverse
1130 for (int j = y2 - 1; j >= y1; j--)
1131 SendLayerData(x1, j, map);
1132
1133 if (x2 - x1 > 0)
1134 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1135 }
1136
1137 /// <summary> 1133 /// <summary>
1138 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1134 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1139 /// </summary> 1135 /// </summary>
1140 /// <param name="map">heightmap</param> 1136 /// <param name="map">heightmap</param>
1141 /// <param name="px">X coordinate for patches 0..12</param> 1137 /// <param name="px">X coordinate for patches 0..12</param>
1142 /// <param name="py">Y coordinate for patches 0..15</param> 1138 /// <param name="py">Y coordinate for patches 0..15</param>
1143 // private void SendLayerPacket(float[] map, int y, int x) 1139 private void SendLayerPacket(int x, int y, float[] map)
1144 // { 1140 {
1145 // int[] patches = new int[4]; 1141 int[] patches = new int[4];
1146 // patches[0] = x + 0 + y * 16; 1142 patches[0] = x + 0 + y * 16;
1147 // patches[1] = x + 1 + y * 16; 1143 patches[1] = x + 1 + y * 16;
1148 // patches[2] = x + 2 + y * 16; 1144 patches[2] = x + 2 + y * 16;
1149 // patches[3] = x + 3 + y * 16; 1145 patches[3] = x + 3 + y * 16;
1150 1146
1151 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1147 float[] heightmap = (map.Length == 65536) ?
1152 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1148 map :
1153 // } 1149 LLHeightFieldMoronize(map);
1150
1151 try
1152 {
1153 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1154 OutPacket(layerpack, ThrottleOutPacketType.Land);
1155 }
1156 catch
1157 {
1158 for (int px = x ; px < x + 4 ; px++)
1159 SendLayerData(px, y, map);
1160 }
1161 }
1154 1162
1155 /// <summary> 1163 /// <summary>
1156 /// Sends a specified patch to a client 1164 /// Sends a specified patch to a client
@@ -1170,7 +1178,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1170 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1178 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1171 layerpack.Header.Reliable = true; 1179 layerpack.Header.Reliable = true;
1172 1180
1173 OutPacket(layerpack, ThrottleOutPacketType.Land); 1181 OutPacket(layerpack, ThrottleOutPacketType.Task);
1174 } 1182 }
1175 catch (Exception e) 1183 catch (Exception e)
1176 { 1184 {
@@ -2294,6 +2302,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2294 OutPacket(sound, ThrottleOutPacketType.Task); 2302 OutPacket(sound, ThrottleOutPacketType.Task);
2295 } 2303 }
2296 2304
2305 public void SendTransferAbort(TransferRequestPacket transferRequest)
2306 {
2307 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2308 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2309 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2310 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2311 OutPacket(abort, ThrottleOutPacketType.Task);
2312 }
2313
2297 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2314 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2298 { 2315 {
2299 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2316 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3596,7 +3613,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3596 /// </summary> 3613 /// </summary>
3597 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3614 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3598 { 3615 {
3599 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3616 if (entity is SceneObjectPart)
3617 {
3618 SceneObjectPart e = (SceneObjectPart)entity;
3619 SceneObjectGroup g = e.ParentGroup;
3620 if (g.RootPart.Shape.State > 30) // HUD
3621 if (g.OwnerID != AgentId)
3622 return; // Don't send updates for other people's HUDs
3623 }
3624
3600 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3625 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3601 3626
3602 lock (m_entityUpdates.SyncRoot) 3627 lock (m_entityUpdates.SyncRoot)
@@ -3663,211 +3688,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3663 3688
3664 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3689 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3665 // condition where a kill can be processed before an out-of-date update for the same object. 3690 // condition where a kill can be processed before an out-of-date update for the same object.
3666 lock (m_killRecord) 3691 float avgTimeDilation = 1.0f;
3692 IEntityUpdate iupdate;
3693 Int32 timeinqueue; // this is just debugging code & can be dropped later
3694
3695 while (updatesThisCall < maxUpdates)
3667 { 3696 {
3668 float avgTimeDilation = 1.0f; 3697 lock (m_entityUpdates.SyncRoot)
3669 IEntityUpdate iupdate; 3698 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3670 Int32 timeinqueue; // this is just debugging code & can be dropped later 3699 break;
3671
3672 while (updatesThisCall < maxUpdates)
3673 {
3674 lock (m_entityUpdates.SyncRoot)
3675 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3676 break;
3677 3700
3678 EntityUpdate update = (EntityUpdate)iupdate; 3701 EntityUpdate update = (EntityUpdate)iupdate;
3679 3702
3680 avgTimeDilation += update.TimeDilation; 3703 avgTimeDilation += update.TimeDilation;
3681 avgTimeDilation *= 0.5f; 3704 avgTimeDilation *= 0.5f;
3682 3705
3683 if (update.Entity is SceneObjectPart) 3706 if (update.Entity is SceneObjectPart)
3707 {
3708 SceneObjectPart part = (SceneObjectPart)update.Entity;
3709
3710 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3711 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3712 // safety measure.
3713 //
3714 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3715 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3716 // updates and kills on different threads with different scheduling strategies, hence this protection.
3717 //
3718 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3719 // after the root prim has been deleted.
3720 lock (m_killRecord)
3684 { 3721 {
3685 SceneObjectPart part = (SceneObjectPart)update.Entity;
3686
3687 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3688 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3689 // safety measure.
3690 //
3691 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3692 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3693 // updates and kills on different threads with different scheduling strategies, hence this protection.
3694 //
3695 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3696 // after the root prim has been deleted.
3697 if (m_killRecord.Contains(part.LocalId)) 3722 if (m_killRecord.Contains(part.LocalId))
3698 {
3699 // m_log.WarnFormat(
3700 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3701 // part.LocalId, Name);
3702 continue; 3723 continue;
3703 } 3724 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3704 3725 continue;
3705 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3726 }
3727
3728 if (part.ParentGroup.IsDeleted)
3729 continue;
3730
3731 if (part.ParentGroup.IsAttachment)
3732 { // Someone else's HUD, why are we getting these?
3733 if (part.ParentGroup.OwnerID != AgentId &&
3734 part.ParentGroup.RootPart.Shape.State >= 30)
3735 continue;
3736 ScenePresence sp;
3737 // Owner is not in the sim, don't update it to
3738 // anyone
3739 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3740 continue;
3741
3742 List<SceneObjectGroup> atts = sp.GetAttachments();
3743 bool found = false;
3744 foreach (SceneObjectGroup att in atts)
3706 { 3745 {
3707 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3746 if (att == part.ParentGroup)
3708 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3709 { 3747 {
3710 part.Shape.LightEntry = false; 3748 found = true;
3749 break;
3711 } 3750 }
3712 } 3751 }
3752
3753 // It's an attachment of a valid avatar, but
3754 // doesn't seem to be attached, skip
3755 if (!found)
3756 continue;
3713 } 3757 }
3714 3758 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3715 ++updatesThisCall;
3716
3717 #region UpdateFlags to packet type conversion
3718
3719 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3720
3721 bool canUseCompressed = true;
3722 bool canUseImproved = true;
3723
3724 // Compressed object updates only make sense for LL primitives
3725 if (!(update.Entity is SceneObjectPart))
3726 {
3727 canUseCompressed = false;
3728 }
3729
3730 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3731 {
3732 canUseCompressed = false;
3733 canUseImproved = false;
3734 }
3735 else
3736 { 3759 {
3737 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3760 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3738 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3761 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3739 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3740 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3741 {
3742 canUseCompressed = false;
3743 }
3744
3745 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3746 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3747 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3748 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3751 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3759 { 3762 {
3760 canUseImproved = false; 3763 part.Shape.LightEntry = false;
3761 } 3764 }
3762 } 3765 }
3763 3766 }
3764 #endregion UpdateFlags to packet type conversion 3767
3765 3768 ++updatesThisCall;
3766 #region Block Construction 3769
3767 3770 #region UpdateFlags to packet type conversion
3768 // TODO: Remove this once we can build compressed updates 3771
3772 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3773
3774 bool canUseCompressed = true;
3775 bool canUseImproved = true;
3776
3777 // Compressed object updates only make sense for LL primitives
3778 if (!(update.Entity is SceneObjectPart))
3779 {
3769 canUseCompressed = false; 3780 canUseCompressed = false;
3770 3781 }
3771 if (!canUseImproved && !canUseCompressed) 3782
3772 { 3783 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3773 if (update.Entity is ScenePresence) 3784 {
3774 { 3785 canUseCompressed = false;
3775 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3786 canUseImproved = false;
3776 objectUpdates.Value.Add(update); 3787 }
3777 } 3788 else
3778 else 3789 {
3779 { 3790 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3780 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3791 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3781 objectUpdates.Value.Add(update); 3792 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3782 } 3793 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3783 }
3784 else if (!canUseImproved)
3785 { 3794 {
3786 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3795 canUseCompressed = false;
3787 compressedUpdates.Value.Add(update);
3788 } 3796 }
3789 else 3797
3798 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3790 { 3812 {
3791 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3813 canUseImproved = false;
3792 {
3793 // Self updates go into a special list
3794 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3795 terseAgentUpdates.Value.Add(update);
3796 }
3797 else
3798 {
3799 // Everything else goes here
3800 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3801 terseUpdates.Value.Add(update);
3802 }
3803 } 3814 }
3804
3805 #endregion Block Construction
3806 } 3815 }
3807
3808
3809 #region Packet Sending
3810 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3811 3816
3812 if (terseAgentUpdateBlocks.IsValueCreated) 3817 #endregion UpdateFlags to packet type conversion
3813 {
3814 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3815 3818
3816 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3819 #region Block Construction
3817 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3818 packet.RegionData.TimeDilation = timeDilation;
3819 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3820 3820
3821 for (int i = 0; i < blocks.Count; i++) 3821 // TODO: Remove this once we can build compressed updates
3822 packet.ObjectData[i] = blocks[i]; 3822 canUseCompressed = false;
3823 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3824 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3825 }
3826 3823
3827 if (objectUpdateBlocks.IsValueCreated) 3824 if (!canUseImproved && !canUseCompressed)
3828 { 3825 {
3829 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3826 if (update.Entity is ScenePresence)
3830 3827 {
3831 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3828 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3832 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3829 }
3833 packet.RegionData.TimeDilation = timeDilation; 3830 else
3834 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3831 {
3835 3832 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3836 for (int i = 0; i < blocks.Count; i++) 3833 }
3837 packet.ObjectData[i] = blocks[i];
3838 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3839 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3840 } 3834 }
3841 3835 else if (!canUseImproved)
3842 if (compressedUpdateBlocks.IsValueCreated)
3843 { 3836 {
3844 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3837 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3845
3846 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3847 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3848 packet.RegionData.TimeDilation = timeDilation;
3849 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3850
3851 for (int i = 0; i < blocks.Count; i++)
3852 packet.ObjectData[i] = blocks[i];
3853 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3854 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3855 } 3838 }
3856 3839 else
3857 if (terseUpdateBlocks.IsValueCreated)
3858 { 3840 {
3859 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3841 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3860 3842 // Self updates go into a special list
3861 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3843 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3862 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3844 else
3863 packet.RegionData.TimeDilation = timeDilation; 3845 // Everything else goes here
3864 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3846 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3865
3866 for (int i = 0; i < blocks.Count; i++)
3867 packet.ObjectData[i] = blocks[i];
3868 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3869 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3870 } 3847 }
3848
3849 #endregion Block Construction
3850 }
3851
3852 #region Packet Sending
3853
3854 const float TIME_DILATION = 1.0f;
3855 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3856
3857 if (terseAgentUpdateBlocks.IsValueCreated)
3858 {
3859 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3860
3861 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3862 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3863 packet.RegionData.TimeDilation = timeDilation;
3864 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3865
3866 for (int i = 0; i < blocks.Count; i++)
3867 packet.ObjectData[i] = blocks[i];
3868
3869 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3870 }
3871
3872 if (objectUpdateBlocks.IsValueCreated)
3873 {
3874 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3875
3876 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3877 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3878 packet.RegionData.TimeDilation = timeDilation;
3879 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3880
3881 for (int i = 0; i < blocks.Count; i++)
3882 packet.ObjectData[i] = blocks[i];
3883
3884 OutPacket(packet, ThrottleOutPacketType.Task, true);
3885 }
3886
3887 if (compressedUpdateBlocks.IsValueCreated)
3888 {
3889 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3890
3891 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3892 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3893 packet.RegionData.TimeDilation = timeDilation;
3894 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3895
3896 for (int i = 0; i < blocks.Count; i++)
3897 packet.ObjectData[i] = blocks[i];
3898
3899 OutPacket(packet, ThrottleOutPacketType.Task, true);
3900 }
3901
3902 if (terseUpdateBlocks.IsValueCreated)
3903 {
3904 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3905
3906 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3907 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3908 packet.RegionData.TimeDilation = timeDilation;
3909 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3910
3911 for (int i = 0; i < blocks.Count; i++)
3912 packet.ObjectData[i] = blocks[i];
3913
3914 OutPacket(packet, ThrottleOutPacketType.Task, true);
3871 } 3915 }
3872 3916
3873 #endregion Packet Sending 3917 #endregion Packet Sending
@@ -4168,11 +4212,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4168 4212
4169 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4213 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4170 // of the object rather than the properties when the packet was created 4214 // of the object rather than the properties when the packet was created
4171 OutPacket(packet, ThrottleOutPacketType.Task, true, 4215 // HACK : Remove intelligent resending until it's fixed in core
4172 delegate(OutgoingPacket oPacket) 4216 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4173 { 4217 // delegate(OutgoingPacket oPacket)
4174 ResendPropertyUpdates(updates, oPacket); 4218 // {
4175 }); 4219 // ResendPropertyUpdates(updates, oPacket);
4220 // });
4221 OutPacket(packet, ThrottleOutPacketType.Task, true);
4176 4222
4177 // pbcnt += blocks.Count; 4223 // pbcnt += blocks.Count;
4178 // ppcnt++; 4224 // ppcnt++;
@@ -4198,11 +4244,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4198 // of the object rather than the properties when the packet was created 4244 // of the object rather than the properties when the packet was created
4199 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4245 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4200 updates.Add(familyUpdates.Value[i]); 4246 updates.Add(familyUpdates.Value[i]);
4201 OutPacket(packet, ThrottleOutPacketType.Task, true, 4247 // HACK : Remove intelligent resending until it's fixed in core
4202 delegate(OutgoingPacket oPacket) 4248 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4203 { 4249 // delegate(OutgoingPacket oPacket)
4204 ResendPropertyUpdates(updates, oPacket); 4250 // {
4205 }); 4251 // ResendPropertyUpdates(updates, oPacket);
4252 // });
4253 OutPacket(packet, ThrottleOutPacketType.Task, true);
4206 4254
4207 // fpcnt++; 4255 // fpcnt++;
4208 // fbcnt++; 4256 // fbcnt++;
@@ -4351,37 +4399,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4351 if (bl[i].BannedUserID == UUID.Zero) 4399 if (bl[i].BannedUserID == UUID.Zero)
4352 continue; 4400 continue;
4353 BannedUsers.Add(bl[i].BannedUserID); 4401 BannedUsers.Add(bl[i].BannedUserID);
4354 }
4355 4402
4356 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4403 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4357 packet.AgentData.TransactionID = UUID.Random(); 4404 {
4358 packet.AgentData.AgentID = AgentId; 4405 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4359 packet.AgentData.SessionID = SessionId; 4406 packet.AgentData.TransactionID = UUID.Random();
4360 packet.MethodData.Invoice = invoice; 4407 packet.AgentData.AgentID = AgentId;
4361 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4408 packet.AgentData.SessionID = SessionId;
4409 packet.MethodData.Invoice = invoice;
4410 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4362 4411
4363 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4412 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4364 4413
4365 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4414 int j;
4366 { 4415 for (j = 0; j < (6 + BannedUsers.Count); j++)
4367 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4416 {
4368 } 4417 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4369 int j = 0; 4418 }
4419 j = 0;
4370 4420
4371 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4421 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4372 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4422 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4373 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4423 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4374 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4424 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4375 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4425 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4426 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4377 4427
4378 foreach (UUID banned in BannedUsers) 4428 foreach (UUID banned in BannedUsers)
4379 { 4429 {
4380 returnblock[j].Parameter = banned.GetBytes(); j++; 4430 returnblock[j].Parameter = banned.GetBytes(); j++;
4431 }
4432 packet.ParamList = returnblock;
4433 packet.Header.Reliable = true;
4434 OutPacket(packet, ThrottleOutPacketType.Task);
4435
4436 BannedUsers.Clear();
4437 }
4381 } 4438 }
4382 packet.ParamList = returnblock; 4439
4383 packet.Header.Reliable = false;
4384 OutPacket(packet, ThrottleOutPacketType.Task);
4385 } 4440 }
4386 4441
4387 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4442 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4550,7 +4605,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4550 4605
4551 if (landData.SimwideArea > 0) 4606 if (landData.SimwideArea > 0)
4552 { 4607 {
4553 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4608 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4609 // Never report more than sim total capacity
4610 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4611 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4554 updateMessage.SimWideMaxPrims = simulatorCapacity; 4612 updateMessage.SimWideMaxPrims = simulatorCapacity;
4555 } 4613 }
4556 else 4614 else
@@ -4679,14 +4737,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4679 4737
4680 if (notifyCount > 0) 4738 if (notifyCount > 0)
4681 { 4739 {
4682 if (notifyCount > 32) 4740// if (notifyCount > 32)
4683 { 4741// {
4684 m_log.InfoFormat( 4742// m_log.InfoFormat(
4685 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4743// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4686 + " - a developer might want to investigate whether this is a hard limit", 32); 4744// + " - a developer might want to investigate whether this is a hard limit", 32);
4687 4745//
4688 notifyCount = 32; 4746// notifyCount = 32;
4689 } 4747// }
4690 4748
4691 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4749 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4692 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4750 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5220,6 +5278,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5220 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5278 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5221 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5279 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5222 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5280 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5281 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5223 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5282 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5224 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5283 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5225 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5284 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5286,6 +5345,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5286 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5345 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5287 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5346 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5288 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5347 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5348 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5289 5349
5290 AddGenericPacketHandler("autopilot", HandleAutopilot); 5350 AddGenericPacketHandler("autopilot", HandleAutopilot);
5291 } 5351 }
@@ -5321,6 +5381,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5321 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5381 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5322 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5382 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5323 (x.ControlFlags != lastarg.ControlFlags) || 5383 (x.ControlFlags != lastarg.ControlFlags) ||
5384 (x.ControlFlags != 0) ||
5324 (x.Far != lastarg.Far) || 5385 (x.Far != lastarg.Far) ||
5325 (x.Flags != lastarg.Flags) || 5386 (x.Flags != lastarg.Flags) ||
5326 (x.State != lastarg.State) || 5387 (x.State != lastarg.State) ||
@@ -5698,7 +5759,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5698 args.Channel = ch; 5759 args.Channel = ch;
5699 args.From = String.Empty; 5760 args.From = String.Empty;
5700 args.Message = Utils.BytesToString(msg); 5761 args.Message = Utils.BytesToString(msg);
5701 args.Type = ChatTypeEnum.Shout; 5762 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5702 args.Position = new Vector3(); 5763 args.Position = new Vector3();
5703 args.Scene = Scene; 5764 args.Scene = Scene;
5704 args.Sender = this; 5765 args.Sender = this;
@@ -9704,7 +9765,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9704 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9765 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9705 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9766 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9706 UpdateMuteListEntry.MuteData.MuteType, 9767 UpdateMuteListEntry.MuteData.MuteType,
9707 UpdateMuteListEntry.AgentData.AgentID); 9768 UpdateMuteListEntry.MuteData.MuteFlags);
9708 return true; 9769 return true;
9709 } 9770 }
9710 return false; 9771 return false;
@@ -9719,8 +9780,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9719 { 9780 {
9720 handlerRemoveMuteListEntry(this, 9781 handlerRemoveMuteListEntry(this,
9721 RemoveMuteListEntry.MuteData.MuteID, 9782 RemoveMuteListEntry.MuteData.MuteID,
9722 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9783 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9723 RemoveMuteListEntry.AgentData.AgentID);
9724 return true; 9784 return true;
9725 } 9785 }
9726 return false; 9786 return false;
@@ -9764,10 +9824,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9764 return false; 9824 return false;
9765 } 9825 }
9766 9826
9827 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9828 {
9829 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9830 (ChangeInventoryItemFlagsPacket)packet;
9831 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9832 if (handlerChangeInventoryItemFlags != null)
9833 {
9834 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9835 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9836 return true;
9837 }
9838 return false;
9839 }
9840
9767 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9841 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9768 { 9842 {
9769 return true; 9843 return true;
9770 } 9844 }
9845
9846 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9847 {
9848 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9849
9850 #region Packet Session and User Check
9851 if (m_checkPackets)
9852 {
9853 if (packet.AgentData.SessionID != SessionId ||
9854 packet.AgentData.AgentID != AgentId)
9855 return true;
9856 }
9857 #endregion
9858 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9859 List<InventoryItemBase> items = new List<InventoryItemBase>();
9860 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9861 {
9862 InventoryItemBase b = new InventoryItemBase();
9863 b.ID = n.OldItemID;
9864 b.Folder = n.OldFolderID;
9865 items.Add(b);
9866 }
9867
9868 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9869 if (handlerMoveItemsAndLeaveCopy != null)
9870 {
9871 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9872 }
9873
9874 return true;
9875 }
9771 9876
9772 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9877 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9773 { 9878 {
@@ -10194,6 +10299,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10194 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10299 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10195 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10300 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10196 10301
10302 Scene scene = (Scene)m_scene;
10303 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10304 {
10305 ScenePresence p;
10306 if (scene.TryGetScenePresence(sender.AgentId, out p))
10307 {
10308 if (p.GodLevel >= 200)
10309 {
10310 groupProfileReply.GroupData.OpenEnrollment = true;
10311 groupProfileReply.GroupData.MembershipFee = 0;
10312 }
10313 }
10314 }
10315
10197 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10316 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10198 } 10317 }
10199 return true; 10318 return true;
@@ -10766,11 +10885,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10766 10885
10767 StartLure handlerStartLure = OnStartLure; 10886 StartLure handlerStartLure = OnStartLure;
10768 if (handlerStartLure != null) 10887 if (handlerStartLure != null)
10769 handlerStartLure(startLureRequest.Info.LureType, 10888 {
10770 Utils.BytesToString( 10889 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10771 startLureRequest.Info.Message), 10890 {
10772 startLureRequest.TargetData[0].TargetID, 10891 handlerStartLure(startLureRequest.Info.LureType,
10773 this); 10892 Utils.BytesToString(
10893 startLureRequest.Info.Message),
10894 startLureRequest.TargetData[i].TargetID,
10895 this);
10896 }
10897 }
10774 return true; 10898 return true;
10775 } 10899 }
10776 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10900 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10884,10 +11008,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10884 } 11008 }
10885 #endregion 11009 #endregion
10886 11010
10887 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11011 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10888 if (handlerClassifiedGodDelete != null) 11012 if (handlerClassifiedGodDelete != null)
10889 handlerClassifiedGodDelete( 11013 handlerClassifiedGodDelete(
10890 classifiedGodDelete.Data.ClassifiedID, 11014 classifiedGodDelete.Data.ClassifiedID,
11015 classifiedGodDelete.Data.QueryID,
10891 this); 11016 this);
10892 return true; 11017 return true;
10893 } 11018 }
@@ -11923,7 +12048,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11923 12048
11924// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12049// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11925 12050
12051
12052 //Note, the bool returned from the below function is useless since it is always false.
11926 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12053 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12054
11927 } 12055 }
11928 12056
11929 /// <summary> 12057 /// <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 ccad241..ae8251a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -991,7 +991,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
991 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 991 if (m_scene.TryGetClient(udpClient.AgentID, out client))
992 { 992 {
993 client.IsLoggingOut = true; 993 client.IsLoggingOut = true;
994 client.Close(); 994 client.Close(false);
995 } 995 }
996 } 996 }
997 997
@@ -1003,6 +1003,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1003 1003
1004 while (base.IsRunning) 1004 while (base.IsRunning)
1005 { 1005 {
1006 m_scene.ThreadAlive(1);
1006 try 1007 try
1007 { 1008 {
1008 IncomingPacket incomingPacket = null; 1009 IncomingPacket incomingPacket = null;
@@ -1045,6 +1046,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1045 1046
1046 while (base.IsRunning) 1047 while (base.IsRunning)
1047 { 1048 {
1049 m_scene.ThreadAlive(2);
1048 try 1050 try
1049 { 1051 {
1050 m_packetSent = false; 1052 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6eebd9d..d2779ba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,