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 f53e236..6048518 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; } }
@@ -484,18 +494,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
484 494
485 #region Client Methods 495 #region Client Methods
486 496
497
487 /// <summary> 498 /// <summary>
488 /// Shut down the client view 499 /// Shut down the client view
489 /// </summary> 500 /// </summary>
490 public void Close() 501 public void Close()
491 { 502 {
503 Close(true);
504 }
505
506 /// <summary>
507 /// Shut down the client view
508 /// </summary>
509 public void Close(bool sendStop)
510 {
492 m_log.DebugFormat( 511 m_log.DebugFormat(
493 "[CLIENT]: Close has been called for {0} attached to scene {1}", 512 "[CLIENT]: Close has been called for {0} attached to scene {1}",
494 Name, m_scene.RegionInfo.RegionName); 513 Name, m_scene.RegionInfo.RegionName);
495 514
496 // Send the STOP packet 515 if (sendStop)
497 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 516 {
498 OutPacket(disable, ThrottleOutPacketType.Unknown); 517 // Send the STOP packet
518 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
519 OutPacket(disable, ThrottleOutPacketType.Unknown);
520 }
499 521
500 IsActive = false; 522 IsActive = false;
501 523
@@ -776,7 +798,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
776 reply.ChatData.OwnerID = fromAgentID; 798 reply.ChatData.OwnerID = fromAgentID;
777 reply.ChatData.SourceID = fromAgentID; 799 reply.ChatData.SourceID = fromAgentID;
778 800
779 OutPacket(reply, ThrottleOutPacketType.Task); 801 OutPacket(reply, ThrottleOutPacketType.Unknown);
780 } 802 }
781 803
782 /// <summary> 804 /// <summary>
@@ -1062,6 +1084,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1062 public virtual void SendLayerData(float[] map) 1084 public virtual void SendLayerData(float[] map)
1063 { 1085 {
1064 Util.FireAndForget(DoSendLayerData, map); 1086 Util.FireAndForget(DoSendLayerData, map);
1087
1088 // Send it sync, and async. It's not that much data
1089 // and it improves user experience just so much!
1090 DoSendLayerData(map);
1065 } 1091 }
1066 1092
1067 /// <summary> 1093 /// <summary>
@@ -1074,16 +1100,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1074 1100
1075 try 1101 try
1076 { 1102 {
1077 //for (int y = 0; y < 16; y++) 1103 for (int y = 0; y < 16; y++)
1078 //{ 1104 {
1079 // for (int x = 0; x < 16; x++) 1105 for (int x = 0; x < 16; x+=4)
1080 // { 1106 {
1081 // SendLayerData(x, y, map); 1107 SendLayerPacket(x, y, map);
1082 // } 1108 }
1083 //} 1109 }
1084
1085 // Send LayerData in a spiral pattern. Fun!
1086 SendLayerTopRight(map, 0, 0, 15, 15);
1087 } 1110 }
1088 catch (Exception e) 1111 catch (Exception e)
1089 { 1112 {
@@ -1091,51 +1114,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1091 } 1114 }
1092 } 1115 }
1093 1116
1094 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1095 {
1096 // Row
1097 for (int i = x1; i <= x2; i++)
1098 SendLayerData(i, y1, map);
1099
1100 // Column
1101 for (int j = y1 + 1; j <= y2; j++)
1102 SendLayerData(x2, j, map);
1103
1104 if (x2 - x1 > 0)
1105 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1106 }
1107
1108 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1109 {
1110 // Row in reverse
1111 for (int i = x2; i >= x1; i--)
1112 SendLayerData(i, y2, map);
1113
1114 // Column in reverse
1115 for (int j = y2 - 1; j >= y1; j--)
1116 SendLayerData(x1, j, map);
1117
1118 if (x2 - x1 > 0)
1119 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1120 }
1121
1122 /// <summary> 1117 /// <summary>
1123 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1118 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1124 /// </summary> 1119 /// </summary>
1125 /// <param name="map">heightmap</param> 1120 /// <param name="map">heightmap</param>
1126 /// <param name="px">X coordinate for patches 0..12</param> 1121 /// <param name="px">X coordinate for patches 0..12</param>
1127 /// <param name="py">Y coordinate for patches 0..15</param> 1122 /// <param name="py">Y coordinate for patches 0..15</param>
1128 // private void SendLayerPacket(float[] map, int y, int x) 1123 private void SendLayerPacket(int x, int y, float[] map)
1129 // { 1124 {
1130 // int[] patches = new int[4]; 1125 int[] patches = new int[4];
1131 // patches[0] = x + 0 + y * 16; 1126 patches[0] = x + 0 + y * 16;
1132 // patches[1] = x + 1 + y * 16; 1127 patches[1] = x + 1 + y * 16;
1133 // patches[2] = x + 2 + y * 16; 1128 patches[2] = x + 2 + y * 16;
1134 // patches[3] = x + 3 + y * 16; 1129 patches[3] = x + 3 + y * 16;
1135 1130
1136 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1131 float[] heightmap = (map.Length == 65536) ?
1137 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1132 map :
1138 // } 1133 LLHeightFieldMoronize(map);
1134
1135 try
1136 {
1137 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1138 OutPacket(layerpack, ThrottleOutPacketType.Land);
1139 }
1140 catch
1141 {
1142 for (int px = x ; px < x + 4 ; px++)
1143 SendLayerData(px, y, map);
1144 }
1145 }
1139 1146
1140 /// <summary> 1147 /// <summary>
1141 /// Sends a specified patch to a client 1148 /// Sends a specified patch to a client
@@ -1155,7 +1162,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1155 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1162 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1156 layerpack.Header.Reliable = true; 1163 layerpack.Header.Reliable = true;
1157 1164
1158 OutPacket(layerpack, ThrottleOutPacketType.Land); 1165 OutPacket(layerpack, ThrottleOutPacketType.Task);
1159 } 1166 }
1160 catch (Exception e) 1167 catch (Exception e)
1161 { 1168 {
@@ -1516,38 +1523,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1516 OutPacket(pc, ThrottleOutPacketType.Unknown); 1523 OutPacket(pc, ThrottleOutPacketType.Unknown);
1517 } 1524 }
1518 1525
1519 public void SendKillObject(ulong regionHandle, uint localID) 1526 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1520 { 1527 {
1521// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1528// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1522 1529
1523 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1530 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1524 // TODO: don't create new blocks if recycling an old packet 1531 // TODO: don't create new blocks if recycling an old packet
1525 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1532 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1526 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1533 for (int i = 0 ; i < localIDs.Count ; i++ )
1527 kill.ObjectData[0].ID = localID; 1534 {
1535 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1536 kill.ObjectData[i].ID = localIDs[i];
1537 }
1528 kill.Header.Reliable = true; 1538 kill.Header.Reliable = true;
1529 kill.Header.Zerocoded = true; 1539 kill.Header.Zerocoded = true;
1530 1540
1531 if (m_scene.GetScenePresence(localID) == null) 1541 lock (m_killRecord)
1532 { 1542 {
1533 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 1543 if (localIDs.Count == 1)
1534 // condition where a kill can be processed before an out-of-date update for the same object.
1535 lock (m_killRecord)
1536 { 1544 {
1537 m_killRecord.Add(localID); 1545 if (m_scene.GetScenePresence(localIDs[0]) != null)
1538 1546 {
1539 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1547 OutPacket(kill, ThrottleOutPacketType.State);
1540 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1548 return;
1541 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1549 }
1542 // scene objects in a viewer until that viewer is relogged in. 1550 m_killRecord.Add(localIDs[0]);
1543 OutPacket(kill, ThrottleOutPacketType.Task); 1551 }
1552 else
1553 {
1554 lock (m_entityUpdates.SyncRoot)
1555 {
1556 foreach (uint localID in localIDs)
1557 m_killRecord.Add(localID);
1558 }
1544 } 1559 }
1545 } 1560 }
1546 else 1561
1547 { 1562 // The throttle queue used here must match that being used for
1548 // OutPacket(kill, ThrottleOutPacketType.State); 1563 // updates. Otherwise, there is a chance that a kill packet put
1549 OutPacket(kill, ThrottleOutPacketType.Task); 1564 // on a separate queue will be sent to the client before an
1550 } 1565 // existing update packet on another queue. Receiving updates
1566 // after kills results in unowned and undeletable
1567 // scene objects in a viewer until that viewer is relogged in.
1568 OutPacket(kill, ThrottleOutPacketType.Task);
1551 } 1569 }
1552 1570
1553 /// <summary> 1571 /// <summary>
@@ -2272,6 +2290,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2272 OutPacket(sound, ThrottleOutPacketType.Task); 2290 OutPacket(sound, ThrottleOutPacketType.Task);
2273 } 2291 }
2274 2292
2293 public void SendTransferAbort(TransferRequestPacket transferRequest)
2294 {
2295 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2296 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2297 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2298 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2299 OutPacket(abort, ThrottleOutPacketType.Task);
2300 }
2301
2275 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2302 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2276 { 2303 {
2277 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2304 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3574,7 +3601,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3574 /// </summary> 3601 /// </summary>
3575 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3602 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3576 { 3603 {
3577 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3604 if (entity is SceneObjectPart)
3605 {
3606 SceneObjectPart e = (SceneObjectPart)entity;
3607 SceneObjectGroup g = e.ParentGroup;
3608 if (g.RootPart.Shape.State > 30) // HUD
3609 if (g.OwnerID != AgentId)
3610 return; // Don't send updates for other people's HUDs
3611 }
3612
3578 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3613 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3579 3614
3580 lock (m_entityUpdates.SyncRoot) 3615 lock (m_entityUpdates.SyncRoot)
@@ -3641,211 +3676,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3641 3676
3642 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3677 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3643 // condition where a kill can be processed before an out-of-date update for the same object. 3678 // condition where a kill can be processed before an out-of-date update for the same object.
3644 lock (m_killRecord) 3679 float avgTimeDilation = 1.0f;
3680 IEntityUpdate iupdate;
3681 Int32 timeinqueue; // this is just debugging code & can be dropped later
3682
3683 while (updatesThisCall < maxUpdates)
3645 { 3684 {
3646 float avgTimeDilation = 1.0f; 3685 lock (m_entityUpdates.SyncRoot)
3647 IEntityUpdate iupdate; 3686 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3648 Int32 timeinqueue; // this is just debugging code & can be dropped later 3687 break;
3649
3650 while (updatesThisCall < maxUpdates)
3651 {
3652 lock (m_entityUpdates.SyncRoot)
3653 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3654 break;
3655 3688
3656 EntityUpdate update = (EntityUpdate)iupdate; 3689 EntityUpdate update = (EntityUpdate)iupdate;
3657 3690
3658 avgTimeDilation += update.TimeDilation; 3691 avgTimeDilation += update.TimeDilation;
3659 avgTimeDilation *= 0.5f; 3692 avgTimeDilation *= 0.5f;
3660 3693
3661 if (update.Entity is SceneObjectPart) 3694 if (update.Entity is SceneObjectPart)
3695 {
3696 SceneObjectPart part = (SceneObjectPart)update.Entity;
3697
3698 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3699 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3700 // safety measure.
3701 //
3702 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3703 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3704 // updates and kills on different threads with different scheduling strategies, hence this protection.
3705 //
3706 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3707 // after the root prim has been deleted.
3708 lock (m_killRecord)
3662 { 3709 {
3663 SceneObjectPart part = (SceneObjectPart)update.Entity;
3664
3665 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3666 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3667 // safety measure.
3668 //
3669 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3670 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3671 // updates and kills on different threads with different scheduling strategies, hence this protection.
3672 //
3673 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3674 // after the root prim has been deleted.
3675 if (m_killRecord.Contains(part.LocalId)) 3710 if (m_killRecord.Contains(part.LocalId))
3676 {
3677 // m_log.WarnFormat(
3678 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3679 // part.LocalId, Name);
3680 continue; 3711 continue;
3681 } 3712 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3682 3713 continue;
3683 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3714 }
3715
3716 if (part.ParentGroup.IsDeleted)
3717 continue;
3718
3719 if (part.ParentGroup.IsAttachment)
3720 { // Someone else's HUD, why are we getting these?
3721 if (part.ParentGroup.OwnerID != AgentId &&
3722 part.ParentGroup.RootPart.Shape.State >= 30)
3723 continue;
3724 ScenePresence sp;
3725 // Owner is not in the sim, don't update it to
3726 // anyone
3727 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3728 continue;
3729
3730 List<SceneObjectGroup> atts = sp.Attachments;
3731 bool found = false;
3732 foreach (SceneObjectGroup att in atts)
3684 { 3733 {
3685 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3734 if (att == part.ParentGroup)
3686 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3687 { 3735 {
3688 part.Shape.LightEntry = false; 3736 found = true;
3737 break;
3689 } 3738 }
3690 } 3739 }
3740
3741 // It's an attachment of a valid avatar, but
3742 // doesn't seem to be attached, skip
3743 if (!found)
3744 continue;
3691 } 3745 }
3692 3746 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3693 ++updatesThisCall;
3694
3695 #region UpdateFlags to packet type conversion
3696
3697 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3698
3699 bool canUseCompressed = true;
3700 bool canUseImproved = true;
3701
3702 // Compressed object updates only make sense for LL primitives
3703 if (!(update.Entity is SceneObjectPart))
3704 {
3705 canUseCompressed = false;
3706 }
3707
3708 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3709 {
3710 canUseCompressed = false;
3711 canUseImproved = false;
3712 }
3713 else
3714 { 3747 {
3715 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3748 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3716 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3749 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3717 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3718 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3719 { 3750 {
3720 canUseCompressed = false; 3751 part.Shape.LightEntry = false;
3721 }
3722
3723 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3724 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3725 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3726 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3727 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3728 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3729 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3730 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3731 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3732 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3733 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3734 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3735 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3736 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3737 {
3738 canUseImproved = false;
3739 } 3752 }
3740 } 3753 }
3741 3754 }
3742 #endregion UpdateFlags to packet type conversion 3755
3743 3756 ++updatesThisCall;
3744 #region Block Construction 3757
3745 3758 #region UpdateFlags to packet type conversion
3746 // TODO: Remove this once we can build compressed updates 3759
3760 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3761
3762 bool canUseCompressed = true;
3763 bool canUseImproved = true;
3764
3765 // Compressed object updates only make sense for LL primitives
3766 if (!(update.Entity is SceneObjectPart))
3767 {
3747 canUseCompressed = false; 3768 canUseCompressed = false;
3748 3769 }
3749 if (!canUseImproved && !canUseCompressed) 3770
3750 { 3771 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3751 if (update.Entity is ScenePresence) 3772 {
3752 { 3773 canUseCompressed = false;
3753 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3774 canUseImproved = false;
3754 objectUpdates.Value.Add(update); 3775 }
3755 } 3776 else
3756 else 3777 {
3757 { 3778 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3758 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3779 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3759 objectUpdates.Value.Add(update); 3780 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3760 } 3781 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3761 }
3762 else if (!canUseImproved)
3763 { 3782 {
3764 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3783 canUseCompressed = false;
3765 compressedUpdates.Value.Add(update);
3766 } 3784 }
3767 else 3785
3786 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3787 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3788 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3789 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3790 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3791 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3792 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3793 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3794 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3795 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3796 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3797 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3798 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3768 { 3800 {
3769 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3801 canUseImproved = false;
3770 {
3771 // Self updates go into a special list
3772 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3773 terseAgentUpdates.Value.Add(update);
3774 }
3775 else
3776 {
3777 // Everything else goes here
3778 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3779 terseUpdates.Value.Add(update);
3780 }
3781 } 3802 }
3782
3783 #endregion Block Construction
3784 } 3803 }
3785
3786
3787 #region Packet Sending
3788 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3789 3804
3790 if (terseAgentUpdateBlocks.IsValueCreated) 3805 #endregion UpdateFlags to packet type conversion
3791 {
3792 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3793 3806
3794 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3807 #region Block Construction
3795 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3796 packet.RegionData.TimeDilation = timeDilation;
3797 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3798 3808
3799 for (int i = 0; i < blocks.Count; i++) 3809 // TODO: Remove this once we can build compressed updates
3800 packet.ObjectData[i] = blocks[i]; 3810 canUseCompressed = false;
3801 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3802 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3803 }
3804 3811
3805 if (objectUpdateBlocks.IsValueCreated) 3812 if (!canUseImproved && !canUseCompressed)
3806 { 3813 {
3807 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3814 if (update.Entity is ScenePresence)
3808 3815 {
3809 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3816 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3810 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3817 }
3811 packet.RegionData.TimeDilation = timeDilation; 3818 else
3812 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3819 {
3813 3820 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3814 for (int i = 0; i < blocks.Count; i++) 3821 }
3815 packet.ObjectData[i] = blocks[i];
3816 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3817 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3818 } 3822 }
3819 3823 else if (!canUseImproved)
3820 if (compressedUpdateBlocks.IsValueCreated)
3821 { 3824 {
3822 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3825 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3823
3824 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3825 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3826 packet.RegionData.TimeDilation = timeDilation;
3827 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3828
3829 for (int i = 0; i < blocks.Count; i++)
3830 packet.ObjectData[i] = blocks[i];
3831 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3832 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3833 } 3826 }
3834 3827 else
3835 if (terseUpdateBlocks.IsValueCreated)
3836 { 3828 {
3837 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3829 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3838 3830 // Self updates go into a special list
3839 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3831 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3840 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3832 else
3841 packet.RegionData.TimeDilation = timeDilation; 3833 // Everything else goes here
3842 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3834 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
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(terseUpdates.Value, oPacket); });
3848 } 3835 }
3836
3837 #endregion Block Construction
3838 }
3839
3840 #region Packet Sending
3841
3842 const float TIME_DILATION = 1.0f;
3843 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3844
3845 if (terseAgentUpdateBlocks.IsValueCreated)
3846 {
3847 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3848
3849 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3850 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3851 packet.RegionData.TimeDilation = timeDilation;
3852 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3853
3854 for (int i = 0; i < blocks.Count; i++)
3855 packet.ObjectData[i] = blocks[i];
3856
3857 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3858 }
3859
3860 if (objectUpdateBlocks.IsValueCreated)
3861 {
3862 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3863
3864 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3865 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3866 packet.RegionData.TimeDilation = timeDilation;
3867 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3868
3869 for (int i = 0; i < blocks.Count; i++)
3870 packet.ObjectData[i] = blocks[i];
3871
3872 OutPacket(packet, ThrottleOutPacketType.Task, true);
3873 }
3874
3875 if (compressedUpdateBlocks.IsValueCreated)
3876 {
3877 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3878
3879 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3880 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3881 packet.RegionData.TimeDilation = timeDilation;
3882 packet.ObjectData = new ObjectUpdateCompressedPacket.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 (terseUpdateBlocks.IsValueCreated)
3891 {
3892 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3893
3894 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3895 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3896 packet.RegionData.TimeDilation = timeDilation;
3897 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.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);
3849 } 3903 }
3850 3904
3851 #endregion Packet Sending 3905 #endregion Packet Sending
@@ -4329,37 +4383,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4329 if (bl[i].BannedUserID == UUID.Zero) 4383 if (bl[i].BannedUserID == UUID.Zero)
4330 continue; 4384 continue;
4331 BannedUsers.Add(bl[i].BannedUserID); 4385 BannedUsers.Add(bl[i].BannedUserID);
4332 }
4333 4386
4334 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4387 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4335 packet.AgentData.TransactionID = UUID.Random(); 4388 {
4336 packet.AgentData.AgentID = AgentId; 4389 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4337 packet.AgentData.SessionID = SessionId; 4390 packet.AgentData.TransactionID = UUID.Random();
4338 packet.MethodData.Invoice = invoice; 4391 packet.AgentData.AgentID = AgentId;
4339 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4392 packet.AgentData.SessionID = SessionId;
4393 packet.MethodData.Invoice = invoice;
4394 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4340 4395
4341 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4396 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4342 4397
4343 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4398 int j;
4344 { 4399 for (j = 0; j < (6 + BannedUsers.Count); j++)
4345 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4400 {
4346 } 4401 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4347 int j = 0; 4402 }
4403 j = 0;
4348 4404
4349 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4405 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4350 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4406 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4351 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4407 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4352 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4408 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4353 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4409 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4354 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4410 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4355 4411
4356 foreach (UUID banned in BannedUsers) 4412 foreach (UUID banned in BannedUsers)
4357 { 4413 {
4358 returnblock[j].Parameter = banned.GetBytes(); j++; 4414 returnblock[j].Parameter = banned.GetBytes(); j++;
4415 }
4416 packet.ParamList = returnblock;
4417 packet.Header.Reliable = true;
4418 OutPacket(packet, ThrottleOutPacketType.Task);
4419
4420 BannedUsers.Clear();
4421 }
4359 } 4422 }
4360 packet.ParamList = returnblock; 4423
4361 packet.Header.Reliable = false;
4362 OutPacket(packet, ThrottleOutPacketType.Task);
4363 } 4424 }
4364 4425
4365 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4426 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4657,14 +4718,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4657 4718
4658 if (notifyCount > 0) 4719 if (notifyCount > 0)
4659 { 4720 {
4660 if (notifyCount > 32) 4721// if (notifyCount > 32)
4661 { 4722// {
4662 m_log.InfoFormat( 4723// m_log.InfoFormat(
4663 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4724// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4664 + " - a developer might want to investigate whether this is a hard limit", 32); 4725// + " - a developer might want to investigate whether this is a hard limit", 32);
4665 4726//
4666 notifyCount = 32; 4727// notifyCount = 32;
4667 } 4728// }
4668 4729
4669 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4730 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4670 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4731 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5180,6 +5241,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5180 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5241 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5181 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5242 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5182 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5243 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5244 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5183 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5245 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5184 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5246 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5185 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5247 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5279,6 +5341,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5279 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5341 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5280 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5342 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5281 (x.ControlFlags != lastarg.ControlFlags) || 5343 (x.ControlFlags != lastarg.ControlFlags) ||
5344 (x.ControlFlags != 0) ||
5282 (x.Far != lastarg.Far) || 5345 (x.Far != lastarg.Far) ||
5283 (x.Flags != lastarg.Flags) || 5346 (x.Flags != lastarg.Flags) ||
5284 (x.State != lastarg.State) || 5347 (x.State != lastarg.State) ||
@@ -5652,7 +5715,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5652 args.Channel = ch; 5715 args.Channel = ch;
5653 args.From = String.Empty; 5716 args.From = String.Empty;
5654 args.Message = Utils.BytesToString(msg); 5717 args.Message = Utils.BytesToString(msg);
5655 args.Type = ChatTypeEnum.Shout; 5718 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5656 args.Position = new Vector3(); 5719 args.Position = new Vector3();
5657 args.Scene = Scene; 5720 args.Scene = Scene;
5658 args.Sender = this; 5721 args.Sender = this;
@@ -9658,7 +9721,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9658 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9721 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9659 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9722 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9660 UpdateMuteListEntry.MuteData.MuteType, 9723 UpdateMuteListEntry.MuteData.MuteType,
9661 UpdateMuteListEntry.AgentData.AgentID); 9724 UpdateMuteListEntry.MuteData.MuteFlags);
9662 return true; 9725 return true;
9663 } 9726 }
9664 return false; 9727 return false;
@@ -9673,8 +9736,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9673 { 9736 {
9674 handlerRemoveMuteListEntry(this, 9737 handlerRemoveMuteListEntry(this,
9675 RemoveMuteListEntry.MuteData.MuteID, 9738 RemoveMuteListEntry.MuteData.MuteID,
9676 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9739 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9677 RemoveMuteListEntry.AgentData.AgentID);
9678 return true; 9740 return true;
9679 } 9741 }
9680 return false; 9742 return false;
@@ -9722,6 +9784,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9722 { 9784 {
9723 return true; 9785 return true;
9724 } 9786 }
9787
9788 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9789 {
9790 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9791
9792 #region Packet Session and User Check
9793 if (m_checkPackets)
9794 {
9795 if (packet.AgentData.SessionID != SessionId ||
9796 packet.AgentData.AgentID != AgentId)
9797 return true;
9798 }
9799 #endregion
9800 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9801 List<InventoryItemBase> items = new List<InventoryItemBase>();
9802 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9803 {
9804 InventoryItemBase b = new InventoryItemBase();
9805 b.ID = n.OldItemID;
9806 b.Folder = n.OldFolderID;
9807 items.Add(b);
9808 }
9809
9810 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9811 if (handlerMoveItemsAndLeaveCopy != null)
9812 {
9813 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9814 }
9815
9816 return true;
9817 }
9725 9818
9726 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9819 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9727 { 9820 {
@@ -10148,6 +10241,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10148 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10241 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10149 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10242 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10150 10243
10244 Scene scene = (Scene)m_scene;
10245 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10246 {
10247 ScenePresence p;
10248 if (scene.TryGetScenePresence(sender.AgentId, out p))
10249 {
10250 if (p.GodLevel >= 200)
10251 {
10252 groupProfileReply.GroupData.OpenEnrollment = true;
10253 groupProfileReply.GroupData.MembershipFee = 0;
10254 }
10255 }
10256 }
10257
10151 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10258 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10152 } 10259 }
10153 return true; 10260 return true;
@@ -10720,11 +10827,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10720 10827
10721 StartLure handlerStartLure = OnStartLure; 10828 StartLure handlerStartLure = OnStartLure;
10722 if (handlerStartLure != null) 10829 if (handlerStartLure != null)
10723 handlerStartLure(startLureRequest.Info.LureType, 10830 {
10724 Utils.BytesToString( 10831 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10725 startLureRequest.Info.Message), 10832 {
10726 startLureRequest.TargetData[0].TargetID, 10833 handlerStartLure(startLureRequest.Info.LureType,
10727 this); 10834 Utils.BytesToString(
10835 startLureRequest.Info.Message),
10836 startLureRequest.TargetData[i].TargetID,
10837 this);
10838 }
10839 }
10728 return true; 10840 return true;
10729 } 10841 }
10730 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10842 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10838,10 +10950,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10838 } 10950 }
10839 #endregion 10951 #endregion
10840 10952
10841 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10953 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10842 if (handlerClassifiedGodDelete != null) 10954 if (handlerClassifiedGodDelete != null)
10843 handlerClassifiedGodDelete( 10955 handlerClassifiedGodDelete(
10844 classifiedGodDelete.Data.ClassifiedID, 10956 classifiedGodDelete.Data.ClassifiedID,
10957 classifiedGodDelete.Data.QueryID,
10845 this); 10958 this);
10846 return true; 10959 return true;
10847 } 10960 }
@@ -11219,7 +11332,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11219 { 11332 {
11220 // It's a ghost! tell the client to delete it from view. 11333 // It's a ghost! tell the client to delete it from view.
11221 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11334 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11222 localId); 11335 new List<uint>() { localId });
11223 } 11336 }
11224 else 11337 else
11225 { 11338 {
@@ -11608,22 +11721,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11608 /// <param name="Pack">OpenMetaverse.packet</param> 11721 /// <param name="Pack">OpenMetaverse.packet</param>
11609 public void ProcessInPacket(Packet packet) 11722 public void ProcessInPacket(Packet packet)
11610 { 11723 {
11611 if (m_debugPacketLevel > 0) 11724 if (m_debugPacketLevel >= 255)
11612 { 11725 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11613 bool outputPacket = true;
11614
11615 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11616 outputPacket = false;
11617
11618 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11619 outputPacket = false;
11620
11621 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11622 outputPacket = false;
11623
11624 if (outputPacket)
11625 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11626 }
11627 11726
11628 if (!ProcessPacketMethod(packet)) 11727 if (!ProcessPacketMethod(packet))
11629 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11728 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11865,7 +11964,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11865 11964
11866// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11965// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11867 11966
11967
11968 //Note, the bool returned from the below function is useless since it is always false.
11868 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11969 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11970
11869 } 11971 }
11870 11972
11871 /// <summary> 11973 /// <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,