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.cs753
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 448 insertions, 328 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index e9e2dca..9dd6663 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -202,6 +202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 m_stopPacket = TexturePacketCount(); 202 m_stopPacket = TexturePacketCount();
203 } 203 }
204 204
205 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
206 if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
207
205 m_currentPacket = StartPacket; 208 m_currentPacket = StartPacket;
206 } 209 }
207 } 210 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 29dce17..0c92308 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -157,6 +157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
157 public event RequestTaskInventory OnRequestTaskInventory; 157 public event RequestTaskInventory OnRequestTaskInventory;
158 public event UpdateInventoryItem OnUpdateInventoryItem; 158 public event UpdateInventoryItem OnUpdateInventoryItem;
159 public event CopyInventoryItem OnCopyInventoryItem; 159 public event CopyInventoryItem OnCopyInventoryItem;
160 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
160 public event MoveInventoryItem OnMoveInventoryItem; 161 public event MoveInventoryItem OnMoveInventoryItem;
161 public event RemoveInventoryItem OnRemoveInventoryItem; 162 public event RemoveInventoryItem OnRemoveInventoryItem;
162 public event RemoveInventoryFolder OnRemoveInventoryFolder; 163 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -254,7 +255,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
254 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 255 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
255 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 256 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
256 public event ClassifiedDelete OnClassifiedDelete; 257 public event ClassifiedDelete OnClassifiedDelete;
257 public event ClassifiedDelete OnClassifiedGodDelete; 258 public event ClassifiedGodDelete OnClassifiedGodDelete;
258 public event EventNotificationAddRequest OnEventNotificationAddRequest; 259 public event EventNotificationAddRequest OnEventNotificationAddRequest;
259 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 260 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
260 public event EventGodDelete OnEventGodDelete; 261 public event EventGodDelete OnEventGodDelete;
@@ -330,7 +331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
330 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 331 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
331 /// ownerless phantom. 332 /// ownerless phantom.
332 /// 333 ///
333 /// All manipulation of this set has to occur under a lock 334 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
334 /// 335 ///
335 /// </value> 336 /// </value>
336 protected HashSet<uint> m_killRecord; 337 protected HashSet<uint> m_killRecord;
@@ -338,6 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338// protected HashSet<uint> m_attachmentsSent; 339// protected HashSet<uint> m_attachmentsSent;
339 340
340 private int m_moneyBalance; 341 private int m_moneyBalance;
342 private bool m_deliverPackets = true;
341 private int m_animationSequenceNumber = 1; 343 private int m_animationSequenceNumber = 1;
342 private bool m_SendLogoutPacketWhenClosing = true; 344 private bool m_SendLogoutPacketWhenClosing = true;
343 private AgentUpdateArgs lastarg; 345 private AgentUpdateArgs lastarg;
@@ -378,6 +380,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
378 get { return m_startpos; } 380 get { return m_startpos; }
379 set { m_startpos = value; } 381 set { m_startpos = value; }
380 } 382 }
383 public bool DeliverPackets
384 {
385 get { return m_deliverPackets; }
386 set {
387 m_deliverPackets = value;
388 m_udpClient.m_deliverPackets = value;
389 }
390 }
381 public UUID AgentId { get { return m_agentId; } } 391 public UUID AgentId { get { return m_agentId; } }
382 public UUID ActiveGroupId { get { return m_activeGroupID; } } 392 public UUID ActiveGroupId { get { return m_activeGroupID; } }
383 public string ActiveGroupName { get { return m_activeGroupName; } } 393 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -484,18 +494,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
484 494
485 #region Client Methods 495 #region Client Methods
486 496
497
487 /// <summary> 498 /// <summary>
488 /// Shut down the client view 499 /// Shut down the client view
489 /// </summary> 500 /// </summary>
490 public void Close() 501 public void Close()
491 { 502 {
503 Close(true);
504 }
505
506 /// <summary>
507 /// Shut down the client view
508 /// </summary>
509 public void Close(bool sendStop)
510 {
492 m_log.DebugFormat( 511 m_log.DebugFormat(
493 "[CLIENT]: Close has been called for {0} attached to scene {1}", 512 "[CLIENT]: Close has been called for {0} attached to scene {1}",
494 Name, m_scene.RegionInfo.RegionName); 513 Name, m_scene.RegionInfo.RegionName);
495 514
496 // Send the STOP packet 515 if (sendStop)
497 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 516 {
498 OutPacket(disable, ThrottleOutPacketType.Unknown); 517 // Send the STOP packet
518 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
519 OutPacket(disable, ThrottleOutPacketType.Unknown);
520 }
499 521
500 IsActive = false; 522 IsActive = false;
501 523
@@ -796,7 +818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
796 reply.ChatData.OwnerID = fromAgentID; 818 reply.ChatData.OwnerID = fromAgentID;
797 reply.ChatData.SourceID = fromAgentID; 819 reply.ChatData.SourceID = fromAgentID;
798 820
799 OutPacket(reply, ThrottleOutPacketType.Task); 821 OutPacket(reply, ThrottleOutPacketType.Unknown);
800 } 822 }
801 823
802 /// <summary> 824 /// <summary>
@@ -1082,6 +1104,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1082 public virtual void SendLayerData(float[] map) 1104 public virtual void SendLayerData(float[] map)
1083 { 1105 {
1084 Util.FireAndForget(DoSendLayerData, map); 1106 Util.FireAndForget(DoSendLayerData, map);
1107
1108 // Send it sync, and async. It's not that much data
1109 // and it improves user experience just so much!
1110 DoSendLayerData(map);
1085 } 1111 }
1086 1112
1087 /// <summary> 1113 /// <summary>
@@ -1094,16 +1120,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1094 1120
1095 try 1121 try
1096 { 1122 {
1097 //for (int y = 0; y < 16; y++) 1123 for (int y = 0; y < 16; y++)
1098 //{ 1124 {
1099 // for (int x = 0; x < 16; x++) 1125 for (int x = 0; x < 16; x+=4)
1100 // { 1126 {
1101 // SendLayerData(x, y, map); 1127 SendLayerPacket(x, y, map);
1102 // } 1128 }
1103 //} 1129 }
1104
1105 // Send LayerData in a spiral pattern. Fun!
1106 SendLayerTopRight(map, 0, 0, 15, 15);
1107 } 1130 }
1108 catch (Exception e) 1131 catch (Exception e)
1109 { 1132 {
@@ -1111,51 +1134,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1111 } 1134 }
1112 } 1135 }
1113 1136
1114 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1115 {
1116 // Row
1117 for (int i = x1; i <= x2; i++)
1118 SendLayerData(i, y1, map);
1119
1120 // Column
1121 for (int j = y1 + 1; j <= y2; j++)
1122 SendLayerData(x2, j, map);
1123
1124 if (x2 - x1 > 0)
1125 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1126 }
1127
1128 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1129 {
1130 // Row in reverse
1131 for (int i = x2; i >= x1; i--)
1132 SendLayerData(i, y2, map);
1133
1134 // Column in reverse
1135 for (int j = y2 - 1; j >= y1; j--)
1136 SendLayerData(x1, j, map);
1137
1138 if (x2 - x1 > 0)
1139 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1140 }
1141
1142 /// <summary> 1137 /// <summary>
1143 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1138 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1144 /// </summary> 1139 /// </summary>
1145 /// <param name="map">heightmap</param> 1140 /// <param name="map">heightmap</param>
1146 /// <param name="px">X coordinate for patches 0..12</param> 1141 /// <param name="px">X coordinate for patches 0..12</param>
1147 /// <param name="py">Y coordinate for patches 0..15</param> 1142 /// <param name="py">Y coordinate for patches 0..15</param>
1148 // private void SendLayerPacket(float[] map, int y, int x) 1143 private void SendLayerPacket(int x, int y, float[] map)
1149 // { 1144 {
1150 // int[] patches = new int[4]; 1145 int[] patches = new int[4];
1151 // patches[0] = x + 0 + y * 16; 1146 patches[0] = x + 0 + y * 16;
1152 // patches[1] = x + 1 + y * 16; 1147 patches[1] = x + 1 + y * 16;
1153 // patches[2] = x + 2 + y * 16; 1148 patches[2] = x + 2 + y * 16;
1154 // patches[3] = x + 3 + y * 16; 1149 patches[3] = x + 3 + y * 16;
1155 1150
1156 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1151 float[] heightmap = (map.Length == 65536) ?
1157 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1152 map :
1158 // } 1153 LLHeightFieldMoronize(map);
1154
1155 try
1156 {
1157 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1158 OutPacket(layerpack, ThrottleOutPacketType.Land);
1159 }
1160 catch
1161 {
1162 for (int px = x ; px < x + 4 ; px++)
1163 SendLayerData(px, y, map);
1164 }
1165 }
1159 1166
1160 /// <summary> 1167 /// <summary>
1161 /// Sends a specified patch to a client 1168 /// Sends a specified patch to a client
@@ -1175,7 +1182,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1175 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1182 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1176 layerpack.Header.Reliable = true; 1183 layerpack.Header.Reliable = true;
1177 1184
1178 OutPacket(layerpack, ThrottleOutPacketType.Land); 1185 OutPacket(layerpack, ThrottleOutPacketType.Task);
1179 } 1186 }
1180 catch (Exception e) 1187 catch (Exception e)
1181 { 1188 {
@@ -1536,38 +1543,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1536 OutPacket(pc, ThrottleOutPacketType.Unknown); 1543 OutPacket(pc, ThrottleOutPacketType.Unknown);
1537 } 1544 }
1538 1545
1539 public void SendKillObject(ulong regionHandle, uint localID) 1546 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1540 { 1547 {
1541// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1548// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1542 1549
1543 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1550 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1544 // TODO: don't create new blocks if recycling an old packet 1551 // TODO: don't create new blocks if recycling an old packet
1545 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1552 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1546 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1553 for (int i = 0 ; i < localIDs.Count ; i++ )
1547 kill.ObjectData[0].ID = localID; 1554 {
1555 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1556 kill.ObjectData[i].ID = localIDs[i];
1557 }
1548 kill.Header.Reliable = true; 1558 kill.Header.Reliable = true;
1549 kill.Header.Zerocoded = true; 1559 kill.Header.Zerocoded = true;
1550 1560
1551 if (m_scene.GetScenePresence(localID) == null) 1561 lock (m_killRecord)
1552 { 1562 {
1553 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1563 if (localIDs.Count == 1)
1554 // condition where a kill can be processed before an out-of-date update for the same object.
1555 lock (m_killRecord)
1556 { 1564 {
1557 m_killRecord.Add(localID); 1565 if (m_scene.GetScenePresence(localIDs[0]) != null)
1558 1566 {
1559 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1567 OutPacket(kill, ThrottleOutPacketType.State);
1560 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1568 return;
1561 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1569 }
1562 // scene objects in a viewer until that viewer is relogged in. 1570 m_killRecord.Add(localIDs[0]);
1563 OutPacket(kill, ThrottleOutPacketType.Task); 1571 }
1572 else
1573 {
1574 lock (m_entityUpdates.SyncRoot)
1575 {
1576 foreach (uint localID in localIDs)
1577 m_killRecord.Add(localID);
1578 }
1564 } 1579 }
1565 } 1580 }
1566 else 1581
1567 { 1582 // The throttle queue used here must match that being used for
1568 // OutPacket(kill, ThrottleOutPacketType.State); 1583 // updates. Otherwise, there is a chance that a kill packet put
1569 OutPacket(kill, ThrottleOutPacketType.Task); 1584 // on a separate queue will be sent to the client before an
1570 } 1585 // existing update packet on another queue. Receiving updates
1586 // after kills results in unowned and undeletable
1587 // scene objects in a viewer until that viewer is relogged in.
1588 OutPacket(kill, ThrottleOutPacketType.Task);
1571 } 1589 }
1572 1590
1573 /// <summary> 1591 /// <summary>
@@ -2292,6 +2310,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2292 OutPacket(sound, ThrottleOutPacketType.Task); 2310 OutPacket(sound, ThrottleOutPacketType.Task);
2293 } 2311 }
2294 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
2295 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)
2296 { 2323 {
2297 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2324 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3594,7 +3621,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3594 /// </summary> 3621 /// </summary>
3595 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3622 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3596 { 3623 {
3597 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3624 if (entity is SceneObjectPart)
3625 {
3626 SceneObjectPart e = (SceneObjectPart)entity;
3627 SceneObjectGroup g = e.ParentGroup;
3628 if (g.RootPart.Shape.State > 30) // HUD
3629 if (g.OwnerID != AgentId)
3630 return; // Don't send updates for other people's HUDs
3631 }
3632
3598 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3633 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3599 3634
3600 lock (m_entityUpdates.SyncRoot) 3635 lock (m_entityUpdates.SyncRoot)
@@ -3661,211 +3696,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3661 3696
3662 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3697 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3663 // condition where a kill can be processed before an out-of-date update for the same object. 3698 // condition where a kill can be processed before an out-of-date update for the same object.
3664 lock (m_killRecord) 3699 float avgTimeDilation = 1.0f;
3700 IEntityUpdate iupdate;
3701 Int32 timeinqueue; // this is just debugging code & can be dropped later
3702
3703 while (updatesThisCall < maxUpdates)
3665 { 3704 {
3666 float avgTimeDilation = 1.0f; 3705 lock (m_entityUpdates.SyncRoot)
3667 IEntityUpdate iupdate; 3706 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3668 Int32 timeinqueue; // this is just debugging code & can be dropped later 3707 break;
3669
3670 while (updatesThisCall < maxUpdates)
3671 {
3672 lock (m_entityUpdates.SyncRoot)
3673 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3674 break;
3675 3708
3676 EntityUpdate update = (EntityUpdate)iupdate; 3709 EntityUpdate update = (EntityUpdate)iupdate;
3677 3710
3678 avgTimeDilation += update.TimeDilation; 3711 avgTimeDilation += update.TimeDilation;
3679 avgTimeDilation *= 0.5f; 3712 avgTimeDilation *= 0.5f;
3680 3713
3681 if (update.Entity is SceneObjectPart) 3714 if (update.Entity is SceneObjectPart)
3715 {
3716 SceneObjectPart part = (SceneObjectPart)update.Entity;
3717
3718 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3719 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3720 // safety measure.
3721 //
3722 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3723 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3724 // updates and kills on different threads with different scheduling strategies, hence this protection.
3725 //
3726 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3727 // after the root prim has been deleted.
3728 lock (m_killRecord)
3682 { 3729 {
3683 SceneObjectPart part = (SceneObjectPart)update.Entity;
3684
3685 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3686 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3687 // safety measure.
3688 //
3689 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3690 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3691 // updates and kills on different threads with different scheduling strategies, hence this protection.
3692 //
3693 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3694 // after the root prim has been deleted.
3695 if (m_killRecord.Contains(part.LocalId)) 3730 if (m_killRecord.Contains(part.LocalId))
3696 {
3697 // m_log.WarnFormat(
3698 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3699 // part.LocalId, Name);
3700 continue; 3731 continue;
3701 } 3732 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3702 3733 continue;
3703 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3734 }
3735
3736 if (part.ParentGroup.IsDeleted)
3737 continue;
3738
3739 if (part.ParentGroup.IsAttachment)
3740 { // Someone else's HUD, why are we getting these?
3741 if (part.ParentGroup.OwnerID != AgentId &&
3742 part.ParentGroup.RootPart.Shape.State >= 30)
3743 continue;
3744 ScenePresence sp;
3745 // Owner is not in the sim, don't update it to
3746 // anyone
3747 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3748 continue;
3749
3750 List<SceneObjectGroup> atts = sp.GetAttachments();
3751 bool found = false;
3752 foreach (SceneObjectGroup att in atts)
3704 { 3753 {
3705 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3754 if (att == part.ParentGroup)
3706 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3707 { 3755 {
3708 part.Shape.LightEntry = false; 3756 found = true;
3757 break;
3709 } 3758 }
3710 } 3759 }
3760
3761 // It's an attachment of a valid avatar, but
3762 // doesn't seem to be attached, skip
3763 if (!found)
3764 continue;
3711 } 3765 }
3712 3766 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3713 ++updatesThisCall;
3714
3715 #region UpdateFlags to packet type conversion
3716
3717 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3718
3719 bool canUseCompressed = true;
3720 bool canUseImproved = true;
3721
3722 // Compressed object updates only make sense for LL primitives
3723 if (!(update.Entity is SceneObjectPart))
3724 {
3725 canUseCompressed = false;
3726 }
3727
3728 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3729 {
3730 canUseCompressed = false;
3731 canUseImproved = false;
3732 }
3733 else
3734 { 3767 {
3735 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3768 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3736 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3769 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3737 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3738 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3739 {
3740 canUseCompressed = false;
3741 }
3742
3743 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3744 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3745 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3746 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3747 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3748 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3751 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3757 { 3770 {
3758 canUseImproved = false; 3771 part.Shape.LightEntry = false;
3759 } 3772 }
3760 } 3773 }
3761 3774 }
3762 #endregion UpdateFlags to packet type conversion 3775
3763 3776 ++updatesThisCall;
3764 #region Block Construction 3777
3765 3778 #region UpdateFlags to packet type conversion
3766 // TODO: Remove this once we can build compressed updates 3779
3780 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3781
3782 bool canUseCompressed = true;
3783 bool canUseImproved = true;
3784
3785 // Compressed object updates only make sense for LL primitives
3786 if (!(update.Entity is SceneObjectPart))
3787 {
3767 canUseCompressed = false; 3788 canUseCompressed = false;
3768 3789 }
3769 if (!canUseImproved && !canUseCompressed) 3790
3770 { 3791 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3771 if (update.Entity is ScenePresence) 3792 {
3772 { 3793 canUseCompressed = false;
3773 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3794 canUseImproved = false;
3774 objectUpdates.Value.Add(update); 3795 }
3775 } 3796 else
3776 else 3797 {
3777 { 3798 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3778 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3799 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3779 objectUpdates.Value.Add(update); 3800 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3780 } 3801 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3781 }
3782 else if (!canUseImproved)
3783 { 3802 {
3784 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3803 canUseCompressed = false;
3785 compressedUpdates.Value.Add(update);
3786 } 3804 }
3787 else 3805
3806 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3788 { 3820 {
3789 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3821 canUseImproved = false;
3790 {
3791 // Self updates go into a special list
3792 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3793 terseAgentUpdates.Value.Add(update);
3794 }
3795 else
3796 {
3797 // Everything else goes here
3798 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3799 terseUpdates.Value.Add(update);
3800 }
3801 } 3822 }
3802
3803 #endregion Block Construction
3804 } 3823 }
3805
3806
3807 #region Packet Sending
3808 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3809 3824
3810 if (terseAgentUpdateBlocks.IsValueCreated) 3825 #endregion UpdateFlags to packet type conversion
3811 {
3812 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3813 3826
3814 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3827 #region Block Construction
3815 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3816 packet.RegionData.TimeDilation = timeDilation;
3817 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3818 3828
3819 for (int i = 0; i < blocks.Count; i++) 3829 // TODO: Remove this once we can build compressed updates
3820 packet.ObjectData[i] = blocks[i]; 3830 canUseCompressed = false;
3821 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3822 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3823 }
3824 3831
3825 if (objectUpdateBlocks.IsValueCreated) 3832 if (!canUseImproved && !canUseCompressed)
3826 { 3833 {
3827 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3834 if (update.Entity is ScenePresence)
3828 3835 {
3829 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3836 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3830 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3837 }
3831 packet.RegionData.TimeDilation = timeDilation; 3838 else
3832 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3839 {
3833 3840 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3834 for (int i = 0; i < blocks.Count; i++) 3841 }
3835 packet.ObjectData[i] = blocks[i];
3836 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3837 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3838 } 3842 }
3839 3843 else if (!canUseImproved)
3840 if (compressedUpdateBlocks.IsValueCreated)
3841 { 3844 {
3842 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3845 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3843
3844 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3845 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3846 packet.RegionData.TimeDilation = timeDilation;
3847 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3848
3849 for (int i = 0; i < blocks.Count; i++)
3850 packet.ObjectData[i] = blocks[i];
3851 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3852 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3853 } 3846 }
3854 3847 else
3855 if (terseUpdateBlocks.IsValueCreated)
3856 { 3848 {
3857 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3849 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3858 3850 // Self updates go into a special list
3859 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3851 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3860 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3852 else
3861 packet.RegionData.TimeDilation = timeDilation; 3853 // Everything else goes here
3862 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3854 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3863
3864 for (int i = 0; i < blocks.Count; i++)
3865 packet.ObjectData[i] = blocks[i];
3866 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3867 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3868 } 3855 }
3856
3857 #endregion Block Construction
3858 }
3859
3860 #region Packet Sending
3861
3862 const float TIME_DILATION = 1.0f;
3863 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3864
3865 if (terseAgentUpdateBlocks.IsValueCreated)
3866 {
3867 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3868
3869 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3870 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3871 packet.RegionData.TimeDilation = timeDilation;
3872 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3873
3874 for (int i = 0; i < blocks.Count; i++)
3875 packet.ObjectData[i] = blocks[i];
3876
3877 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3878 }
3879
3880 if (objectUpdateBlocks.IsValueCreated)
3881 {
3882 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3883
3884 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3885 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3886 packet.RegionData.TimeDilation = timeDilation;
3887 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3888
3889 for (int i = 0; i < blocks.Count; i++)
3890 packet.ObjectData[i] = blocks[i];
3891
3892 OutPacket(packet, ThrottleOutPacketType.Task, true);
3893 }
3894
3895 if (compressedUpdateBlocks.IsValueCreated)
3896 {
3897 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3898
3899 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3900 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3901 packet.RegionData.TimeDilation = timeDilation;
3902 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3903
3904 for (int i = 0; i < blocks.Count; i++)
3905 packet.ObjectData[i] = blocks[i];
3906
3907 OutPacket(packet, ThrottleOutPacketType.Task, true);
3908 }
3909
3910 if (terseUpdateBlocks.IsValueCreated)
3911 {
3912 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3913
3914 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3915 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3916 packet.RegionData.TimeDilation = timeDilation;
3917 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3918
3919 for (int i = 0; i < blocks.Count; i++)
3920 packet.ObjectData[i] = blocks[i];
3921
3922 OutPacket(packet, ThrottleOutPacketType.Task, true);
3869 } 3923 }
3870 3924
3871 #endregion Packet Sending 3925 #endregion Packet Sending
@@ -4166,11 +4220,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4166 4220
4167 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4221 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4168 // of the object rather than the properties when the packet was created 4222 // of the object rather than the properties when the packet was created
4169 OutPacket(packet, ThrottleOutPacketType.Task, true, 4223 // HACK : Remove intelligent resending until it's fixed in core
4170 delegate(OutgoingPacket oPacket) 4224 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4171 { 4225 // delegate(OutgoingPacket oPacket)
4172 ResendPropertyUpdates(updates, oPacket); 4226 // {
4173 }); 4227 // ResendPropertyUpdates(updates, oPacket);
4228 // });
4229 OutPacket(packet, ThrottleOutPacketType.Task, true);
4174 4230
4175 // pbcnt += blocks.Count; 4231 // pbcnt += blocks.Count;
4176 // ppcnt++; 4232 // ppcnt++;
@@ -4196,11 +4252,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4196 // of the object rather than the properties when the packet was created 4252 // of the object rather than the properties when the packet was created
4197 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4253 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4198 updates.Add(familyUpdates.Value[i]); 4254 updates.Add(familyUpdates.Value[i]);
4199 OutPacket(packet, ThrottleOutPacketType.Task, true, 4255 // HACK : Remove intelligent resending until it's fixed in core
4200 delegate(OutgoingPacket oPacket) 4256 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4201 { 4257 // delegate(OutgoingPacket oPacket)
4202 ResendPropertyUpdates(updates, oPacket); 4258 // {
4203 }); 4259 // ResendPropertyUpdates(updates, oPacket);
4260 // });
4261 OutPacket(packet, ThrottleOutPacketType.Task, true);
4204 4262
4205 // fpcnt++; 4263 // fpcnt++;
4206 // fbcnt++; 4264 // fbcnt++;
@@ -4349,37 +4407,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4349 if (bl[i].BannedUserID == UUID.Zero) 4407 if (bl[i].BannedUserID == UUID.Zero)
4350 continue; 4408 continue;
4351 BannedUsers.Add(bl[i].BannedUserID); 4409 BannedUsers.Add(bl[i].BannedUserID);
4352 }
4353 4410
4354 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4411 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4355 packet.AgentData.TransactionID = UUID.Random(); 4412 {
4356 packet.AgentData.AgentID = AgentId; 4413 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4357 packet.AgentData.SessionID = SessionId; 4414 packet.AgentData.TransactionID = UUID.Random();
4358 packet.MethodData.Invoice = invoice; 4415 packet.AgentData.AgentID = AgentId;
4359 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4416 packet.AgentData.SessionID = SessionId;
4417 packet.MethodData.Invoice = invoice;
4418 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4360 4419
4361 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4420 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4362 4421
4363 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4422 int j;
4364 { 4423 for (j = 0; j < (6 + BannedUsers.Count); j++)
4365 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4424 {
4366 } 4425 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4367 int j = 0; 4426 }
4427 j = 0;
4368 4428
4369 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4429 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4370 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4430 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4371 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4431 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4372 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4432 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4373 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4433 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4374 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4434 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4375 4435
4376 foreach (UUID banned in BannedUsers) 4436 foreach (UUID banned in BannedUsers)
4377 { 4437 {
4378 returnblock[j].Parameter = banned.GetBytes(); j++; 4438 returnblock[j].Parameter = banned.GetBytes(); j++;
4439 }
4440 packet.ParamList = returnblock;
4441 packet.Header.Reliable = true;
4442 OutPacket(packet, ThrottleOutPacketType.Task);
4443
4444 BannedUsers.Clear();
4445 }
4379 } 4446 }
4380 packet.ParamList = returnblock; 4447
4381 packet.Header.Reliable = false;
4382 OutPacket(packet, ThrottleOutPacketType.Task);
4383 } 4448 }
4384 4449
4385 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4450 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4548,7 +4613,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4548 4613
4549 if (landData.SimwideArea > 0) 4614 if (landData.SimwideArea > 0)
4550 { 4615 {
4551 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4616 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4617 // Never report more than sim total capacity
4618 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4619 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4552 updateMessage.SimWideMaxPrims = simulatorCapacity; 4620 updateMessage.SimWideMaxPrims = simulatorCapacity;
4553 } 4621 }
4554 else 4622 else
@@ -4677,14 +4745,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4677 4745
4678 if (notifyCount > 0) 4746 if (notifyCount > 0)
4679 { 4747 {
4680 if (notifyCount > 32) 4748// if (notifyCount > 32)
4681 { 4749// {
4682 m_log.InfoFormat( 4750// m_log.InfoFormat(
4683 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4751// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4684 + " - a developer might want to investigate whether this is a hard limit", 32); 4752// + " - a developer might want to investigate whether this is a hard limit", 32);
4685 4753//
4686 notifyCount = 32; 4754// notifyCount = 32;
4687 } 4755// }
4688 4756
4689 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4757 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4690 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4758 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5212,6 +5280,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5212 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5280 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5213 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5281 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5214 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5282 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5283 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5215 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5284 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5216 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5285 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5217 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5286 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5313,6 +5382,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5313 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5382 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5314 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5383 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5315 (x.ControlFlags != lastarg.ControlFlags) || 5384 (x.ControlFlags != lastarg.ControlFlags) ||
5385 (x.ControlFlags != 0) ||
5316 (x.Far != lastarg.Far) || 5386 (x.Far != lastarg.Far) ||
5317 (x.Flags != lastarg.Flags) || 5387 (x.Flags != lastarg.Flags) ||
5318 (x.State != lastarg.State) || 5388 (x.State != lastarg.State) ||
@@ -5690,7 +5760,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5690 args.Channel = ch; 5760 args.Channel = ch;
5691 args.From = String.Empty; 5761 args.From = String.Empty;
5692 args.Message = Utils.BytesToString(msg); 5762 args.Message = Utils.BytesToString(msg);
5693 args.Type = ChatTypeEnum.Shout; 5763 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5694 args.Position = new Vector3(); 5764 args.Position = new Vector3();
5695 args.Scene = Scene; 5765 args.Scene = Scene;
5696 args.Sender = this; 5766 args.Sender = this;
@@ -9696,7 +9766,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9696 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9766 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9697 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9767 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9698 UpdateMuteListEntry.MuteData.MuteType, 9768 UpdateMuteListEntry.MuteData.MuteType,
9699 UpdateMuteListEntry.AgentData.AgentID); 9769 UpdateMuteListEntry.MuteData.MuteFlags);
9700 return true; 9770 return true;
9701 } 9771 }
9702 return false; 9772 return false;
@@ -9711,8 +9781,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9711 { 9781 {
9712 handlerRemoveMuteListEntry(this, 9782 handlerRemoveMuteListEntry(this,
9713 RemoveMuteListEntry.MuteData.MuteID, 9783 RemoveMuteListEntry.MuteData.MuteID,
9714 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9784 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9715 RemoveMuteListEntry.AgentData.AgentID);
9716 return true; 9785 return true;
9717 } 9786 }
9718 return false; 9787 return false;
@@ -9760,6 +9829,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9760 { 9829 {
9761 return true; 9830 return true;
9762 } 9831 }
9832
9833 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9834 {
9835 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9836
9837 #region Packet Session and User Check
9838 if (m_checkPackets)
9839 {
9840 if (packet.AgentData.SessionID != SessionId ||
9841 packet.AgentData.AgentID != AgentId)
9842 return true;
9843 }
9844 #endregion
9845 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9846 List<InventoryItemBase> items = new List<InventoryItemBase>();
9847 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9848 {
9849 InventoryItemBase b = new InventoryItemBase();
9850 b.ID = n.OldItemID;
9851 b.Folder = n.OldFolderID;
9852 items.Add(b);
9853 }
9854
9855 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9856 if (handlerMoveItemsAndLeaveCopy != null)
9857 {
9858 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9859 }
9860
9861 return true;
9862 }
9763 9863
9764 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9864 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9765 { 9865 {
@@ -10186,6 +10286,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10186 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10286 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10187 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10287 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10188 10288
10289 Scene scene = (Scene)m_scene;
10290 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10291 {
10292 ScenePresence p;
10293 if (scene.TryGetScenePresence(sender.AgentId, out p))
10294 {
10295 if (p.GodLevel >= 200)
10296 {
10297 groupProfileReply.GroupData.OpenEnrollment = true;
10298 groupProfileReply.GroupData.MembershipFee = 0;
10299 }
10300 }
10301 }
10302
10189 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10303 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10190 } 10304 }
10191 return true; 10305 return true;
@@ -10758,11 +10872,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10758 10872
10759 StartLure handlerStartLure = OnStartLure; 10873 StartLure handlerStartLure = OnStartLure;
10760 if (handlerStartLure != null) 10874 if (handlerStartLure != null)
10761 handlerStartLure(startLureRequest.Info.LureType, 10875 {
10762 Utils.BytesToString( 10876 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10763 startLureRequest.Info.Message), 10877 {
10764 startLureRequest.TargetData[0].TargetID, 10878 handlerStartLure(startLureRequest.Info.LureType,
10765 this); 10879 Utils.BytesToString(
10880 startLureRequest.Info.Message),
10881 startLureRequest.TargetData[i].TargetID,
10882 this);
10883 }
10884 }
10766 return true; 10885 return true;
10767 } 10886 }
10768 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10887 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10876,10 +10995,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10876 } 10995 }
10877 #endregion 10996 #endregion
10878 10997
10879 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10998 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10880 if (handlerClassifiedGodDelete != null) 10999 if (handlerClassifiedGodDelete != null)
10881 handlerClassifiedGodDelete( 11000 handlerClassifiedGodDelete(
10882 classifiedGodDelete.Data.ClassifiedID, 11001 classifiedGodDelete.Data.ClassifiedID,
11002 classifiedGodDelete.Data.QueryID,
10883 this); 11003 this);
10884 return true; 11004 return true;
10885 } 11005 }
@@ -11262,7 +11382,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11262 { 11382 {
11263 // It's a ghost! tell the client to delete it from view. 11383 // It's a ghost! tell the client to delete it from view.
11264 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11384 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11265 localId); 11385 new List<uint>() { localId });
11266 } 11386 }
11267 else 11387 else
11268 { 11388 {
@@ -11652,22 +11772,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11652 /// <param name="Pack">OpenMetaverse.packet</param> 11772 /// <param name="Pack">OpenMetaverse.packet</param>
11653 public void ProcessInPacket(Packet packet) 11773 public void ProcessInPacket(Packet packet)
11654 { 11774 {
11655 if (m_debugPacketLevel > 0) 11775 if (m_debugPacketLevel >= 255)
11656 { 11776 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11657 bool outputPacket = true;
11658
11659 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11660 outputPacket = false;
11661
11662 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11663 outputPacket = false;
11664
11665 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11666 outputPacket = false;
11667
11668 if (outputPacket)
11669 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11670 }
11671 11777
11672 if (!ProcessPacketMethod(packet)) 11778 if (!ProcessPacketMethod(packet))
11673 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11779 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11909,7 +12015,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11909 12015
11910// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12016// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11911 12017
12018
12019 //Note, the bool returned from the below function is useless since it is always false.
11912 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12020 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12021
11913 } 12022 }
11914 12023
11915 /// <summary> 12024 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 31cc515..3802482 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,6 +496,8 @@ 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 {
499 if (m_deliverPackets == false) return false;
500
491 OutgoingPacket packet; 501 OutgoingPacket packet;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
@@ -520,7 +530,7 @@ 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 && queue.Dequeue(out packet))
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 // A packet was pulled off the queue. See if we have
526 // enough tokens in the bucket to send it out 536 // enough tokens in the bucket to send it out
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ccad241..ae8251a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -991,7 +991,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
991 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 991 if (m_scene.TryGetClient(udpClient.AgentID, out client))
992 { 992 {
993 client.IsLoggingOut = true; 993 client.IsLoggingOut = true;
994 client.Close(); 994 client.Close(false);
995 } 995 }
996 } 996 }
997 997
@@ -1003,6 +1003,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1003 1003
1004 while (base.IsRunning) 1004 while (base.IsRunning)
1005 { 1005 {
1006 m_scene.ThreadAlive(1);
1006 try 1007 try
1007 { 1008 {
1008 IncomingPacket incomingPacket = null; 1009 IncomingPacket incomingPacket = null;
@@ -1045,6 +1046,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1045 1046
1046 while (base.IsRunning) 1047 while (base.IsRunning)
1047 { 1048 {
1049 m_scene.ThreadAlive(2);
1048 try 1050 try
1049 { 1051 {
1050 m_packetSent = false; 1052 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6eebd9d..d2779ba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,