aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs735
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 446 insertions, 312 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 7affa45..de08f90 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
@@ -791,7 +813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 reply.ChatData.OwnerID = fromAgentID; 813 reply.ChatData.OwnerID = fromAgentID;
792 reply.ChatData.SourceID = fromAgentID; 814 reply.ChatData.SourceID = fromAgentID;
793 815
794 OutPacket(reply, ThrottleOutPacketType.Task); 816 OutPacket(reply, ThrottleOutPacketType.Unknown);
795 } 817 }
796 818
797 /// <summary> 819 /// <summary>
@@ -1077,6 +1099,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1077 public virtual void SendLayerData(float[] map) 1099 public virtual void SendLayerData(float[] map)
1078 { 1100 {
1079 Util.FireAndForget(DoSendLayerData, map); 1101 Util.FireAndForget(DoSendLayerData, map);
1102
1103 // Send it sync, and async. It's not that much data
1104 // and it improves user experience just so much!
1105 DoSendLayerData(map);
1080 } 1106 }
1081 1107
1082 /// <summary> 1108 /// <summary>
@@ -1089,16 +1115,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1089 1115
1090 try 1116 try
1091 { 1117 {
1092 //for (int y = 0; y < 16; y++) 1118 for (int y = 0; y < 16; y++)
1093 //{ 1119 {
1094 // for (int x = 0; x < 16; x++) 1120 for (int x = 0; x < 16; x+=4)
1095 // { 1121 {
1096 // SendLayerData(x, y, map); 1122 SendLayerPacket(x, y, map);
1097 // } 1123 }
1098 //} 1124 }
1099
1100 // Send LayerData in a spiral pattern. Fun!
1101 SendLayerTopRight(map, 0, 0, 15, 15);
1102 } 1125 }
1103 catch (Exception e) 1126 catch (Exception e)
1104 { 1127 {
@@ -1106,51 +1129,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1106 } 1129 }
1107 } 1130 }
1108 1131
1109 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1110 {
1111 // Row
1112 for (int i = x1; i <= x2; i++)
1113 SendLayerData(i, y1, map);
1114
1115 // Column
1116 for (int j = y1 + 1; j <= y2; j++)
1117 SendLayerData(x2, j, map);
1118
1119 if (x2 - x1 > 0)
1120 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1121 }
1122
1123 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1124 {
1125 // Row in reverse
1126 for (int i = x2; i >= x1; i--)
1127 SendLayerData(i, y2, map);
1128
1129 // Column in reverse
1130 for (int j = y2 - 1; j >= y1; j--)
1131 SendLayerData(x1, j, map);
1132
1133 if (x2 - x1 > 0)
1134 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1135 }
1136
1137 /// <summary> 1132 /// <summary>
1138 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1133 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1139 /// </summary> 1134 /// </summary>
1140 /// <param name="map">heightmap</param> 1135 /// <param name="map">heightmap</param>
1141 /// <param name="px">X coordinate for patches 0..12</param> 1136 /// <param name="px">X coordinate for patches 0..12</param>
1142 /// <param name="py">Y coordinate for patches 0..15</param> 1137 /// <param name="py">Y coordinate for patches 0..15</param>
1143 // private void SendLayerPacket(float[] map, int y, int x) 1138 private void SendLayerPacket(int x, int y, float[] map)
1144 // { 1139 {
1145 // int[] patches = new int[4]; 1140 int[] patches = new int[4];
1146 // patches[0] = x + 0 + y * 16; 1141 patches[0] = x + 0 + y * 16;
1147 // patches[1] = x + 1 + y * 16; 1142 patches[1] = x + 1 + y * 16;
1148 // patches[2] = x + 2 + y * 16; 1143 patches[2] = x + 2 + y * 16;
1149 // patches[3] = x + 3 + y * 16; 1144 patches[3] = x + 3 + y * 16;
1150 1145
1151 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1146 float[] heightmap = (map.Length == 65536) ?
1152 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1147 map :
1153 // } 1148 LLHeightFieldMoronize(map);
1149
1150 try
1151 {
1152 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1153 OutPacket(layerpack, ThrottleOutPacketType.Land);
1154 }
1155 catch
1156 {
1157 for (int px = x ; px < x + 4 ; px++)
1158 SendLayerData(px, y, map);
1159 }
1160 }
1154 1161
1155 /// <summary> 1162 /// <summary>
1156 /// Sends a specified patch to a client 1163 /// Sends a specified patch to a client
@@ -1170,7 +1177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1170 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1177 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1171 layerpack.Header.Reliable = true; 1178 layerpack.Header.Reliable = true;
1172 1179
1173 OutPacket(layerpack, ThrottleOutPacketType.Land); 1180 OutPacket(layerpack, ThrottleOutPacketType.Task);
1174 } 1181 }
1175 catch (Exception e) 1182 catch (Exception e)
1176 { 1183 {
@@ -1531,38 +1538,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1531 OutPacket(pc, ThrottleOutPacketType.Unknown); 1538 OutPacket(pc, ThrottleOutPacketType.Unknown);
1532 } 1539 }
1533 1540
1534 public void SendKillObject(ulong regionHandle, uint localID) 1541 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1535 { 1542 {
1536// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1543// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1537 1544
1538 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1545 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1539 // TODO: don't create new blocks if recycling an old packet 1546 // TODO: don't create new blocks if recycling an old packet
1540 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1547 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1541 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1548 for (int i = 0 ; i < localIDs.Count ; i++ )
1542 kill.ObjectData[0].ID = localID; 1549 {
1550 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1551 kill.ObjectData[i].ID = localIDs[i];
1552 }
1543 kill.Header.Reliable = true; 1553 kill.Header.Reliable = true;
1544 kill.Header.Zerocoded = true; 1554 kill.Header.Zerocoded = true;
1545 1555
1546 if (m_scene.GetScenePresence(localID) == null) 1556 lock (m_killRecord)
1547 { 1557 {
1548 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1558 if (localIDs.Count == 1)
1549 // condition where a kill can be processed before an out-of-date update for the same object.
1550 lock (m_killRecord)
1551 { 1559 {
1552 m_killRecord.Add(localID); 1560 if (m_scene.GetScenePresence(localIDs[0]) != null)
1553 1561 {
1554 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1562 OutPacket(kill, ThrottleOutPacketType.State);
1555 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1563 return;
1556 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1564 }
1557 // scene objects in a viewer until that viewer is relogged in. 1565 m_killRecord.Add(localIDs[0]);
1558 OutPacket(kill, ThrottleOutPacketType.Task); 1566 }
1567 else
1568 {
1569 lock (m_entityUpdates.SyncRoot)
1570 {
1571 foreach (uint localID in localIDs)
1572 m_killRecord.Add(localID);
1573 }
1559 } 1574 }
1560 } 1575 }
1561 else 1576
1562 { 1577 // The throttle queue used here must match that being used for
1563 // OutPacket(kill, ThrottleOutPacketType.State); 1578 // updates. Otherwise, there is a chance that a kill packet put
1564 OutPacket(kill, ThrottleOutPacketType.Task); 1579 // on a separate queue will be sent to the client before an
1565 } 1580 // existing update packet on another queue. Receiving updates
1581 // after kills results in unowned and undeletable
1582 // scene objects in a viewer until that viewer is relogged in.
1583 OutPacket(kill, ThrottleOutPacketType.Task);
1566 } 1584 }
1567 1585
1568 /// <summary> 1586 /// <summary>
@@ -2287,6 +2305,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2287 OutPacket(sound, ThrottleOutPacketType.Task); 2305 OutPacket(sound, ThrottleOutPacketType.Task);
2288 } 2306 }
2289 2307
2308 public void SendTransferAbort(TransferRequestPacket transferRequest)
2309 {
2310 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2311 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2312 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2313 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2314 OutPacket(abort, ThrottleOutPacketType.Task);
2315 }
2316
2290 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2317 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2291 { 2318 {
2292 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2319 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3589,7 +3616,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3589 /// </summary> 3616 /// </summary>
3590 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3617 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3591 { 3618 {
3592 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3619 if (entity is SceneObjectPart)
3620 {
3621 SceneObjectPart e = (SceneObjectPart)entity;
3622 SceneObjectGroup g = e.ParentGroup;
3623 if (g.RootPart.Shape.State > 30) // HUD
3624 if (g.OwnerID != AgentId)
3625 return; // Don't send updates for other people's HUDs
3626 }
3627
3593 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3628 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3594 3629
3595 lock (m_entityUpdates.SyncRoot) 3630 lock (m_entityUpdates.SyncRoot)
@@ -3656,211 +3691,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3656 3691
3657 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3692 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3658 // condition where a kill can be processed before an out-of-date update for the same object. 3693 // condition where a kill can be processed before an out-of-date update for the same object.
3659 lock (m_killRecord) 3694 float avgTimeDilation = 1.0f;
3695 IEntityUpdate iupdate;
3696 Int32 timeinqueue; // this is just debugging code & can be dropped later
3697
3698 while (updatesThisCall < maxUpdates)
3660 { 3699 {
3661 float avgTimeDilation = 1.0f; 3700 lock (m_entityUpdates.SyncRoot)
3662 IEntityUpdate iupdate; 3701 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3663 Int32 timeinqueue; // this is just debugging code & can be dropped later 3702 break;
3664
3665 while (updatesThisCall < maxUpdates)
3666 {
3667 lock (m_entityUpdates.SyncRoot)
3668 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3669 break;
3670 3703
3671 EntityUpdate update = (EntityUpdate)iupdate; 3704 EntityUpdate update = (EntityUpdate)iupdate;
3672 3705
3673 avgTimeDilation += update.TimeDilation; 3706 avgTimeDilation += update.TimeDilation;
3674 avgTimeDilation *= 0.5f; 3707 avgTimeDilation *= 0.5f;
3675 3708
3676 if (update.Entity is SceneObjectPart) 3709 if (update.Entity is SceneObjectPart)
3710 {
3711 SceneObjectPart part = (SceneObjectPart)update.Entity;
3712
3713 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3714 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3715 // safety measure.
3716 //
3717 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3718 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3719 // updates and kills on different threads with different scheduling strategies, hence this protection.
3720 //
3721 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3722 // after the root prim has been deleted.
3723 lock (m_killRecord)
3677 { 3724 {
3678 SceneObjectPart part = (SceneObjectPart)update.Entity;
3679
3680 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3681 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3682 // safety measure.
3683 //
3684 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3685 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3686 // updates and kills on different threads with different scheduling strategies, hence this protection.
3687 //
3688 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3689 // after the root prim has been deleted.
3690 if (m_killRecord.Contains(part.LocalId)) 3725 if (m_killRecord.Contains(part.LocalId))
3691 {
3692 // m_log.WarnFormat(
3693 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3694 // part.LocalId, Name);
3695 continue; 3726 continue;
3696 } 3727 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3697 3728 continue;
3698 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3729 }
3730
3731 if (part.ParentGroup.IsDeleted)
3732 continue;
3733
3734 if (part.ParentGroup.IsAttachment)
3735 { // Someone else's HUD, why are we getting these?
3736 if (part.ParentGroup.OwnerID != AgentId &&
3737 part.ParentGroup.RootPart.Shape.State >= 30)
3738 continue;
3739 ScenePresence sp;
3740 // Owner is not in the sim, don't update it to
3741 // anyone
3742 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3743 continue;
3744
3745 List<SceneObjectGroup> atts = sp.GetAttachments();
3746 bool found = false;
3747 foreach (SceneObjectGroup att in atts)
3699 { 3748 {
3700 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3749 if (att == part.ParentGroup)
3701 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3702 { 3750 {
3703 part.Shape.LightEntry = false; 3751 found = true;
3752 break;
3704 } 3753 }
3705 } 3754 }
3755
3756 // It's an attachment of a valid avatar, but
3757 // doesn't seem to be attached, skip
3758 if (!found)
3759 continue;
3706 } 3760 }
3707 3761 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3708 ++updatesThisCall;
3709
3710 #region UpdateFlags to packet type conversion
3711
3712 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3713
3714 bool canUseCompressed = true;
3715 bool canUseImproved = true;
3716
3717 // Compressed object updates only make sense for LL primitives
3718 if (!(update.Entity is SceneObjectPart))
3719 {
3720 canUseCompressed = false;
3721 }
3722
3723 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3724 {
3725 canUseCompressed = false;
3726 canUseImproved = false;
3727 }
3728 else
3729 { 3762 {
3730 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3763 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3731 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3764 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3732 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3733 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3734 {
3735 canUseCompressed = false;
3736 }
3737
3738 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3739 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3740 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3741 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3742 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3743 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3744 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3745 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3746 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3747 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3748 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3751 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3752 { 3765 {
3753 canUseImproved = false; 3766 part.Shape.LightEntry = false;
3754 } 3767 }
3755 } 3768 }
3756 3769 }
3757 #endregion UpdateFlags to packet type conversion 3770
3758 3771 ++updatesThisCall;
3759 #region Block Construction 3772
3760 3773 #region UpdateFlags to packet type conversion
3761 // TODO: Remove this once we can build compressed updates 3774
3775 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3776
3777 bool canUseCompressed = true;
3778 bool canUseImproved = true;
3779
3780 // Compressed object updates only make sense for LL primitives
3781 if (!(update.Entity is SceneObjectPart))
3782 {
3762 canUseCompressed = false; 3783 canUseCompressed = false;
3763 3784 }
3764 if (!canUseImproved && !canUseCompressed) 3785
3765 { 3786 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3766 if (update.Entity is ScenePresence) 3787 {
3767 { 3788 canUseCompressed = false;
3768 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3789 canUseImproved = false;
3769 objectUpdates.Value.Add(update); 3790 }
3770 } 3791 else
3771 else 3792 {
3772 { 3793 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3773 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3794 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3774 objectUpdates.Value.Add(update); 3795 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3775 } 3796 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3776 }
3777 else if (!canUseImproved)
3778 { 3797 {
3779 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3798 canUseCompressed = false;
3780 compressedUpdates.Value.Add(update);
3781 } 3799 }
3782 else 3800
3801 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3783 { 3815 {
3784 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3816 canUseImproved = false;
3785 {
3786 // Self updates go into a special list
3787 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3788 terseAgentUpdates.Value.Add(update);
3789 }
3790 else
3791 {
3792 // Everything else goes here
3793 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3794 terseUpdates.Value.Add(update);
3795 }
3796 } 3817 }
3797
3798 #endregion Block Construction
3799 } 3818 }
3800
3801
3802 #region Packet Sending
3803 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3804 3819
3805 if (terseAgentUpdateBlocks.IsValueCreated) 3820 #endregion UpdateFlags to packet type conversion
3806 {
3807 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3808 3821
3809 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3822 #region Block Construction
3810 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3811 packet.RegionData.TimeDilation = timeDilation;
3812 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3813 3823
3814 for (int i = 0; i < blocks.Count; i++) 3824 // TODO: Remove this once we can build compressed updates
3815 packet.ObjectData[i] = blocks[i]; 3825 canUseCompressed = false;
3816 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3817 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3818 }
3819 3826
3820 if (objectUpdateBlocks.IsValueCreated) 3827 if (!canUseImproved && !canUseCompressed)
3821 { 3828 {
3822 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3829 if (update.Entity is ScenePresence)
3823 3830 {
3824 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3831 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3825 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3832 }
3826 packet.RegionData.TimeDilation = timeDilation; 3833 else
3827 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3834 {
3828 3835 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3829 for (int i = 0; i < blocks.Count; i++) 3836 }
3830 packet.ObjectData[i] = blocks[i];
3831 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3832 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3833 } 3837 }
3834 3838 else if (!canUseImproved)
3835 if (compressedUpdateBlocks.IsValueCreated)
3836 { 3839 {
3837 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3840 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3838
3839 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3840 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3841 packet.RegionData.TimeDilation = timeDilation;
3842 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3843
3844 for (int i = 0; i < blocks.Count; i++)
3845 packet.ObjectData[i] = blocks[i];
3846 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3847 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3848 } 3841 }
3849 3842 else
3850 if (terseUpdateBlocks.IsValueCreated)
3851 { 3843 {
3852 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3844 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3853 3845 // Self updates go into a special list
3854 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3846 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3855 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3847 else
3856 packet.RegionData.TimeDilation = timeDilation; 3848 // Everything else goes here
3857 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3849 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3858
3859 for (int i = 0; i < blocks.Count; i++)
3860 packet.ObjectData[i] = blocks[i];
3861 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3862 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3863 } 3850 }
3851
3852 #endregion Block Construction
3853 }
3854
3855 #region Packet Sending
3856
3857 const float TIME_DILATION = 1.0f;
3858 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3859
3860 if (terseAgentUpdateBlocks.IsValueCreated)
3861 {
3862 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3863
3864 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3865 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3866 packet.RegionData.TimeDilation = timeDilation;
3867 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3868
3869 for (int i = 0; i < blocks.Count; i++)
3870 packet.ObjectData[i] = blocks[i];
3871
3872 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3873 }
3874
3875 if (objectUpdateBlocks.IsValueCreated)
3876 {
3877 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3878
3879 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3880 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3881 packet.RegionData.TimeDilation = timeDilation;
3882 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3883
3884 for (int i = 0; i < blocks.Count; i++)
3885 packet.ObjectData[i] = blocks[i];
3886
3887 OutPacket(packet, ThrottleOutPacketType.Task, true);
3888 }
3889
3890 if (compressedUpdateBlocks.IsValueCreated)
3891 {
3892 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3893
3894 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3895 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3896 packet.RegionData.TimeDilation = timeDilation;
3897 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3898
3899 for (int i = 0; i < blocks.Count; i++)
3900 packet.ObjectData[i] = blocks[i];
3901
3902 OutPacket(packet, ThrottleOutPacketType.Task, true);
3903 }
3904
3905 if (terseUpdateBlocks.IsValueCreated)
3906 {
3907 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3908
3909 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3910 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3911 packet.RegionData.TimeDilation = timeDilation;
3912 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3913
3914 for (int i = 0; i < blocks.Count; i++)
3915 packet.ObjectData[i] = blocks[i];
3916
3917 OutPacket(packet, ThrottleOutPacketType.Task, true);
3864 } 3918 }
3865 3919
3866 #endregion Packet Sending 3920 #endregion Packet Sending
@@ -4161,11 +4215,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4161 4215
4162 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4216 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4163 // of the object rather than the properties when the packet was created 4217 // of the object rather than the properties when the packet was created
4164 OutPacket(packet, ThrottleOutPacketType.Task, true, 4218 // HACK : Remove intelligent resending until it's fixed in core
4165 delegate(OutgoingPacket oPacket) 4219 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4166 { 4220 // delegate(OutgoingPacket oPacket)
4167 ResendPropertyUpdates(updates, oPacket); 4221 // {
4168 }); 4222 // ResendPropertyUpdates(updates, oPacket);
4223 // });
4224 OutPacket(packet, ThrottleOutPacketType.Task, true);
4169 4225
4170 // pbcnt += blocks.Count; 4226 // pbcnt += blocks.Count;
4171 // ppcnt++; 4227 // ppcnt++;
@@ -4191,11 +4247,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4191 // of the object rather than the properties when the packet was created 4247 // of the object rather than the properties when the packet was created
4192 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4248 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4193 updates.Add(familyUpdates.Value[i]); 4249 updates.Add(familyUpdates.Value[i]);
4194 OutPacket(packet, ThrottleOutPacketType.Task, true, 4250 // HACK : Remove intelligent resending until it's fixed in core
4195 delegate(OutgoingPacket oPacket) 4251 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4196 { 4252 // delegate(OutgoingPacket oPacket)
4197 ResendPropertyUpdates(updates, oPacket); 4253 // {
4198 }); 4254 // ResendPropertyUpdates(updates, oPacket);
4255 // });
4256 OutPacket(packet, ThrottleOutPacketType.Task, true);
4199 4257
4200 // fpcnt++; 4258 // fpcnt++;
4201 // fbcnt++; 4259 // fbcnt++;
@@ -4344,37 +4402,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4344 if (bl[i].BannedUserID == UUID.Zero) 4402 if (bl[i].BannedUserID == UUID.Zero)
4345 continue; 4403 continue;
4346 BannedUsers.Add(bl[i].BannedUserID); 4404 BannedUsers.Add(bl[i].BannedUserID);
4347 }
4348 4405
4349 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4406 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4350 packet.AgentData.TransactionID = UUID.Random(); 4407 {
4351 packet.AgentData.AgentID = AgentId; 4408 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4352 packet.AgentData.SessionID = SessionId; 4409 packet.AgentData.TransactionID = UUID.Random();
4353 packet.MethodData.Invoice = invoice; 4410 packet.AgentData.AgentID = AgentId;
4354 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4411 packet.AgentData.SessionID = SessionId;
4412 packet.MethodData.Invoice = invoice;
4413 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4355 4414
4356 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4415 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4357 4416
4358 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4417 int j;
4359 { 4418 for (j = 0; j < (6 + BannedUsers.Count); j++)
4360 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4419 {
4361 } 4420 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4362 int j = 0; 4421 }
4422 j = 0;
4363 4423
4364 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4424 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4365 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4425 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4366 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4426 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4367 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4427 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4368 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4428 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4369 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4429 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4370 4430
4371 foreach (UUID banned in BannedUsers) 4431 foreach (UUID banned in BannedUsers)
4372 { 4432 {
4373 returnblock[j].Parameter = banned.GetBytes(); j++; 4433 returnblock[j].Parameter = banned.GetBytes(); j++;
4434 }
4435 packet.ParamList = returnblock;
4436 packet.Header.Reliable = true;
4437 OutPacket(packet, ThrottleOutPacketType.Task);
4438
4439 BannedUsers.Clear();
4440 }
4374 } 4441 }
4375 packet.ParamList = returnblock; 4442
4376 packet.Header.Reliable = false;
4377 OutPacket(packet, ThrottleOutPacketType.Task);
4378 } 4443 }
4379 4444
4380 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4445 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4543,7 +4608,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4543 4608
4544 if (landData.SimwideArea > 0) 4609 if (landData.SimwideArea > 0)
4545 { 4610 {
4546 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4611 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4612 // Never report more than sim total capacity
4613 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4614 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4547 updateMessage.SimWideMaxPrims = simulatorCapacity; 4615 updateMessage.SimWideMaxPrims = simulatorCapacity;
4548 } 4616 }
4549 else 4617 else
@@ -4672,14 +4740,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4672 4740
4673 if (notifyCount > 0) 4741 if (notifyCount > 0)
4674 { 4742 {
4675 if (notifyCount > 32) 4743// if (notifyCount > 32)
4676 { 4744// {
4677 m_log.InfoFormat( 4745// m_log.InfoFormat(
4678 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4746// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4679 + " - a developer might want to investigate whether this is a hard limit", 32); 4747// + " - a developer might want to investigate whether this is a hard limit", 32);
4680 4748//
4681 notifyCount = 32; 4749// notifyCount = 32;
4682 } 4750// }
4683 4751
4684 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4752 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4685 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4753 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5213,6 +5281,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5213 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5281 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5214 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5282 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5215 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5283 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5284 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5216 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5285 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5217 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5286 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5218 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5287 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5314,6 +5383,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5314 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5383 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5315 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5384 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5316 (x.ControlFlags != lastarg.ControlFlags) || 5385 (x.ControlFlags != lastarg.ControlFlags) ||
5386 (x.ControlFlags != 0) ||
5317 (x.Far != lastarg.Far) || 5387 (x.Far != lastarg.Far) ||
5318 (x.Flags != lastarg.Flags) || 5388 (x.Flags != lastarg.Flags) ||
5319 (x.State != lastarg.State) || 5389 (x.State != lastarg.State) ||
@@ -5691,7 +5761,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5691 args.Channel = ch; 5761 args.Channel = ch;
5692 args.From = String.Empty; 5762 args.From = String.Empty;
5693 args.Message = Utils.BytesToString(msg); 5763 args.Message = Utils.BytesToString(msg);
5694 args.Type = ChatTypeEnum.Shout; 5764 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5695 args.Position = new Vector3(); 5765 args.Position = new Vector3();
5696 args.Scene = Scene; 5766 args.Scene = Scene;
5697 args.Sender = this; 5767 args.Sender = this;
@@ -9697,7 +9767,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9697 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9767 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9698 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9768 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9699 UpdateMuteListEntry.MuteData.MuteType, 9769 UpdateMuteListEntry.MuteData.MuteType,
9700 UpdateMuteListEntry.AgentData.AgentID); 9770 UpdateMuteListEntry.MuteData.MuteFlags);
9701 return true; 9771 return true;
9702 } 9772 }
9703 return false; 9773 return false;
@@ -9712,8 +9782,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9712 { 9782 {
9713 handlerRemoveMuteListEntry(this, 9783 handlerRemoveMuteListEntry(this,
9714 RemoveMuteListEntry.MuteData.MuteID, 9784 RemoveMuteListEntry.MuteData.MuteID,
9715 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9785 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9716 RemoveMuteListEntry.AgentData.AgentID);
9717 return true; 9786 return true;
9718 } 9787 }
9719 return false; 9788 return false;
@@ -9761,6 +9830,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9761 { 9830 {
9762 return true; 9831 return true;
9763 } 9832 }
9833
9834 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9835 {
9836 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9837
9838 #region Packet Session and User Check
9839 if (m_checkPackets)
9840 {
9841 if (packet.AgentData.SessionID != SessionId ||
9842 packet.AgentData.AgentID != AgentId)
9843 return true;
9844 }
9845 #endregion
9846 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9847 List<InventoryItemBase> items = new List<InventoryItemBase>();
9848 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9849 {
9850 InventoryItemBase b = new InventoryItemBase();
9851 b.ID = n.OldItemID;
9852 b.Folder = n.OldFolderID;
9853 items.Add(b);
9854 }
9855
9856 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9857 if (handlerMoveItemsAndLeaveCopy != null)
9858 {
9859 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9860 }
9861
9862 return true;
9863 }
9764 9864
9765 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9865 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9766 { 9866 {
@@ -10187,6 +10287,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10187 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10287 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10188 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10288 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10189 10289
10290 Scene scene = (Scene)m_scene;
10291 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10292 {
10293 ScenePresence p;
10294 if (scene.TryGetScenePresence(sender.AgentId, out p))
10295 {
10296 if (p.GodLevel >= 200)
10297 {
10298 groupProfileReply.GroupData.OpenEnrollment = true;
10299 groupProfileReply.GroupData.MembershipFee = 0;
10300 }
10301 }
10302 }
10303
10190 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10304 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10191 } 10305 }
10192 return true; 10306 return true;
@@ -10759,11 +10873,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10759 10873
10760 StartLure handlerStartLure = OnStartLure; 10874 StartLure handlerStartLure = OnStartLure;
10761 if (handlerStartLure != null) 10875 if (handlerStartLure != null)
10762 handlerStartLure(startLureRequest.Info.LureType, 10876 {
10763 Utils.BytesToString( 10877 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10764 startLureRequest.Info.Message), 10878 {
10765 startLureRequest.TargetData[0].TargetID, 10879 handlerStartLure(startLureRequest.Info.LureType,
10766 this); 10880 Utils.BytesToString(
10881 startLureRequest.Info.Message),
10882 startLureRequest.TargetData[i].TargetID,
10883 this);
10884 }
10885 }
10767 return true; 10886 return true;
10768 } 10887 }
10769 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10888 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10877,10 +10996,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10877 } 10996 }
10878 #endregion 10997 #endregion
10879 10998
10880 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10999 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10881 if (handlerClassifiedGodDelete != null) 11000 if (handlerClassifiedGodDelete != null)
10882 handlerClassifiedGodDelete( 11001 handlerClassifiedGodDelete(
10883 classifiedGodDelete.Data.ClassifiedID, 11002 classifiedGodDelete.Data.ClassifiedID,
11003 classifiedGodDelete.Data.QueryID,
10884 this); 11004 this);
10885 return true; 11005 return true;
10886 } 11006 }
@@ -11263,7 +11383,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11263 { 11383 {
11264 // It's a ghost! tell the client to delete it from view. 11384 // It's a ghost! tell the client to delete it from view.
11265 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11385 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11266 localId); 11386 new List<uint>() { localId });
11267 } 11387 }
11268 else 11388 else
11269 { 11389 {
@@ -11910,7 +12030,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11910 12030
11911// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12031// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11912 12032
12033
12034 //Note, the bool returned from the below function is useless since it is always false.
11913 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12035 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12036
11914 } 12037 }
11915 12038
11916 /// <summary> 12039 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..c951071 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -439,6 +440,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
439 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
440 { 441 {
441 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
443
444 if (m_deliverPackets == false)
445 {
446 queue.Enqueue(packet);
447 return true;
448 }
449
442 TokenBucket bucket = m_throttleCategories[category]; 450 TokenBucket bucket = m_throttleCategories[category];
443 451
444 // Don't send this packet if there is already a packet waiting in the queue 452 // Don't send this packet if there is already a packet waiting in the queue
@@ -488,6 +496,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 /// <returns>True if any packets were sent, otherwise false</returns> 496 /// <returns>True if any packets were sent, otherwise false</returns>
489 public bool DequeueOutgoing() 497 public bool DequeueOutgoing()
490 { 498 {
499 if (m_deliverPackets == false) return false;
500
491 OutgoingPacket packet; 501 OutgoingPacket packet;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
@@ -520,7 +530,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 // No dequeued packet waiting to be sent, try to pull one off 530 // No dequeued packet waiting to be sent, try to pull one off
521 // this queue 531 // this queue
522 queue = m_packetOutboxes[i]; 532 queue = m_packetOutboxes[i];
523 if (queue.Dequeue(out packet)) 533 if (queue != null && queue.Dequeue(out packet))
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 // A packet was pulled off the queue. See if we have
526 // enough tokens in the bucket to send it out 536 // enough tokens in the bucket to send it out
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ccad241..ae8251a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -991,7 +991,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
991 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 991 if (m_scene.TryGetClient(udpClient.AgentID, out client))
992 { 992 {
993 client.IsLoggingOut = true; 993 client.IsLoggingOut = true;
994 client.Close(); 994 client.Close(false);
995 } 995 }
996 } 996 }
997 997
@@ -1003,6 +1003,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1003 1003
1004 while (base.IsRunning) 1004 while (base.IsRunning)
1005 { 1005 {
1006 m_scene.ThreadAlive(1);
1006 try 1007 try
1007 { 1008 {
1008 IncomingPacket incomingPacket = null; 1009 IncomingPacket incomingPacket = null;
@@ -1045,6 +1046,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1045 1046
1046 while (base.IsRunning) 1047 while (base.IsRunning)
1047 { 1048 {
1049 m_scene.ThreadAlive(2);
1048 try 1050 try
1049 { 1051 {
1050 m_packetSent = false; 1052 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6eebd9d..d2779ba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,