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.cs724
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 429 insertions, 316 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 cefceb0..eed8878 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -157,6 +157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
157 public event RequestTaskInventory OnRequestTaskInventory; 157 public event RequestTaskInventory OnRequestTaskInventory;
158 public event UpdateInventoryItem OnUpdateInventoryItem; 158 public event UpdateInventoryItem OnUpdateInventoryItem;
159 public event CopyInventoryItem OnCopyInventoryItem; 159 public event CopyInventoryItem OnCopyInventoryItem;
160 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
160 public event MoveInventoryItem OnMoveInventoryItem; 161 public event MoveInventoryItem OnMoveInventoryItem;
161 public event RemoveInventoryItem OnRemoveInventoryItem; 162 public event RemoveInventoryItem OnRemoveInventoryItem;
162 public event RemoveInventoryFolder OnRemoveInventoryFolder; 163 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -254,7 +255,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
254 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 255 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
255 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 256 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
256 public event ClassifiedDelete OnClassifiedDelete; 257 public event ClassifiedDelete OnClassifiedDelete;
257 public event ClassifiedDelete OnClassifiedGodDelete; 258 public event ClassifiedGodDelete OnClassifiedGodDelete;
258 public event EventNotificationAddRequest OnEventNotificationAddRequest; 259 public event EventNotificationAddRequest OnEventNotificationAddRequest;
259 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 260 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
260 public event EventGodDelete OnEventGodDelete; 261 public event EventGodDelete OnEventGodDelete;
@@ -330,7 +331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
330 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 331 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
331 /// ownerless phantom. 332 /// ownerless phantom.
332 /// 333 ///
333 /// All manipulation of this set has to occur under a lock 334 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
334 /// 335 ///
335 /// </value> 336 /// </value>
336 protected HashSet<uint> m_killRecord; 337 protected HashSet<uint> m_killRecord;
@@ -338,6 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338// protected HashSet<uint> m_attachmentsSent; 339// protected HashSet<uint> m_attachmentsSent;
339 340
340 private int m_moneyBalance; 341 private int m_moneyBalance;
342 private bool m_deliverPackets = true;
341 private int m_animationSequenceNumber = 1; 343 private int m_animationSequenceNumber = 1;
342 private bool m_SendLogoutPacketWhenClosing = true; 344 private bool m_SendLogoutPacketWhenClosing = true;
343 private AgentUpdateArgs lastarg; 345 private AgentUpdateArgs lastarg;
@@ -378,6 +380,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
378 get { return m_startpos; } 380 get { return m_startpos; }
379 set { m_startpos = value; } 381 set { m_startpos = value; }
380 } 382 }
383 public bool DeliverPackets
384 {
385 get { return m_deliverPackets; }
386 set {
387 m_deliverPackets = value;
388 m_udpClient.m_deliverPackets = value;
389 }
390 }
381 public UUID AgentId { get { return m_agentId; } } 391 public UUID AgentId { get { return m_agentId; } }
382 public UUID ActiveGroupId { get { return m_activeGroupID; } } 392 public UUID ActiveGroupId { get { return m_activeGroupID; } }
383 public string ActiveGroupName { get { return m_activeGroupName; } } 393 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -479,18 +489,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
479 489
480 #region Client Methods 490 #region Client Methods
481 491
492
482 /// <summary> 493 /// <summary>
483 /// Shut down the client view 494 /// Shut down the client view
484 /// </summary> 495 /// </summary>
485 public void Close() 496 public void Close()
486 { 497 {
498 Close(true);
499 }
500
501 /// <summary>
502 /// Shut down the client view
503 /// </summary>
504 public void Close(bool sendStop)
505 {
487 m_log.DebugFormat( 506 m_log.DebugFormat(
488 "[CLIENT]: Close has been called for {0} attached to scene {1}", 507 "[CLIENT]: Close has been called for {0} attached to scene {1}",
489 Name, m_scene.RegionInfo.RegionName); 508 Name, m_scene.RegionInfo.RegionName);
490 509
491 // Send the STOP packet 510 if (sendStop)
492 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 511 {
493 OutPacket(disable, ThrottleOutPacketType.Unknown); 512 // Send the STOP packet
513 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
514 OutPacket(disable, ThrottleOutPacketType.Unknown);
515 }
494 516
495 IsActive = false; 517 IsActive = false;
496 518
@@ -771,7 +793,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
771 reply.ChatData.OwnerID = fromAgentID; 793 reply.ChatData.OwnerID = fromAgentID;
772 reply.ChatData.SourceID = fromAgentID; 794 reply.ChatData.SourceID = fromAgentID;
773 795
774 OutPacket(reply, ThrottleOutPacketType.Task); 796 OutPacket(reply, ThrottleOutPacketType.Unknown);
775 } 797 }
776 798
777 /// <summary> 799 /// <summary>
@@ -1057,6 +1079,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1057 public virtual void SendLayerData(float[] map) 1079 public virtual void SendLayerData(float[] map)
1058 { 1080 {
1059 Util.FireAndForget(DoSendLayerData, map); 1081 Util.FireAndForget(DoSendLayerData, map);
1082
1083 // Send it sync, and async. It's not that much data
1084 // and it improves user experience just so much!
1085 DoSendLayerData(map);
1060 } 1086 }
1061 1087
1062 /// <summary> 1088 /// <summary>
@@ -1069,16 +1095,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1069 1095
1070 try 1096 try
1071 { 1097 {
1072 //for (int y = 0; y < 16; y++) 1098 for (int y = 0; y < 16; y++)
1073 //{ 1099 {
1074 // for (int x = 0; x < 16; x++) 1100 for (int x = 0; x < 16; x+=4)
1075 // { 1101 {
1076 // SendLayerData(x, y, map); 1102 SendLayerPacket(x, y, map);
1077 // } 1103 }
1078 //} 1104 }
1079
1080 // Send LayerData in a spiral pattern. Fun!
1081 SendLayerTopRight(map, 0, 0, 15, 15);
1082 } 1105 }
1083 catch (Exception e) 1106 catch (Exception e)
1084 { 1107 {
@@ -1086,51 +1109,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1086 } 1109 }
1087 } 1110 }
1088 1111
1089 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1090 {
1091 // Row
1092 for (int i = x1; i <= x2; i++)
1093 SendLayerData(i, y1, map);
1094
1095 // Column
1096 for (int j = y1 + 1; j <= y2; j++)
1097 SendLayerData(x2, j, map);
1098
1099 if (x2 - x1 > 0)
1100 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1101 }
1102
1103 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1104 {
1105 // Row in reverse
1106 for (int i = x2; i >= x1; i--)
1107 SendLayerData(i, y2, map);
1108
1109 // Column in reverse
1110 for (int j = y2 - 1; j >= y1; j--)
1111 SendLayerData(x1, j, map);
1112
1113 if (x2 - x1 > 0)
1114 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1115 }
1116
1117 /// <summary> 1112 /// <summary>
1118 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1113 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1119 /// </summary> 1114 /// </summary>
1120 /// <param name="map">heightmap</param> 1115 /// <param name="map">heightmap</param>
1121 /// <param name="px">X coordinate for patches 0..12</param> 1116 /// <param name="px">X coordinate for patches 0..12</param>
1122 /// <param name="py">Y coordinate for patches 0..15</param> 1117 /// <param name="py">Y coordinate for patches 0..15</param>
1123 // private void SendLayerPacket(float[] map, int y, int x) 1118 private void SendLayerPacket(int x, int y, float[] map)
1124 // { 1119 {
1125 // int[] patches = new int[4]; 1120 int[] patches = new int[4];
1126 // patches[0] = x + 0 + y * 16; 1121 patches[0] = x + 0 + y * 16;
1127 // patches[1] = x + 1 + y * 16; 1122 patches[1] = x + 1 + y * 16;
1128 // patches[2] = x + 2 + y * 16; 1123 patches[2] = x + 2 + y * 16;
1129 // patches[3] = x + 3 + y * 16; 1124 patches[3] = x + 3 + y * 16;
1130 1125
1131 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1126 float[] heightmap = (map.Length == 65536) ?
1132 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1127 map :
1133 // } 1128 LLHeightFieldMoronize(map);
1129
1130 try
1131 {
1132 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1133 OutPacket(layerpack, ThrottleOutPacketType.Land);
1134 }
1135 catch
1136 {
1137 for (int px = x ; px < x + 4 ; px++)
1138 SendLayerData(px, y, map);
1139 }
1140 }
1134 1141
1135 /// <summary> 1142 /// <summary>
1136 /// Sends a specified patch to a client 1143 /// Sends a specified patch to a client
@@ -1150,7 +1157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1150 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1157 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1151 layerpack.Header.Reliable = true; 1158 layerpack.Header.Reliable = true;
1152 1159
1153 OutPacket(layerpack, ThrottleOutPacketType.Land); 1160 OutPacket(layerpack, ThrottleOutPacketType.Task);
1154 } 1161 }
1155 catch (Exception e) 1162 catch (Exception e)
1156 { 1163 {
@@ -1511,38 +1518,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1511 OutPacket(pc, ThrottleOutPacketType.Unknown); 1518 OutPacket(pc, ThrottleOutPacketType.Unknown);
1512 } 1519 }
1513 1520
1514 public void SendKillObject(ulong regionHandle, uint localID) 1521 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1515 { 1522 {
1516// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1523// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1517 1524
1518 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1525 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1519 // TODO: don't create new blocks if recycling an old packet 1526 // TODO: don't create new blocks if recycling an old packet
1520 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1527 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1521 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1528 for (int i = 0 ; i < localIDs.Count ; i++ )
1522 kill.ObjectData[0].ID = localID; 1529 {
1530 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1531 kill.ObjectData[i].ID = localIDs[i];
1532 }
1523 kill.Header.Reliable = true; 1533 kill.Header.Reliable = true;
1524 kill.Header.Zerocoded = true; 1534 kill.Header.Zerocoded = true;
1525 1535
1526 if (m_scene.GetScenePresence(localID) == null) 1536 lock (m_killRecord)
1527 { 1537 {
1528 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1538 if (localIDs.Count == 1)
1529 // condition where a kill can be processed before an out-of-date update for the same object.
1530 lock (m_killRecord)
1531 { 1539 {
1532 m_killRecord.Add(localID); 1540 if (m_scene.GetScenePresence(localIDs[0]) != null)
1533 1541 {
1534 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1542 OutPacket(kill, ThrottleOutPacketType.State);
1535 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1543 return;
1536 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1544 }
1537 // scene objects in a viewer until that viewer is relogged in. 1545 m_killRecord.Add(localIDs[0]);
1538 OutPacket(kill, ThrottleOutPacketType.Task); 1546 }
1547 else
1548 {
1549 lock (m_entityUpdates.SyncRoot)
1550 {
1551 foreach (uint localID in localIDs)
1552 m_killRecord.Add(localID);
1553 }
1539 } 1554 }
1540 } 1555 }
1541 else 1556
1542 { 1557 // The throttle queue used here must match that being used for
1543 // OutPacket(kill, ThrottleOutPacketType.State); 1558 // updates. Otherwise, there is a chance that a kill packet put
1544 OutPacket(kill, ThrottleOutPacketType.Task); 1559 // on a separate queue will be sent to the client before an
1545 } 1560 // existing update packet on another queue. Receiving updates
1561 // after kills results in unowned and undeletable
1562 // scene objects in a viewer until that viewer is relogged in.
1563 OutPacket(kill, ThrottleOutPacketType.Task);
1546 } 1564 }
1547 1565
1548 /// <summary> 1566 /// <summary>
@@ -2267,6 +2285,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2267 OutPacket(sound, ThrottleOutPacketType.Task); 2285 OutPacket(sound, ThrottleOutPacketType.Task);
2268 } 2286 }
2269 2287
2288 public void SendTransferAbort(TransferRequestPacket transferRequest)
2289 {
2290 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2291 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2292 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2293 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2294 OutPacket(abort, ThrottleOutPacketType.Task);
2295 }
2296
2270 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2297 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2271 { 2298 {
2272 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2299 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3569,7 +3596,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3569 /// </summary> 3596 /// </summary>
3570 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3597 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3571 { 3598 {
3572 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3599 if (entity is SceneObjectPart)
3600 {
3601 SceneObjectPart e = (SceneObjectPart)entity;
3602 SceneObjectGroup g = e.ParentGroup;
3603 if (g.RootPart.Shape.State > 30) // HUD
3604 if (g.OwnerID != AgentId)
3605 return; // Don't send updates for other people's HUDs
3606 }
3607
3573 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3608 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3574 3609
3575 lock (m_entityUpdates.SyncRoot) 3610 lock (m_entityUpdates.SyncRoot)
@@ -3636,211 +3671,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3636 3671
3637 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3672 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3638 // condition where a kill can be processed before an out-of-date update for the same object. 3673 // condition where a kill can be processed before an out-of-date update for the same object.
3639 lock (m_killRecord) 3674 float avgTimeDilation = 1.0f;
3675 IEntityUpdate iupdate;
3676 Int32 timeinqueue; // this is just debugging code & can be dropped later
3677
3678 while (updatesThisCall < maxUpdates)
3640 { 3679 {
3641 float avgTimeDilation = 1.0f; 3680 lock (m_entityUpdates.SyncRoot)
3642 IEntityUpdate iupdate; 3681 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3643 Int32 timeinqueue; // this is just debugging code & can be dropped later 3682 break;
3644
3645 while (updatesThisCall < maxUpdates)
3646 {
3647 lock (m_entityUpdates.SyncRoot)
3648 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3649 break;
3650 3683
3651 EntityUpdate update = (EntityUpdate)iupdate; 3684 EntityUpdate update = (EntityUpdate)iupdate;
3652 3685
3653 avgTimeDilation += update.TimeDilation; 3686 avgTimeDilation += update.TimeDilation;
3654 avgTimeDilation *= 0.5f; 3687 avgTimeDilation *= 0.5f;
3655 3688
3656 if (update.Entity is SceneObjectPart) 3689 if (update.Entity is SceneObjectPart)
3690 {
3691 SceneObjectPart part = (SceneObjectPart)update.Entity;
3692
3693 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3694 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3695 // safety measure.
3696 //
3697 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3698 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3699 // updates and kills on different threads with different scheduling strategies, hence this protection.
3700 //
3701 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3702 // after the root prim has been deleted.
3703 lock (m_killRecord)
3657 { 3704 {
3658 SceneObjectPart part = (SceneObjectPart)update.Entity;
3659
3660 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3661 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3662 // safety measure.
3663 //
3664 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3665 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3666 // updates and kills on different threads with different scheduling strategies, hence this protection.
3667 //
3668 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3669 // after the root prim has been deleted.
3670 if (m_killRecord.Contains(part.LocalId)) 3705 if (m_killRecord.Contains(part.LocalId))
3671 {
3672 // m_log.WarnFormat(
3673 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3674 // part.LocalId, Name);
3675 continue; 3706 continue;
3676 } 3707 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3677 3708 continue;
3678 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3709 }
3710
3711 if (part.ParentGroup.IsDeleted)
3712 continue;
3713
3714 if (part.ParentGroup.IsAttachment)
3715 { // Someone else's HUD, why are we getting these?
3716 if (part.ParentGroup.OwnerID != AgentId &&
3717 part.ParentGroup.RootPart.Shape.State >= 30)
3718 continue;
3719 ScenePresence sp;
3720 // Owner is not in the sim, don't update it to
3721 // anyone
3722 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3723 continue;
3724
3725 List<SceneObjectGroup> atts = sp.Attachments;
3726 bool found = false;
3727 foreach (SceneObjectGroup att in atts)
3679 { 3728 {
3680 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3729 if (att == part.ParentGroup)
3681 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3682 { 3730 {
3683 part.Shape.LightEntry = false; 3731 found = true;
3732 break;
3684 } 3733 }
3685 } 3734 }
3735
3736 // It's an attachment of a valid avatar, but
3737 // doesn't seem to be attached, skip
3738 if (!found)
3739 continue;
3686 } 3740 }
3687 3741 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3688 ++updatesThisCall;
3689
3690 #region UpdateFlags to packet type conversion
3691
3692 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3693
3694 bool canUseCompressed = true;
3695 bool canUseImproved = true;
3696
3697 // Compressed object updates only make sense for LL primitives
3698 if (!(update.Entity is SceneObjectPart))
3699 {
3700 canUseCompressed = false;
3701 }
3702
3703 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3704 {
3705 canUseCompressed = false;
3706 canUseImproved = false;
3707 }
3708 else
3709 { 3742 {
3710 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3743 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3711 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3744 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3712 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3713 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3714 { 3745 {
3715 canUseCompressed = false; 3746 part.Shape.LightEntry = false;
3716 }
3717
3718 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3719 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3720 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3721 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3722 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3723 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3724 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3725 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3726 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3727 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3728 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3729 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3730 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3731 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3732 {
3733 canUseImproved = false;
3734 } 3747 }
3735 } 3748 }
3736 3749 }
3737 #endregion UpdateFlags to packet type conversion 3750
3738 3751 ++updatesThisCall;
3739 #region Block Construction 3752
3740 3753 #region UpdateFlags to packet type conversion
3741 // TODO: Remove this once we can build compressed updates 3754
3755 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3756
3757 bool canUseCompressed = true;
3758 bool canUseImproved = true;
3759
3760 // Compressed object updates only make sense for LL primitives
3761 if (!(update.Entity is SceneObjectPart))
3762 {
3742 canUseCompressed = false; 3763 canUseCompressed = false;
3743 3764 }
3744 if (!canUseImproved && !canUseCompressed) 3765
3745 { 3766 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3746 if (update.Entity is ScenePresence) 3767 {
3747 { 3768 canUseCompressed = false;
3748 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3769 canUseImproved = false;
3749 objectUpdates.Value.Add(update); 3770 }
3750 } 3771 else
3751 else 3772 {
3752 { 3773 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3753 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3774 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3754 objectUpdates.Value.Add(update); 3775 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3755 } 3776 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3756 }
3757 else if (!canUseImproved)
3758 { 3777 {
3759 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3778 canUseCompressed = false;
3760 compressedUpdates.Value.Add(update);
3761 } 3779 }
3762 else 3780
3781 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3782 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3783 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3784 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3785 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3786 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3787 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3788 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3789 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3790 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3791 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3792 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3793 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3794 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3763 { 3795 {
3764 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3796 canUseImproved = false;
3765 {
3766 // Self updates go into a special list
3767 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3768 terseAgentUpdates.Value.Add(update);
3769 }
3770 else
3771 {
3772 // Everything else goes here
3773 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3774 terseUpdates.Value.Add(update);
3775 }
3776 } 3797 }
3777
3778 #endregion Block Construction
3779 } 3798 }
3780
3781
3782 #region Packet Sending
3783 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3784 3799
3785 if (terseAgentUpdateBlocks.IsValueCreated) 3800 #endregion UpdateFlags to packet type conversion
3786 {
3787 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3788 3801
3789 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3802 #region Block Construction
3790 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3791 packet.RegionData.TimeDilation = timeDilation;
3792 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3793 3803
3794 for (int i = 0; i < blocks.Count; i++) 3804 // TODO: Remove this once we can build compressed updates
3795 packet.ObjectData[i] = blocks[i]; 3805 canUseCompressed = false;
3796 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3797 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3798 }
3799 3806
3800 if (objectUpdateBlocks.IsValueCreated) 3807 if (!canUseImproved && !canUseCompressed)
3801 { 3808 {
3802 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3809 if (update.Entity is ScenePresence)
3803 3810 {
3804 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3811 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3805 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3812 }
3806 packet.RegionData.TimeDilation = timeDilation; 3813 else
3807 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3814 {
3808 3815 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3809 for (int i = 0; i < blocks.Count; i++) 3816 }
3810 packet.ObjectData[i] = blocks[i];
3811 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3812 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3813 } 3817 }
3814 3818 else if (!canUseImproved)
3815 if (compressedUpdateBlocks.IsValueCreated)
3816 { 3819 {
3817 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3820 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3818
3819 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3820 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3821 packet.RegionData.TimeDilation = timeDilation;
3822 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3823
3824 for (int i = 0; i < blocks.Count; i++)
3825 packet.ObjectData[i] = blocks[i];
3826 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3827 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3828 } 3821 }
3829 3822 else
3830 if (terseUpdateBlocks.IsValueCreated)
3831 { 3823 {
3832 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3824 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3833 3825 // Self updates go into a special list
3834 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3826 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3835 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3827 else
3836 packet.RegionData.TimeDilation = timeDilation; 3828 // Everything else goes here
3837 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3829 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3838
3839 for (int i = 0; i < blocks.Count; i++)
3840 packet.ObjectData[i] = blocks[i];
3841 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3842 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3843 } 3830 }
3831
3832 #endregion Block Construction
3833 }
3834
3835 #region Packet Sending
3836
3837 const float TIME_DILATION = 1.0f;
3838 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3839
3840 if (terseAgentUpdateBlocks.IsValueCreated)
3841 {
3842 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3843
3844 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3845 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3846 packet.RegionData.TimeDilation = timeDilation;
3847 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3848
3849 for (int i = 0; i < blocks.Count; i++)
3850 packet.ObjectData[i] = blocks[i];
3851
3852 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3853 }
3854
3855 if (objectUpdateBlocks.IsValueCreated)
3856 {
3857 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3858
3859 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3860 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3861 packet.RegionData.TimeDilation = timeDilation;
3862 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3863
3864 for (int i = 0; i < blocks.Count; i++)
3865 packet.ObjectData[i] = blocks[i];
3866
3867 OutPacket(packet, ThrottleOutPacketType.Task, true);
3868 }
3869
3870 if (compressedUpdateBlocks.IsValueCreated)
3871 {
3872 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3873
3874 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3875 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3876 packet.RegionData.TimeDilation = timeDilation;
3877 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3878
3879 for (int i = 0; i < blocks.Count; i++)
3880 packet.ObjectData[i] = blocks[i];
3881
3882 OutPacket(packet, ThrottleOutPacketType.Task, true);
3883 }
3884
3885 if (terseUpdateBlocks.IsValueCreated)
3886 {
3887 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3888
3889 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3890 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3891 packet.RegionData.TimeDilation = timeDilation;
3892 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3893
3894 for (int i = 0; i < blocks.Count; i++)
3895 packet.ObjectData[i] = blocks[i];
3896
3897 OutPacket(packet, ThrottleOutPacketType.Task, true);
3844 } 3898 }
3845 3899
3846 #endregion Packet Sending 3900 #endregion Packet Sending
@@ -4324,37 +4378,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4324 if (bl[i].BannedUserID == UUID.Zero) 4378 if (bl[i].BannedUserID == UUID.Zero)
4325 continue; 4379 continue;
4326 BannedUsers.Add(bl[i].BannedUserID); 4380 BannedUsers.Add(bl[i].BannedUserID);
4327 }
4328 4381
4329 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4382 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4330 packet.AgentData.TransactionID = UUID.Random(); 4383 {
4331 packet.AgentData.AgentID = AgentId; 4384 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4332 packet.AgentData.SessionID = SessionId; 4385 packet.AgentData.TransactionID = UUID.Random();
4333 packet.MethodData.Invoice = invoice; 4386 packet.AgentData.AgentID = AgentId;
4334 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4387 packet.AgentData.SessionID = SessionId;
4388 packet.MethodData.Invoice = invoice;
4389 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4335 4390
4336 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4391 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4337 4392
4338 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4393 int j;
4339 { 4394 for (j = 0; j < (6 + BannedUsers.Count); j++)
4340 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4395 {
4341 } 4396 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4342 int j = 0; 4397 }
4398 j = 0;
4343 4399
4344 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4400 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4345 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4401 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4346 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4402 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4347 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4403 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4348 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4404 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4349 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4405 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4350 4406
4351 foreach (UUID banned in BannedUsers) 4407 foreach (UUID banned in BannedUsers)
4352 { 4408 {
4353 returnblock[j].Parameter = banned.GetBytes(); j++; 4409 returnblock[j].Parameter = banned.GetBytes(); j++;
4410 }
4411 packet.ParamList = returnblock;
4412 packet.Header.Reliable = true;
4413 OutPacket(packet, ThrottleOutPacketType.Task);
4414
4415 BannedUsers.Clear();
4416 }
4354 } 4417 }
4355 packet.ParamList = returnblock; 4418
4356 packet.Header.Reliable = false;
4357 OutPacket(packet, ThrottleOutPacketType.Task);
4358 } 4419 }
4359 4420
4360 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4421 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4652,14 +4713,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4652 4713
4653 if (notifyCount > 0) 4714 if (notifyCount > 0)
4654 { 4715 {
4655 if (notifyCount > 32) 4716// if (notifyCount > 32)
4656 { 4717// {
4657 m_log.InfoFormat( 4718// m_log.InfoFormat(
4658 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4719// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4659 + " - a developer might want to investigate whether this is a hard limit", 32); 4720// + " - a developer might want to investigate whether this is a hard limit", 32);
4660 4721//
4661 notifyCount = 32; 4722// notifyCount = 32;
4662 } 4723// }
4663 4724
4664 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4725 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4665 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4726 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5175,6 +5236,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5175 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5236 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5176 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5237 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5177 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5238 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5239 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5178 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5240 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5179 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5241 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5180 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5242 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5274,6 +5336,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5274 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5336 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5275 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5337 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5276 (x.ControlFlags != lastarg.ControlFlags) || 5338 (x.ControlFlags != lastarg.ControlFlags) ||
5339 (x.ControlFlags != 0) ||
5277 (x.Far != lastarg.Far) || 5340 (x.Far != lastarg.Far) ||
5278 (x.Flags != lastarg.Flags) || 5341 (x.Flags != lastarg.Flags) ||
5279 (x.State != lastarg.State) || 5342 (x.State != lastarg.State) ||
@@ -5647,7 +5710,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5647 args.Channel = ch; 5710 args.Channel = ch;
5648 args.From = String.Empty; 5711 args.From = String.Empty;
5649 args.Message = Utils.BytesToString(msg); 5712 args.Message = Utils.BytesToString(msg);
5650 args.Type = ChatTypeEnum.Shout; 5713 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5651 args.Position = new Vector3(); 5714 args.Position = new Vector3();
5652 args.Scene = Scene; 5715 args.Scene = Scene;
5653 args.Sender = this; 5716 args.Sender = this;
@@ -9653,7 +9716,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9653 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9716 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9654 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9717 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9655 UpdateMuteListEntry.MuteData.MuteType, 9718 UpdateMuteListEntry.MuteData.MuteType,
9656 UpdateMuteListEntry.AgentData.AgentID); 9719 UpdateMuteListEntry.MuteData.MuteFlags);
9657 return true; 9720 return true;
9658 } 9721 }
9659 return false; 9722 return false;
@@ -9668,8 +9731,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9668 { 9731 {
9669 handlerRemoveMuteListEntry(this, 9732 handlerRemoveMuteListEntry(this,
9670 RemoveMuteListEntry.MuteData.MuteID, 9733 RemoveMuteListEntry.MuteData.MuteID,
9671 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9734 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9672 RemoveMuteListEntry.AgentData.AgentID);
9673 return true; 9735 return true;
9674 } 9736 }
9675 return false; 9737 return false;
@@ -9717,6 +9779,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9717 { 9779 {
9718 return true; 9780 return true;
9719 } 9781 }
9782
9783 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9784 {
9785 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9786
9787 #region Packet Session and User Check
9788 if (m_checkPackets)
9789 {
9790 if (packet.AgentData.SessionID != SessionId ||
9791 packet.AgentData.AgentID != AgentId)
9792 return true;
9793 }
9794 #endregion
9795 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9796 List<InventoryItemBase> items = new List<InventoryItemBase>();
9797 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9798 {
9799 InventoryItemBase b = new InventoryItemBase();
9800 b.ID = n.OldItemID;
9801 b.Folder = n.OldFolderID;
9802 items.Add(b);
9803 }
9804
9805 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9806 if (handlerMoveItemsAndLeaveCopy != null)
9807 {
9808 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9809 }
9810
9811 return true;
9812 }
9720 9813
9721 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9814 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9722 { 9815 {
@@ -10143,6 +10236,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10143 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10236 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10144 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10237 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10145 10238
10239 Scene scene = (Scene)m_scene;
10240 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10241 {
10242 ScenePresence p;
10243 if (scene.TryGetScenePresence(sender.AgentId, out p))
10244 {
10245 if (p.GodLevel >= 200)
10246 {
10247 groupProfileReply.GroupData.OpenEnrollment = true;
10248 groupProfileReply.GroupData.MembershipFee = 0;
10249 }
10250 }
10251 }
10252
10146 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10253 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10147 } 10254 }
10148 return true; 10255 return true;
@@ -10715,11 +10822,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10715 10822
10716 StartLure handlerStartLure = OnStartLure; 10823 StartLure handlerStartLure = OnStartLure;
10717 if (handlerStartLure != null) 10824 if (handlerStartLure != null)
10718 handlerStartLure(startLureRequest.Info.LureType, 10825 {
10719 Utils.BytesToString( 10826 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10720 startLureRequest.Info.Message), 10827 {
10721 startLureRequest.TargetData[0].TargetID, 10828 handlerStartLure(startLureRequest.Info.LureType,
10722 this); 10829 Utils.BytesToString(
10830 startLureRequest.Info.Message),
10831 startLureRequest.TargetData[i].TargetID,
10832 this);
10833 }
10834 }
10723 return true; 10835 return true;
10724 } 10836 }
10725 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10837 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10833,10 +10945,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10833 } 10945 }
10834 #endregion 10946 #endregion
10835 10947
10836 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10948 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10837 if (handlerClassifiedGodDelete != null) 10949 if (handlerClassifiedGodDelete != null)
10838 handlerClassifiedGodDelete( 10950 handlerClassifiedGodDelete(
10839 classifiedGodDelete.Data.ClassifiedID, 10951 classifiedGodDelete.Data.ClassifiedID,
10952 classifiedGodDelete.Data.QueryID,
10840 this); 10953 this);
10841 return true; 10954 return true;
10842 } 10955 }
@@ -11214,7 +11327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11214 { 11327 {
11215 // It's a ghost! tell the client to delete it from view. 11328 // It's a ghost! tell the client to delete it from view.
11216 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11329 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11217 localId); 11330 new List<uint>() { localId });
11218 } 11331 }
11219 else 11332 else
11220 { 11333 {
@@ -11603,22 +11716,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11603 /// <param name="Pack">OpenMetaverse.packet</param> 11716 /// <param name="Pack">OpenMetaverse.packet</param>
11604 public void ProcessInPacket(Packet packet) 11717 public void ProcessInPacket(Packet packet)
11605 { 11718 {
11606 if (m_debugPacketLevel > 0) 11719 if (m_debugPacketLevel >= 255)
11607 { 11720 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11608 bool outputPacket = true;
11609
11610 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11611 outputPacket = false;
11612
11613 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11614 outputPacket = false;
11615
11616 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11617 outputPacket = false;
11618
11619 if (outputPacket)
11620 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11621 }
11622 11721
11623 if (!ProcessPacketMethod(packet)) 11722 if (!ProcessPacketMethod(packet))
11624 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11723 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11860,7 +11959,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11860 11959
11861// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11960// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11862 11961
11962
11963 //Note, the bool returned from the below function is useless since it is always false.
11863 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11964 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11965
11864 } 11966 }
11865 11967
11866 /// <summary> 11968 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ca5501d..95a8e23 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -430,6 +431,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
430 if (category >= 0 && category < m_packetOutboxes.Length) 431 if (category >= 0 && category < m_packetOutboxes.Length)
431 { 432 {
432 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 433 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
434
435 if (m_deliverPackets == false)
436 {
437 queue.Enqueue(packet);
438 return true;
439 }
440
433 TokenBucket bucket = m_throttleCategories[category]; 441 TokenBucket bucket = m_throttleCategories[category];
434 442
435 // Don't send this packet if there is already a packet waiting in the queue 443 // Don't send this packet if there is already a packet waiting in the queue
@@ -479,6 +487,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
479 /// <returns>True if any packets were sent, otherwise false</returns> 487 /// <returns>True if any packets were sent, otherwise false</returns>
480 public bool DequeueOutgoing() 488 public bool DequeueOutgoing()
481 { 489 {
490 if (m_deliverPackets == false) return false;
491
482 OutgoingPacket packet; 492 OutgoingPacket packet;
483 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 493 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
484 TokenBucket bucket; 494 TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index aff90c5..ab6674d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -960,7 +960,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
960 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 960 if (m_scene.TryGetClient(udpClient.AgentID, out client))
961 { 961 {
962 client.IsLoggingOut = true; 962 client.IsLoggingOut = true;
963 client.Close(); 963 client.Close(false);
964 } 964 }
965 } 965 }
966 966
@@ -972,6 +972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
972 972
973 while (base.IsRunning) 973 while (base.IsRunning)
974 { 974 {
975 m_scene.ThreadAlive(1);
975 try 976 try
976 { 977 {
977 IncomingPacket incomingPacket = null; 978 IncomingPacket incomingPacket = null;
@@ -1014,6 +1015,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1014 1015
1015 while (base.IsRunning) 1016 while (base.IsRunning)
1016 { 1017 {
1018 m_scene.ThreadAlive(2);
1017 try 1019 try
1018 { 1020 {
1019 m_packetSent = false; 1021 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6eebd9d..d2779ba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,