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 43903ce..910fb76 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 {
@@ -1511,38 +1518,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1511 OutPacket(pc, ThrottleOutPacketType.Unknown); 1518 OutPacket(pc, ThrottleOutPacketType.Unknown);
1512 } 1519 }
1513 1520
1514 public void SendKillObject(ulong regionHandle, uint localID) 1521 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1515 { 1522 {
1516// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1523// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1517 1524
1518 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1525 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1519 // TODO: don't create new blocks if recycling an old packet 1526 // TODO: don't create new blocks if recycling an old packet
1520 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1527 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1521 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1528 for (int i = 0 ; i < localIDs.Count ; i++ )
1522 kill.ObjectData[0].ID = localID; 1529 {
1530 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1531 kill.ObjectData[i].ID = localIDs[i];
1532 }
1523 kill.Header.Reliable = true; 1533 kill.Header.Reliable = true;
1524 kill.Header.Zerocoded = true; 1534 kill.Header.Zerocoded = true;
1525 1535
1526 if (m_scene.GetScenePresence(localID) == null) 1536 lock (m_killRecord)
1527 { 1537 {
1528 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1538 if (localIDs.Count == 1)
1529 // condition where a kill can be processed before an out-of-date update for the same object.
1530 lock (m_killRecord)
1531 { 1539 {
1532 m_killRecord.Add(localID); 1540 if (m_scene.GetScenePresence(localIDs[0]) != null)
1533 1541 {
1534 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1542 OutPacket(kill, ThrottleOutPacketType.State);
1535 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1543 return;
1536 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1544 }
1537 // scene objects in a viewer until that viewer is relogged in. 1545 m_killRecord.Add(localIDs[0]);
1538 OutPacket(kill, ThrottleOutPacketType.Task); 1546 }
1547 else
1548 {
1549 lock (m_entityUpdates.SyncRoot)
1550 {
1551 foreach (uint localID in localIDs)
1552 m_killRecord.Add(localID);
1553 }
1539 } 1554 }
1540 } 1555 }
1541 else 1556
1542 { 1557 // The throttle queue used here must match that being used for
1543 // OutPacket(kill, ThrottleOutPacketType.State); 1558 // updates. Otherwise, there is a chance that a kill packet put
1544 OutPacket(kill, ThrottleOutPacketType.Task); 1559 // on a separate queue will be sent to the client before an
1545 } 1560 // existing update packet on another queue. Receiving updates
1561 // after kills results in unowned and undeletable
1562 // scene objects in a viewer until that viewer is relogged in.
1563 OutPacket(kill, ThrottleOutPacketType.Task);
1546 } 1564 }
1547 1565
1548 /// <summary> 1566 /// <summary>
@@ -2255,6 +2273,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2255 OutPacket(sound, ThrottleOutPacketType.Task); 2273 OutPacket(sound, ThrottleOutPacketType.Task);
2256 } 2274 }
2257 2275
2276 public void SendTransferAbort(TransferRequestPacket transferRequest)
2277 {
2278 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2279 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2280 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2281 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2282 OutPacket(abort, ThrottleOutPacketType.Task);
2283 }
2284
2258 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2285 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2259 { 2286 {
2260 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2287 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3559,7 +3586,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3559 /// </summary> 3586 /// </summary>
3560 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3587 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3561 { 3588 {
3562 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3589 if (entity is SceneObjectPart)
3590 {
3591 SceneObjectPart e = (SceneObjectPart)entity;
3592 SceneObjectGroup g = e.ParentGroup;
3593 if (g.RootPart.Shape.State > 30) // HUD
3594 if (g.OwnerID != AgentId)
3595 return; // Don't send updates for other people's HUDs
3596 }
3597
3563 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3598 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3564 3599
3565 lock (m_entityUpdates.SyncRoot) 3600 lock (m_entityUpdates.SyncRoot)
@@ -3626,211 +3661,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3626 3661
3627 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3662 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3628 // condition where a kill can be processed before an out-of-date update for the same object. 3663 // condition where a kill can be processed before an out-of-date update for the same object.
3629 lock (m_killRecord) 3664 float avgTimeDilation = 1.0f;
3665 IEntityUpdate iupdate;
3666 Int32 timeinqueue; // this is just debugging code & can be dropped later
3667
3668 while (updatesThisCall < maxUpdates)
3630 { 3669 {
3631 float avgTimeDilation = 1.0f; 3670 lock (m_entityUpdates.SyncRoot)
3632 IEntityUpdate iupdate; 3671 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3633 Int32 timeinqueue; // this is just debugging code & can be dropped later 3672 break;
3634
3635 while (updatesThisCall < maxUpdates)
3636 {
3637 lock (m_entityUpdates.SyncRoot)
3638 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3639 break;
3640 3673
3641 EntityUpdate update = (EntityUpdate)iupdate; 3674 EntityUpdate update = (EntityUpdate)iupdate;
3642 3675
3643 avgTimeDilation += update.TimeDilation; 3676 avgTimeDilation += update.TimeDilation;
3644 avgTimeDilation *= 0.5f; 3677 avgTimeDilation *= 0.5f;
3645 3678
3646 if (update.Entity is SceneObjectPart) 3679 if (update.Entity is SceneObjectPart)
3680 {
3681 SceneObjectPart part = (SceneObjectPart)update.Entity;
3682
3683 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3684 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3685 // safety measure.
3686 //
3687 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3688 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3689 // updates and kills on different threads with different scheduling strategies, hence this protection.
3690 //
3691 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3692 // after the root prim has been deleted.
3693 lock (m_killRecord)
3647 { 3694 {
3648 SceneObjectPart part = (SceneObjectPart)update.Entity;
3649
3650 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3651 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3652 // safety measure.
3653 //
3654 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3655 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3656 // updates and kills on different threads with different scheduling strategies, hence this protection.
3657 //
3658 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3659 // after the root prim has been deleted.
3660 if (m_killRecord.Contains(part.LocalId)) 3695 if (m_killRecord.Contains(part.LocalId))
3661 {
3662 // m_log.WarnFormat(
3663 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3664 // part.LocalId, Name);
3665 continue; 3696 continue;
3666 } 3697 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3667 3698 continue;
3668 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3699 }
3700
3701 if (part.ParentGroup.IsDeleted)
3702 continue;
3703
3704 if (part.ParentGroup.IsAttachment)
3705 { // Someone else's HUD, why are we getting these?
3706 if (part.ParentGroup.OwnerID != AgentId &&
3707 part.ParentGroup.RootPart.Shape.State >= 30)
3708 continue;
3709 ScenePresence sp;
3710 // Owner is not in the sim, don't update it to
3711 // anyone
3712 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3713 continue;
3714
3715 List<SceneObjectGroup> atts = sp.Attachments;
3716 bool found = false;
3717 foreach (SceneObjectGroup att in atts)
3669 { 3718 {
3670 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3719 if (att == part.ParentGroup)
3671 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3672 { 3720 {
3673 part.Shape.LightEntry = false; 3721 found = true;
3722 break;
3674 } 3723 }
3675 } 3724 }
3725
3726 // It's an attachment of a valid avatar, but
3727 // doesn't seem to be attached, skip
3728 if (!found)
3729 continue;
3676 } 3730 }
3677 3731 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3678 ++updatesThisCall;
3679
3680 #region UpdateFlags to packet type conversion
3681
3682 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3683
3684 bool canUseCompressed = true;
3685 bool canUseImproved = true;
3686
3687 // Compressed object updates only make sense for LL primitives
3688 if (!(update.Entity is SceneObjectPart))
3689 {
3690 canUseCompressed = false;
3691 }
3692
3693 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3694 {
3695 canUseCompressed = false;
3696 canUseImproved = false;
3697 }
3698 else
3699 { 3732 {
3700 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3733 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3701 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3734 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3702 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3703 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3704 { 3735 {
3705 canUseCompressed = false; 3736 part.Shape.LightEntry = false;
3706 }
3707
3708 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3709 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3710 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3711 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3712 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3713 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3714 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3715 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3716 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3717 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3718 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3719 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3720 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3721 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3722 {
3723 canUseImproved = false;
3724 } 3737 }
3725 } 3738 }
3726 3739 }
3727 #endregion UpdateFlags to packet type conversion 3740
3728 3741 ++updatesThisCall;
3729 #region Block Construction 3742
3730 3743 #region UpdateFlags to packet type conversion
3731 // TODO: Remove this once we can build compressed updates 3744
3745 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3746
3747 bool canUseCompressed = true;
3748 bool canUseImproved = true;
3749
3750 // Compressed object updates only make sense for LL primitives
3751 if (!(update.Entity is SceneObjectPart))
3752 {
3732 canUseCompressed = false; 3753 canUseCompressed = false;
3733 3754 }
3734 if (!canUseImproved && !canUseCompressed) 3755
3735 { 3756 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3736 if (update.Entity is ScenePresence) 3757 {
3737 { 3758 canUseCompressed = false;
3738 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3759 canUseImproved = false;
3739 objectUpdates.Value.Add(update); 3760 }
3740 } 3761 else
3741 else 3762 {
3742 { 3763 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3743 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3764 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3744 objectUpdates.Value.Add(update); 3765 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3745 } 3766 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3746 }
3747 else if (!canUseImproved)
3748 { 3767 {
3749 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3768 canUseCompressed = false;
3750 compressedUpdates.Value.Add(update);
3751 } 3769 }
3752 else 3770
3771 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3775 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3776 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3777 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3778 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3779 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3780 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3781 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3782 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3783 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3784 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3753 { 3785 {
3754 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3786 canUseImproved = false;
3755 {
3756 // Self updates go into a special list
3757 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3758 terseAgentUpdates.Value.Add(update);
3759 }
3760 else
3761 {
3762 // Everything else goes here
3763 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3764 terseUpdates.Value.Add(update);
3765 }
3766 } 3787 }
3767
3768 #endregion Block Construction
3769 } 3788 }
3770
3771
3772 #region Packet Sending
3773 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3774 3789
3775 if (terseAgentUpdateBlocks.IsValueCreated) 3790 #endregion UpdateFlags to packet type conversion
3776 {
3777 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3778 3791
3779 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3792 #region Block Construction
3780 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3781 packet.RegionData.TimeDilation = timeDilation;
3782 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3783 3793
3784 for (int i = 0; i < blocks.Count; i++) 3794 // TODO: Remove this once we can build compressed updates
3785 packet.ObjectData[i] = blocks[i]; 3795 canUseCompressed = false;
3786 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3787 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3788 }
3789 3796
3790 if (objectUpdateBlocks.IsValueCreated) 3797 if (!canUseImproved && !canUseCompressed)
3791 { 3798 {
3792 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3799 if (update.Entity is ScenePresence)
3793 3800 {
3794 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3801 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3795 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3802 }
3796 packet.RegionData.TimeDilation = timeDilation; 3803 else
3797 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3804 {
3798 3805 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3799 for (int i = 0; i < blocks.Count; i++) 3806 }
3800 packet.ObjectData[i] = blocks[i];
3801 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3802 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3803 } 3807 }
3804 3808 else if (!canUseImproved)
3805 if (compressedUpdateBlocks.IsValueCreated)
3806 { 3809 {
3807 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3810 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3808
3809 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3810 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3811 packet.RegionData.TimeDilation = timeDilation;
3812 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3813
3814 for (int i = 0; i < blocks.Count; i++)
3815 packet.ObjectData[i] = blocks[i];
3816 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3817 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3818 } 3811 }
3819 3812 else
3820 if (terseUpdateBlocks.IsValueCreated)
3821 { 3813 {
3822 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3814 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3823 3815 // Self updates go into a special list
3824 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3816 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3825 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3817 else
3826 packet.RegionData.TimeDilation = timeDilation; 3818 // Everything else goes here
3827 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3819 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3828
3829 for (int i = 0; i < blocks.Count; i++)
3830 packet.ObjectData[i] = blocks[i];
3831 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3832 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3833 } 3820 }
3821
3822 #endregion Block Construction
3823 }
3824
3825 #region Packet Sending
3826
3827 const float TIME_DILATION = 1.0f;
3828 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3829
3830 if (terseAgentUpdateBlocks.IsValueCreated)
3831 {
3832 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3833
3834 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3835 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3836 packet.RegionData.TimeDilation = timeDilation;
3837 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3838
3839 for (int i = 0; i < blocks.Count; i++)
3840 packet.ObjectData[i] = blocks[i];
3841
3842 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3843 }
3844
3845 if (objectUpdateBlocks.IsValueCreated)
3846 {
3847 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3848
3849 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3850 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3851 packet.RegionData.TimeDilation = timeDilation;
3852 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3853
3854 for (int i = 0; i < blocks.Count; i++)
3855 packet.ObjectData[i] = blocks[i];
3856
3857 OutPacket(packet, ThrottleOutPacketType.Task, true);
3858 }
3859
3860 if (compressedUpdateBlocks.IsValueCreated)
3861 {
3862 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3863
3864 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3865 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3866 packet.RegionData.TimeDilation = timeDilation;
3867 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3868
3869 for (int i = 0; i < blocks.Count; i++)
3870 packet.ObjectData[i] = blocks[i];
3871
3872 OutPacket(packet, ThrottleOutPacketType.Task, true);
3873 }
3874
3875 if (terseUpdateBlocks.IsValueCreated)
3876 {
3877 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3878
3879 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3880 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3881 packet.RegionData.TimeDilation = timeDilation;
3882 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3883
3884 for (int i = 0; i < blocks.Count; i++)
3885 packet.ObjectData[i] = blocks[i];
3886
3887 OutPacket(packet, ThrottleOutPacketType.Task, true);
3834 } 3888 }
3835 3889
3836 #endregion Packet Sending 3890 #endregion Packet Sending
@@ -4642,14 +4696,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4642 4696
4643 if (notifyCount > 0) 4697 if (notifyCount > 0)
4644 { 4698 {
4645 if (notifyCount > 32) 4699// if (notifyCount > 32)
4646 { 4700// {
4647 m_log.InfoFormat( 4701// m_log.InfoFormat(
4648 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4702// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4649 + " - a developer might want to investigate whether this is a hard limit", 32); 4703// + " - a developer might want to investigate whether this is a hard limit", 32);
4650 4704//
4651 notifyCount = 32; 4705// notifyCount = 32;
4652 } 4706// }
4653 4707
4654 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4708 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4655 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4709 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5165,6 +5219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5165 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5219 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5166 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5220 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5167 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5221 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5222 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5168 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5223 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5169 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5224 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5170 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5225 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5264,6 +5319,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5264 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5319 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5265 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5320 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5266 (x.ControlFlags != lastarg.ControlFlags) || 5321 (x.ControlFlags != lastarg.ControlFlags) ||
5322 (x.ControlFlags != 0) ||
5267 (x.Far != lastarg.Far) || 5323 (x.Far != lastarg.Far) ||
5268 (x.Flags != lastarg.Flags) || 5324 (x.Flags != lastarg.Flags) ||
5269 (x.State != lastarg.State) || 5325 (x.State != lastarg.State) ||
@@ -5637,7 +5693,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5637 args.Channel = ch; 5693 args.Channel = ch;
5638 args.From = String.Empty; 5694 args.From = String.Empty;
5639 args.Message = Utils.BytesToString(msg); 5695 args.Message = Utils.BytesToString(msg);
5640 args.Type = ChatTypeEnum.Shout; 5696 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5641 args.Position = new Vector3(); 5697 args.Position = new Vector3();
5642 args.Scene = Scene; 5698 args.Scene = Scene;
5643 args.Sender = this; 5699 args.Sender = this;
@@ -9625,7 +9681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9625 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9681 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9626 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9682 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9627 UpdateMuteListEntry.MuteData.MuteType, 9683 UpdateMuteListEntry.MuteData.MuteType,
9628 UpdateMuteListEntry.AgentData.AgentID); 9684 UpdateMuteListEntry.MuteData.MuteFlags);
9629 return true; 9685 return true;
9630 } 9686 }
9631 return false; 9687 return false;
@@ -9640,8 +9696,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9640 { 9696 {
9641 handlerRemoveMuteListEntry(this, 9697 handlerRemoveMuteListEntry(this,
9642 RemoveMuteListEntry.MuteData.MuteID, 9698 RemoveMuteListEntry.MuteData.MuteID,
9643 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9699 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9644 RemoveMuteListEntry.AgentData.AgentID);
9645 return true; 9700 return true;
9646 } 9701 }
9647 return false; 9702 return false;
@@ -9689,6 +9744,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9689 { 9744 {
9690 return true; 9745 return true;
9691 } 9746 }
9747
9748 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9749 {
9750 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9751
9752 #region Packet Session and User Check
9753 if (m_checkPackets)
9754 {
9755 if (packet.AgentData.SessionID != SessionId ||
9756 packet.AgentData.AgentID != AgentId)
9757 return true;
9758 }
9759 #endregion
9760 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9761 List<InventoryItemBase> items = new List<InventoryItemBase>();
9762 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9763 {
9764 InventoryItemBase b = new InventoryItemBase();
9765 b.ID = n.OldItemID;
9766 b.Folder = n.OldFolderID;
9767 items.Add(b);
9768 }
9769
9770 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9771 if (handlerMoveItemsAndLeaveCopy != null)
9772 {
9773 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9774 }
9775
9776 return true;
9777 }
9692 9778
9693 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9779 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9694 { 9780 {
@@ -10115,6 +10201,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10115 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10201 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10116 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10202 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10117 10203
10204 Scene scene = (Scene)m_scene;
10205 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10206 {
10207 ScenePresence p;
10208 if (scene.TryGetScenePresence(sender.AgentId, out p))
10209 {
10210 if (p.GodLevel >= 200)
10211 {
10212 groupProfileReply.GroupData.OpenEnrollment = true;
10213 groupProfileReply.GroupData.MembershipFee = 0;
10214 }
10215 }
10216 }
10217
10118 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10218 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10119 } 10219 }
10120 return true; 10220 return true;
@@ -10687,11 +10787,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10687 10787
10688 StartLure handlerStartLure = OnStartLure; 10788 StartLure handlerStartLure = OnStartLure;
10689 if (handlerStartLure != null) 10789 if (handlerStartLure != null)
10690 handlerStartLure(startLureRequest.Info.LureType, 10790 {
10691 Utils.BytesToString( 10791 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10692 startLureRequest.Info.Message), 10792 {
10693 startLureRequest.TargetData[0].TargetID, 10793 handlerStartLure(startLureRequest.Info.LureType,
10694 this); 10794 Utils.BytesToString(
10795 startLureRequest.Info.Message),
10796 startLureRequest.TargetData[i].TargetID,
10797 this);
10798 }
10799 }
10695 return true; 10800 return true;
10696 } 10801 }
10697 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10802 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10805,10 +10910,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10805 } 10910 }
10806 #endregion 10911 #endregion
10807 10912
10808 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10913 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10809 if (handlerClassifiedGodDelete != null) 10914 if (handlerClassifiedGodDelete != null)
10810 handlerClassifiedGodDelete( 10915 handlerClassifiedGodDelete(
10811 classifiedGodDelete.Data.ClassifiedID, 10916 classifiedGodDelete.Data.ClassifiedID,
10917 classifiedGodDelete.Data.QueryID,
10812 this); 10918 this);
10813 return true; 10919 return true;
10814 } 10920 }
@@ -11186,7 +11292,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11186 { 11292 {
11187 // It's a ghost! tell the client to delete it from view. 11293 // It's a ghost! tell the client to delete it from view.
11188 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11294 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11189 localId); 11295 new List<uint>() { localId });
11190 } 11296 }
11191 else 11297 else
11192 { 11298 {
@@ -11575,22 +11681,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11575 /// <param name="Pack">OpenMetaverse.packet</param> 11681 /// <param name="Pack">OpenMetaverse.packet</param>
11576 public void ProcessInPacket(Packet packet) 11682 public void ProcessInPacket(Packet packet)
11577 { 11683 {
11578 if (m_debugPacketLevel > 0) 11684 if (m_debugPacketLevel >= 255)
11579 { 11685 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11580 bool outputPacket = true;
11581
11582 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11583 outputPacket = false;
11584
11585 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11586 outputPacket = false;
11587
11588 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11589 outputPacket = false;
11590
11591 if (outputPacket)
11592 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11593 }
11594 11686
11595 if (!ProcessPacketMethod(packet)) 11687 if (!ProcessPacketMethod(packet))
11596 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11688 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11832,7 +11924,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11832 11924
11833// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11925// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11834 11926
11927
11928 //Note, the bool returned from the below function is useless since it is always false.
11835 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11929 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11930
11836 } 11931 }
11837 11932
11838 /// <summary> 11933 /// <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,