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.cs703
1 files changed, 417 insertions, 286 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 29ad966..4f09d8f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 158 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 159 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 160 public event CopyInventoryItem OnCopyInventoryItem;
161 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 162 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 163 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 164 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 257 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 258 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 259 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 260 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 261 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 262 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 263 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +288,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 288 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 289 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 290 public event SendPostcard OnSendPostcard;
291 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 292 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 293 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 294 public event GodlikeMessage onGodlikeMessage;
@@ -337,7 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 339 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 340 /// ownerless phantom.
339 /// 341 ///
340 /// All manipulation of this set has to occur under a lock 342 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 343 ///
342 /// </value> 344 /// </value>
343 protected HashSet<uint> m_killRecord; 345 protected HashSet<uint> m_killRecord;
@@ -345,6 +347,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
345// protected HashSet<uint> m_attachmentsSent; 347// protected HashSet<uint> m_attachmentsSent;
346 348
347 private int m_moneyBalance; 349 private int m_moneyBalance;
350 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 351 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 352 private bool m_SendLogoutPacketWhenClosing = true;
350 private AgentUpdateArgs lastarg; 353 private AgentUpdateArgs lastarg;
@@ -384,6 +387,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
384 get { return m_startpos; } 387 get { return m_startpos; }
385 set { m_startpos = value; } 388 set { m_startpos = value; }
386 } 389 }
390 public bool DeliverPackets
391 {
392 get { return m_deliverPackets; }
393 set {
394 m_deliverPackets = value;
395 m_udpClient.m_deliverPackets = value;
396 }
397 }
387 public UUID AgentId { get { return m_agentId; } } 398 public UUID AgentId { get { return m_agentId; } }
388 public ISceneAgent SceneAgent { get; private set; } 399 public ISceneAgent SceneAgent { get; private set; }
389 public UUID ActiveGroupId { get { return m_activeGroupID; } } 400 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -488,18 +499,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 499
489 #region Client Methods 500 #region Client Methods
490 501
502
491 /// <summary> 503 /// <summary>
492 /// Shut down the client view 504 /// Shut down the client view
493 /// </summary> 505 /// </summary>
494 public void Close() 506 public void Close()
495 { 507 {
508 Close(true);
509 }
510
511 /// <summary>
512 /// Shut down the client view
513 /// </summary>
514 public void Close(bool sendStop)
515 {
496 m_log.DebugFormat( 516 m_log.DebugFormat(
497 "[CLIENT]: Close has been called for {0} attached to scene {1}", 517 "[CLIENT]: Close has been called for {0} attached to scene {1}",
498 Name, m_scene.RegionInfo.RegionName); 518 Name, m_scene.RegionInfo.RegionName);
499 519
500 // Send the STOP packet 520 if (sendStop)
501 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 521 {
502 OutPacket(disable, ThrottleOutPacketType.Unknown); 522 // Send the STOP packet
523 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
524 OutPacket(disable, ThrottleOutPacketType.Unknown);
525 }
503 526
504 IsActive = false; 527 IsActive = false;
505 528
@@ -799,7 +822,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
799 reply.ChatData.OwnerID = fromAgentID; 822 reply.ChatData.OwnerID = fromAgentID;
800 reply.ChatData.SourceID = fromAgentID; 823 reply.ChatData.SourceID = fromAgentID;
801 824
802 OutPacket(reply, ThrottleOutPacketType.Task); 825 OutPacket(reply, ThrottleOutPacketType.Unknown);
803 } 826 }
804 827
805 /// <summary> 828 /// <summary>
@@ -1085,6 +1108,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1085 public virtual void SendLayerData(float[] map) 1108 public virtual void SendLayerData(float[] map)
1086 { 1109 {
1087 Util.FireAndForget(DoSendLayerData, map); 1110 Util.FireAndForget(DoSendLayerData, map);
1111
1112 // Send it sync, and async. It's not that much data
1113 // and it improves user experience just so much!
1114 DoSendLayerData(map);
1088 } 1115 }
1089 1116
1090 /// <summary> 1117 /// <summary>
@@ -1097,16 +1124,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1097 1124
1098 try 1125 try
1099 { 1126 {
1100 //for (int y = 0; y < 16; y++) 1127 for (int y = 0; y < 16; y++)
1101 //{ 1128 {
1102 // for (int x = 0; x < 16; x++) 1129 for (int x = 0; x < 16; x+=4)
1103 // { 1130 {
1104 // SendLayerData(x, y, map); 1131 SendLayerPacket(x, y, map);
1105 // } 1132 }
1106 //} 1133 }
1107
1108 // Send LayerData in a spiral pattern. Fun!
1109 SendLayerTopRight(map, 0, 0, 15, 15);
1110 } 1134 }
1111 catch (Exception e) 1135 catch (Exception e)
1112 { 1136 {
@@ -1114,51 +1138,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1114 } 1138 }
1115 } 1139 }
1116 1140
1117 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1118 {
1119 // Row
1120 for (int i = x1; i <= x2; i++)
1121 SendLayerData(i, y1, map);
1122
1123 // Column
1124 for (int j = y1 + 1; j <= y2; j++)
1125 SendLayerData(x2, j, map);
1126
1127 if (x2 - x1 > 0)
1128 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1129 }
1130
1131 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1132 {
1133 // Row in reverse
1134 for (int i = x2; i >= x1; i--)
1135 SendLayerData(i, y2, map);
1136
1137 // Column in reverse
1138 for (int j = y2 - 1; j >= y1; j--)
1139 SendLayerData(x1, j, map);
1140
1141 if (x2 - x1 > 0)
1142 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1143 }
1144
1145 /// <summary> 1141 /// <summary>
1146 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1142 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1147 /// </summary> 1143 /// </summary>
1148 /// <param name="map">heightmap</param> 1144 /// <param name="map">heightmap</param>
1149 /// <param name="px">X coordinate for patches 0..12</param> 1145 /// <param name="px">X coordinate for patches 0..12</param>
1150 /// <param name="py">Y coordinate for patches 0..15</param> 1146 /// <param name="py">Y coordinate for patches 0..15</param>
1151 // private void SendLayerPacket(float[] map, int y, int x) 1147 private void SendLayerPacket(int x, int y, float[] map)
1152 // { 1148 {
1153 // int[] patches = new int[4]; 1149 int[] patches = new int[4];
1154 // patches[0] = x + 0 + y * 16; 1150 patches[0] = x + 0 + y * 16;
1155 // patches[1] = x + 1 + y * 16; 1151 patches[1] = x + 1 + y * 16;
1156 // patches[2] = x + 2 + y * 16; 1152 patches[2] = x + 2 + y * 16;
1157 // patches[3] = x + 3 + y * 16; 1153 patches[3] = x + 3 + y * 16;
1158 1154
1159 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1155 float[] heightmap = (map.Length == 65536) ?
1160 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1156 map :
1161 // } 1157 LLHeightFieldMoronize(map);
1158
1159 try
1160 {
1161 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1162 OutPacket(layerpack, ThrottleOutPacketType.Land);
1163 }
1164 catch
1165 {
1166 for (int px = x ; px < x + 4 ; px++)
1167 SendLayerData(px, y, map);
1168 }
1169 }
1162 1170
1163 /// <summary> 1171 /// <summary>
1164 /// Sends a specified patch to a client 1172 /// Sends a specified patch to a client
@@ -1178,7 +1186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1178 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1186 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1179 layerpack.Header.Reliable = true; 1187 layerpack.Header.Reliable = true;
1180 1188
1181 OutPacket(layerpack, ThrottleOutPacketType.Land); 1189 OutPacket(layerpack, ThrottleOutPacketType.Task);
1182 } 1190 }
1183 catch (Exception e) 1191 catch (Exception e)
1184 { 1192 {
@@ -2302,6 +2310,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2302 OutPacket(sound, ThrottleOutPacketType.Task); 2310 OutPacket(sound, ThrottleOutPacketType.Task);
2303 } 2311 }
2304 2312
2313 public void SendTransferAbort(TransferRequestPacket transferRequest)
2314 {
2315 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2316 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2317 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2318 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2319 OutPacket(abort, ThrottleOutPacketType.Task);
2320 }
2321
2305 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2322 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2306 { 2323 {
2307 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2324 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2749,7 +2766,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2749 reply.Data.ParcelID = parcelID; 2766 reply.Data.ParcelID = parcelID;
2750 reply.Data.OwnerID = land.OwnerID; 2767 reply.Data.OwnerID = land.OwnerID;
2751 reply.Data.Name = Utils.StringToBytes(land.Name); 2768 reply.Data.Name = Utils.StringToBytes(land.Name);
2752 reply.Data.Desc = Utils.StringToBytes(land.Description); 2769 if (land != null && land.Description != null && land.Description != String.Empty)
2770 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2771 else
2772 reply.Data.Desc = new Byte[0];
2753 reply.Data.ActualArea = land.Area; 2773 reply.Data.ActualArea = land.Area;
2754 reply.Data.BillableArea = land.Area; // TODO: what is this? 2774 reply.Data.BillableArea = land.Area; // TODO: what is this?
2755 2775
@@ -3612,7 +3632,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3612 /// </summary> 3632 /// </summary>
3613 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3633 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3614 { 3634 {
3615 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3635 if (entity is SceneObjectPart)
3636 {
3637 SceneObjectPart e = (SceneObjectPart)entity;
3638 SceneObjectGroup g = e.ParentGroup;
3639 if (g.RootPart.Shape.State > 30) // HUD
3640 if (g.OwnerID != AgentId)
3641 return; // Don't send updates for other people's HUDs
3642 }
3643
3616 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3644 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3617 3645
3618 lock (m_entityUpdates.SyncRoot) 3646 lock (m_entityUpdates.SyncRoot)
@@ -3679,211 +3707,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3679 3707
3680 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3708 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3681 // condition where a kill can be processed before an out-of-date update for the same object. 3709 // condition where a kill can be processed before an out-of-date update for the same object.
3682 lock (m_killRecord) 3710 float avgTimeDilation = 1.0f;
3711 IEntityUpdate iupdate;
3712 Int32 timeinqueue; // this is just debugging code & can be dropped later
3713
3714 while (updatesThisCall < maxUpdates)
3683 { 3715 {
3684 float avgTimeDilation = 1.0f; 3716 lock (m_entityUpdates.SyncRoot)
3685 IEntityUpdate iupdate; 3717 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3686 Int32 timeinqueue; // this is just debugging code & can be dropped later 3718 break;
3687
3688 while (updatesThisCall < maxUpdates)
3689 {
3690 lock (m_entityUpdates.SyncRoot)
3691 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3692 break;
3693 3719
3694 EntityUpdate update = (EntityUpdate)iupdate; 3720 EntityUpdate update = (EntityUpdate)iupdate;
3695 3721
3696 avgTimeDilation += update.TimeDilation; 3722 avgTimeDilation += update.TimeDilation;
3697 avgTimeDilation *= 0.5f; 3723 avgTimeDilation *= 0.5f;
3698 3724
3699 if (update.Entity is SceneObjectPart) 3725 if (update.Entity is SceneObjectPart)
3726 {
3727 SceneObjectPart part = (SceneObjectPart)update.Entity;
3728
3729 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3730 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3731 // safety measure.
3732 //
3733 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3734 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3735 // updates and kills on different threads with different scheduling strategies, hence this protection.
3736 //
3737 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3738 // after the root prim has been deleted.
3739 lock (m_killRecord)
3700 { 3740 {
3701 SceneObjectPart part = (SceneObjectPart)update.Entity;
3702
3703 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3704 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3705 // safety measure.
3706 //
3707 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3708 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3709 // updates and kills on different threads with different scheduling strategies, hence this protection.
3710 //
3711 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3712 // after the root prim has been deleted.
3713 if (m_killRecord.Contains(part.LocalId)) 3741 if (m_killRecord.Contains(part.LocalId))
3714 {
3715 // m_log.WarnFormat(
3716 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3717 // part.LocalId, Name);
3718 continue; 3742 continue;
3719 } 3743 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3720 3744 continue;
3721 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3745 }
3746
3747 if (part.ParentGroup.IsDeleted)
3748 continue;
3749
3750 if (part.ParentGroup.IsAttachment)
3751 { // Someone else's HUD, why are we getting these?
3752 if (part.ParentGroup.OwnerID != AgentId &&
3753 part.ParentGroup.RootPart.Shape.State >= 30)
3754 continue;
3755 ScenePresence sp;
3756 // Owner is not in the sim, don't update it to
3757 // anyone
3758 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3759 continue;
3760
3761 List<SceneObjectGroup> atts = sp.GetAttachments();
3762 bool found = false;
3763 foreach (SceneObjectGroup att in atts)
3722 { 3764 {
3723 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3765 if (att == part.ParentGroup)
3724 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3725 { 3766 {
3726 part.Shape.LightEntry = false; 3767 found = true;
3768 break;
3727 } 3769 }
3728 } 3770 }
3771
3772 // It's an attachment of a valid avatar, but
3773 // doesn't seem to be attached, skip
3774 if (!found)
3775 continue;
3729 } 3776 }
3730 3777 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3731 ++updatesThisCall;
3732
3733 #region UpdateFlags to packet type conversion
3734
3735 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3736
3737 bool canUseCompressed = true;
3738 bool canUseImproved = true;
3739
3740 // Compressed object updates only make sense for LL primitives
3741 if (!(update.Entity is SceneObjectPart))
3742 {
3743 canUseCompressed = false;
3744 }
3745
3746 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3747 {
3748 canUseCompressed = false;
3749 canUseImproved = false;
3750 }
3751 else
3752 { 3778 {
3753 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3779 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3754 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3780 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3755 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3757 { 3781 {
3758 canUseCompressed = false; 3782 part.Shape.LightEntry = false;
3759 }
3760
3761 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3775 {
3776 canUseImproved = false;
3777 } 3783 }
3778 } 3784 }
3779 3785 }
3780 #endregion UpdateFlags to packet type conversion 3786
3781 3787 ++updatesThisCall;
3782 #region Block Construction 3788
3783 3789 #region UpdateFlags to packet type conversion
3784 // TODO: Remove this once we can build compressed updates 3790
3791 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3792
3793 bool canUseCompressed = true;
3794 bool canUseImproved = true;
3795
3796 // Compressed object updates only make sense for LL primitives
3797 if (!(update.Entity is SceneObjectPart))
3798 {
3785 canUseCompressed = false; 3799 canUseCompressed = false;
3786 3800 }
3787 if (!canUseImproved && !canUseCompressed) 3801
3788 { 3802 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3789 if (update.Entity is ScenePresence) 3803 {
3790 { 3804 canUseCompressed = false;
3791 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3805 canUseImproved = false;
3792 objectUpdates.Value.Add(update); 3806 }
3793 } 3807 else
3794 else 3808 {
3795 { 3809 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3796 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3810 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3797 objectUpdates.Value.Add(update); 3811 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3798 } 3812 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3799 }
3800 else if (!canUseImproved)
3801 { 3813 {
3802 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3814 canUseCompressed = false;
3803 compressedUpdates.Value.Add(update);
3804 } 3815 }
3805 else 3816
3817 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3821 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3822 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3823 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3824 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3825 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3826 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3827 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3828 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3829 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3830 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3806 { 3831 {
3807 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3832 canUseImproved = false;
3808 {
3809 // Self updates go into a special list
3810 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3811 terseAgentUpdates.Value.Add(update);
3812 }
3813 else
3814 {
3815 // Everything else goes here
3816 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3817 terseUpdates.Value.Add(update);
3818 }
3819 } 3833 }
3820
3821 #endregion Block Construction
3822 } 3834 }
3823
3824
3825 #region Packet Sending
3826 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3827 3835
3828 if (terseAgentUpdateBlocks.IsValueCreated) 3836 #endregion UpdateFlags to packet type conversion
3829 {
3830 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3831 3837
3832 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3838 #region Block Construction
3833 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3834 packet.RegionData.TimeDilation = timeDilation;
3835 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3836 3839
3837 for (int i = 0; i < blocks.Count; i++) 3840 // TODO: Remove this once we can build compressed updates
3838 packet.ObjectData[i] = blocks[i]; 3841 canUseCompressed = false;
3839 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3840 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3841 }
3842 3842
3843 if (objectUpdateBlocks.IsValueCreated) 3843 if (!canUseImproved && !canUseCompressed)
3844 { 3844 {
3845 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3845 if (update.Entity is ScenePresence)
3846 3846 {
3847 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3847 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3848 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3848 }
3849 packet.RegionData.TimeDilation = timeDilation; 3849 else
3850 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3850 {
3851 3851 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3852 for (int i = 0; i < blocks.Count; i++) 3852 }
3853 packet.ObjectData[i] = blocks[i];
3854 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3855 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3856 } 3853 }
3857 3854 else if (!canUseImproved)
3858 if (compressedUpdateBlocks.IsValueCreated)
3859 { 3855 {
3860 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3856 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3861
3862 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3863 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3864 packet.RegionData.TimeDilation = timeDilation;
3865 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3866
3867 for (int i = 0; i < blocks.Count; i++)
3868 packet.ObjectData[i] = blocks[i];
3869 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3870 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3871 } 3857 }
3872 3858 else
3873 if (terseUpdateBlocks.IsValueCreated)
3874 { 3859 {
3875 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3860 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3876 3861 // Self updates go into a special list
3877 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3862 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3863 else
3879 packet.RegionData.TimeDilation = timeDilation; 3864 // Everything else goes here
3880 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3865 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3881
3882 for (int i = 0; i < blocks.Count; i++)
3883 packet.ObjectData[i] = blocks[i];
3884 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3885 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3886 } 3866 }
3867
3868 #endregion Block Construction
3869 }
3870
3871 #region Packet Sending
3872
3873 const float TIME_DILATION = 1.0f;
3874 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3875
3876 if (terseAgentUpdateBlocks.IsValueCreated)
3877 {
3878 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3879
3880 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3881 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3882 packet.RegionData.TimeDilation = timeDilation;
3883 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3884
3885 for (int i = 0; i < blocks.Count; i++)
3886 packet.ObjectData[i] = blocks[i];
3887
3888 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3889 }
3890
3891 if (objectUpdateBlocks.IsValueCreated)
3892 {
3893 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3894
3895 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3896 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3897 packet.RegionData.TimeDilation = timeDilation;
3898 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3899
3900 for (int i = 0; i < blocks.Count; i++)
3901 packet.ObjectData[i] = blocks[i];
3902
3903 OutPacket(packet, ThrottleOutPacketType.Task, true);
3904 }
3905
3906 if (compressedUpdateBlocks.IsValueCreated)
3907 {
3908 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3909
3910 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3911 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3912 packet.RegionData.TimeDilation = timeDilation;
3913 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3914
3915 for (int i = 0; i < blocks.Count; i++)
3916 packet.ObjectData[i] = blocks[i];
3917
3918 OutPacket(packet, ThrottleOutPacketType.Task, true);
3919 }
3920
3921 if (terseUpdateBlocks.IsValueCreated)
3922 {
3923 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3924
3925 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3926 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3927 packet.RegionData.TimeDilation = timeDilation;
3928 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3929
3930 for (int i = 0; i < blocks.Count; i++)
3931 packet.ObjectData[i] = blocks[i];
3932
3933 OutPacket(packet, ThrottleOutPacketType.Task, true);
3887 } 3934 }
3888 3935
3889 #endregion Packet Sending 3936 #endregion Packet Sending
@@ -4176,11 +4223,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4176 4223
4177 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4224 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4178 // of the object rather than the properties when the packet was created 4225 // of the object rather than the properties when the packet was created
4179 OutPacket(packet, ThrottleOutPacketType.Task, true, 4226 // HACK : Remove intelligent resending until it's fixed in core
4180 delegate(OutgoingPacket oPacket) 4227 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4181 { 4228 // delegate(OutgoingPacket oPacket)
4182 ResendPropertyUpdates(updates, oPacket); 4229 // {
4183 }); 4230 // ResendPropertyUpdates(updates, oPacket);
4231 // });
4232 OutPacket(packet, ThrottleOutPacketType.Task, true);
4184 4233
4185 // pbcnt += blocks.Count; 4234 // pbcnt += blocks.Count;
4186 // ppcnt++; 4235 // ppcnt++;
@@ -4206,11 +4255,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4206 // of the object rather than the properties when the packet was created 4255 // of the object rather than the properties when the packet was created
4207 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4256 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4208 updates.Add(familyUpdates.Value[i]); 4257 updates.Add(familyUpdates.Value[i]);
4209 OutPacket(packet, ThrottleOutPacketType.Task, true, 4258 // HACK : Remove intelligent resending until it's fixed in core
4210 delegate(OutgoingPacket oPacket) 4259 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4211 { 4260 // delegate(OutgoingPacket oPacket)
4212 ResendPropertyUpdates(updates, oPacket); 4261 // {
4213 }); 4262 // ResendPropertyUpdates(updates, oPacket);
4263 // });
4264 OutPacket(packet, ThrottleOutPacketType.Task, true);
4214 4265
4215 // fpcnt++; 4266 // fpcnt++;
4216 // fbcnt++; 4267 // fbcnt++;
@@ -4359,37 +4410,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4359 if (bl[i].BannedUserID == UUID.Zero) 4410 if (bl[i].BannedUserID == UUID.Zero)
4360 continue; 4411 continue;
4361 BannedUsers.Add(bl[i].BannedUserID); 4412 BannedUsers.Add(bl[i].BannedUserID);
4362 }
4363 4413
4364 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4414 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4365 packet.AgentData.TransactionID = UUID.Random(); 4415 {
4366 packet.AgentData.AgentID = AgentId; 4416 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4367 packet.AgentData.SessionID = SessionId; 4417 packet.AgentData.TransactionID = UUID.Random();
4368 packet.MethodData.Invoice = invoice; 4418 packet.AgentData.AgentID = AgentId;
4369 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4419 packet.AgentData.SessionID = SessionId;
4420 packet.MethodData.Invoice = invoice;
4421 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4370 4422
4371 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4423 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4372 4424
4373 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4425 int j;
4374 { 4426 for (j = 0; j < (6 + BannedUsers.Count); j++)
4375 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4427 {
4376 } 4428 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4377 int j = 0; 4429 }
4430 j = 0;
4378 4431
4379 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4432 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4433 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4434 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4435 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4383 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4436 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4384 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4437 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4385 4438
4386 foreach (UUID banned in BannedUsers) 4439 foreach (UUID banned in BannedUsers)
4387 { 4440 {
4388 returnblock[j].Parameter = banned.GetBytes(); j++; 4441 returnblock[j].Parameter = banned.GetBytes(); j++;
4442 }
4443 packet.ParamList = returnblock;
4444 packet.Header.Reliable = true;
4445 OutPacket(packet, ThrottleOutPacketType.Task);
4446
4447 BannedUsers.Clear();
4448 }
4389 } 4449 }
4390 packet.ParamList = returnblock; 4450
4391 packet.Header.Reliable = false;
4392 OutPacket(packet, ThrottleOutPacketType.Task);
4393 } 4451 }
4394 4452
4395 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4453 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4575,7 +4633,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4575 4633
4576 if (landData.SimwideArea > 0) 4634 if (landData.SimwideArea > 0)
4577 { 4635 {
4578 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4636 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4637 // Never report more than sim total capacity
4638 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4639 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4579 updateMessage.SimWideMaxPrims = simulatorCapacity; 4640 updateMessage.SimWideMaxPrims = simulatorCapacity;
4580 } 4641 }
4581 else 4642 else
@@ -4704,14 +4765,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4704 4765
4705 if (notifyCount > 0) 4766 if (notifyCount > 0)
4706 { 4767 {
4707 if (notifyCount > 32) 4768// if (notifyCount > 32)
4708 { 4769// {
4709 m_log.InfoFormat( 4770// m_log.InfoFormat(
4710 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4771// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4711 + " - a developer might want to investigate whether this is a hard limit", 32); 4772// + " - a developer might want to investigate whether this is a hard limit", 32);
4712 4773//
4713 notifyCount = 32; 4774// notifyCount = 32;
4714 } 4775// }
4715 4776
4716 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4777 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4717 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4778 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5244,6 +5305,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5244 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5305 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5245 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5306 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5246 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5307 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5308 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5247 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5309 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5248 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5310 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5249 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5311 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5310,6 +5372,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5310 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5372 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5311 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5373 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5312 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5374 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5375 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5313 5376
5314 AddGenericPacketHandler("autopilot", HandleAutopilot); 5377 AddGenericPacketHandler("autopilot", HandleAutopilot);
5315 } 5378 }
@@ -5345,6 +5408,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5345 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5408 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5346 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5409 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5347 (x.ControlFlags != lastarg.ControlFlags) || 5410 (x.ControlFlags != lastarg.ControlFlags) ||
5411 (x.ControlFlags != 0) ||
5348 (x.Far != lastarg.Far) || 5412 (x.Far != lastarg.Far) ||
5349 (x.Flags != lastarg.Flags) || 5413 (x.Flags != lastarg.Flags) ||
5350 (x.State != lastarg.State) || 5414 (x.State != lastarg.State) ||
@@ -5722,7 +5786,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5722 args.Channel = ch; 5786 args.Channel = ch;
5723 args.From = String.Empty; 5787 args.From = String.Empty;
5724 args.Message = Utils.BytesToString(msg); 5788 args.Message = Utils.BytesToString(msg);
5725 args.Type = ChatTypeEnum.Shout; 5789 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5726 args.Position = new Vector3(); 5790 args.Position = new Vector3();
5727 args.Scene = Scene; 5791 args.Scene = Scene;
5728 args.Sender = this; 5792 args.Sender = this;
@@ -9761,7 +9825,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9761 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9825 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9762 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9826 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9763 UpdateMuteListEntry.MuteData.MuteType, 9827 UpdateMuteListEntry.MuteData.MuteType,
9764 UpdateMuteListEntry.AgentData.AgentID); 9828 UpdateMuteListEntry.MuteData.MuteFlags);
9765 return true; 9829 return true;
9766 } 9830 }
9767 return false; 9831 return false;
@@ -9776,8 +9840,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9776 { 9840 {
9777 handlerRemoveMuteListEntry(this, 9841 handlerRemoveMuteListEntry(this,
9778 RemoveMuteListEntry.MuteData.MuteID, 9842 RemoveMuteListEntry.MuteData.MuteID,
9779 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9843 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9780 RemoveMuteListEntry.AgentData.AgentID);
9781 return true; 9844 return true;
9782 } 9845 }
9783 return false; 9846 return false;
@@ -9821,10 +9884,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9821 return false; 9884 return false;
9822 } 9885 }
9823 9886
9887 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9888 {
9889 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9890 (ChangeInventoryItemFlagsPacket)packet;
9891 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9892 if (handlerChangeInventoryItemFlags != null)
9893 {
9894 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9895 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9896 return true;
9897 }
9898 return false;
9899 }
9900
9824 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9901 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9825 { 9902 {
9826 return true; 9903 return true;
9827 } 9904 }
9905
9906 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9907 {
9908 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9909
9910 #region Packet Session and User Check
9911 if (m_checkPackets)
9912 {
9913 if (packet.AgentData.SessionID != SessionId ||
9914 packet.AgentData.AgentID != AgentId)
9915 return true;
9916 }
9917 #endregion
9918 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9919 List<InventoryItemBase> items = new List<InventoryItemBase>();
9920 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9921 {
9922 InventoryItemBase b = new InventoryItemBase();
9923 b.ID = n.OldItemID;
9924 b.Folder = n.OldFolderID;
9925 items.Add(b);
9926 }
9927
9928 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9929 if (handlerMoveItemsAndLeaveCopy != null)
9930 {
9931 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9932 }
9933
9934 return true;
9935 }
9828 9936
9829 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9937 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9830 { 9938 {
@@ -10251,6 +10359,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10251 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10359 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10252 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10360 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10253 10361
10362 Scene scene = (Scene)m_scene;
10363 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10364 {
10365 ScenePresence p;
10366 if (scene.TryGetScenePresence(sender.AgentId, out p))
10367 {
10368 if (p.GodLevel >= 200)
10369 {
10370 groupProfileReply.GroupData.OpenEnrollment = true;
10371 groupProfileReply.GroupData.MembershipFee = 0;
10372 }
10373 }
10374 }
10375
10254 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10376 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10255 } 10377 }
10256 return true; 10378 return true;
@@ -10824,11 +10946,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10824 10946
10825 StartLure handlerStartLure = OnStartLure; 10947 StartLure handlerStartLure = OnStartLure;
10826 if (handlerStartLure != null) 10948 if (handlerStartLure != null)
10827 handlerStartLure(startLureRequest.Info.LureType, 10949 {
10828 Utils.BytesToString( 10950 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10829 startLureRequest.Info.Message), 10951 {
10830 startLureRequest.TargetData[0].TargetID, 10952 handlerStartLure(startLureRequest.Info.LureType,
10831 this); 10953 Utils.BytesToString(
10954 startLureRequest.Info.Message),
10955 startLureRequest.TargetData[i].TargetID,
10956 this);
10957 }
10958 }
10832 return true; 10959 return true;
10833 } 10960 }
10834 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10961 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10942,10 +11069,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10942 } 11069 }
10943 #endregion 11070 #endregion
10944 11071
10945 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11072 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10946 if (handlerClassifiedGodDelete != null) 11073 if (handlerClassifiedGodDelete != null)
10947 handlerClassifiedGodDelete( 11074 handlerClassifiedGodDelete(
10948 classifiedGodDelete.Data.ClassifiedID, 11075 classifiedGodDelete.Data.ClassifiedID,
11076 classifiedGodDelete.Data.QueryID,
10949 this); 11077 this);
10950 return true; 11078 return true;
10951 } 11079 }
@@ -11989,7 +12117,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11989 12117
11990// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12118// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11991 12119
12120
12121 //Note, the bool returned from the below function is useless since it is always false.
11992 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12122 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12123
11993 } 12124 }
11994 12125
11995 /// <summary> 12126 /// <summary>