aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs667
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs10
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs4
5 files changed, 397 insertions, 291 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index e9e2dca..9dd6663 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/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/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1e8bbb8..cd438d6 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/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; } }
@@ -474,18 +484,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
474 484
475 #region Client Methods 485 #region Client Methods
476 486
487
477 /// <summary> 488 /// <summary>
478 /// Shut down the client view 489 /// Shut down the client view
479 /// </summary> 490 /// </summary>
480 public void Close() 491 public void Close()
481 { 492 {
493 Close(true);
494 }
495
496 /// <summary>
497 /// Shut down the client view
498 /// </summary>
499 public void Close(bool sendStop)
500 {
482 m_log.DebugFormat( 501 m_log.DebugFormat(
483 "[CLIENT]: Close has been called for {0} attached to scene {1}", 502 "[CLIENT]: Close has been called for {0} attached to scene {1}",
484 Name, m_scene.RegionInfo.RegionName); 503 Name, m_scene.RegionInfo.RegionName);
485 504
486 // Send the STOP packet 505 if (sendStop)
487 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 506 {
488 OutPacket(disable, ThrottleOutPacketType.Unknown); 507 // Send the STOP packet
508 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
509 OutPacket(disable, ThrottleOutPacketType.Unknown);
510 }
489 511
490 IsActive = false; 512 IsActive = false;
491 513
@@ -766,7 +788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
766 reply.ChatData.OwnerID = fromAgentID; 788 reply.ChatData.OwnerID = fromAgentID;
767 reply.ChatData.SourceID = fromAgentID; 789 reply.ChatData.SourceID = fromAgentID;
768 790
769 OutPacket(reply, ThrottleOutPacketType.Task); 791 OutPacket(reply, ThrottleOutPacketType.Unknown);
770 } 792 }
771 793
772 /// <summary> 794 /// <summary>
@@ -1052,6 +1074,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1052 public virtual void SendLayerData(float[] map) 1074 public virtual void SendLayerData(float[] map)
1053 { 1075 {
1054 Util.FireAndForget(DoSendLayerData, map); 1076 Util.FireAndForget(DoSendLayerData, map);
1077
1078 // Send it sync, and async. It's not that much data
1079 // and it improves user experience just so much!
1080 DoSendLayerData(map);
1055 } 1081 }
1056 1082
1057 /// <summary> 1083 /// <summary>
@@ -1064,16 +1090,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1064 1090
1065 try 1091 try
1066 { 1092 {
1067 //for (int y = 0; y < 16; y++) 1093 for (int y = 0; y < 16; y++)
1068 //{ 1094 {
1069 // for (int x = 0; x < 16; x++) 1095 for (int x = 0; x < 16; x+=4)
1070 // { 1096 {
1071 // SendLayerData(x, y, map); 1097 SendLayerPacket(x, y, map);
1072 // } 1098 }
1073 //} 1099 }
1074
1075 // Send LayerData in a spiral pattern. Fun!
1076 SendLayerTopRight(map, 0, 0, 15, 15);
1077 } 1100 }
1078 catch (Exception e) 1101 catch (Exception e)
1079 { 1102 {
@@ -1081,51 +1104,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1081 } 1104 }
1082 } 1105 }
1083 1106
1084 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1085 {
1086 // Row
1087 for (int i = x1; i <= x2; i++)
1088 SendLayerData(i, y1, map);
1089
1090 // Column
1091 for (int j = y1 + 1; j <= y2; j++)
1092 SendLayerData(x2, j, map);
1093
1094 if (x2 - x1 > 0)
1095 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1096 }
1097
1098 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1099 {
1100 // Row in reverse
1101 for (int i = x2; i >= x1; i--)
1102 SendLayerData(i, y2, map);
1103
1104 // Column in reverse
1105 for (int j = y2 - 1; j >= y1; j--)
1106 SendLayerData(x1, j, map);
1107
1108 if (x2 - x1 > 0)
1109 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1110 }
1111
1112 /// <summary> 1107 /// <summary>
1113 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1108 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1114 /// </summary> 1109 /// </summary>
1115 /// <param name="map">heightmap</param> 1110 /// <param name="map">heightmap</param>
1116 /// <param name="px">X coordinate for patches 0..12</param> 1111 /// <param name="px">X coordinate for patches 0..12</param>
1117 /// <param name="py">Y coordinate for patches 0..15</param> 1112 /// <param name="py">Y coordinate for patches 0..15</param>
1118 // private void SendLayerPacket(float[] map, int y, int x) 1113 private void SendLayerPacket(int x, int y, float[] map)
1119 // { 1114 {
1120 // int[] patches = new int[4]; 1115 int[] patches = new int[4];
1121 // patches[0] = x + 0 + y * 16; 1116 patches[0] = x + 0 + y * 16;
1122 // patches[1] = x + 1 + y * 16; 1117 patches[1] = x + 1 + y * 16;
1123 // patches[2] = x + 2 + y * 16; 1118 patches[2] = x + 2 + y * 16;
1124 // patches[3] = x + 3 + y * 16; 1119 patches[3] = x + 3 + y * 16;
1125 1120
1126 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1121 float[] heightmap = (map.Length == 65536) ?
1127 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1122 map :
1128 // } 1123 LLHeightFieldMoronize(map);
1124
1125 try
1126 {
1127 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1128 OutPacket(layerpack, ThrottleOutPacketType.Land);
1129 }
1130 catch
1131 {
1132 for (int px = x ; px < x + 4 ; px++)
1133 SendLayerData(px, y, map);
1134 }
1135 }
1129 1136
1130 /// <summary> 1137 /// <summary>
1131 /// Sends a specified patch to a client 1138 /// Sends a specified patch to a client
@@ -1145,7 +1152,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1145 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1152 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1146 layerpack.Header.Reliable = true; 1153 layerpack.Header.Reliable = true;
1147 1154
1148 OutPacket(layerpack, ThrottleOutPacketType.Land); 1155 OutPacket(layerpack, ThrottleOutPacketType.Task);
1149 } 1156 }
1150 catch (Exception e) 1157 catch (Exception e)
1151 { 1158 {
@@ -1506,38 +1513,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1506 OutPacket(pc, ThrottleOutPacketType.Unknown); 1513 OutPacket(pc, ThrottleOutPacketType.Unknown);
1507 } 1514 }
1508 1515
1509 public void SendKillObject(ulong regionHandle, uint localID) 1516 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1510 { 1517 {
1511// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1518// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1512 1519
1513 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1520 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1514 // TODO: don't create new blocks if recycling an old packet 1521 // TODO: don't create new blocks if recycling an old packet
1515 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1522 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1516 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1523 for (int i = 0 ; i < localIDs.Count ; i++ )
1517 kill.ObjectData[0].ID = localID; 1524 {
1525 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1526 kill.ObjectData[i].ID = localIDs[i];
1527 }
1518 kill.Header.Reliable = true; 1528 kill.Header.Reliable = true;
1519 kill.Header.Zerocoded = true; 1529 kill.Header.Zerocoded = true;
1520 1530
1521 if (m_scene.GetScenePresence(localID) == null) 1531 lock (m_killRecord)
1522 { 1532 {
1523 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1533 if (localIDs.Count == 1)
1524 // condition where a kill can be processed before an out-of-date update for the same object.
1525 lock (m_killRecord)
1526 { 1534 {
1527 m_killRecord.Add(localID); 1535 if (m_scene.GetScenePresence(localIDs[0]) != null)
1528 1536 {
1529 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1537 OutPacket(kill, ThrottleOutPacketType.State);
1530 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1538 return;
1531 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1539 }
1532 // scene objects in a viewer until that viewer is relogged in. 1540 m_killRecord.Add(localIDs[0]);
1533 OutPacket(kill, ThrottleOutPacketType.Task); 1541 }
1542 else
1543 {
1544 lock (m_entityUpdates.SyncRoot)
1545 {
1546 foreach (uint localID in localIDs)
1547 m_killRecord.Add(localID);
1548 }
1534 } 1549 }
1535 } 1550 }
1536 else 1551
1537 { 1552 // The throttle queue used here must match that being used for
1538 // OutPacket(kill, ThrottleOutPacketType.State); 1553 // updates. Otherwise, there is a chance that a kill packet put
1539 OutPacket(kill, ThrottleOutPacketType.Task); 1554 // on a separate queue will be sent to the client before an
1540 } 1555 // existing update packet on another queue. Receiving updates
1556 // after kills results in unowned and undeletable
1557 // scene objects in a viewer until that viewer is relogged in.
1558 OutPacket(kill, ThrottleOutPacketType.Task);
1541 } 1559 }
1542 1560
1543 /// <summary> 1561 /// <summary>
@@ -2250,6 +2268,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2250 OutPacket(sound, ThrottleOutPacketType.Task); 2268 OutPacket(sound, ThrottleOutPacketType.Task);
2251 } 2269 }
2252 2270
2271 public void SendTransferAbort(TransferRequestPacket transferRequest)
2272 {
2273 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2274 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2275 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2276 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2277 OutPacket(abort, ThrottleOutPacketType.Task);
2278 }
2279
2253 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2280 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2254 { 2281 {
2255 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2282 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3554,7 +3581,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3554 /// </summary> 3581 /// </summary>
3555 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3582 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3556 { 3583 {
3557 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3584 if (entity is SceneObjectPart)
3585 {
3586 SceneObjectPart e = (SceneObjectPart)entity;
3587 SceneObjectGroup g = e.ParentGroup;
3588 if (g.RootPart.Shape.State > 30) // HUD
3589 if (g.OwnerID != AgentId)
3590 return; // Don't send updates for other people's HUDs
3591 }
3592
3558 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3593 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3559 3594
3560 lock (m_entityUpdates.SyncRoot) 3595 lock (m_entityUpdates.SyncRoot)
@@ -3617,211 +3652,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3617 3652
3618 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3653 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3619 // condition where a kill can be processed before an out-of-date update for the same object. 3654 // condition where a kill can be processed before an out-of-date update for the same object.
3620 lock (m_killRecord) 3655 float avgTimeDilation = 1.0f;
3656 IEntityUpdate iupdate;
3657 Int32 timeinqueue; // this is just debugging code & can be dropped later
3658
3659 while (updatesThisCall < maxUpdates)
3621 { 3660 {
3622 float avgTimeDilation = 1.0f; 3661 lock (m_entityUpdates.SyncRoot)
3623 IEntityUpdate iupdate; 3662 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3624 Int32 timeinqueue; // this is just debugging code & can be dropped later 3663 break;
3625
3626 while (updatesThisCall < maxUpdates)
3627 {
3628 lock (m_entityUpdates.SyncRoot)
3629 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3630 break;
3631 3664
3632 EntityUpdate update = (EntityUpdate)iupdate; 3665 EntityUpdate update = (EntityUpdate)iupdate;
3633 3666
3634 avgTimeDilation += update.TimeDilation; 3667 avgTimeDilation += update.TimeDilation;
3635 avgTimeDilation *= 0.5f; 3668 avgTimeDilation *= 0.5f;
3636 3669
3637 if (update.Entity is SceneObjectPart) 3670 if (update.Entity is SceneObjectPart)
3671 {
3672 SceneObjectPart part = (SceneObjectPart)update.Entity;
3673
3674 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3675 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3676 // safety measure.
3677 //
3678 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3679 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3680 // updates and kills on different threads with different scheduling strategies, hence this protection.
3681 //
3682 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3683 // after the root prim has been deleted.
3684 lock (m_killRecord)
3638 { 3685 {
3639 SceneObjectPart part = (SceneObjectPart)update.Entity;
3640
3641 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3642 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3643 // safety measure.
3644 //
3645 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3646 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3647 // updates and kills on different threads with different scheduling strategies, hence this protection.
3648 //
3649 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3650 // after the root prim has been deleted.
3651 if (m_killRecord.Contains(part.LocalId)) 3686 if (m_killRecord.Contains(part.LocalId))
3652 {
3653 // m_log.WarnFormat(
3654 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3655 // part.LocalId, Name);
3656 continue; 3687 continue;
3657 } 3688 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3658 3689 continue;
3659 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3690 }
3691
3692 if (part.ParentGroup.IsDeleted)
3693 continue;
3694
3695 if (part.ParentGroup.IsAttachment)
3696 { // Someone else's HUD, why are we getting these?
3697 if (part.ParentGroup.OwnerID != AgentId &&
3698 part.ParentGroup.RootPart.Shape.State >= 30)
3699 continue;
3700 ScenePresence sp;
3701 // Owner is not in the sim, don't update it to
3702 // anyone
3703 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3704 continue;
3705
3706 List<SceneObjectGroup> atts = sp.Attachments;
3707 bool found = false;
3708 foreach (SceneObjectGroup att in atts)
3660 { 3709 {
3661 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3710 if (att == part.ParentGroup)
3662 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3663 { 3711 {
3664 part.Shape.LightEntry = false; 3712 found = true;
3713 break;
3665 } 3714 }
3666 } 3715 }
3716
3717 // It's an attachment of a valid avatar, but
3718 // doesn't seem to be attached, skip
3719 if (!found)
3720 continue;
3667 } 3721 }
3668 3722 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3669 ++updatesThisCall;
3670
3671 #region UpdateFlags to packet type conversion
3672
3673 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3674
3675 bool canUseCompressed = true;
3676 bool canUseImproved = true;
3677
3678 // Compressed object updates only make sense for LL primitives
3679 if (!(update.Entity is SceneObjectPart))
3680 {
3681 canUseCompressed = false;
3682 }
3683
3684 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3685 {
3686 canUseCompressed = false;
3687 canUseImproved = false;
3688 }
3689 else
3690 { 3723 {
3691 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3724 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3692 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3725 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3693 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3694 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3695 { 3726 {
3696 canUseCompressed = false; 3727 part.Shape.LightEntry = false;
3697 }
3698
3699 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3700 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3701 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3702 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3703 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3704 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3705 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3706 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3707 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3708 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3709 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3710 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3711 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3712 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3713 {
3714 canUseImproved = false;
3715 } 3728 }
3716 } 3729 }
3717 3730 }
3718 #endregion UpdateFlags to packet type conversion 3731
3719 3732 ++updatesThisCall;
3720 #region Block Construction 3733
3721 3734 #region UpdateFlags to packet type conversion
3722 // TODO: Remove this once we can build compressed updates 3735
3736 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3737
3738 bool canUseCompressed = true;
3739 bool canUseImproved = true;
3740
3741 // Compressed object updates only make sense for LL primitives
3742 if (!(update.Entity is SceneObjectPart))
3743 {
3723 canUseCompressed = false; 3744 canUseCompressed = false;
3724 3745 }
3725 if (!canUseImproved && !canUseCompressed) 3746
3726 { 3747 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3727 if (update.Entity is ScenePresence) 3748 {
3728 { 3749 canUseCompressed = false;
3729 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3750 canUseImproved = false;
3730 objectUpdates.Value.Add(update); 3751 }
3731 } 3752 else
3732 else 3753 {
3733 { 3754 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3734 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3755 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3735 objectUpdates.Value.Add(update); 3756 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3736 } 3757 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3737 }
3738 else if (!canUseImproved)
3739 { 3758 {
3740 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3759 canUseCompressed = false;
3741 compressedUpdates.Value.Add(update);
3742 } 3760 }
3743 else 3761
3762 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3775 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3744 { 3776 {
3745 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3777 canUseImproved = false;
3746 {
3747 // Self updates go into a special list
3748 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3749 terseAgentUpdates.Value.Add(update);
3750 }
3751 else
3752 {
3753 // Everything else goes here
3754 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3755 terseUpdates.Value.Add(update);
3756 }
3757 } 3778 }
3758
3759 #endregion Block Construction
3760 } 3779 }
3761
3762
3763 #region Packet Sending
3764 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3765 3780
3766 if (terseAgentUpdateBlocks.IsValueCreated) 3781 #endregion UpdateFlags to packet type conversion
3767 {
3768 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3769 3782
3770 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3783 #region Block Construction
3771 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3772 packet.RegionData.TimeDilation = timeDilation;
3773 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3774 3784
3775 for (int i = 0; i < blocks.Count; i++) 3785 // TODO: Remove this once we can build compressed updates
3776 packet.ObjectData[i] = blocks[i]; 3786 canUseCompressed = false;
3777 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3778 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3779 }
3780 3787
3781 if (objectUpdateBlocks.IsValueCreated) 3788 if (!canUseImproved && !canUseCompressed)
3782 { 3789 {
3783 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3790 if (update.Entity is ScenePresence)
3784 3791 {
3785 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3792 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3786 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3793 }
3787 packet.RegionData.TimeDilation = timeDilation; 3794 else
3788 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3795 {
3789 3796 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3790 for (int i = 0; i < blocks.Count; i++) 3797 }
3791 packet.ObjectData[i] = blocks[i];
3792 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3793 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3794 } 3798 }
3795 3799 else if (!canUseImproved)
3796 if (compressedUpdateBlocks.IsValueCreated)
3797 { 3800 {
3798 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3801 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3799
3800 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3801 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3802 packet.RegionData.TimeDilation = timeDilation;
3803 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3804
3805 for (int i = 0; i < blocks.Count; i++)
3806 packet.ObjectData[i] = blocks[i];
3807 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3808 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3809 } 3802 }
3810 3803 else
3811 if (terseUpdateBlocks.IsValueCreated)
3812 { 3804 {
3813 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3805 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3814 3806 // Self updates go into a special list
3815 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3807 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3816 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3808 else
3817 packet.RegionData.TimeDilation = timeDilation; 3809 // Everything else goes here
3818 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3810 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3819
3820 for (int i = 0; i < blocks.Count; i++)
3821 packet.ObjectData[i] = blocks[i];
3822 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3823 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3824 } 3811 }
3812
3813 #endregion Block Construction
3814 }
3815
3816 #region Packet Sending
3817
3818 const float TIME_DILATION = 1.0f;
3819 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3820
3821 if (terseAgentUpdateBlocks.IsValueCreated)
3822 {
3823 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3824
3825 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3826 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3827 packet.RegionData.TimeDilation = timeDilation;
3828 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3829
3830 for (int i = 0; i < blocks.Count; i++)
3831 packet.ObjectData[i] = blocks[i];
3832
3833 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3834 }
3835
3836 if (objectUpdateBlocks.IsValueCreated)
3837 {
3838 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3839
3840 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3841 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3842 packet.RegionData.TimeDilation = timeDilation;
3843 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3844
3845 for (int i = 0; i < blocks.Count; i++)
3846 packet.ObjectData[i] = blocks[i];
3847
3848 OutPacket(packet, ThrottleOutPacketType.Task, true);
3849 }
3850
3851 if (compressedUpdateBlocks.IsValueCreated)
3852 {
3853 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3854
3855 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3856 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3857 packet.RegionData.TimeDilation = timeDilation;
3858 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3859
3860 for (int i = 0; i < blocks.Count; i++)
3861 packet.ObjectData[i] = blocks[i];
3862
3863 OutPacket(packet, ThrottleOutPacketType.Task, true);
3864 }
3865
3866 if (terseUpdateBlocks.IsValueCreated)
3867 {
3868 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3869
3870 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3871 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3872 packet.RegionData.TimeDilation = timeDilation;
3873 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3874
3875 for (int i = 0; i < blocks.Count; i++)
3876 packet.ObjectData[i] = blocks[i];
3877
3878 OutPacket(packet, ThrottleOutPacketType.Task, true);
3825 } 3879 }
3826 3880
3827 #endregion Packet Sending 3881 #endregion Packet Sending
@@ -4629,14 +4683,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4629 4683
4630 if (notifyCount > 0) 4684 if (notifyCount > 0)
4631 { 4685 {
4632 if (notifyCount > 32) 4686// if (notifyCount > 32)
4633 { 4687// {
4634 m_log.InfoFormat( 4688// m_log.InfoFormat(
4635 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4689// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4636 + " - a developer might want to investigate whether this is a hard limit", 32); 4690// + " - a developer might want to investigate whether this is a hard limit", 32);
4637 4691//
4638 notifyCount = 32; 4692// notifyCount = 32;
4639 } 4693// }
4640 4694
4641 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4695 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4642 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4696 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5144,6 +5198,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5144 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5198 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5145 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5199 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5146 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5200 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5201 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5147 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5202 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5148 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5203 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5149 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5204 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5243,6 +5298,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5243 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5298 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5244 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5299 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5245 (x.ControlFlags != lastarg.ControlFlags) || 5300 (x.ControlFlags != lastarg.ControlFlags) ||
5301 (x.ControlFlags != 0) ||
5246 (x.Far != lastarg.Far) || 5302 (x.Far != lastarg.Far) ||
5247 (x.Flags != lastarg.Flags) || 5303 (x.Flags != lastarg.Flags) ||
5248 (x.State != lastarg.State) || 5304 (x.State != lastarg.State) ||
@@ -5616,7 +5672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5616 args.Channel = ch; 5672 args.Channel = ch;
5617 args.From = String.Empty; 5673 args.From = String.Empty;
5618 args.Message = Utils.BytesToString(msg); 5674 args.Message = Utils.BytesToString(msg);
5619 args.Type = ChatTypeEnum.Shout; 5675 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5620 args.Position = new Vector3(); 5676 args.Position = new Vector3();
5621 args.Scene = Scene; 5677 args.Scene = Scene;
5622 args.Sender = this; 5678 args.Sender = this;
@@ -9604,7 +9660,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9604 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9660 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9605 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9661 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9606 UpdateMuteListEntry.MuteData.MuteType, 9662 UpdateMuteListEntry.MuteData.MuteType,
9607 UpdateMuteListEntry.AgentData.AgentID); 9663 UpdateMuteListEntry.MuteData.MuteFlags);
9608 return true; 9664 return true;
9609 } 9665 }
9610 return false; 9666 return false;
@@ -9619,8 +9675,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9619 { 9675 {
9620 handlerRemoveMuteListEntry(this, 9676 handlerRemoveMuteListEntry(this,
9621 RemoveMuteListEntry.MuteData.MuteID, 9677 RemoveMuteListEntry.MuteData.MuteID,
9622 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9678 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9623 RemoveMuteListEntry.AgentData.AgentID);
9624 return true; 9679 return true;
9625 } 9680 }
9626 return false; 9681 return false;
@@ -9668,6 +9723,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9668 { 9723 {
9669 return true; 9724 return true;
9670 } 9725 }
9726
9727 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9728 {
9729 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9730
9731 #region Packet Session and User Check
9732 if (m_checkPackets)
9733 {
9734 if (packet.AgentData.SessionID != SessionId ||
9735 packet.AgentData.AgentID != AgentId)
9736 return true;
9737 }
9738 #endregion
9739 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9740 List<InventoryItemBase> items = new List<InventoryItemBase>();
9741 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9742 {
9743 InventoryItemBase b = new InventoryItemBase();
9744 b.ID = n.OldItemID;
9745 b.Folder = n.OldFolderID;
9746 items.Add(b);
9747 }
9748
9749 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9750 if (handlerMoveItemsAndLeaveCopy != null)
9751 {
9752 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9753 }
9754
9755 return true;
9756 }
9671 9757
9672 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9758 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9673 { 9759 {
@@ -10094,6 +10180,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10094 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10180 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10095 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10181 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10096 10182
10183 Scene scene = (Scene)m_scene;
10184 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10185 {
10186 ScenePresence p;
10187 if (scene.TryGetScenePresence(sender.AgentId, out p))
10188 {
10189 if (p.GodLevel >= 200)
10190 {
10191 groupProfileReply.GroupData.OpenEnrollment = true;
10192 groupProfileReply.GroupData.MembershipFee = 0;
10193 }
10194 }
10195 }
10196
10097 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10197 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10098 } 10198 }
10099 return true; 10199 return true;
@@ -10666,11 +10766,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10666 10766
10667 StartLure handlerStartLure = OnStartLure; 10767 StartLure handlerStartLure = OnStartLure;
10668 if (handlerStartLure != null) 10768 if (handlerStartLure != null)
10669 handlerStartLure(startLureRequest.Info.LureType, 10769 {
10670 Utils.BytesToString( 10770 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10671 startLureRequest.Info.Message), 10771 {
10672 startLureRequest.TargetData[0].TargetID, 10772 handlerStartLure(startLureRequest.Info.LureType,
10673 this); 10773 Utils.BytesToString(
10774 startLureRequest.Info.Message),
10775 startLureRequest.TargetData[i].TargetID,
10776 this);
10777 }
10778 }
10674 return true; 10779 return true;
10675 } 10780 }
10676 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10781 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10784,10 +10889,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10784 } 10889 }
10785 #endregion 10890 #endregion
10786 10891
10787 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10892 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10788 if (handlerClassifiedGodDelete != null) 10893 if (handlerClassifiedGodDelete != null)
10789 handlerClassifiedGodDelete( 10894 handlerClassifiedGodDelete(
10790 classifiedGodDelete.Data.ClassifiedID, 10895 classifiedGodDelete.Data.ClassifiedID,
10896 classifiedGodDelete.Data.QueryID,
10791 this); 10897 this);
10792 return true; 10898 return true;
10793 } 10899 }
@@ -11165,7 +11271,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11165 { 11271 {
11166 // It's a ghost! tell the client to delete it from view. 11272 // It's a ghost! tell the client to delete it from view.
11167 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11273 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11168 localId); 11274 new List<uint>() { localId });
11169 } 11275 }
11170 else 11276 else
11171 { 11277 {
@@ -11554,22 +11660,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11554 /// <param name="Pack">OpenMetaverse.packet</param> 11660 /// <param name="Pack">OpenMetaverse.packet</param>
11555 public void ProcessInPacket(Packet packet) 11661 public void ProcessInPacket(Packet packet)
11556 { 11662 {
11557 if (m_debugPacketLevel > 0) 11663 if (m_debugPacketLevel >= 255)
11558 { 11664 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11559 bool outputPacket = true;
11560
11561 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11562 outputPacket = false;
11563
11564 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11565 outputPacket = false;
11566
11567 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11568 outputPacket = false;
11569
11570 if (outputPacket)
11571 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11572 }
11573 11665
11574 if (!ProcessPacketMethod(packet)) 11666 if (!ProcessPacketMethod(packet))
11575 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11667 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11811,7 +11903,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11811 11903
11812// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11904// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11813 11905
11906
11907 //Note, the bool returned from the below function is useless since it is always false.
11814 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11908 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11909
11815 } 11910 }
11816 11911
11817 /// <summary> 11912 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 20bfec8..e54d326 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/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
@@ -443,6 +444,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
443 if (category >= 0 && category < m_packetOutboxes.Length) 444 if (category >= 0 && category < m_packetOutboxes.Length)
444 { 445 {
445 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 446 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
447
448 if (m_deliverPackets == false)
449 {
450 queue.Enqueue(packet);
451 return true;
452 }
453
446 TokenBucket bucket = m_throttleCategories[category]; 454 TokenBucket bucket = m_throttleCategories[category];
447 455
448 // Don't send this packet if there is already a packet waiting in the queue 456 // Don't send this packet if there is already a packet waiting in the queue
@@ -492,6 +500,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
492 /// <returns>True if any packets were sent, otherwise false</returns> 500 /// <returns>True if any packets were sent, otherwise false</returns>
493 public bool DequeueOutgoing() 501 public bool DequeueOutgoing()
494 { 502 {
503 if (m_deliverPackets == false) return false;
504
495 OutgoingPacket packet; 505 OutgoingPacket packet;
496 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 506 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
497 TokenBucket bucket; 507 TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index bd58ddc..a1a58e5 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/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/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index 6eebd9d..d2779ba 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/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,