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.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 024ebce..d579f91 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];
@@ -5218,6 +5286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5218 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5286 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5219 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5287 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5220 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5288 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5289 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5221 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5290 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5222 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5291 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5223 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5292 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5319,6 +5388,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5319 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5388 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5320 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5389 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5321 (x.ControlFlags != lastarg.ControlFlags) || 5390 (x.ControlFlags != lastarg.ControlFlags) ||
5391 (x.ControlFlags != 0) ||
5322 (x.Far != lastarg.Far) || 5392 (x.Far != lastarg.Far) ||
5323 (x.Flags != lastarg.Flags) || 5393 (x.Flags != lastarg.Flags) ||
5324 (x.State != lastarg.State) || 5394 (x.State != lastarg.State) ||
@@ -5696,7 +5766,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5696 args.Channel = ch; 5766 args.Channel = ch;
5697 args.From = String.Empty; 5767 args.From = String.Empty;
5698 args.Message = Utils.BytesToString(msg); 5768 args.Message = Utils.BytesToString(msg);
5699 args.Type = ChatTypeEnum.Shout; 5769 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5700 args.Position = new Vector3(); 5770 args.Position = new Vector3();
5701 args.Scene = Scene; 5771 args.Scene = Scene;
5702 args.Sender = this; 5772 args.Sender = this;
@@ -9702,7 +9772,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9702 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9772 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9703 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9773 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9704 UpdateMuteListEntry.MuteData.MuteType, 9774 UpdateMuteListEntry.MuteData.MuteType,
9705 UpdateMuteListEntry.AgentData.AgentID); 9775 UpdateMuteListEntry.MuteData.MuteFlags);
9706 return true; 9776 return true;
9707 } 9777 }
9708 return false; 9778 return false;
@@ -9717,8 +9787,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9717 { 9787 {
9718 handlerRemoveMuteListEntry(this, 9788 handlerRemoveMuteListEntry(this,
9719 RemoveMuteListEntry.MuteData.MuteID, 9789 RemoveMuteListEntry.MuteData.MuteID,
9720 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9790 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9721 RemoveMuteListEntry.AgentData.AgentID);
9722 return true; 9791 return true;
9723 } 9792 }
9724 return false; 9793 return false;
@@ -9766,6 +9835,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9766 { 9835 {
9767 return true; 9836 return true;
9768 } 9837 }
9838
9839 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9840 {
9841 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9842
9843 #region Packet Session and User Check
9844 if (m_checkPackets)
9845 {
9846 if (packet.AgentData.SessionID != SessionId ||
9847 packet.AgentData.AgentID != AgentId)
9848 return true;
9849 }
9850 #endregion
9851 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9852 List<InventoryItemBase> items = new List<InventoryItemBase>();
9853 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9854 {
9855 InventoryItemBase b = new InventoryItemBase();
9856 b.ID = n.OldItemID;
9857 b.Folder = n.OldFolderID;
9858 items.Add(b);
9859 }
9860
9861 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9862 if (handlerMoveItemsAndLeaveCopy != null)
9863 {
9864 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9865 }
9866
9867 return true;
9868 }
9769 9869
9770 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9870 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9771 { 9871 {
@@ -10192,6 +10292,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10192 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10292 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10193 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10293 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10194 10294
10295 Scene scene = (Scene)m_scene;
10296 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10297 {
10298 ScenePresence p;
10299 if (scene.TryGetScenePresence(sender.AgentId, out p))
10300 {
10301 if (p.GodLevel >= 200)
10302 {
10303 groupProfileReply.GroupData.OpenEnrollment = true;
10304 groupProfileReply.GroupData.MembershipFee = 0;
10305 }
10306 }
10307 }
10308
10195 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10309 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10196 } 10310 }
10197 return true; 10311 return true;
@@ -10764,11 +10878,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10764 10878
10765 StartLure handlerStartLure = OnStartLure; 10879 StartLure handlerStartLure = OnStartLure;
10766 if (handlerStartLure != null) 10880 if (handlerStartLure != null)
10767 handlerStartLure(startLureRequest.Info.LureType, 10881 {
10768 Utils.BytesToString( 10882 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10769 startLureRequest.Info.Message), 10883 {
10770 startLureRequest.TargetData[0].TargetID, 10884 handlerStartLure(startLureRequest.Info.LureType,
10771 this); 10885 Utils.BytesToString(
10886 startLureRequest.Info.Message),
10887 startLureRequest.TargetData[i].TargetID,
10888 this);
10889 }
10890 }
10772 return true; 10891 return true;
10773 } 10892 }
10774 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10893 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10882,10 +11001,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10882 } 11001 }
10883 #endregion 11002 #endregion
10884 11003
10885 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11004 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10886 if (handlerClassifiedGodDelete != null) 11005 if (handlerClassifiedGodDelete != null)
10887 handlerClassifiedGodDelete( 11006 handlerClassifiedGodDelete(
10888 classifiedGodDelete.Data.ClassifiedID, 11007 classifiedGodDelete.Data.ClassifiedID,
11008 classifiedGodDelete.Data.QueryID,
10889 this); 11009 this);
10890 return true; 11010 return true;
10891 } 11011 }
@@ -11268,7 +11388,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11268 { 11388 {
11269 // It's a ghost! tell the client to delete it from view. 11389 // It's a ghost! tell the client to delete it from view.
11270 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11390 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11271 localId); 11391 new List<uint>() { localId });
11272 } 11392 }
11273 else 11393 else
11274 { 11394 {
@@ -11658,22 +11778,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11658 /// <param name="Pack">OpenMetaverse.packet</param> 11778 /// <param name="Pack">OpenMetaverse.packet</param>
11659 public void ProcessInPacket(Packet packet) 11779 public void ProcessInPacket(Packet packet)
11660 { 11780 {
11661 if (m_debugPacketLevel > 0) 11781 if (m_debugPacketLevel >= 255)
11662 { 11782 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11663 bool outputPacket = true;
11664
11665 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11666 outputPacket = false;
11667
11668 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11669 outputPacket = false;
11670
11671 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11672 outputPacket = false;
11673
11674 if (outputPacket)
11675 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11676 }
11677 11783
11678 if (!ProcessPacketMethod(packet)) 11784 if (!ProcessPacketMethod(packet))
11679 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11785 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11915,7 +12021,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11915 12021
11916// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12022// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11917 12023
12024
12025 //Note, the bool returned from the below function is useless since it is always false.
11918 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12026 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12027
11919 } 12028 }
11920 12029
11921 /// <summary> 12030 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..c951071 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,