aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-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 185a909..8aa2ff3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -206,6 +206,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
206 m_stopPacket = TexturePacketCount(); 206 m_stopPacket = TexturePacketCount();
207 } 207 }
208 208
209 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
210 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
211
209 m_currentPacket = StartPacket; 212 m_currentPacket = StartPacket;
210 } 213 }
211 } 214 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index eb1a50e..4d3a30c 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; } }
@@ -483,18 +494,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
483 494
484 #region Client Methods 495 #region Client Methods
485 496
497
486 /// <summary> 498 /// <summary>
487 /// Shut down the client view 499 /// Shut down the client view
488 /// </summary> 500 /// </summary>
489 public void Close() 501 public void Close()
490 { 502 {
503 Close(true);
504 }
505
506 /// <summary>
507 /// Shut down the client view
508 /// </summary>
509 public void Close(bool sendStop)
510 {
491 m_log.DebugFormat( 511 m_log.DebugFormat(
492 "[CLIENT]: Close has been called for {0} attached to scene {1}", 512 "[CLIENT]: Close has been called for {0} attached to scene {1}",
493 Name, m_scene.RegionInfo.RegionName); 513 Name, m_scene.RegionInfo.RegionName);
494 514
495 // Send the STOP packet 515 if (sendStop)
496 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 516 {
497 OutPacket(disable, ThrottleOutPacketType.Unknown); 517 // Send the STOP packet
518 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
519 OutPacket(disable, ThrottleOutPacketType.Unknown);
520 }
498 521
499 IsActive = false; 522 IsActive = false;
500 523
@@ -797,7 +820,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
797 reply.ChatData.OwnerID = fromAgentID; 820 reply.ChatData.OwnerID = fromAgentID;
798 reply.ChatData.SourceID = fromAgentID; 821 reply.ChatData.SourceID = fromAgentID;
799 822
800 OutPacket(reply, ThrottleOutPacketType.Task); 823 OutPacket(reply, ThrottleOutPacketType.Unknown);
801 } 824 }
802 825
803 /// <summary> 826 /// <summary>
@@ -1083,6 +1106,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1083 public virtual void SendLayerData(float[] map) 1106 public virtual void SendLayerData(float[] map)
1084 { 1107 {
1085 Util.FireAndForget(DoSendLayerData, map); 1108 Util.FireAndForget(DoSendLayerData, map);
1109
1110 // Send it sync, and async. It's not that much data
1111 // and it improves user experience just so much!
1112 DoSendLayerData(map);
1086 } 1113 }
1087 1114
1088 /// <summary> 1115 /// <summary>
@@ -1095,16 +1122,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1095 1122
1096 try 1123 try
1097 { 1124 {
1098 //for (int y = 0; y < 16; y++) 1125 for (int y = 0; y < 16; y++)
1099 //{ 1126 {
1100 // for (int x = 0; x < 16; x++) 1127 for (int x = 0; x < 16; x+=4)
1101 // { 1128 {
1102 // SendLayerData(x, y, map); 1129 SendLayerPacket(x, y, map);
1103 // } 1130 }
1104 //} 1131 }
1105
1106 // Send LayerData in a spiral pattern. Fun!
1107 SendLayerTopRight(map, 0, 0, 15, 15);
1108 } 1132 }
1109 catch (Exception e) 1133 catch (Exception e)
1110 { 1134 {
@@ -1112,51 +1136,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1112 } 1136 }
1113 } 1137 }
1114 1138
1115 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1116 {
1117 // Row
1118 for (int i = x1; i <= x2; i++)
1119 SendLayerData(i, y1, map);
1120
1121 // Column
1122 for (int j = y1 + 1; j <= y2; j++)
1123 SendLayerData(x2, j, map);
1124
1125 if (x2 - x1 > 0)
1126 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1127 }
1128
1129 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1130 {
1131 // Row in reverse
1132 for (int i = x2; i >= x1; i--)
1133 SendLayerData(i, y2, map);
1134
1135 // Column in reverse
1136 for (int j = y2 - 1; j >= y1; j--)
1137 SendLayerData(x1, j, map);
1138
1139 if (x2 - x1 > 0)
1140 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1141 }
1142
1143 /// <summary> 1139 /// <summary>
1144 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1140 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1145 /// </summary> 1141 /// </summary>
1146 /// <param name="map">heightmap</param> 1142 /// <param name="map">heightmap</param>
1147 /// <param name="px">X coordinate for patches 0..12</param> 1143 /// <param name="px">X coordinate for patches 0..12</param>
1148 /// <param name="py">Y coordinate for patches 0..15</param> 1144 /// <param name="py">Y coordinate for patches 0..15</param>
1149 // private void SendLayerPacket(float[] map, int y, int x) 1145 private void SendLayerPacket(int x, int y, float[] map)
1150 // { 1146 {
1151 // int[] patches = new int[4]; 1147 int[] patches = new int[4];
1152 // patches[0] = x + 0 + y * 16; 1148 patches[0] = x + 0 + y * 16;
1153 // patches[1] = x + 1 + y * 16; 1149 patches[1] = x + 1 + y * 16;
1154 // patches[2] = x + 2 + y * 16; 1150 patches[2] = x + 2 + y * 16;
1155 // patches[3] = x + 3 + y * 16; 1151 patches[3] = x + 3 + y * 16;
1156 1152
1157 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1153 float[] heightmap = (map.Length == 65536) ?
1158 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1154 map :
1159 // } 1155 LLHeightFieldMoronize(map);
1156
1157 try
1158 {
1159 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1160 OutPacket(layerpack, ThrottleOutPacketType.Land);
1161 }
1162 catch
1163 {
1164 for (int px = x ; px < x + 4 ; px++)
1165 SendLayerData(px, y, map);
1166 }
1167 }
1160 1168
1161 /// <summary> 1169 /// <summary>
1162 /// Sends a specified patch to a client 1170 /// Sends a specified patch to a client
@@ -1176,7 +1184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1176 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1184 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1177 layerpack.Header.Reliable = true; 1185 layerpack.Header.Reliable = true;
1178 1186
1179 OutPacket(layerpack, ThrottleOutPacketType.Land); 1187 OutPacket(layerpack, ThrottleOutPacketType.Task);
1180 } 1188 }
1181 catch (Exception e) 1189 catch (Exception e)
1182 { 1190 {
@@ -2300,6 +2308,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2300 OutPacket(sound, ThrottleOutPacketType.Task); 2308 OutPacket(sound, ThrottleOutPacketType.Task);
2301 } 2309 }
2302 2310
2311 public void SendTransferAbort(TransferRequestPacket transferRequest)
2312 {
2313 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2314 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2315 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2316 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2317 OutPacket(abort, ThrottleOutPacketType.Task);
2318 }
2319
2303 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2320 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2304 { 2321 {
2305 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2322 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3602,7 +3619,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3602 /// </summary> 3619 /// </summary>
3603 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3620 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3604 { 3621 {
3605 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3622 if (entity is SceneObjectPart)
3623 {
3624 SceneObjectPart e = (SceneObjectPart)entity;
3625 SceneObjectGroup g = e.ParentGroup;
3626 if (g.RootPart.Shape.State > 30) // HUD
3627 if (g.OwnerID != AgentId)
3628 return; // Don't send updates for other people's HUDs
3629 }
3630
3606 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3631 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3607 3632
3608 lock (m_entityUpdates.SyncRoot) 3633 lock (m_entityUpdates.SyncRoot)
@@ -3669,211 +3694,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3669 3694
3670 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3695 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3671 // condition where a kill can be processed before an out-of-date update for the same object. 3696 // condition where a kill can be processed before an out-of-date update for the same object.
3672 lock (m_killRecord) 3697 float avgTimeDilation = 1.0f;
3698 IEntityUpdate iupdate;
3699 Int32 timeinqueue; // this is just debugging code & can be dropped later
3700
3701 while (updatesThisCall < maxUpdates)
3673 { 3702 {
3674 float avgTimeDilation = 1.0f; 3703 lock (m_entityUpdates.SyncRoot)
3675 IEntityUpdate iupdate; 3704 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3676 Int32 timeinqueue; // this is just debugging code & can be dropped later 3705 break;
3677
3678 while (updatesThisCall < maxUpdates)
3679 {
3680 lock (m_entityUpdates.SyncRoot)
3681 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3682 break;
3683 3706
3684 EntityUpdate update = (EntityUpdate)iupdate; 3707 EntityUpdate update = (EntityUpdate)iupdate;
3685 3708
3686 avgTimeDilation += update.TimeDilation; 3709 avgTimeDilation += update.TimeDilation;
3687 avgTimeDilation *= 0.5f; 3710 avgTimeDilation *= 0.5f;
3688 3711
3689 if (update.Entity is SceneObjectPart) 3712 if (update.Entity is SceneObjectPart)
3713 {
3714 SceneObjectPart part = (SceneObjectPart)update.Entity;
3715
3716 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3717 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3718 // safety measure.
3719 //
3720 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3721 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3722 // updates and kills on different threads with different scheduling strategies, hence this protection.
3723 //
3724 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3725 // after the root prim has been deleted.
3726 lock (m_killRecord)
3690 { 3727 {
3691 SceneObjectPart part = (SceneObjectPart)update.Entity;
3692
3693 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3694 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3695 // safety measure.
3696 //
3697 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3698 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3699 // updates and kills on different threads with different scheduling strategies, hence this protection.
3700 //
3701 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3702 // after the root prim has been deleted.
3703 if (m_killRecord.Contains(part.LocalId)) 3728 if (m_killRecord.Contains(part.LocalId))
3704 {
3705 // m_log.WarnFormat(
3706 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3707 // part.LocalId, Name);
3708 continue; 3729 continue;
3709 } 3730 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3710 3731 continue;
3711 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3732 }
3733
3734 if (part.ParentGroup.IsDeleted)
3735 continue;
3736
3737 if (part.ParentGroup.IsAttachment)
3738 { // Someone else's HUD, why are we getting these?
3739 if (part.ParentGroup.OwnerID != AgentId &&
3740 part.ParentGroup.RootPart.Shape.State >= 30)
3741 continue;
3742 ScenePresence sp;
3743 // Owner is not in the sim, don't update it to
3744 // anyone
3745 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3746 continue;
3747
3748 List<SceneObjectGroup> atts = sp.GetAttachments();
3749 bool found = false;
3750 foreach (SceneObjectGroup att in atts)
3712 { 3751 {
3713 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3752 if (att == part.ParentGroup)
3714 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3715 { 3753 {
3716 part.Shape.LightEntry = false; 3754 found = true;
3755 break;
3717 } 3756 }
3718 } 3757 }
3758
3759 // It's an attachment of a valid avatar, but
3760 // doesn't seem to be attached, skip
3761 if (!found)
3762 continue;
3719 } 3763 }
3720 3764 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3721 ++updatesThisCall;
3722
3723 #region UpdateFlags to packet type conversion
3724
3725 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3726
3727 bool canUseCompressed = true;
3728 bool canUseImproved = true;
3729
3730 // Compressed object updates only make sense for LL primitives
3731 if (!(update.Entity is SceneObjectPart))
3732 {
3733 canUseCompressed = false;
3734 }
3735
3736 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3737 {
3738 canUseCompressed = false;
3739 canUseImproved = false;
3740 }
3741 else
3742 { 3765 {
3743 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3766 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3744 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3767 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3745 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3746 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3747 {
3748 canUseCompressed = false;
3749 }
3750
3751 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3765 { 3768 {
3766 canUseImproved = false; 3769 part.Shape.LightEntry = false;
3767 } 3770 }
3768 } 3771 }
3769 3772 }
3770 #endregion UpdateFlags to packet type conversion 3773
3771 3774 ++updatesThisCall;
3772 #region Block Construction 3775
3773 3776 #region UpdateFlags to packet type conversion
3774 // TODO: Remove this once we can build compressed updates 3777
3778 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3779
3780 bool canUseCompressed = true;
3781 bool canUseImproved = true;
3782
3783 // Compressed object updates only make sense for LL primitives
3784 if (!(update.Entity is SceneObjectPart))
3785 {
3775 canUseCompressed = false; 3786 canUseCompressed = false;
3776 3787 }
3777 if (!canUseImproved && !canUseCompressed) 3788
3778 { 3789 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3779 if (update.Entity is ScenePresence) 3790 {
3780 { 3791 canUseCompressed = false;
3781 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3792 canUseImproved = false;
3782 objectUpdates.Value.Add(update); 3793 }
3783 } 3794 else
3784 else 3795 {
3785 { 3796 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3786 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3797 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3787 objectUpdates.Value.Add(update); 3798 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3788 } 3799 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3789 }
3790 else if (!canUseImproved)
3791 { 3800 {
3792 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3801 canUseCompressed = false;
3793 compressedUpdates.Value.Add(update);
3794 } 3802 }
3795 else 3803
3804 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3796 { 3818 {
3797 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3819 canUseImproved = false;
3798 {
3799 // Self updates go into a special list
3800 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3801 terseAgentUpdates.Value.Add(update);
3802 }
3803 else
3804 {
3805 // Everything else goes here
3806 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3807 terseUpdates.Value.Add(update);
3808 }
3809 } 3820 }
3810
3811 #endregion Block Construction
3812 } 3821 }
3813
3814
3815 #region Packet Sending
3816 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3817 3822
3818 if (terseAgentUpdateBlocks.IsValueCreated) 3823 #endregion UpdateFlags to packet type conversion
3819 {
3820 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3821 3824
3822 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3825 #region Block Construction
3823 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3824 packet.RegionData.TimeDilation = timeDilation;
3825 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3826 3826
3827 for (int i = 0; i < blocks.Count; i++) 3827 // TODO: Remove this once we can build compressed updates
3828 packet.ObjectData[i] = blocks[i]; 3828 canUseCompressed = false;
3829 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3830 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3831 }
3832 3829
3833 if (objectUpdateBlocks.IsValueCreated) 3830 if (!canUseImproved && !canUseCompressed)
3834 { 3831 {
3835 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3832 if (update.Entity is ScenePresence)
3836 3833 {
3837 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3834 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3838 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3835 }
3839 packet.RegionData.TimeDilation = timeDilation; 3836 else
3840 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3837 {
3841 3838 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3842 for (int i = 0; i < blocks.Count; i++) 3839 }
3843 packet.ObjectData[i] = blocks[i];
3844 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3845 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3846 } 3840 }
3847 3841 else if (!canUseImproved)
3848 if (compressedUpdateBlocks.IsValueCreated)
3849 { 3842 {
3850 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3843 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3851
3852 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3853 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3854 packet.RegionData.TimeDilation = timeDilation;
3855 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3856
3857 for (int i = 0; i < blocks.Count; i++)
3858 packet.ObjectData[i] = blocks[i];
3859 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3860 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3861 } 3844 }
3862 3845 else
3863 if (terseUpdateBlocks.IsValueCreated)
3864 { 3846 {
3865 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3847 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3866 3848 // Self updates go into a special list
3867 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3849 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3868 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3850 else
3869 packet.RegionData.TimeDilation = timeDilation; 3851 // Everything else goes here
3870 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3852 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3871
3872 for (int i = 0; i < blocks.Count; i++)
3873 packet.ObjectData[i] = blocks[i];
3874 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3875 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3876 } 3853 }
3854
3855 #endregion Block Construction
3856 }
3857
3858 #region Packet Sending
3859
3860 const float TIME_DILATION = 1.0f;
3861 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3862
3863 if (terseAgentUpdateBlocks.IsValueCreated)
3864 {
3865 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3866
3867 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3868 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3869 packet.RegionData.TimeDilation = timeDilation;
3870 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3871
3872 for (int i = 0; i < blocks.Count; i++)
3873 packet.ObjectData[i] = blocks[i];
3874
3875 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3876 }
3877
3878 if (objectUpdateBlocks.IsValueCreated)
3879 {
3880 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3881
3882 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3883 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3884 packet.RegionData.TimeDilation = timeDilation;
3885 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3886
3887 for (int i = 0; i < blocks.Count; i++)
3888 packet.ObjectData[i] = blocks[i];
3889
3890 OutPacket(packet, ThrottleOutPacketType.Task, true);
3891 }
3892
3893 if (compressedUpdateBlocks.IsValueCreated)
3894 {
3895 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3896
3897 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3898 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3899 packet.RegionData.TimeDilation = timeDilation;
3900 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3901
3902 for (int i = 0; i < blocks.Count; i++)
3903 packet.ObjectData[i] = blocks[i];
3904
3905 OutPacket(packet, ThrottleOutPacketType.Task, true);
3906 }
3907
3908 if (terseUpdateBlocks.IsValueCreated)
3909 {
3910 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3911
3912 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3913 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3914 packet.RegionData.TimeDilation = timeDilation;
3915 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3916
3917 for (int i = 0; i < blocks.Count; i++)
3918 packet.ObjectData[i] = blocks[i];
3919
3920 OutPacket(packet, ThrottleOutPacketType.Task, true);
3877 } 3921 }
3878 3922
3879 #endregion Packet Sending 3923 #endregion Packet Sending
@@ -4166,11 +4210,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4166 4210
4167 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4211 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4168 // of the object rather than the properties when the packet was created 4212 // of the object rather than the properties when the packet was created
4169 OutPacket(packet, ThrottleOutPacketType.Task, true, 4213 // HACK : Remove intelligent resending until it's fixed in core
4170 delegate(OutgoingPacket oPacket) 4214 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4171 { 4215 // delegate(OutgoingPacket oPacket)
4172 ResendPropertyUpdates(updates, oPacket); 4216 // {
4173 }); 4217 // ResendPropertyUpdates(updates, oPacket);
4218 // });
4219 OutPacket(packet, ThrottleOutPacketType.Task, true);
4174 4220
4175 // pbcnt += blocks.Count; 4221 // pbcnt += blocks.Count;
4176 // ppcnt++; 4222 // ppcnt++;
@@ -4196,11 +4242,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4196 // of the object rather than the properties when the packet was created 4242 // of the object rather than the properties when the packet was created
4197 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4243 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4198 updates.Add(familyUpdates.Value[i]); 4244 updates.Add(familyUpdates.Value[i]);
4199 OutPacket(packet, ThrottleOutPacketType.Task, true, 4245 // HACK : Remove intelligent resending until it's fixed in core
4200 delegate(OutgoingPacket oPacket) 4246 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4201 { 4247 // delegate(OutgoingPacket oPacket)
4202 ResendPropertyUpdates(updates, oPacket); 4248 // {
4203 }); 4249 // ResendPropertyUpdates(updates, oPacket);
4250 // });
4251 OutPacket(packet, ThrottleOutPacketType.Task, true);
4204 4252
4205 // fpcnt++; 4253 // fpcnt++;
4206 // fbcnt++; 4254 // fbcnt++;
@@ -4349,37 +4397,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4349 if (bl[i].BannedUserID == UUID.Zero) 4397 if (bl[i].BannedUserID == UUID.Zero)
4350 continue; 4398 continue;
4351 BannedUsers.Add(bl[i].BannedUserID); 4399 BannedUsers.Add(bl[i].BannedUserID);
4352 }
4353 4400
4354 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4401 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4355 packet.AgentData.TransactionID = UUID.Random(); 4402 {
4356 packet.AgentData.AgentID = AgentId; 4403 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4357 packet.AgentData.SessionID = SessionId; 4404 packet.AgentData.TransactionID = UUID.Random();
4358 packet.MethodData.Invoice = invoice; 4405 packet.AgentData.AgentID = AgentId;
4359 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4406 packet.AgentData.SessionID = SessionId;
4407 packet.MethodData.Invoice = invoice;
4408 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4360 4409
4361 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4410 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4362 4411
4363 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4412 int j;
4364 { 4413 for (j = 0; j < (6 + BannedUsers.Count); j++)
4365 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4414 {
4366 } 4415 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4367 int j = 0; 4416 }
4417 j = 0;
4368 4418
4369 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4419 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4370 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4420 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4371 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4421 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4372 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4422 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4373 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4423 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4374 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4424 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4375 4425
4376 foreach (UUID banned in BannedUsers) 4426 foreach (UUID banned in BannedUsers)
4377 { 4427 {
4378 returnblock[j].Parameter = banned.GetBytes(); j++; 4428 returnblock[j].Parameter = banned.GetBytes(); j++;
4429 }
4430 packet.ParamList = returnblock;
4431 packet.Header.Reliable = true;
4432 OutPacket(packet, ThrottleOutPacketType.Task);
4433
4434 BannedUsers.Clear();
4435 }
4379 } 4436 }
4380 packet.ParamList = returnblock; 4437
4381 packet.Header.Reliable = false;
4382 OutPacket(packet, ThrottleOutPacketType.Task);
4383 } 4438 }
4384 4439
4385 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4440 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4548,7 +4603,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4548 4603
4549 if (landData.SimwideArea > 0) 4604 if (landData.SimwideArea > 0)
4550 { 4605 {
4551 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4606 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4607 // Never report more than sim total capacity
4608 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4609 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4552 updateMessage.SimWideMaxPrims = simulatorCapacity; 4610 updateMessage.SimWideMaxPrims = simulatorCapacity;
4553 } 4611 }
4554 else 4612 else
@@ -4677,14 +4735,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4677 4735
4678 if (notifyCount > 0) 4736 if (notifyCount > 0)
4679 { 4737 {
4680 if (notifyCount > 32) 4738// if (notifyCount > 32)
4681 { 4739// {
4682 m_log.InfoFormat( 4740// m_log.InfoFormat(
4683 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4741// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4684 + " - a developer might want to investigate whether this is a hard limit", 32); 4742// + " - a developer might want to investigate whether this is a hard limit", 32);
4685 4743//
4686 notifyCount = 32; 4744// notifyCount = 32;
4687 } 4745// }
4688 4746
4689 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4747 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4690 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4748 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5217,6 +5275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5217 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5275 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5218 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5276 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5219 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5277 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5278 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5220 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5279 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5221 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5280 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5222 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5281 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5283,6 +5342,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5283 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5342 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5284 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5343 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5285 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5344 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5345 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5286 5346
5287 AddGenericPacketHandler("autopilot", HandleAutopilot); 5347 AddGenericPacketHandler("autopilot", HandleAutopilot);
5288 } 5348 }
@@ -5318,6 +5378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5318 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5378 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5319 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5379 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5320 (x.ControlFlags != lastarg.ControlFlags) || 5380 (x.ControlFlags != lastarg.ControlFlags) ||
5381 (x.ControlFlags != 0) ||
5321 (x.Far != lastarg.Far) || 5382 (x.Far != lastarg.Far) ||
5322 (x.Flags != lastarg.Flags) || 5383 (x.Flags != lastarg.Flags) ||
5323 (x.State != lastarg.State) || 5384 (x.State != lastarg.State) ||
@@ -5695,7 +5756,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5695 args.Channel = ch; 5756 args.Channel = ch;
5696 args.From = String.Empty; 5757 args.From = String.Empty;
5697 args.Message = Utils.BytesToString(msg); 5758 args.Message = Utils.BytesToString(msg);
5698 args.Type = ChatTypeEnum.Shout; 5759 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5699 args.Position = new Vector3(); 5760 args.Position = new Vector3();
5700 args.Scene = Scene; 5761 args.Scene = Scene;
5701 args.Sender = this; 5762 args.Sender = this;
@@ -9707,7 +9768,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9707 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9768 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9708 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9769 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9709 UpdateMuteListEntry.MuteData.MuteType, 9770 UpdateMuteListEntry.MuteData.MuteType,
9710 UpdateMuteListEntry.AgentData.AgentID); 9771 UpdateMuteListEntry.MuteData.MuteFlags);
9711 return true; 9772 return true;
9712 } 9773 }
9713 return false; 9774 return false;
@@ -9722,8 +9783,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9722 { 9783 {
9723 handlerRemoveMuteListEntry(this, 9784 handlerRemoveMuteListEntry(this,
9724 RemoveMuteListEntry.MuteData.MuteID, 9785 RemoveMuteListEntry.MuteData.MuteID,
9725 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9786 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9726 RemoveMuteListEntry.AgentData.AgentID);
9727 return true; 9787 return true;
9728 } 9788 }
9729 return false; 9789 return false;
@@ -9767,10 +9827,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9767 return false; 9827 return false;
9768 } 9828 }
9769 9829
9830 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9831 {
9832 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9833 (ChangeInventoryItemFlagsPacket)packet;
9834 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9835 if (handlerChangeInventoryItemFlags != null)
9836 {
9837 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9838 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9839 return true;
9840 }
9841 return false;
9842 }
9843
9770 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9844 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9771 { 9845 {
9772 return true; 9846 return true;
9773 } 9847 }
9848
9849 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9850 {
9851 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9852
9853 #region Packet Session and User Check
9854 if (m_checkPackets)
9855 {
9856 if (packet.AgentData.SessionID != SessionId ||
9857 packet.AgentData.AgentID != AgentId)
9858 return true;
9859 }
9860 #endregion
9861 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9862 List<InventoryItemBase> items = new List<InventoryItemBase>();
9863 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9864 {
9865 InventoryItemBase b = new InventoryItemBase();
9866 b.ID = n.OldItemID;
9867 b.Folder = n.OldFolderID;
9868 items.Add(b);
9869 }
9870
9871 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9872 if (handlerMoveItemsAndLeaveCopy != null)
9873 {
9874 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9875 }
9876
9877 return true;
9878 }
9774 9879
9775 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9880 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9776 { 9881 {
@@ -10197,6 +10302,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10197 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10302 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10198 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10303 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10199 10304
10305 Scene scene = (Scene)m_scene;
10306 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10307 {
10308 ScenePresence p;
10309 if (scene.TryGetScenePresence(sender.AgentId, out p))
10310 {
10311 if (p.GodLevel >= 200)
10312 {
10313 groupProfileReply.GroupData.OpenEnrollment = true;
10314 groupProfileReply.GroupData.MembershipFee = 0;
10315 }
10316 }
10317 }
10318
10200 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10319 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10201 } 10320 }
10202 return true; 10321 return true;
@@ -10770,11 +10889,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10770 10889
10771 StartLure handlerStartLure = OnStartLure; 10890 StartLure handlerStartLure = OnStartLure;
10772 if (handlerStartLure != null) 10891 if (handlerStartLure != null)
10773 handlerStartLure(startLureRequest.Info.LureType, 10892 {
10774 Utils.BytesToString( 10893 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10775 startLureRequest.Info.Message), 10894 {
10776 startLureRequest.TargetData[0].TargetID, 10895 handlerStartLure(startLureRequest.Info.LureType,
10777 this); 10896 Utils.BytesToString(
10897 startLureRequest.Info.Message),
10898 startLureRequest.TargetData[i].TargetID,
10899 this);
10900 }
10901 }
10778 return true; 10902 return true;
10779 } 10903 }
10780 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10904 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10888,10 +11012,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10888 } 11012 }
10889 #endregion 11013 #endregion
10890 11014
10891 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11015 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10892 if (handlerClassifiedGodDelete != null) 11016 if (handlerClassifiedGodDelete != null)
10893 handlerClassifiedGodDelete( 11017 handlerClassifiedGodDelete(
10894 classifiedGodDelete.Data.ClassifiedID, 11018 classifiedGodDelete.Data.ClassifiedID,
11019 classifiedGodDelete.Data.QueryID,
10895 this); 11020 this);
10896 return true; 11021 return true;
10897 } 11022 }
@@ -11935,7 +12060,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11935 12060
11936// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12061// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11937 12062
12063
12064 //Note, the bool returned from the below function is useless since it is always false.
11938 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12065 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12066
11939 } 12067 }
11940 12068
11941 /// <summary> 12069 /// <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,