aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs667
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 397 insertions, 291 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 1da9d5e..de40abd 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; } }
@@ -479,18 +489,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
479 489
480 #region Client Methods 490 #region Client Methods
481 491
492
482 /// <summary> 493 /// <summary>
483 /// Shut down the client view 494 /// Shut down the client view
484 /// </summary> 495 /// </summary>
485 public void Close() 496 public void Close()
486 { 497 {
498 Close(true);
499 }
500
501 /// <summary>
502 /// Shut down the client view
503 /// </summary>
504 public void Close(bool sendStop)
505 {
487 m_log.DebugFormat( 506 m_log.DebugFormat(
488 "[CLIENT]: Close has been called for {0} attached to scene {1}", 507 "[CLIENT]: Close has been called for {0} attached to scene {1}",
489 Name, m_scene.RegionInfo.RegionName); 508 Name, m_scene.RegionInfo.RegionName);
490 509
491 // Send the STOP packet 510 if (sendStop)
492 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 511 {
493 OutPacket(disable, ThrottleOutPacketType.Unknown); 512 // Send the STOP packet
513 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
514 OutPacket(disable, ThrottleOutPacketType.Unknown);
515 }
494 516
495 IsActive = false; 517 IsActive = false;
496 518
@@ -771,7 +793,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
771 reply.ChatData.OwnerID = fromAgentID; 793 reply.ChatData.OwnerID = fromAgentID;
772 reply.ChatData.SourceID = fromAgentID; 794 reply.ChatData.SourceID = fromAgentID;
773 795
774 OutPacket(reply, ThrottleOutPacketType.Task); 796 OutPacket(reply, ThrottleOutPacketType.Unknown);
775 } 797 }
776 798
777 /// <summary> 799 /// <summary>
@@ -1057,6 +1079,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1057 public virtual void SendLayerData(float[] map) 1079 public virtual void SendLayerData(float[] map)
1058 { 1080 {
1059 Util.FireAndForget(DoSendLayerData, map); 1081 Util.FireAndForget(DoSendLayerData, map);
1082
1083 // Send it sync, and async. It's not that much data
1084 // and it improves user experience just so much!
1085 DoSendLayerData(map);
1060 } 1086 }
1061 1087
1062 /// <summary> 1088 /// <summary>
@@ -1069,16 +1095,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1069 1095
1070 try 1096 try
1071 { 1097 {
1072 //for (int y = 0; y < 16; y++) 1098 for (int y = 0; y < 16; y++)
1073 //{ 1099 {
1074 // for (int x = 0; x < 16; x++) 1100 for (int x = 0; x < 16; x+=4)
1075 // { 1101 {
1076 // SendLayerData(x, y, map); 1102 SendLayerPacket(x, y, map);
1077 // } 1103 }
1078 //} 1104 }
1079
1080 // Send LayerData in a spiral pattern. Fun!
1081 SendLayerTopRight(map, 0, 0, 15, 15);
1082 } 1105 }
1083 catch (Exception e) 1106 catch (Exception e)
1084 { 1107 {
@@ -1086,51 +1109,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1086 } 1109 }
1087 } 1110 }
1088 1111
1089 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1090 {
1091 // Row
1092 for (int i = x1; i <= x2; i++)
1093 SendLayerData(i, y1, map);
1094
1095 // Column
1096 for (int j = y1 + 1; j <= y2; j++)
1097 SendLayerData(x2, j, map);
1098
1099 if (x2 - x1 > 0)
1100 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1101 }
1102
1103 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1104 {
1105 // Row in reverse
1106 for (int i = x2; i >= x1; i--)
1107 SendLayerData(i, y2, map);
1108
1109 // Column in reverse
1110 for (int j = y2 - 1; j >= y1; j--)
1111 SendLayerData(x1, j, map);
1112
1113 if (x2 - x1 > 0)
1114 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1115 }
1116
1117 /// <summary> 1112 /// <summary>
1118 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1113 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1119 /// </summary> 1114 /// </summary>
1120 /// <param name="map">heightmap</param> 1115 /// <param name="map">heightmap</param>
1121 /// <param name="px">X coordinate for patches 0..12</param> 1116 /// <param name="px">X coordinate for patches 0..12</param>
1122 /// <param name="py">Y coordinate for patches 0..15</param> 1117 /// <param name="py">Y coordinate for patches 0..15</param>
1123 // private void SendLayerPacket(float[] map, int y, int x) 1118 private void SendLayerPacket(int x, int y, float[] map)
1124 // { 1119 {
1125 // int[] patches = new int[4]; 1120 int[] patches = new int[4];
1126 // patches[0] = x + 0 + y * 16; 1121 patches[0] = x + 0 + y * 16;
1127 // patches[1] = x + 1 + y * 16; 1122 patches[1] = x + 1 + y * 16;
1128 // patches[2] = x + 2 + y * 16; 1123 patches[2] = x + 2 + y * 16;
1129 // patches[3] = x + 3 + y * 16; 1124 patches[3] = x + 3 + y * 16;
1130 1125
1131 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1126 float[] heightmap = (map.Length == 65536) ?
1132 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1127 map :
1133 // } 1128 LLHeightFieldMoronize(map);
1129
1130 try
1131 {
1132 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1133 OutPacket(layerpack, ThrottleOutPacketType.Land);
1134 }
1135 catch
1136 {
1137 for (int px = x ; px < x + 4 ; px++)
1138 SendLayerData(px, y, map);
1139 }
1140 }
1134 1141
1135 /// <summary> 1142 /// <summary>
1136 /// Sends a specified patch to a client 1143 /// Sends a specified patch to a client
@@ -1150,7 +1157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1150 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1157 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1151 layerpack.Header.Reliable = true; 1158 layerpack.Header.Reliable = true;
1152 1159
1153 OutPacket(layerpack, ThrottleOutPacketType.Land); 1160 OutPacket(layerpack, ThrottleOutPacketType.Task);
1154 } 1161 }
1155 catch (Exception e) 1162 catch (Exception e)
1156 { 1163 {
@@ -1510,38 +1517,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1510 OutPacket(pc, ThrottleOutPacketType.Unknown); 1517 OutPacket(pc, ThrottleOutPacketType.Unknown);
1511 } 1518 }
1512 1519
1513 public void SendKillObject(ulong regionHandle, uint localID) 1520 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1514 { 1521 {
1515// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1522// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1516 1523
1517 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1524 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1518 // TODO: don't create new blocks if recycling an old packet 1525 // TODO: don't create new blocks if recycling an old packet
1519 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1526 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1520 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1527 for (int i = 0 ; i < localIDs.Count ; i++ )
1521 kill.ObjectData[0].ID = localID; 1528 {
1529 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1530 kill.ObjectData[i].ID = localIDs[i];
1531 }
1522 kill.Header.Reliable = true; 1532 kill.Header.Reliable = true;
1523 kill.Header.Zerocoded = true; 1533 kill.Header.Zerocoded = true;
1524 1534
1525 if (m_scene.GetScenePresence(localID) == null) 1535 lock (m_killRecord)
1526 { 1536 {
1527 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1537 if (localIDs.Count == 1)
1528 // condition where a kill can be processed before an out-of-date update for the same object.
1529 lock (m_killRecord)
1530 { 1538 {
1531 m_killRecord.Add(localID); 1539 if (m_scene.GetScenePresence(localIDs[0]) != null)
1532 1540 {
1533 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1541 OutPacket(kill, ThrottleOutPacketType.State);
1534 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1542 return;
1535 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1543 }
1536 // scene objects in a viewer until that viewer is relogged in. 1544 m_killRecord.Add(localIDs[0]);
1537 OutPacket(kill, ThrottleOutPacketType.Task); 1545 }
1546 else
1547 {
1548 lock (m_entityUpdates.SyncRoot)
1549 {
1550 foreach (uint localID in localIDs)
1551 m_killRecord.Add(localID);
1552 }
1538 } 1553 }
1539 } 1554 }
1540 else 1555
1541 { 1556 // The throttle queue used here must match that being used for
1542 // OutPacket(kill, ThrottleOutPacketType.State); 1557 // updates. Otherwise, there is a chance that a kill packet put
1543 OutPacket(kill, ThrottleOutPacketType.Task); 1558 // on a separate queue will be sent to the client before an
1544 } 1559 // existing update packet on another queue. Receiving updates
1560 // after kills results in unowned and undeletable
1561 // scene objects in a viewer until that viewer is relogged in.
1562 OutPacket(kill, ThrottleOutPacketType.Task);
1545 } 1563 }
1546 1564
1547 /// <summary> 1565 /// <summary>
@@ -2254,6 +2272,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2254 OutPacket(sound, ThrottleOutPacketType.Task); 2272 OutPacket(sound, ThrottleOutPacketType.Task);
2255 } 2273 }
2256 2274
2275 public void SendTransferAbort(TransferRequestPacket transferRequest)
2276 {
2277 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2278 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2279 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2280 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2281 OutPacket(abort, ThrottleOutPacketType.Task);
2282 }
2283
2257 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2284 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2258 { 2285 {
2259 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2286 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3558,7 +3585,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3558 /// </summary> 3585 /// </summary>
3559 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3586 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3560 { 3587 {
3561 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3588 if (entity is SceneObjectPart)
3589 {
3590 SceneObjectPart e = (SceneObjectPart)entity;
3591 SceneObjectGroup g = e.ParentGroup;
3592 if (g.RootPart.Shape.State > 30) // HUD
3593 if (g.OwnerID != AgentId)
3594 return; // Don't send updates for other people's HUDs
3595 }
3596
3562 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3597 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3563 3598
3564 lock (m_entityUpdates.SyncRoot) 3599 lock (m_entityUpdates.SyncRoot)
@@ -3625,211 +3660,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3625 3660
3626 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3661 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3627 // condition where a kill can be processed before an out-of-date update for the same object. 3662 // condition where a kill can be processed before an out-of-date update for the same object.
3628 lock (m_killRecord) 3663 float avgTimeDilation = 1.0f;
3664 IEntityUpdate iupdate;
3665 Int32 timeinqueue; // this is just debugging code & can be dropped later
3666
3667 while (updatesThisCall < maxUpdates)
3629 { 3668 {
3630 float avgTimeDilation = 1.0f; 3669 lock (m_entityUpdates.SyncRoot)
3631 IEntityUpdate iupdate; 3670 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3632 Int32 timeinqueue; // this is just debugging code & can be dropped later 3671 break;
3633
3634 while (updatesThisCall < maxUpdates)
3635 {
3636 lock (m_entityUpdates.SyncRoot)
3637 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3638 break;
3639 3672
3640 EntityUpdate update = (EntityUpdate)iupdate; 3673 EntityUpdate update = (EntityUpdate)iupdate;
3641 3674
3642 avgTimeDilation += update.TimeDilation; 3675 avgTimeDilation += update.TimeDilation;
3643 avgTimeDilation *= 0.5f; 3676 avgTimeDilation *= 0.5f;
3644 3677
3645 if (update.Entity is SceneObjectPart) 3678 if (update.Entity is SceneObjectPart)
3679 {
3680 SceneObjectPart part = (SceneObjectPart)update.Entity;
3681
3682 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3683 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3684 // safety measure.
3685 //
3686 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3687 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3688 // updates and kills on different threads with different scheduling strategies, hence this protection.
3689 //
3690 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3691 // after the root prim has been deleted.
3692 lock (m_killRecord)
3646 { 3693 {
3647 SceneObjectPart part = (SceneObjectPart)update.Entity;
3648
3649 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3650 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3651 // safety measure.
3652 //
3653 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3654 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3655 // updates and kills on different threads with different scheduling strategies, hence this protection.
3656 //
3657 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3658 // after the root prim has been deleted.
3659 if (m_killRecord.Contains(part.LocalId)) 3694 if (m_killRecord.Contains(part.LocalId))
3660 {
3661 // m_log.WarnFormat(
3662 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3663 // part.LocalId, Name);
3664 continue; 3695 continue;
3665 } 3696 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3666 3697 continue;
3667 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3698 }
3699
3700 if (part.ParentGroup.IsDeleted)
3701 continue;
3702
3703 if (part.ParentGroup.IsAttachment)
3704 { // Someone else's HUD, why are we getting these?
3705 if (part.ParentGroup.OwnerID != AgentId &&
3706 part.ParentGroup.RootPart.Shape.State >= 30)
3707 continue;
3708 ScenePresence sp;
3709 // Owner is not in the sim, don't update it to
3710 // anyone
3711 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3712 continue;
3713
3714 List<SceneObjectGroup> atts = sp.Attachments;
3715 bool found = false;
3716 foreach (SceneObjectGroup att in atts)
3668 { 3717 {
3669 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3718 if (att == part.ParentGroup)
3670 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3671 { 3719 {
3672 part.Shape.LightEntry = false; 3720 found = true;
3721 break;
3673 } 3722 }
3674 } 3723 }
3724
3725 // It's an attachment of a valid avatar, but
3726 // doesn't seem to be attached, skip
3727 if (!found)
3728 continue;
3675 } 3729 }
3676 3730 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3677 ++updatesThisCall;
3678
3679 #region UpdateFlags to packet type conversion
3680
3681 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3682
3683 bool canUseCompressed = true;
3684 bool canUseImproved = true;
3685
3686 // Compressed object updates only make sense for LL primitives
3687 if (!(update.Entity is SceneObjectPart))
3688 {
3689 canUseCompressed = false;
3690 }
3691
3692 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3693 {
3694 canUseCompressed = false;
3695 canUseImproved = false;
3696 }
3697 else
3698 { 3731 {
3699 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3732 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3700 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3733 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3701 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3702 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3703 { 3734 {
3704 canUseCompressed = false; 3735 part.Shape.LightEntry = false;
3705 }
3706
3707 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3708 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3709 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3710 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3711 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3712 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3713 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3714 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3715 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3716 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3717 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3718 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3719 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3720 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3721 {
3722 canUseImproved = false;
3723 } 3736 }
3724 } 3737 }
3725 3738 }
3726 #endregion UpdateFlags to packet type conversion 3739
3727 3740 ++updatesThisCall;
3728 #region Block Construction 3741
3729 3742 #region UpdateFlags to packet type conversion
3730 // TODO: Remove this once we can build compressed updates 3743
3744 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3745
3746 bool canUseCompressed = true;
3747 bool canUseImproved = true;
3748
3749 // Compressed object updates only make sense for LL primitives
3750 if (!(update.Entity is SceneObjectPart))
3751 {
3731 canUseCompressed = false; 3752 canUseCompressed = false;
3732 3753 }
3733 if (!canUseImproved && !canUseCompressed) 3754
3734 { 3755 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3735 if (update.Entity is ScenePresence) 3756 {
3736 { 3757 canUseCompressed = false;
3737 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3758 canUseImproved = false;
3738 objectUpdates.Value.Add(update); 3759 }
3739 } 3760 else
3740 else 3761 {
3741 { 3762 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3742 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3763 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3743 objectUpdates.Value.Add(update); 3764 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3744 } 3765 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3745 }
3746 else if (!canUseImproved)
3747 { 3766 {
3748 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3767 canUseCompressed = false;
3749 compressedUpdates.Value.Add(update);
3750 } 3768 }
3751 else 3769
3770 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3775 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3776 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3777 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3778 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3779 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3780 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3781 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3782 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3783 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3752 { 3784 {
3753 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3785 canUseImproved = false;
3754 {
3755 // Self updates go into a special list
3756 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3757 terseAgentUpdates.Value.Add(update);
3758 }
3759 else
3760 {
3761 // Everything else goes here
3762 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3763 terseUpdates.Value.Add(update);
3764 }
3765 } 3786 }
3766
3767 #endregion Block Construction
3768 } 3787 }
3769
3770
3771 #region Packet Sending
3772 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3773 3788
3774 if (terseAgentUpdateBlocks.IsValueCreated) 3789 #endregion UpdateFlags to packet type conversion
3775 {
3776 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3777 3790
3778 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3791 #region Block Construction
3779 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3780 packet.RegionData.TimeDilation = timeDilation;
3781 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3782 3792
3783 for (int i = 0; i < blocks.Count; i++) 3793 // TODO: Remove this once we can build compressed updates
3784 packet.ObjectData[i] = blocks[i]; 3794 canUseCompressed = false;
3785 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3786 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3787 }
3788 3795
3789 if (objectUpdateBlocks.IsValueCreated) 3796 if (!canUseImproved && !canUseCompressed)
3790 { 3797 {
3791 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3798 if (update.Entity is ScenePresence)
3792 3799 {
3793 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3800 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3794 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3801 }
3795 packet.RegionData.TimeDilation = timeDilation; 3802 else
3796 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3803 {
3797 3804 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3798 for (int i = 0; i < blocks.Count; i++) 3805 }
3799 packet.ObjectData[i] = blocks[i];
3800 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3801 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3802 } 3806 }
3803 3807 else if (!canUseImproved)
3804 if (compressedUpdateBlocks.IsValueCreated)
3805 { 3808 {
3806 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3809 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3807
3808 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3809 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3810 packet.RegionData.TimeDilation = timeDilation;
3811 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3812
3813 for (int i = 0; i < blocks.Count; i++)
3814 packet.ObjectData[i] = blocks[i];
3815 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3816 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3817 } 3810 }
3818 3811 else
3819 if (terseUpdateBlocks.IsValueCreated)
3820 { 3812 {
3821 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3813 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3822 3814 // Self updates go into a special list
3823 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3815 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3824 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3816 else
3825 packet.RegionData.TimeDilation = timeDilation; 3817 // Everything else goes here
3826 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3818 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3827
3828 for (int i = 0; i < blocks.Count; i++)
3829 packet.ObjectData[i] = blocks[i];
3830 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3831 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3832 } 3819 }
3820
3821 #endregion Block Construction
3822 }
3823
3824 #region Packet Sending
3825
3826 const float TIME_DILATION = 1.0f;
3827 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3828
3829 if (terseAgentUpdateBlocks.IsValueCreated)
3830 {
3831 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3832
3833 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3834 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3835 packet.RegionData.TimeDilation = timeDilation;
3836 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3837
3838 for (int i = 0; i < blocks.Count; i++)
3839 packet.ObjectData[i] = blocks[i];
3840
3841 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3842 }
3843
3844 if (objectUpdateBlocks.IsValueCreated)
3845 {
3846 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3847
3848 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3849 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3850 packet.RegionData.TimeDilation = timeDilation;
3851 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3852
3853 for (int i = 0; i < blocks.Count; i++)
3854 packet.ObjectData[i] = blocks[i];
3855
3856 OutPacket(packet, ThrottleOutPacketType.Task, true);
3857 }
3858
3859 if (compressedUpdateBlocks.IsValueCreated)
3860 {
3861 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3862
3863 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3864 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3865 packet.RegionData.TimeDilation = timeDilation;
3866 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3867
3868 for (int i = 0; i < blocks.Count; i++)
3869 packet.ObjectData[i] = blocks[i];
3870
3871 OutPacket(packet, ThrottleOutPacketType.Task, true);
3872 }
3873
3874 if (terseUpdateBlocks.IsValueCreated)
3875 {
3876 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3877
3878 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3879 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3880 packet.RegionData.TimeDilation = timeDilation;
3881 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3882
3883 for (int i = 0; i < blocks.Count; i++)
3884 packet.ObjectData[i] = blocks[i];
3885
3886 OutPacket(packet, ThrottleOutPacketType.Task, true);
3833 } 3887 }
3834 3888
3835 #endregion Packet Sending 3889 #endregion Packet Sending
@@ -4641,14 +4695,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4641 4695
4642 if (notifyCount > 0) 4696 if (notifyCount > 0)
4643 { 4697 {
4644 if (notifyCount > 32) 4698// if (notifyCount > 32)
4645 { 4699// {
4646 m_log.InfoFormat( 4700// m_log.InfoFormat(
4647 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4701// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4648 + " - a developer might want to investigate whether this is a hard limit", 32); 4702// + " - a developer might want to investigate whether this is a hard limit", 32);
4649 4703//
4650 notifyCount = 32; 4704// notifyCount = 32;
4651 } 4705// }
4652 4706
4653 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4707 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4654 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4708 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5164,6 +5218,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5164 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5218 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5165 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5219 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5166 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5220 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5221 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5167 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5222 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5168 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5223 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5169 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5224 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5263,6 +5318,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5263 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5318 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5264 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5319 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5265 (x.ControlFlags != lastarg.ControlFlags) || 5320 (x.ControlFlags != lastarg.ControlFlags) ||
5321 (x.ControlFlags != 0) ||
5266 (x.Far != lastarg.Far) || 5322 (x.Far != lastarg.Far) ||
5267 (x.Flags != lastarg.Flags) || 5323 (x.Flags != lastarg.Flags) ||
5268 (x.State != lastarg.State) || 5324 (x.State != lastarg.State) ||
@@ -5636,7 +5692,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5636 args.Channel = ch; 5692 args.Channel = ch;
5637 args.From = String.Empty; 5693 args.From = String.Empty;
5638 args.Message = Utils.BytesToString(msg); 5694 args.Message = Utils.BytesToString(msg);
5639 args.Type = ChatTypeEnum.Shout; 5695 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5640 args.Position = new Vector3(); 5696 args.Position = new Vector3();
5641 args.Scene = Scene; 5697 args.Scene = Scene;
5642 args.Sender = this; 5698 args.Sender = this;
@@ -9623,7 +9679,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9623 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9679 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9624 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9680 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9625 UpdateMuteListEntry.MuteData.MuteType, 9681 UpdateMuteListEntry.MuteData.MuteType,
9626 UpdateMuteListEntry.AgentData.AgentID); 9682 UpdateMuteListEntry.MuteData.MuteFlags);
9627 return true; 9683 return true;
9628 } 9684 }
9629 return false; 9685 return false;
@@ -9638,8 +9694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9638 { 9694 {
9639 handlerRemoveMuteListEntry(this, 9695 handlerRemoveMuteListEntry(this,
9640 RemoveMuteListEntry.MuteData.MuteID, 9696 RemoveMuteListEntry.MuteData.MuteID,
9641 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9697 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9642 RemoveMuteListEntry.AgentData.AgentID);
9643 return true; 9698 return true;
9644 } 9699 }
9645 return false; 9700 return false;
@@ -9687,6 +9742,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9687 { 9742 {
9688 return true; 9743 return true;
9689 } 9744 }
9745
9746 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9747 {
9748 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9749
9750 #region Packet Session and User Check
9751 if (m_checkPackets)
9752 {
9753 if (packet.AgentData.SessionID != SessionId ||
9754 packet.AgentData.AgentID != AgentId)
9755 return true;
9756 }
9757 #endregion
9758 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9759 List<InventoryItemBase> items = new List<InventoryItemBase>();
9760 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9761 {
9762 InventoryItemBase b = new InventoryItemBase();
9763 b.ID = n.OldItemID;
9764 b.Folder = n.OldFolderID;
9765 items.Add(b);
9766 }
9767
9768 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9769 if (handlerMoveItemsAndLeaveCopy != null)
9770 {
9771 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9772 }
9773
9774 return true;
9775 }
9690 9776
9691 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9777 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9692 { 9778 {
@@ -10113,6 +10199,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10113 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10199 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10114 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10200 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10115 10201
10202 Scene scene = (Scene)m_scene;
10203 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10204 {
10205 ScenePresence p;
10206 if (scene.TryGetScenePresence(sender.AgentId, out p))
10207 {
10208 if (p.GodLevel >= 200)
10209 {
10210 groupProfileReply.GroupData.OpenEnrollment = true;
10211 groupProfileReply.GroupData.MembershipFee = 0;
10212 }
10213 }
10214 }
10215
10116 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10216 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10117 } 10217 }
10118 return true; 10218 return true;
@@ -10685,11 +10785,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10685 10785
10686 StartLure handlerStartLure = OnStartLure; 10786 StartLure handlerStartLure = OnStartLure;
10687 if (handlerStartLure != null) 10787 if (handlerStartLure != null)
10688 handlerStartLure(startLureRequest.Info.LureType, 10788 {
10689 Utils.BytesToString( 10789 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10690 startLureRequest.Info.Message), 10790 {
10691 startLureRequest.TargetData[0].TargetID, 10791 handlerStartLure(startLureRequest.Info.LureType,
10692 this); 10792 Utils.BytesToString(
10793 startLureRequest.Info.Message),
10794 startLureRequest.TargetData[i].TargetID,
10795 this);
10796 }
10797 }
10693 return true; 10798 return true;
10694 } 10799 }
10695 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10800 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10803,10 +10908,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10803 } 10908 }
10804 #endregion 10909 #endregion
10805 10910
10806 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10911 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10807 if (handlerClassifiedGodDelete != null) 10912 if (handlerClassifiedGodDelete != null)
10808 handlerClassifiedGodDelete( 10913 handlerClassifiedGodDelete(
10809 classifiedGodDelete.Data.ClassifiedID, 10914 classifiedGodDelete.Data.ClassifiedID,
10915 classifiedGodDelete.Data.QueryID,
10810 this); 10916 this);
10811 return true; 10917 return true;
10812 } 10918 }
@@ -11184,7 +11290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11184 { 11290 {
11185 // It's a ghost! tell the client to delete it from view. 11291 // It's a ghost! tell the client to delete it from view.
11186 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11292 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11187 localId); 11293 new List<uint>() { localId });
11188 } 11294 }
11189 else 11295 else
11190 { 11296 {
@@ -11573,22 +11679,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11573 /// <param name="Pack">OpenMetaverse.packet</param> 11679 /// <param name="Pack">OpenMetaverse.packet</param>
11574 public void ProcessInPacket(Packet packet) 11680 public void ProcessInPacket(Packet packet)
11575 { 11681 {
11576 if (m_debugPacketLevel > 0) 11682 if (m_debugPacketLevel >= 255)
11577 { 11683 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11578 bool outputPacket = true;
11579
11580 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11581 outputPacket = false;
11582
11583 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11584 outputPacket = false;
11585
11586 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11587 outputPacket = false;
11588
11589 if (outputPacket)
11590 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11591 }
11592 11684
11593 if (!ProcessPacketMethod(packet)) 11685 if (!ProcessPacketMethod(packet))
11594 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11686 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11830,7 +11922,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11830 11922
11831// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11923// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11832 11924
11925
11926 //Note, the bool returned from the below function is useless since it is always false.
11833 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11927 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11928
11834 } 11929 }
11835 11930
11836 /// <summary> 11931 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ca5501d..95a8e23 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
@@ -430,6 +431,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
430 if (category >= 0 && category < m_packetOutboxes.Length) 431 if (category >= 0 && category < m_packetOutboxes.Length)
431 { 432 {
432 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 433 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
434
435 if (m_deliverPackets == false)
436 {
437 queue.Enqueue(packet);
438 return true;
439 }
440
433 TokenBucket bucket = m_throttleCategories[category]; 441 TokenBucket bucket = m_throttleCategories[category];
434 442
435 // Don't send this packet if there is already a packet waiting in the queue 443 // Don't send this packet if there is already a packet waiting in the queue
@@ -479,6 +487,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
479 /// <returns>True if any packets were sent, otherwise false</returns> 487 /// <returns>True if any packets were sent, otherwise false</returns>
480 public bool DequeueOutgoing() 488 public bool DequeueOutgoing()
481 { 489 {
490 if (m_deliverPackets == false) return false;
491
482 OutgoingPacket packet; 492 OutgoingPacket packet;
483 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 493 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
484 TokenBucket bucket; 494 TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index aff90c5..ab6674d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -960,7 +960,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
960 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 960 if (m_scene.TryGetClient(udpClient.AgentID, out client))
961 { 961 {
962 client.IsLoggingOut = true; 962 client.IsLoggingOut = true;
963 client.Close(); 963 client.Close(false);
964 } 964 }
965 } 965 }
966 966
@@ -972,6 +972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
972 972
973 while (base.IsRunning) 973 while (base.IsRunning)
974 { 974 {
975 m_scene.ThreadAlive(1);
975 try 976 try
976 { 977 {
977 IncomingPacket incomingPacket = null; 978 IncomingPacket incomingPacket = null;
@@ -1014,6 +1015,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1014 1015
1015 while (base.IsRunning) 1016 while (base.IsRunning)
1016 { 1017 {
1018 m_scene.ThreadAlive(2);
1017 try 1019 try
1018 { 1020 {
1019 m_packetSent = false; 1021 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,