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