aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs729
1 files changed, 417 insertions, 312 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index c176c2b..99552f1 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)
@@ -4528,7 +4589,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4528 4589
4529 if (landData.SimwideArea > 0) 4590 if (landData.SimwideArea > 0)
4530 { 4591 {
4531 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4592 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4593 // Never report more than sim total capacity
4594 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4595 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4532 updateMessage.SimWideMaxPrims = simulatorCapacity; 4596 updateMessage.SimWideMaxPrims = simulatorCapacity;
4533 } 4597 }
4534 else 4598 else
@@ -4657,14 +4721,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4657 4721
4658 if (notifyCount > 0) 4722 if (notifyCount > 0)
4659 { 4723 {
4660 if (notifyCount > 32) 4724// if (notifyCount > 32)
4661 { 4725// {
4662 m_log.InfoFormat( 4726// m_log.InfoFormat(
4663 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4727// "[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); 4728// + " - a developer might want to investigate whether this is a hard limit", 32);
4665 4729//
4666 notifyCount = 32; 4730// notifyCount = 32;
4667 } 4731// }
4668 4732
4669 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4733 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4670 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4734 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5180,6 +5244,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5180 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5244 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5181 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5245 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5182 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5246 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5247 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5183 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5248 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5184 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5249 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5185 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5250 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5279,6 +5344,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5279 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5344 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5280 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5345 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5281 (x.ControlFlags != lastarg.ControlFlags) || 5346 (x.ControlFlags != lastarg.ControlFlags) ||
5347 (x.ControlFlags != 0) ||
5282 (x.Far != lastarg.Far) || 5348 (x.Far != lastarg.Far) ||
5283 (x.Flags != lastarg.Flags) || 5349 (x.Flags != lastarg.Flags) ||
5284 (x.State != lastarg.State) || 5350 (x.State != lastarg.State) ||
@@ -5652,7 +5718,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5652 args.Channel = ch; 5718 args.Channel = ch;
5653 args.From = String.Empty; 5719 args.From = String.Empty;
5654 args.Message = Utils.BytesToString(msg); 5720 args.Message = Utils.BytesToString(msg);
5655 args.Type = ChatTypeEnum.Shout; 5721 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5656 args.Position = new Vector3(); 5722 args.Position = new Vector3();
5657 args.Scene = Scene; 5723 args.Scene = Scene;
5658 args.Sender = this; 5724 args.Sender = this;
@@ -9657,7 +9723,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9657 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9723 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9658 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9724 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9659 UpdateMuteListEntry.MuteData.MuteType, 9725 UpdateMuteListEntry.MuteData.MuteType,
9660 UpdateMuteListEntry.AgentData.AgentID); 9726 UpdateMuteListEntry.MuteData.MuteFlags);
9661 return true; 9727 return true;
9662 } 9728 }
9663 return false; 9729 return false;
@@ -9672,8 +9738,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9672 { 9738 {
9673 handlerRemoveMuteListEntry(this, 9739 handlerRemoveMuteListEntry(this,
9674 RemoveMuteListEntry.MuteData.MuteID, 9740 RemoveMuteListEntry.MuteData.MuteID,
9675 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9741 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9676 RemoveMuteListEntry.AgentData.AgentID);
9677 return true; 9742 return true;
9678 } 9743 }
9679 return false; 9744 return false;
@@ -9721,6 +9786,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9721 { 9786 {
9722 return true; 9787 return true;
9723 } 9788 }
9789
9790 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9791 {
9792 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9793
9794 #region Packet Session and User Check
9795 if (m_checkPackets)
9796 {
9797 if (packet.AgentData.SessionID != SessionId ||
9798 packet.AgentData.AgentID != AgentId)
9799 return true;
9800 }
9801 #endregion
9802 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9803 List<InventoryItemBase> items = new List<InventoryItemBase>();
9804 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9805 {
9806 InventoryItemBase b = new InventoryItemBase();
9807 b.ID = n.OldItemID;
9808 b.Folder = n.OldFolderID;
9809 items.Add(b);
9810 }
9811
9812 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9813 if (handlerMoveItemsAndLeaveCopy != null)
9814 {
9815 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9816 }
9817
9818 return true;
9819 }
9724 9820
9725 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9821 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9726 { 9822 {
@@ -10147,6 +10243,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10147 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10243 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10148 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10244 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10149 10245
10246 Scene scene = (Scene)m_scene;
10247 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10248 {
10249 ScenePresence p;
10250 if (scene.TryGetScenePresence(sender.AgentId, out p))
10251 {
10252 if (p.GodLevel >= 200)
10253 {
10254 groupProfileReply.GroupData.OpenEnrollment = true;
10255 groupProfileReply.GroupData.MembershipFee = 0;
10256 }
10257 }
10258 }
10259
10150 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10260 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10151 } 10261 }
10152 return true; 10262 return true;
@@ -10719,11 +10829,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10719 10829
10720 StartLure handlerStartLure = OnStartLure; 10830 StartLure handlerStartLure = OnStartLure;
10721 if (handlerStartLure != null) 10831 if (handlerStartLure != null)
10722 handlerStartLure(startLureRequest.Info.LureType, 10832 {
10723 Utils.BytesToString( 10833 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10724 startLureRequest.Info.Message), 10834 {
10725 startLureRequest.TargetData[0].TargetID, 10835 handlerStartLure(startLureRequest.Info.LureType,
10726 this); 10836 Utils.BytesToString(
10837 startLureRequest.Info.Message),
10838 startLureRequest.TargetData[i].TargetID,
10839 this);
10840 }
10841 }
10727 return true; 10842 return true;
10728 } 10843 }
10729 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10844 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10837,10 +10952,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10837 } 10952 }
10838 #endregion 10953 #endregion
10839 10954
10840 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 10955 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10841 if (handlerClassifiedGodDelete != null) 10956 if (handlerClassifiedGodDelete != null)
10842 handlerClassifiedGodDelete( 10957 handlerClassifiedGodDelete(
10843 classifiedGodDelete.Data.ClassifiedID, 10958 classifiedGodDelete.Data.ClassifiedID,
10959 classifiedGodDelete.Data.QueryID,
10844 this); 10960 this);
10845 return true; 10961 return true;
10846 } 10962 }
@@ -11218,7 +11334,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11218 { 11334 {
11219 // It's a ghost! tell the client to delete it from view. 11335 // It's a ghost! tell the client to delete it from view.
11220 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11336 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
11221 localId); 11337 new List<uint>() { localId });
11222 } 11338 }
11223 else 11339 else
11224 { 11340 {
@@ -11607,22 +11723,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11607 /// <param name="Pack">OpenMetaverse.packet</param> 11723 /// <param name="Pack">OpenMetaverse.packet</param>
11608 public void ProcessInPacket(Packet packet) 11724 public void ProcessInPacket(Packet packet)
11609 { 11725 {
11610 if (m_debugPacketLevel > 0) 11726 if (m_debugPacketLevel >= 255)
11611 { 11727 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11612 bool outputPacket = true;
11613
11614 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11615 outputPacket = false;
11616
11617 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11618 outputPacket = false;
11619
11620 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11621 outputPacket = false;
11622
11623 if (outputPacket)
11624 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11625 }
11626 11728
11627 if (!ProcessPacketMethod(packet)) 11729 if (!ProcessPacketMethod(packet))
11628 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11730 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11864,7 +11966,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11864 11966
11865// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11967// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11866 11968
11969
11970 //Note, the bool returned from the below function is useless since it is always false.
11867 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11971 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11972
11868 } 11973 }
11869 11974
11870 /// <summary> 11975 /// <summary>