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