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 5a2c45c..7564907 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>
@@ -2259,6 +2277,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2259 OutPacket(sound, ThrottleOutPacketType.Task); 2277 OutPacket(sound, ThrottleOutPacketType.Task);
2260 } 2278 }
2261 2279
2280 public void SendTransferAbort(TransferRequestPacket transferRequest)
2281 {
2282 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2283 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2284 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2285 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2286 OutPacket(abort, ThrottleOutPacketType.Task);
2287 }
2288
2262 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2289 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2263 { 2290 {
2264 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2291 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3563,7 +3590,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3563 /// </summary> 3590 /// </summary>
3564 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3591 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3565 { 3592 {
3566 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3593 if (entity is SceneObjectPart)
3594 {
3595 SceneObjectPart e = (SceneObjectPart)entity;
3596 SceneObjectGroup g = e.ParentGroup;
3597 if (g.RootPart.Shape.State > 30) // HUD
3598 if (g.OwnerID != AgentId)
3599 return; // Don't send updates for other people's HUDs
3600 }
3601
3567 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3602 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3568 3603
3569 lock (m_entityUpdates.SyncRoot) 3604 lock (m_entityUpdates.SyncRoot)
@@ -3630,211 +3665,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3630 3665
3631 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3666 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3632 // condition where a kill can be processed before an out-of-date update for the same object. 3667 // condition where a kill can be processed before an out-of-date update for the same object.
3633 lock (m_killRecord) 3668 float avgTimeDilation = 1.0f;
3669 IEntityUpdate iupdate;
3670 Int32 timeinqueue; // this is just debugging code & can be dropped later
3671
3672 while (updatesThisCall < maxUpdates)
3634 { 3673 {
3635 float avgTimeDilation = 1.0f; 3674 lock (m_entityUpdates.SyncRoot)
3636 IEntityUpdate iupdate; 3675 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3637 Int32 timeinqueue; // this is just debugging code & can be dropped later 3676 break;
3638
3639 while (updatesThisCall < maxUpdates)
3640 {
3641 lock (m_entityUpdates.SyncRoot)
3642 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3643 break;
3644 3677
3645 EntityUpdate update = (EntityUpdate)iupdate; 3678 EntityUpdate update = (EntityUpdate)iupdate;
3646 3679
3647 avgTimeDilation += update.TimeDilation; 3680 avgTimeDilation += update.TimeDilation;
3648 avgTimeDilation *= 0.5f; 3681 avgTimeDilation *= 0.5f;
3649 3682
3650 if (update.Entity is SceneObjectPart) 3683 if (update.Entity is SceneObjectPart)
3684 {
3685 SceneObjectPart part = (SceneObjectPart)update.Entity;
3686
3687 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3688 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3689 // safety measure.
3690 //
3691 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3692 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3693 // updates and kills on different threads with different scheduling strategies, hence this protection.
3694 //
3695 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3696 // after the root prim has been deleted.
3697 lock (m_killRecord)
3651 { 3698 {
3652 SceneObjectPart part = (SceneObjectPart)update.Entity;
3653
3654 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3655 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3656 // safety measure.
3657 //
3658 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3659 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3660 // updates and kills on different threads with different scheduling strategies, hence this protection.
3661 //
3662 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3663 // after the root prim has been deleted.
3664 if (m_killRecord.Contains(part.LocalId)) 3699 if (m_killRecord.Contains(part.LocalId))
3665 {
3666 // m_log.WarnFormat(
3667 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3668 // part.LocalId, Name);
3669 continue; 3700 continue;
3670 } 3701 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3671 3702 continue;
3672 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3703 }
3704
3705 if (part.ParentGroup.IsDeleted)
3706 continue;
3707
3708 if (part.ParentGroup.IsAttachment)
3709 { // Someone else's HUD, why are we getting these?
3710 if (part.ParentGroup.OwnerID != AgentId &&
3711 part.ParentGroup.RootPart.Shape.State >= 30)
3712 continue;
3713 ScenePresence sp;
3714 // Owner is not in the sim, don't update it to
3715 // anyone
3716 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3717 continue;
3718
3719 List<SceneObjectGroup> atts = sp.Attachments;
3720 bool found = false;
3721 foreach (SceneObjectGroup att in atts)
3673 { 3722 {
3674 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3723 if (att == part.ParentGroup)
3675 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3676 { 3724 {
3677 part.Shape.LightEntry = false; 3725 found = true;
3726 break;
3678 } 3727 }
3679 } 3728 }
3729
3730 // It's an attachment of a valid avatar, but
3731 // doesn't seem to be attached, skip
3732 if (!found)
3733 continue;
3680 } 3734 }
3681 3735 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3682 ++updatesThisCall;
3683
3684 #region UpdateFlags to packet type conversion
3685
3686 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3687
3688 bool canUseCompressed = true;
3689 bool canUseImproved = true;
3690
3691 // Compressed object updates only make sense for LL primitives
3692 if (!(update.Entity is SceneObjectPart))
3693 {
3694 canUseCompressed = false;
3695 }
3696
3697 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3698 {
3699 canUseCompressed = false;
3700 canUseImproved = false;
3701 }
3702 else
3703 { 3736 {
3704 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3737 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3705 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3738 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3706 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3707 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3708 { 3739 {
3709 canUseCompressed = false; 3740 part.Shape.LightEntry = false;
3710 }
3711
3712 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3713 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3714 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3715 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3716 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3717 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3718 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3719 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3720 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3721 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3722 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3723 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3724 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3725 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3726 {
3727 canUseImproved = false;
3728 } 3741 }
3729 } 3742 }
3730 3743 }
3731 #endregion UpdateFlags to packet type conversion 3744
3732 3745 ++updatesThisCall;
3733 #region Block Construction 3746
3734 3747 #region UpdateFlags to packet type conversion
3735 // TODO: Remove this once we can build compressed updates 3748
3749 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3750
3751 bool canUseCompressed = true;
3752 bool canUseImproved = true;
3753
3754 // Compressed object updates only make sense for LL primitives
3755 if (!(update.Entity is SceneObjectPart))
3756 {
3736 canUseCompressed = false; 3757 canUseCompressed = false;
3737 3758 }
3738 if (!canUseImproved && !canUseCompressed) 3759
3739 { 3760 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3740 if (update.Entity is ScenePresence) 3761 {
3741 { 3762 canUseCompressed = false;
3742 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3763 canUseImproved = false;
3743 objectUpdates.Value.Add(update); 3764 }
3744 } 3765 else
3745 else 3766 {
3746 { 3767 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3747 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3768 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3748 objectUpdates.Value.Add(update); 3769 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3749 } 3770 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3750 }
3751 else if (!canUseImproved)
3752 { 3771 {
3753 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3772 canUseCompressed = false;
3754 compressedUpdates.Value.Add(update);
3755 } 3773 }
3756 else 3774
3775 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3776 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3777 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3778 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3779 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3780 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3781 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3782 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3783 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3784 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3785 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3786 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3787 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3788 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3757 { 3789 {
3758 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3790 canUseImproved = false;
3759 {
3760 // Self updates go into a special list
3761 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3762 terseAgentUpdates.Value.Add(update);
3763 }
3764 else
3765 {
3766 // Everything else goes here
3767 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3768 terseUpdates.Value.Add(update);
3769 }
3770 } 3791 }
3771
3772 #endregion Block Construction
3773 } 3792 }
3774
3775
3776 #region Packet Sending
3777 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3778 3793
3779 if (terseAgentUpdateBlocks.IsValueCreated) 3794 #endregion UpdateFlags to packet type conversion
3780 {
3781 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3782 3795
3783 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3796 #region Block Construction
3784 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3785 packet.RegionData.TimeDilation = timeDilation;
3786 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3787 3797
3788 for (int i = 0; i < blocks.Count; i++) 3798 // TODO: Remove this once we can build compressed updates
3789 packet.ObjectData[i] = blocks[i]; 3799 canUseCompressed = false;
3790 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3791 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3792 }
3793 3800
3794 if (objectUpdateBlocks.IsValueCreated) 3801 if (!canUseImproved && !canUseCompressed)
3795 { 3802 {
3796 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3803 if (update.Entity is ScenePresence)
3797 3804 {
3798 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3805 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3799 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3806 }
3800 packet.RegionData.TimeDilation = timeDilation; 3807 else
3801 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3808 {
3802 3809 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3803 for (int i = 0; i < blocks.Count; i++) 3810 }
3804 packet.ObjectData[i] = blocks[i];
3805 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3806 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3807 } 3811 }
3808 3812 else if (!canUseImproved)
3809 if (compressedUpdateBlocks.IsValueCreated)
3810 { 3813 {
3811 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3814 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3812
3813 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3814 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3815 packet.RegionData.TimeDilation = timeDilation;
3816 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3817
3818 for (int i = 0; i < blocks.Count; i++)
3819 packet.ObjectData[i] = blocks[i];
3820 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3821 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3822 } 3815 }
3823 3816 else
3824 if (terseUpdateBlocks.IsValueCreated)
3825 { 3817 {
3826 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3818 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3827 3819 // Self updates go into a special list
3828 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3820 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3829 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3821 else
3830 packet.RegionData.TimeDilation = timeDilation; 3822 // Everything else goes here
3831 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3823 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3832
3833 for (int i = 0; i < blocks.Count; i++)
3834 packet.ObjectData[i] = blocks[i];
3835 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3836 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3837 } 3824 }
3825
3826 #endregion Block Construction
3827 }
3828
3829 #region Packet Sending
3830
3831 const float TIME_DILATION = 1.0f;
3832 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3833
3834 if (terseAgentUpdateBlocks.IsValueCreated)
3835 {
3836 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3837
3838 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3839 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3840 packet.RegionData.TimeDilation = timeDilation;
3841 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3842
3843 for (int i = 0; i < blocks.Count; i++)
3844 packet.ObjectData[i] = blocks[i];
3845
3846 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3847 }
3848
3849 if (objectUpdateBlocks.IsValueCreated)
3850 {
3851 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3852
3853 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3854 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3855 packet.RegionData.TimeDilation = timeDilation;
3856 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3857
3858 for (int i = 0; i < blocks.Count; i++)
3859 packet.ObjectData[i] = blocks[i];
3860
3861 OutPacket(packet, ThrottleOutPacketType.Task, true);
3862 }
3863
3864 if (compressedUpdateBlocks.IsValueCreated)
3865 {
3866 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3867
3868 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3869 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3870 packet.RegionData.TimeDilation = timeDilation;
3871 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3872
3873 for (int i = 0; i < blocks.Count; i++)
3874 packet.ObjectData[i] = blocks[i];
3875
3876 OutPacket(packet, ThrottleOutPacketType.Task, true);
3877 }
3878
3879 if (terseUpdateBlocks.IsValueCreated)
3880 {
3881 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3882
3883 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3884 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3885 packet.RegionData.TimeDilation = timeDilation;
3886 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3887
3888 for (int i = 0; i < blocks.Count; i++)
3889 packet.ObjectData[i] = blocks[i];
3890
3891 OutPacket(packet, ThrottleOutPacketType.Task, true);
3838 } 3892 }
3839 3893
3840 #endregion Packet Sending 3894 #endregion Packet Sending
@@ -4646,14 +4700,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4646 4700
4647 if (notifyCount > 0) 4701 if (notifyCount > 0)
4648 { 4702 {
4649 if (notifyCount > 32) 4703// if (notifyCount > 32)
4650 { 4704// {
4651 m_log.InfoFormat( 4705// m_log.InfoFormat(
4652 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4706// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4653 + " - a developer might want to investigate whether this is a hard limit", 32); 4707// + " - a developer might want to investigate whether this is a hard limit", 32);
4654 4708//
4655 notifyCount = 32; 4709// notifyCount = 32;
4656 } 4710// }
4657 4711
4658 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4712 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4659 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4713 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5169,6 +5223,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5169 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5223 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5170 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5224 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5171 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5225 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5226 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5172 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5227 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5173 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5228 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5174 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5229 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5268,6 +5323,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5268 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5323 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5269 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5324 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5270 (x.ControlFlags != lastarg.ControlFlags) || 5325 (x.ControlFlags != lastarg.ControlFlags) ||
5326 (x.ControlFlags != 0) ||
5271 (x.Far != lastarg.Far) || 5327 (x.Far != lastarg.Far) ||
5272 (x.Flags != lastarg.Flags) || 5328 (x.Flags != lastarg.Flags) ||
5273 (x.State != lastarg.State) || 5329 (x.State != lastarg.State) ||
@@ -5641,7 +5697,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5641 args.Channel = ch; 5697 args.Channel = ch;
5642 args.From = String.Empty; 5698 args.From = String.Empty;
5643 args.Message = Utils.BytesToString(msg); 5699 args.Message = Utils.BytesToString(msg);
5644 args.Type = ChatTypeEnum.Shout; 5700 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5645 args.Position = new Vector3(); 5701 args.Position = new Vector3();
5646 args.Scene = Scene; 5702 args.Scene = Scene;
5647 args.Sender = this; 5703 args.Sender = this;
@@ -9628,7 +9684,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9628 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9684 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9629 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9685 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9630 UpdateMuteListEntry.MuteData.MuteType, 9686 UpdateMuteListEntry.MuteData.MuteType,
9631 UpdateMuteListEntry.AgentData.AgentID); 9687 UpdateMuteListEntry.MuteData.MuteFlags);
9632 return true; 9688 return true;
9633 } 9689 }
9634 return false; 9690 return false;
@@ -9643,8 +9699,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9643 { 9699 {
9644 handlerRemoveMuteListEntry(this, 9700 handlerRemoveMuteListEntry(this,
9645 RemoveMuteListEntry.MuteData.MuteID, 9701 RemoveMuteListEntry.MuteData.MuteID,
9646 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9702 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9647 RemoveMuteListEntry.AgentData.AgentID);
9648 return true; 9703 return true;
9649 } 9704 }
9650 return false; 9705 return false;
@@ -9692,6 +9747,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9692 { 9747 {
9693 return true; 9748 return true;
9694 } 9749 }
9750
9751 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9752 {
9753 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9754
9755 #region Packet Session and User Check
9756 if (m_checkPackets)
9757 {
9758 if (packet.AgentData.SessionID != SessionId ||
9759 packet.AgentData.AgentID != AgentId)
9760 return true;
9761 }
9762 #endregion
9763 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9764 List<InventoryItemBase> items = new List<InventoryItemBase>();
9765 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9766 {
9767 InventoryItemBase b = new InventoryItemBase();
9768 b.ID = n.OldItemID;
9769 b.Folder = n.OldFolderID;
9770 items.Add(b);
9771 }
9772
9773 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9774 if (handlerMoveItemsAndLeaveCopy != null)
9775 {
9776 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9777 }
9778
9779 return true;
9780 }
9695 9781
9696 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9782 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9697 { 9783 {
@@ -10118,6 +10204,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10118 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10204 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10119 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10205 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10120 10206
10207 Scene scene = (Scene)m_scene;
10208 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10209 {
10210 ScenePresence p;
10211 if (scene.TryGetScenePresence(sender.AgentId, out p))
10212 {
10213 if (p.GodLevel >= 200)
10214 {
10215 groupProfileReply.GroupData.OpenEnrollment = true;
10216 groupProfileReply.GroupData.MembershipFee = 0;
10217 }
10218 }
10219 }
10220
10121 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10221 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10122 } 10222 }
10123 return true; 10223 return true;
@@ -10690,11 +10790,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10690 10790
10691 StartLure handlerStartLure = OnStartLure; 10791 StartLure handlerStartLure = OnStartLure;
10692 if (handlerStartLure != null) 10792 if (handlerStartLure != null)
10693 handlerStartLure(startLureRequest.Info.LureType, 10793 {
10694 Utils.BytesToString( 10794 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10695 startLureRequest.Info.Message), 10795 {
10696 startLureRequest.TargetData[0].TargetID, 10796 handlerStartLure(startLureRequest.Info.LureType,
10697 this); 10797 Utils.BytesToString(
10798 startLureRequest.Info.Message),
10799 startLureRequest.TargetData[i].TargetID,
10800 this);
10801 }
10802 }
10698 return true; 10803 return true;
10699 } 10804 }
10700 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10805 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10808,10 +10913,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10808 } 10913 }
10809 #endregion 10914 #endregion
10810 10915
10811 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10916 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10812 if (handlerClassifiedGodDelete != null) 10917 if (handlerClassifiedGodDelete != null)
10813 handlerClassifiedGodDelete( 10918 handlerClassifiedGodDelete(
10814 classifiedGodDelete.Data.ClassifiedID, 10919 classifiedGodDelete.Data.ClassifiedID,
10920 classifiedGodDelete.Data.QueryID,
10815 this); 10921 this);
10816 return true; 10922 return true;
10817 } 10923 }
@@ -11189,7 +11295,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11189 { 11295 {
11190 // It's a ghost! tell the client to delete it from view. 11296 // It's a ghost! tell the client to delete it from view.
11191 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11297 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11192 localId); 11298 new List<uint>() { localId });
11193 } 11299 }
11194 else 11300 else
11195 { 11301 {
@@ -11578,22 +11684,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11578 /// <param name="Pack">OpenMetaverse.packet</param> 11684 /// <param name="Pack">OpenMetaverse.packet</param>
11579 public void ProcessInPacket(Packet packet) 11685 public void ProcessInPacket(Packet packet)
11580 { 11686 {
11581 if (m_debugPacketLevel > 0) 11687 if (m_debugPacketLevel >= 255)
11582 { 11688 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11583 bool outputPacket = true;
11584
11585 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11586 outputPacket = false;
11587
11588 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11589 outputPacket = false;
11590
11591 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11592 outputPacket = false;
11593
11594 if (outputPacket)
11595 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11596 }
11597 11689
11598 if (!ProcessPacketMethod(packet)) 11690 if (!ProcessPacketMethod(packet))
11599 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11691 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11835,7 +11927,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11835 11927
11836// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11928// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11837 11929
11930
11931 //Note, the bool returned from the below function is useless since it is always false.
11838 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11932 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11933
11839 } 11934 }
11840 11935
11841 /// <summary> 11936 /// <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,