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.cs706
-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, 471 insertions, 311 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 d98ff68..161feda 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 {
@@ -1541,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1541 1549
1542 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1550 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1543 { 1551 {
1544// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1552// foreach (uint id in localIDs)
1553// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1545 1554
1546 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1555 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1547 // TODO: don't create new blocks if recycling an old packet 1556 // TODO: don't create new blocks if recycling an old packet
@@ -2302,6 +2311,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2302 OutPacket(sound, ThrottleOutPacketType.Task); 2311 OutPacket(sound, ThrottleOutPacketType.Task);
2303 } 2312 }
2304 2313
2314 public void SendTransferAbort(TransferRequestPacket transferRequest)
2315 {
2316 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2317 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2318 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2319 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2320 OutPacket(abort, ThrottleOutPacketType.Task);
2321 }
2322
2305 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2323 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2306 { 2324 {
2307 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2325 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2749,7 +2767,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2749 reply.Data.ParcelID = parcelID; 2767 reply.Data.ParcelID = parcelID;
2750 reply.Data.OwnerID = land.OwnerID; 2768 reply.Data.OwnerID = land.OwnerID;
2751 reply.Data.Name = Utils.StringToBytes(land.Name); 2769 reply.Data.Name = Utils.StringToBytes(land.Name);
2752 reply.Data.Desc = Utils.StringToBytes(land.Description); 2770 if (land != null && land.Description != null && land.Description != String.Empty)
2771 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2772 else
2773 reply.Data.Desc = new Byte[0];
2753 reply.Data.ActualArea = land.Area; 2774 reply.Data.ActualArea = land.Area;
2754 reply.Data.BillableArea = land.Area; // TODO: what is this? 2775 reply.Data.BillableArea = land.Area; // TODO: what is this?
2755 2776
@@ -3612,7 +3633,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3612 /// </summary> 3633 /// </summary>
3613 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3634 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3614 { 3635 {
3615 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3636 if (entity is SceneObjectPart)
3637 {
3638 SceneObjectPart e = (SceneObjectPart)entity;
3639 SceneObjectGroup g = e.ParentGroup;
3640 if (g.RootPart.Shape.State > 30) // HUD
3641 if (g.OwnerID != AgentId)
3642 return; // Don't send updates for other people's HUDs
3643 }
3644
3616 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3645 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3617 3646
3618 lock (m_entityUpdates.SyncRoot) 3647 lock (m_entityUpdates.SyncRoot)
@@ -3679,211 +3708,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3679 3708
3680 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3709 // 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. 3710 // condition where a kill can be processed before an out-of-date update for the same object.
3682 lock (m_killRecord) 3711 float avgTimeDilation = 1.0f;
3712 IEntityUpdate iupdate;
3713 Int32 timeinqueue; // this is just debugging code & can be dropped later
3714
3715 while (updatesThisCall < maxUpdates)
3683 { 3716 {
3684 float avgTimeDilation = 1.0f; 3717 lock (m_entityUpdates.SyncRoot)
3685 IEntityUpdate iupdate; 3718 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3686 Int32 timeinqueue; // this is just debugging code & can be dropped later 3719 break;
3687
3688 while (updatesThisCall < maxUpdates)
3689 {
3690 lock (m_entityUpdates.SyncRoot)
3691 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3692 break;
3693 3720
3694 EntityUpdate update = (EntityUpdate)iupdate; 3721 EntityUpdate update = (EntityUpdate)iupdate;
3695 3722
3696 avgTimeDilation += update.TimeDilation; 3723 avgTimeDilation += update.TimeDilation;
3697 avgTimeDilation *= 0.5f; 3724 avgTimeDilation *= 0.5f;
3698 3725
3699 if (update.Entity is SceneObjectPart) 3726 if (update.Entity is SceneObjectPart)
3727 {
3728 SceneObjectPart part = (SceneObjectPart)update.Entity;
3729
3730 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3731 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3732 // safety measure.
3733 //
3734 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3735 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3736 // updates and kills on different threads with different scheduling strategies, hence this protection.
3737 //
3738 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3739 // after the root prim has been deleted.
3740 lock (m_killRecord)
3700 { 3741 {
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)) 3742 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; 3743 continue;
3719 } 3744 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3720 3745 continue;
3721 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3746 }
3747
3748 if (part.ParentGroup.IsDeleted)
3749 continue;
3750
3751 if (part.ParentGroup.IsAttachment)
3752 { // Someone else's HUD, why are we getting these?
3753 if (part.ParentGroup.OwnerID != AgentId &&
3754 part.ParentGroup.RootPart.Shape.State >= 30)
3755 continue;
3756 ScenePresence sp;
3757 // Owner is not in the sim, don't update it to
3758 // anyone
3759 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3760 continue;
3761
3762 List<SceneObjectGroup> atts = sp.GetAttachments();
3763 bool found = false;
3764 foreach (SceneObjectGroup att in atts)
3722 { 3765 {
3723 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3766 if (att == part.ParentGroup)
3724 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3725 { 3767 {
3726 part.Shape.LightEntry = false; 3768 found = true;
3769 break;
3727 } 3770 }
3728 } 3771 }
3772
3773 // It's an attachment of a valid avatar, but
3774 // doesn't seem to be attached, skip
3775 if (!found)
3776 continue;
3729 } 3777 }
3730 3778 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 { 3779 {
3753 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3780 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3754 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3781 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3755 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3757 { 3782 {
3758 canUseCompressed = false; 3783 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 } 3784 }
3778 } 3785 }
3779 3786 }
3780 #endregion UpdateFlags to packet type conversion 3787
3781 3788 ++updatesThisCall;
3782 #region Block Construction 3789
3783 3790 #region UpdateFlags to packet type conversion
3784 // TODO: Remove this once we can build compressed updates 3791
3792 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3793
3794 bool canUseCompressed = true;
3795 bool canUseImproved = true;
3796
3797 // Compressed object updates only make sense for LL primitives
3798 if (!(update.Entity is SceneObjectPart))
3799 {
3785 canUseCompressed = false; 3800 canUseCompressed = false;
3786 3801 }
3787 if (!canUseImproved && !canUseCompressed) 3802
3788 { 3803 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3789 if (update.Entity is ScenePresence) 3804 {
3790 { 3805 canUseCompressed = false;
3791 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3806 canUseImproved = false;
3792 objectUpdates.Value.Add(update); 3807 }
3793 } 3808 else
3794 else 3809 {
3795 { 3810 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3796 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3811 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3797 objectUpdates.Value.Add(update); 3812 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3798 } 3813 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3799 }
3800 else if (!canUseImproved)
3801 { 3814 {
3802 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3815 canUseCompressed = false;
3803 compressedUpdates.Value.Add(update);
3804 } 3816 }
3805 else 3817
3818 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3821 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3822 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3823 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3824 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3825 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3826 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3827 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3828 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3829 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3830 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3831 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3806 { 3832 {
3807 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3833 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 } 3834 }
3820
3821 #endregion Block Construction
3822 } 3835 }
3823
3824
3825 #region Packet Sending
3826 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3827 3836
3828 if (terseAgentUpdateBlocks.IsValueCreated) 3837 #endregion UpdateFlags to packet type conversion
3829 {
3830 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3831 3838
3832 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3839 #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 3840
3837 for (int i = 0; i < blocks.Count; i++) 3841 // TODO: Remove this once we can build compressed updates
3838 packet.ObjectData[i] = blocks[i]; 3842 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 3843
3843 if (objectUpdateBlocks.IsValueCreated) 3844 if (!canUseImproved && !canUseCompressed)
3844 { 3845 {
3845 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3846 if (update.Entity is ScenePresence)
3846 3847 {
3847 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3848 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3848 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3849 }
3849 packet.RegionData.TimeDilation = timeDilation; 3850 else
3850 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3851 {
3851 3852 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3852 for (int i = 0; i < blocks.Count; i++) 3853 }
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 } 3854 }
3857 3855 else if (!canUseImproved)
3858 if (compressedUpdateBlocks.IsValueCreated)
3859 { 3856 {
3860 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3857 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 } 3858 }
3872 3859 else
3873 if (terseUpdateBlocks.IsValueCreated)
3874 { 3860 {
3875 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3861 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3876 3862 // Self updates go into a special list
3877 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3863 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3864 else
3879 packet.RegionData.TimeDilation = timeDilation; 3865 // Everything else goes here
3880 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3866 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 } 3867 }
3868
3869 #endregion Block Construction
3870 }
3871
3872 #region Packet Sending
3873
3874 const float TIME_DILATION = 1.0f;
3875 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3876
3877 if (terseAgentUpdateBlocks.IsValueCreated)
3878 {
3879 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3880
3881 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3882 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3883 packet.RegionData.TimeDilation = timeDilation;
3884 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3885
3886 for (int i = 0; i < blocks.Count; i++)
3887 packet.ObjectData[i] = blocks[i];
3888
3889 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3890 }
3891
3892 if (objectUpdateBlocks.IsValueCreated)
3893 {
3894 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3895
3896 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3897 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3898 packet.RegionData.TimeDilation = timeDilation;
3899 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3900
3901 for (int i = 0; i < blocks.Count; i++)
3902 packet.ObjectData[i] = blocks[i];
3903
3904 OutPacket(packet, ThrottleOutPacketType.Task, true);
3905 }
3906
3907 if (compressedUpdateBlocks.IsValueCreated)
3908 {
3909 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3910
3911 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3912 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3913 packet.RegionData.TimeDilation = timeDilation;
3914 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3915
3916 for (int i = 0; i < blocks.Count; i++)
3917 packet.ObjectData[i] = blocks[i];
3918
3919 OutPacket(packet, ThrottleOutPacketType.Task, true);
3920 }
3921
3922 if (terseUpdateBlocks.IsValueCreated)
3923 {
3924 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3925
3926 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3927 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3928 packet.RegionData.TimeDilation = timeDilation;
3929 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3930
3931 for (int i = 0; i < blocks.Count; i++)
3932 packet.ObjectData[i] = blocks[i];
3933
3934 OutPacket(packet, ThrottleOutPacketType.Task, true);
3887 } 3935 }
3888 3936
3889 #endregion Packet Sending 3937 #endregion Packet Sending
@@ -4176,11 +4224,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4176 4224
4177 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4225 // 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 4226 // of the object rather than the properties when the packet was created
4179 OutPacket(packet, ThrottleOutPacketType.Task, true, 4227 // HACK : Remove intelligent resending until it's fixed in core
4180 delegate(OutgoingPacket oPacket) 4228 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4181 { 4229 // delegate(OutgoingPacket oPacket)
4182 ResendPropertyUpdates(updates, oPacket); 4230 // {
4183 }); 4231 // ResendPropertyUpdates(updates, oPacket);
4232 // });
4233 OutPacket(packet, ThrottleOutPacketType.Task, true);
4184 4234
4185 // pbcnt += blocks.Count; 4235 // pbcnt += blocks.Count;
4186 // ppcnt++; 4236 // ppcnt++;
@@ -4206,11 +4256,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4206 // of the object rather than the properties when the packet was created 4256 // of the object rather than the properties when the packet was created
4207 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4257 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4208 updates.Add(familyUpdates.Value[i]); 4258 updates.Add(familyUpdates.Value[i]);
4209 OutPacket(packet, ThrottleOutPacketType.Task, true, 4259 // HACK : Remove intelligent resending until it's fixed in core
4210 delegate(OutgoingPacket oPacket) 4260 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4211 { 4261 // delegate(OutgoingPacket oPacket)
4212 ResendPropertyUpdates(updates, oPacket); 4262 // {
4213 }); 4263 // ResendPropertyUpdates(updates, oPacket);
4264 // });
4265 OutPacket(packet, ThrottleOutPacketType.Task, true);
4214 4266
4215 // fpcnt++; 4267 // fpcnt++;
4216 // fbcnt++; 4268 // fbcnt++;
@@ -4359,37 +4411,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4359 if (bl[i].BannedUserID == UUID.Zero) 4411 if (bl[i].BannedUserID == UUID.Zero)
4360 continue; 4412 continue;
4361 BannedUsers.Add(bl[i].BannedUserID); 4413 BannedUsers.Add(bl[i].BannedUserID);
4362 }
4363 4414
4364 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4415 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4365 packet.AgentData.TransactionID = UUID.Random(); 4416 {
4366 packet.AgentData.AgentID = AgentId; 4417 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4367 packet.AgentData.SessionID = SessionId; 4418 packet.AgentData.TransactionID = UUID.Random();
4368 packet.MethodData.Invoice = invoice; 4419 packet.AgentData.AgentID = AgentId;
4369 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4420 packet.AgentData.SessionID = SessionId;
4421 packet.MethodData.Invoice = invoice;
4422 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4370 4423
4371 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4424 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4372 4425
4373 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4426 int j;
4374 { 4427 for (j = 0; j < (6 + BannedUsers.Count); j++)
4375 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4428 {
4376 } 4429 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4377 int j = 0; 4430 }
4431 j = 0;
4378 4432
4379 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4433 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4434 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4435 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4436 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4383 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4437 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4384 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4438 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4385 4439
4386 foreach (UUID banned in BannedUsers) 4440 foreach (UUID banned in BannedUsers)
4387 { 4441 {
4388 returnblock[j].Parameter = banned.GetBytes(); j++; 4442 returnblock[j].Parameter = banned.GetBytes(); j++;
4443 }
4444 packet.ParamList = returnblock;
4445 packet.Header.Reliable = true;
4446 OutPacket(packet, ThrottleOutPacketType.Task);
4447
4448 BannedUsers.Clear();
4449 }
4389 } 4450 }
4390 packet.ParamList = returnblock; 4451
4391 packet.Header.Reliable = false;
4392 OutPacket(packet, ThrottleOutPacketType.Task);
4393 } 4452 }
4394 4453
4395 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4454 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4575,7 +4634,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4575 4634
4576 if (landData.SimwideArea > 0) 4635 if (landData.SimwideArea > 0)
4577 { 4636 {
4578 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4637 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4638 // Never report more than sim total capacity
4639 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4640 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4579 updateMessage.SimWideMaxPrims = simulatorCapacity; 4641 updateMessage.SimWideMaxPrims = simulatorCapacity;
4580 } 4642 }
4581 else 4643 else
@@ -4704,14 +4766,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4704 4766
4705 if (notifyCount > 0) 4767 if (notifyCount > 0)
4706 { 4768 {
4707 if (notifyCount > 32) 4769// if (notifyCount > 32)
4708 { 4770// {
4709 m_log.InfoFormat( 4771// m_log.InfoFormat(
4710 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4772// "[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); 4773// + " - a developer might want to investigate whether this is a hard limit", 32);
4712 4774//
4713 notifyCount = 32; 4775// notifyCount = 32;
4714 } 4776// }
4715 4777
4716 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4778 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4717 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4779 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5244,6 +5306,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5244 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5306 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5245 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5307 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5246 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5308 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5309 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5247 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5310 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5248 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5311 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5249 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5312 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5310,6 +5373,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5310 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5373 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5311 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5374 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5312 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5375 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5376 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5313 5377
5314 AddGenericPacketHandler("autopilot", HandleAutopilot); 5378 AddGenericPacketHandler("autopilot", HandleAutopilot);
5315 } 5379 }
@@ -5345,6 +5409,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5345 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5409 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5346 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5410 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5347 (x.ControlFlags != lastarg.ControlFlags) || 5411 (x.ControlFlags != lastarg.ControlFlags) ||
5412 (x.ControlFlags != 0) ||
5348 (x.Far != lastarg.Far) || 5413 (x.Far != lastarg.Far) ||
5349 (x.Flags != lastarg.Flags) || 5414 (x.Flags != lastarg.Flags) ||
5350 (x.State != lastarg.State) || 5415 (x.State != lastarg.State) ||
@@ -5722,7 +5787,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5722 args.Channel = ch; 5787 args.Channel = ch;
5723 args.From = String.Empty; 5788 args.From = String.Empty;
5724 args.Message = Utils.BytesToString(msg); 5789 args.Message = Utils.BytesToString(msg);
5725 args.Type = ChatTypeEnum.Shout; 5790 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5726 args.Position = new Vector3(); 5791 args.Position = new Vector3();
5727 args.Scene = Scene; 5792 args.Scene = Scene;
5728 args.Sender = this; 5793 args.Sender = this;
@@ -9767,7 +9832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9767 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9832 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9768 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9833 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9769 UpdateMuteListEntry.MuteData.MuteType, 9834 UpdateMuteListEntry.MuteData.MuteType,
9770 UpdateMuteListEntry.AgentData.AgentID); 9835 UpdateMuteListEntry.MuteData.MuteFlags);
9771 return true; 9836 return true;
9772 } 9837 }
9773 return false; 9838 return false;
@@ -9782,8 +9847,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9782 { 9847 {
9783 handlerRemoveMuteListEntry(this, 9848 handlerRemoveMuteListEntry(this,
9784 RemoveMuteListEntry.MuteData.MuteID, 9849 RemoveMuteListEntry.MuteData.MuteID,
9785 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9850 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9786 RemoveMuteListEntry.AgentData.AgentID);
9787 return true; 9851 return true;
9788 } 9852 }
9789 return false; 9853 return false;
@@ -9827,10 +9891,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9827 return false; 9891 return false;
9828 } 9892 }
9829 9893
9894 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9895 {
9896 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9897 (ChangeInventoryItemFlagsPacket)packet;
9898 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9899 if (handlerChangeInventoryItemFlags != null)
9900 {
9901 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9902 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9903 return true;
9904 }
9905 return false;
9906 }
9907
9830 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9908 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9831 { 9909 {
9832 return true; 9910 return true;
9833 } 9911 }
9912
9913 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9914 {
9915 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9916
9917 #region Packet Session and User Check
9918 if (m_checkPackets)
9919 {
9920 if (packet.AgentData.SessionID != SessionId ||
9921 packet.AgentData.AgentID != AgentId)
9922 return true;
9923 }
9924 #endregion
9925 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9926 List<InventoryItemBase> items = new List<InventoryItemBase>();
9927 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9928 {
9929 InventoryItemBase b = new InventoryItemBase();
9930 b.ID = n.OldItemID;
9931 b.Folder = n.OldFolderID;
9932 items.Add(b);
9933 }
9934
9935 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9936 if (handlerMoveItemsAndLeaveCopy != null)
9937 {
9938 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9939 }
9940
9941 return true;
9942 }
9834 9943
9835 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9944 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9836 { 9945 {
@@ -10257,6 +10366,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10257 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10366 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10258 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10367 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10259 10368
10369 Scene scene = (Scene)m_scene;
10370 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10371 {
10372 ScenePresence p;
10373 if (scene.TryGetScenePresence(sender.AgentId, out p))
10374 {
10375 if (p.GodLevel >= 200)
10376 {
10377 groupProfileReply.GroupData.OpenEnrollment = true;
10378 groupProfileReply.GroupData.MembershipFee = 0;
10379 }
10380 }
10381 }
10382
10260 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10383 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10261 } 10384 }
10262 return true; 10385 return true;
@@ -10830,11 +10953,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10830 10953
10831 StartLure handlerStartLure = OnStartLure; 10954 StartLure handlerStartLure = OnStartLure;
10832 if (handlerStartLure != null) 10955 if (handlerStartLure != null)
10833 handlerStartLure(startLureRequest.Info.LureType, 10956 {
10834 Utils.BytesToString( 10957 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10835 startLureRequest.Info.Message), 10958 {
10836 startLureRequest.TargetData[0].TargetID, 10959 handlerStartLure(startLureRequest.Info.LureType,
10837 this); 10960 Utils.BytesToString(
10961 startLureRequest.Info.Message),
10962 startLureRequest.TargetData[i].TargetID,
10963 this);
10964 }
10965 }
10838 return true; 10966 return true;
10839 } 10967 }
10840 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10968 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10948,10 +11076,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10948 } 11076 }
10949 #endregion 11077 #endregion
10950 11078
10951 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11079 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10952 if (handlerClassifiedGodDelete != null) 11080 if (handlerClassifiedGodDelete != null)
10953 handlerClassifiedGodDelete( 11081 handlerClassifiedGodDelete(
10954 classifiedGodDelete.Data.ClassifiedID, 11082 classifiedGodDelete.Data.ClassifiedID,
11083 classifiedGodDelete.Data.QueryID,
10955 this); 11084 this);
10956 return true; 11085 return true;
10957 } 11086 }
@@ -12000,7 +12129,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12000 12129
12001// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12130// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
12002 12131
12132
12133 //Note, the bool returned from the below function is useless since it is always false.
12003 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12134 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12135
12004 } 12136 }
12005 12137
12006 /// <summary> 12138 /// <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 1e22fcc..a79b387 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1048,7 +1048,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1048 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1048 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1049 { 1049 {
1050 client.IsLoggingOut = true; 1050 client.IsLoggingOut = true;
1051 client.Close(); 1051 client.Close(false);
1052 } 1052 }
1053 } 1053 }
1054 1054
@@ -1060,6 +1060,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1060 1060
1061 while (base.IsRunning) 1061 while (base.IsRunning)
1062 { 1062 {
1063 m_scene.ThreadAlive(1);
1063 try 1064 try
1064 { 1065 {
1065 IncomingPacket incomingPacket = null; 1066 IncomingPacket incomingPacket = null;
@@ -1102,6 +1103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1102 1103
1103 while (base.IsRunning) 1104 while (base.IsRunning)
1104 { 1105 {
1106 m_scene.ThreadAlive(2);
1105 try 1107 try
1106 { 1108 {
1107 m_packetSent = false; 1109 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,