aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs698
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 465 insertions, 309 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index e9e2dca..9dd6663 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -202,6 +202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 m_stopPacket = TexturePacketCount(); 202 m_stopPacket = TexturePacketCount();
203 } 203 }
204 204
205 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
206 if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
207
205 m_currentPacket = StartPacket; 208 m_currentPacket = StartPacket;
206 } 209 }
207 } 210 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index b37fd54..083dcc0 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;
@@ -255,7 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
255 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 256 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
256 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
257 public event ClassifiedDelete OnClassifiedDelete; 258 public event ClassifiedDelete OnClassifiedDelete;
258 public event ClassifiedDelete OnClassifiedGodDelete; 259 public event ClassifiedGodDelete OnClassifiedGodDelete;
259 public event EventNotificationAddRequest OnEventNotificationAddRequest; 260 public event EventNotificationAddRequest OnEventNotificationAddRequest;
260 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
261 public event EventGodDelete OnEventGodDelete; 262 public event EventGodDelete OnEventGodDelete;
@@ -286,6 +287,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
286 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
287 public event SimWideDeletesDelegate OnSimWideDeletes; 288 public event SimWideDeletesDelegate OnSimWideDeletes;
288 public event SendPostcard OnSendPostcard; 289 public event SendPostcard OnSendPostcard;
290 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
289 public event MuteListEntryUpdate OnUpdateMuteListEntry; 291 public event MuteListEntryUpdate OnUpdateMuteListEntry;
290 public event MuteListEntryRemove OnRemoveMuteListEntry; 292 public event MuteListEntryRemove OnRemoveMuteListEntry;
291 public event GodlikeMessage onGodlikeMessage; 293 public event GodlikeMessage onGodlikeMessage;
@@ -331,7 +333,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
331 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 333 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
332 /// ownerless phantom. 334 /// ownerless phantom.
333 /// 335 ///
334 /// All manipulation of this set has to occur under a lock 336 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
335 /// 337 ///
336 /// </value> 338 /// </value>
337 protected HashSet<uint> m_killRecord; 339 protected HashSet<uint> m_killRecord;
@@ -339,6 +341,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339// protected HashSet<uint> m_attachmentsSent; 341// protected HashSet<uint> m_attachmentsSent;
340 342
341 private int m_moneyBalance; 343 private int m_moneyBalance;
344 private bool m_deliverPackets = true;
342 private int m_animationSequenceNumber = 1; 345 private int m_animationSequenceNumber = 1;
343 private bool m_SendLogoutPacketWhenClosing = true; 346 private bool m_SendLogoutPacketWhenClosing = true;
344 private AgentUpdateArgs lastarg; 347 private AgentUpdateArgs lastarg;
@@ -379,6 +382,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
379 get { return m_startpos; } 382 get { return m_startpos; }
380 set { m_startpos = value; } 383 set { m_startpos = value; }
381 } 384 }
385 public bool DeliverPackets
386 {
387 get { return m_deliverPackets; }
388 set {
389 m_deliverPackets = value;
390 m_udpClient.m_deliverPackets = value;
391 }
392 }
382 public UUID AgentId { get { return m_agentId; } } 393 public UUID AgentId { get { return m_agentId; } }
383 public ISceneAgent SceneAgent { get; private set; } 394 public ISceneAgent SceneAgent { get; private set; }
384 public UUID ActiveGroupId { get { return m_activeGroupID; } } 395 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -483,18 +494,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
483 494
484 #region Client Methods 495 #region Client Methods
485 496
497
486 /// <summary> 498 /// <summary>
487 /// Shut down the client view 499 /// Shut down the client view
488 /// </summary> 500 /// </summary>
489 public void Close() 501 public void Close()
490 { 502 {
503 Close(true);
504 }
505
506 /// <summary>
507 /// Shut down the client view
508 /// </summary>
509 public void Close(bool sendStop)
510 {
491 m_log.DebugFormat( 511 m_log.DebugFormat(
492 "[CLIENT]: Close has been called for {0} attached to scene {1}", 512 "[CLIENT]: Close has been called for {0} attached to scene {1}",
493 Name, m_scene.RegionInfo.RegionName); 513 Name, m_scene.RegionInfo.RegionName);
494 514
495 // Send the STOP packet 515 if (sendStop)
496 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 516 {
497 OutPacket(disable, ThrottleOutPacketType.Unknown); 517 // Send the STOP packet
518 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
519 OutPacket(disable, ThrottleOutPacketType.Unknown);
520 }
498 521
499 IsActive = false; 522 IsActive = false;
500 523
@@ -798,7 +821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
798 reply.ChatData.OwnerID = fromAgentID; 821 reply.ChatData.OwnerID = fromAgentID;
799 reply.ChatData.SourceID = fromAgentID; 822 reply.ChatData.SourceID = fromAgentID;
800 823
801 OutPacket(reply, ThrottleOutPacketType.Task); 824 OutPacket(reply, ThrottleOutPacketType.Unknown);
802 } 825 }
803 826
804 /// <summary> 827 /// <summary>
@@ -1084,6 +1107,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1084 public virtual void SendLayerData(float[] map) 1107 public virtual void SendLayerData(float[] map)
1085 { 1108 {
1086 Util.FireAndForget(DoSendLayerData, map); 1109 Util.FireAndForget(DoSendLayerData, map);
1110
1111 // Send it sync, and async. It's not that much data
1112 // and it improves user experience just so much!
1113 DoSendLayerData(map);
1087 } 1114 }
1088 1115
1089 /// <summary> 1116 /// <summary>
@@ -1096,16 +1123,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1096 1123
1097 try 1124 try
1098 { 1125 {
1099 //for (int y = 0; y < 16; y++) 1126 for (int y = 0; y < 16; y++)
1100 //{ 1127 {
1101 // for (int x = 0; x < 16; x++) 1128 for (int x = 0; x < 16; x+=4)
1102 // { 1129 {
1103 // SendLayerData(x, y, map); 1130 SendLayerPacket(x, y, map);
1104 // } 1131 }
1105 //} 1132 }
1106
1107 // Send LayerData in a spiral pattern. Fun!
1108 SendLayerTopRight(map, 0, 0, 15, 15);
1109 } 1133 }
1110 catch (Exception e) 1134 catch (Exception e)
1111 { 1135 {
@@ -1113,51 +1137,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1113 } 1137 }
1114 } 1138 }
1115 1139
1116 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1117 {
1118 // Row
1119 for (int i = x1; i <= x2; i++)
1120 SendLayerData(i, y1, map);
1121
1122 // Column
1123 for (int j = y1 + 1; j <= y2; j++)
1124 SendLayerData(x2, j, map);
1125
1126 if (x2 - x1 > 0)
1127 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1128 }
1129
1130 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1131 {
1132 // Row in reverse
1133 for (int i = x2; i >= x1; i--)
1134 SendLayerData(i, y2, map);
1135
1136 // Column in reverse
1137 for (int j = y2 - 1; j >= y1; j--)
1138 SendLayerData(x1, j, map);
1139
1140 if (x2 - x1 > 0)
1141 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1142 }
1143
1144 /// <summary> 1140 /// <summary>
1145 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1141 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1146 /// </summary> 1142 /// </summary>
1147 /// <param name="map">heightmap</param> 1143 /// <param name="map">heightmap</param>
1148 /// <param name="px">X coordinate for patches 0..12</param> 1144 /// <param name="px">X coordinate for patches 0..12</param>
1149 /// <param name="py">Y coordinate for patches 0..15</param> 1145 /// <param name="py">Y coordinate for patches 0..15</param>
1150 // private void SendLayerPacket(float[] map, int y, int x) 1146 private void SendLayerPacket(int x, int y, float[] map)
1151 // { 1147 {
1152 // int[] patches = new int[4]; 1148 int[] patches = new int[4];
1153 // patches[0] = x + 0 + y * 16; 1149 patches[0] = x + 0 + y * 16;
1154 // patches[1] = x + 1 + y * 16; 1150 patches[1] = x + 1 + y * 16;
1155 // patches[2] = x + 2 + y * 16; 1151 patches[2] = x + 2 + y * 16;
1156 // patches[3] = x + 3 + y * 16; 1152 patches[3] = x + 3 + y * 16;
1157 1153
1158 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1154 float[] heightmap = (map.Length == 65536) ?
1159 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1155 map :
1160 // } 1156 LLHeightFieldMoronize(map);
1157
1158 try
1159 {
1160 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1161 OutPacket(layerpack, ThrottleOutPacketType.Land);
1162 }
1163 catch
1164 {
1165 for (int px = x ; px < x + 4 ; px++)
1166 SendLayerData(px, y, map);
1167 }
1168 }
1161 1169
1162 /// <summary> 1170 /// <summary>
1163 /// Sends a specified patch to a client 1171 /// Sends a specified patch to a client
@@ -1177,7 +1185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1177 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1185 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1178 layerpack.Header.Reliable = true; 1186 layerpack.Header.Reliable = true;
1179 1187
1180 OutPacket(layerpack, ThrottleOutPacketType.Land); 1188 OutPacket(layerpack, ThrottleOutPacketType.Task);
1181 } 1189 }
1182 catch (Exception e) 1190 catch (Exception e)
1183 { 1191 {
@@ -2301,6 +2309,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2301 OutPacket(sound, ThrottleOutPacketType.Task); 2309 OutPacket(sound, ThrottleOutPacketType.Task);
2302 } 2310 }
2303 2311
2312 public void SendTransferAbort(TransferRequestPacket transferRequest)
2313 {
2314 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2315 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2316 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2317 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2318 OutPacket(abort, ThrottleOutPacketType.Task);
2319 }
2320
2304 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2321 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2305 { 2322 {
2306 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2323 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3603,7 +3620,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3603 /// </summary> 3620 /// </summary>
3604 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3621 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3605 { 3622 {
3606 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3623 if (entity is SceneObjectPart)
3624 {
3625 SceneObjectPart e = (SceneObjectPart)entity;
3626 SceneObjectGroup g = e.ParentGroup;
3627 if (g.RootPart.Shape.State > 30) // HUD
3628 if (g.OwnerID != AgentId)
3629 return; // Don't send updates for other people's HUDs
3630 }
3631
3607 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3632 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3608 3633
3609 lock (m_entityUpdates.SyncRoot) 3634 lock (m_entityUpdates.SyncRoot)
@@ -3670,211 +3695,230 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3670 3695
3671 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3696 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3672 // condition where a kill can be processed before an out-of-date update for the same object. 3697 // condition where a kill can be processed before an out-of-date update for the same object.
3673 lock (m_killRecord) 3698 float avgTimeDilation = 1.0f;
3699 IEntityUpdate iupdate;
3700 Int32 timeinqueue; // this is just debugging code & can be dropped later
3701
3702 while (updatesThisCall < maxUpdates)
3674 { 3703 {
3675 float avgTimeDilation = 1.0f; 3704 lock (m_entityUpdates.SyncRoot)
3676 IEntityUpdate iupdate; 3705 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3677 Int32 timeinqueue; // this is just debugging code & can be dropped later 3706 break;
3678
3679 while (updatesThisCall < maxUpdates)
3680 {
3681 lock (m_entityUpdates.SyncRoot)
3682 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3683 break;
3684 3707
3685 EntityUpdate update = (EntityUpdate)iupdate; 3708 EntityUpdate update = (EntityUpdate)iupdate;
3686 3709
3687 avgTimeDilation += update.TimeDilation; 3710 avgTimeDilation += update.TimeDilation;
3688 avgTimeDilation *= 0.5f; 3711 avgTimeDilation *= 0.5f;
3689 3712
3690 if (update.Entity is SceneObjectPart) 3713 if (update.Entity is SceneObjectPart)
3714 {
3715 SceneObjectPart part = (SceneObjectPart)update.Entity;
3716
3717 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3718 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3719 // safety measure.
3720 //
3721 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3722 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3723 // updates and kills on different threads with different scheduling strategies, hence this protection.
3724 //
3725 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3726 // after the root prim has been deleted.
3727 lock (m_killRecord)
3691 { 3728 {
3692 SceneObjectPart part = (SceneObjectPart)update.Entity;
3693
3694 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3695 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3696 // safety measure.
3697 //
3698 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3699 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3700 // updates and kills on different threads with different scheduling strategies, hence this protection.
3701 //
3702 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3703 // after the root prim has been deleted.
3704 if (m_killRecord.Contains(part.LocalId)) 3729 if (m_killRecord.Contains(part.LocalId))
3705 {
3706 // m_log.WarnFormat(
3707 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3708 // part.LocalId, Name);
3709 continue; 3730 continue;
3710 } 3731 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3711 3732 continue;
3712 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3733 }
3734
3735 if (part.ParentGroup.IsDeleted)
3736 continue;
3737
3738 if (part.ParentGroup.IsAttachment)
3739 { // Someone else's HUD, why are we getting these?
3740 if (part.ParentGroup.OwnerID != AgentId &&
3741 part.ParentGroup.RootPart.Shape.State >= 30)
3742 continue;
3743 ScenePresence sp;
3744 // Owner is not in the sim, don't update it to
3745 // anyone
3746 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3747 continue;
3748
3749 List<SceneObjectGroup> atts = sp.GetAttachments();
3750 bool found = false;
3751 foreach (SceneObjectGroup att in atts)
3713 { 3752 {
3714 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3753 if (att == part.ParentGroup)
3715 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3716 { 3754 {
3717 part.Shape.LightEntry = false; 3755 found = true;
3756 break;
3718 } 3757 }
3719 } 3758 }
3759
3760 // It's an attachment of a valid avatar, but
3761 // doesn't seem to be attached, skip
3762 if (!found)
3763 continue;
3720 } 3764 }
3721 3765 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3722 ++updatesThisCall;
3723
3724 #region UpdateFlags to packet type conversion
3725
3726 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3727
3728 bool canUseCompressed = true;
3729 bool canUseImproved = true;
3730
3731 // Compressed object updates only make sense for LL primitives
3732 if (!(update.Entity is SceneObjectPart))
3733 {
3734 canUseCompressed = false;
3735 }
3736
3737 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3738 {
3739 canUseCompressed = false;
3740 canUseImproved = false;
3741 }
3742 else
3743 { 3766 {
3744 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3767 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3745 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3768 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3746 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3747 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3748 {
3749 canUseCompressed = false;
3750 }
3751
3752 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3755 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3766 { 3769 {
3767 canUseImproved = false; 3770 part.Shape.LightEntry = false;
3768 } 3771 }
3769 } 3772 }
3770 3773 }
3771 #endregion UpdateFlags to packet type conversion 3774
3772 3775 ++updatesThisCall;
3773 #region Block Construction 3776
3774 3777 #region UpdateFlags to packet type conversion
3775 // TODO: Remove this once we can build compressed updates 3778
3779 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3780
3781 bool canUseCompressed = true;
3782 bool canUseImproved = true;
3783
3784 // Compressed object updates only make sense for LL primitives
3785 if (!(update.Entity is SceneObjectPart))
3786 {
3776 canUseCompressed = false; 3787 canUseCompressed = false;
3777 3788 }
3778 if (!canUseImproved && !canUseCompressed) 3789
3779 { 3790 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3780 if (update.Entity is ScenePresence) 3791 {
3781 { 3792 canUseCompressed = false;
3782 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3793 canUseImproved = false;
3783 objectUpdates.Value.Add(update); 3794 }
3784 } 3795 else
3785 else 3796 {
3786 { 3797 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3787 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3798 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3788 objectUpdates.Value.Add(update); 3799 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3789 } 3800 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3790 }
3791 else if (!canUseImproved)
3792 { 3801 {
3793 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3802 canUseCompressed = false;
3794 compressedUpdates.Value.Add(update);
3795 } 3803 }
3796 else 3804
3805 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3797 { 3819 {
3798 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3820 canUseImproved = false;
3799 {
3800 // Self updates go into a special list
3801 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3802 terseAgentUpdates.Value.Add(update);
3803 }
3804 else
3805 {
3806 // Everything else goes here
3807 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3808 terseUpdates.Value.Add(update);
3809 }
3810 } 3821 }
3811
3812 #endregion Block Construction
3813 } 3822 }
3814
3815
3816 #region Packet Sending
3817 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3818 3823
3819 if (terseAgentUpdateBlocks.IsValueCreated) 3824 #endregion UpdateFlags to packet type conversion
3820 {
3821 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3822 3825
3823 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3826 #region Block Construction
3824 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3825 packet.RegionData.TimeDilation = timeDilation;
3826 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3827 3827
3828 for (int i = 0; i < blocks.Count; i++) 3828 // TODO: Remove this once we can build compressed updates
3829 packet.ObjectData[i] = blocks[i]; 3829 canUseCompressed = false;
3830 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3831 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3832 }
3833 3830
3834 if (objectUpdateBlocks.IsValueCreated) 3831 if (!canUseImproved && !canUseCompressed)
3835 { 3832 {
3836 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3833 if (update.Entity is ScenePresence)
3837 3834 {
3838 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3835 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3839 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3836 }
3840 packet.RegionData.TimeDilation = timeDilation; 3837 else
3841 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3838 {
3842 3839 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3843 for (int i = 0; i < blocks.Count; i++) 3840 }
3844 packet.ObjectData[i] = blocks[i];
3845 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3846 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3847 } 3841 }
3848 3842 else if (!canUseImproved)
3849 if (compressedUpdateBlocks.IsValueCreated)
3850 { 3843 {
3851 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3844 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3852
3853 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3854 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3855 packet.RegionData.TimeDilation = timeDilation;
3856 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3857
3858 for (int i = 0; i < blocks.Count; i++)
3859 packet.ObjectData[i] = blocks[i];
3860 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3861 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3862 } 3845 }
3863 3846 else
3864 if (terseUpdateBlocks.IsValueCreated)
3865 { 3847 {
3866 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3848 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3867 3849 // Self updates go into a special list
3868 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3850 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3869 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3851 else
3870 packet.RegionData.TimeDilation = timeDilation; 3852 // Everything else goes here
3871 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3853 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3872
3873 for (int i = 0; i < blocks.Count; i++)
3874 packet.ObjectData[i] = blocks[i];
3875 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3876 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3877 } 3854 }
3855
3856 #endregion Block Construction
3857 }
3858
3859 #region Packet Sending
3860
3861 const float TIME_DILATION = 1.0f;
3862 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3863
3864 if (terseAgentUpdateBlocks.IsValueCreated)
3865 {
3866 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3867
3868 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3869 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3870 packet.RegionData.TimeDilation = timeDilation;
3871 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3872
3873 for (int i = 0; i < blocks.Count; i++)
3874 packet.ObjectData[i] = blocks[i];
3875
3876 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3877 }
3878
3879 if (objectUpdateBlocks.IsValueCreated)
3880 {
3881 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3882
3883 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3884 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3885 packet.RegionData.TimeDilation = timeDilation;
3886 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3887
3888 for (int i = 0; i < blocks.Count; i++)
3889 packet.ObjectData[i] = blocks[i];
3890
3891 OutPacket(packet, ThrottleOutPacketType.Task, true);
3892 }
3893
3894 if (compressedUpdateBlocks.IsValueCreated)
3895 {
3896 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3897
3898 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3899 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3900 packet.RegionData.TimeDilation = timeDilation;
3901 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3902
3903 for (int i = 0; i < blocks.Count; i++)
3904 packet.ObjectData[i] = blocks[i];
3905
3906 OutPacket(packet, ThrottleOutPacketType.Task, true);
3907 }
3908
3909 if (terseUpdateBlocks.IsValueCreated)
3910 {
3911 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3912
3913 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3914 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3915 packet.RegionData.TimeDilation = timeDilation;
3916 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3917
3918 for (int i = 0; i < blocks.Count; i++)
3919 packet.ObjectData[i] = blocks[i];
3920
3921 OutPacket(packet, ThrottleOutPacketType.Task, true);
3878 } 3922 }
3879 3923
3880 #endregion Packet Sending 3924 #endregion Packet Sending
@@ -4175,11 +4219,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4175 4219
4176 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4220 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4177 // of the object rather than the properties when the packet was created 4221 // of the object rather than the properties when the packet was created
4178 OutPacket(packet, ThrottleOutPacketType.Task, true, 4222 // HACK : Remove intelligent resending until it's fixed in core
4179 delegate(OutgoingPacket oPacket) 4223 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4180 { 4224 // delegate(OutgoingPacket oPacket)
4181 ResendPropertyUpdates(updates, oPacket); 4225 // {
4182 }); 4226 // ResendPropertyUpdates(updates, oPacket);
4227 // });
4228 OutPacket(packet, ThrottleOutPacketType.Task, true);
4183 4229
4184 // pbcnt += blocks.Count; 4230 // pbcnt += blocks.Count;
4185 // ppcnt++; 4231 // ppcnt++;
@@ -4205,11 +4251,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4205 // of the object rather than the properties when the packet was created 4251 // of the object rather than the properties when the packet was created
4206 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4252 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4207 updates.Add(familyUpdates.Value[i]); 4253 updates.Add(familyUpdates.Value[i]);
4208 OutPacket(packet, ThrottleOutPacketType.Task, true, 4254 // HACK : Remove intelligent resending until it's fixed in core
4209 delegate(OutgoingPacket oPacket) 4255 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4210 { 4256 // delegate(OutgoingPacket oPacket)
4211 ResendPropertyUpdates(updates, oPacket); 4257 // {
4212 }); 4258 // ResendPropertyUpdates(updates, oPacket);
4259 // });
4260 OutPacket(packet, ThrottleOutPacketType.Task, true);
4213 4261
4214 // fpcnt++; 4262 // fpcnt++;
4215 // fbcnt++; 4263 // fbcnt++;
@@ -4358,37 +4406,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4358 if (bl[i].BannedUserID == UUID.Zero) 4406 if (bl[i].BannedUserID == UUID.Zero)
4359 continue; 4407 continue;
4360 BannedUsers.Add(bl[i].BannedUserID); 4408 BannedUsers.Add(bl[i].BannedUserID);
4361 }
4362 4409
4363 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4410 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4364 packet.AgentData.TransactionID = UUID.Random(); 4411 {
4365 packet.AgentData.AgentID = AgentId; 4412 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4366 packet.AgentData.SessionID = SessionId; 4413 packet.AgentData.TransactionID = UUID.Random();
4367 packet.MethodData.Invoice = invoice; 4414 packet.AgentData.AgentID = AgentId;
4368 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4415 packet.AgentData.SessionID = SessionId;
4416 packet.MethodData.Invoice = invoice;
4417 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4369 4418
4370 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4419 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4371 4420
4372 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4421 int j;
4373 { 4422 for (j = 0; j < (6 + BannedUsers.Count); j++)
4374 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4423 {
4375 } 4424 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4376 int j = 0; 4425 }
4426 j = 0;
4377 4427
4378 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4428 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4429 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4430 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4431 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4432 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4383 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4433 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4384 4434
4385 foreach (UUID banned in BannedUsers) 4435 foreach (UUID banned in BannedUsers)
4386 { 4436 {
4387 returnblock[j].Parameter = banned.GetBytes(); j++; 4437 returnblock[j].Parameter = banned.GetBytes(); j++;
4438 }
4439 packet.ParamList = returnblock;
4440 packet.Header.Reliable = true;
4441 OutPacket(packet, ThrottleOutPacketType.Task);
4442
4443 BannedUsers.Clear();
4444 }
4388 } 4445 }
4389 packet.ParamList = returnblock; 4446
4390 packet.Header.Reliable = false;
4391 OutPacket(packet, ThrottleOutPacketType.Task);
4392 } 4447 }
4393 4448
4394 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4449 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4557,7 +4612,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4557 4612
4558 if (landData.SimwideArea > 0) 4613 if (landData.SimwideArea > 0)
4559 { 4614 {
4560 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4615 int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
4616 // Never report more than sim total capacity
4617 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4618 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4561 updateMessage.SimWideMaxPrims = simulatorCapacity; 4619 updateMessage.SimWideMaxPrims = simulatorCapacity;
4562 } 4620 }
4563 else 4621 else
@@ -4686,14 +4744,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4686 4744
4687 if (notifyCount > 0) 4745 if (notifyCount > 0)
4688 { 4746 {
4689 if (notifyCount > 32) 4747// if (notifyCount > 32)
4690 { 4748// {
4691 m_log.InfoFormat( 4749// m_log.InfoFormat(
4692 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4750// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4693 + " - a developer might want to investigate whether this is a hard limit", 32); 4751// + " - a developer might want to investigate whether this is a hard limit", 32);
4694 4752//
4695 notifyCount = 32; 4753// notifyCount = 32;
4696 } 4754// }
4697 4755
4698 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4756 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4699 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4757 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5226,6 +5284,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5226 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5284 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5227 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5285 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5228 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5286 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5287 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5229 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5288 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5230 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5289 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5231 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5290 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5292,6 +5351,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5292 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5351 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5293 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5352 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5294 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5353 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5354 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5295 5355
5296 AddGenericPacketHandler("autopilot", HandleAutopilot); 5356 AddGenericPacketHandler("autopilot", HandleAutopilot);
5297 } 5357 }
@@ -5327,6 +5387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5327 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5387 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5328 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5388 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5329 (x.ControlFlags != lastarg.ControlFlags) || 5389 (x.ControlFlags != lastarg.ControlFlags) ||
5390 (x.ControlFlags != 0) ||
5330 (x.Far != lastarg.Far) || 5391 (x.Far != lastarg.Far) ||
5331 (x.Flags != lastarg.Flags) || 5392 (x.Flags != lastarg.Flags) ||
5332 (x.State != lastarg.State) || 5393 (x.State != lastarg.State) ||
@@ -5704,7 +5765,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5704 args.Channel = ch; 5765 args.Channel = ch;
5705 args.From = String.Empty; 5766 args.From = String.Empty;
5706 args.Message = Utils.BytesToString(msg); 5767 args.Message = Utils.BytesToString(msg);
5707 args.Type = ChatTypeEnum.Shout; 5768 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5708 args.Position = new Vector3(); 5769 args.Position = new Vector3();
5709 args.Scene = Scene; 5770 args.Scene = Scene;
5710 args.Sender = this; 5771 args.Sender = this;
@@ -9719,7 +9780,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9719 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9780 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9720 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9781 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9721 UpdateMuteListEntry.MuteData.MuteType, 9782 UpdateMuteListEntry.MuteData.MuteType,
9722 UpdateMuteListEntry.AgentData.AgentID); 9783 UpdateMuteListEntry.MuteData.MuteFlags);
9723 return true; 9784 return true;
9724 } 9785 }
9725 return false; 9786 return false;
@@ -9734,8 +9795,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9734 { 9795 {
9735 handlerRemoveMuteListEntry(this, 9796 handlerRemoveMuteListEntry(this,
9736 RemoveMuteListEntry.MuteData.MuteID, 9797 RemoveMuteListEntry.MuteData.MuteID,
9737 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9798 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9738 RemoveMuteListEntry.AgentData.AgentID);
9739 return true; 9799 return true;
9740 } 9800 }
9741 return false; 9801 return false;
@@ -9779,10 +9839,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9779 return false; 9839 return false;
9780 } 9840 }
9781 9841
9842 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9843 {
9844 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9845 (ChangeInventoryItemFlagsPacket)packet;
9846 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9847 if (handlerChangeInventoryItemFlags != null)
9848 {
9849 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9850 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9851 return true;
9852 }
9853 return false;
9854 }
9855
9782 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9856 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9783 { 9857 {
9784 return true; 9858 return true;
9785 } 9859 }
9860
9861 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9862 {
9863 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9864
9865 #region Packet Session and User Check
9866 if (m_checkPackets)
9867 {
9868 if (packet.AgentData.SessionID != SessionId ||
9869 packet.AgentData.AgentID != AgentId)
9870 return true;
9871 }
9872 #endregion
9873 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9874 List<InventoryItemBase> items = new List<InventoryItemBase>();
9875 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9876 {
9877 InventoryItemBase b = new InventoryItemBase();
9878 b.ID = n.OldItemID;
9879 b.Folder = n.OldFolderID;
9880 items.Add(b);
9881 }
9882
9883 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9884 if (handlerMoveItemsAndLeaveCopy != null)
9885 {
9886 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9887 }
9888
9889 return true;
9890 }
9786 9891
9787 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9892 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9788 { 9893 {
@@ -10209,6 +10314,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10209 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10314 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10210 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10315 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10211 10316
10317 Scene scene = (Scene)m_scene;
10318 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10319 {
10320 ScenePresence p;
10321 if (scene.TryGetScenePresence(sender.AgentId, out p))
10322 {
10323 if (p.GodLevel >= 200)
10324 {
10325 groupProfileReply.GroupData.OpenEnrollment = true;
10326 groupProfileReply.GroupData.MembershipFee = 0;
10327 }
10328 }
10329 }
10330
10212 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10331 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10213 } 10332 }
10214 return true; 10333 return true;
@@ -10782,11 +10901,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10782 10901
10783 StartLure handlerStartLure = OnStartLure; 10902 StartLure handlerStartLure = OnStartLure;
10784 if (handlerStartLure != null) 10903 if (handlerStartLure != null)
10785 handlerStartLure(startLureRequest.Info.LureType, 10904 {
10786 Utils.BytesToString( 10905 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10787 startLureRequest.Info.Message), 10906 {
10788 startLureRequest.TargetData[0].TargetID, 10907 handlerStartLure(startLureRequest.Info.LureType,
10789 this); 10908 Utils.BytesToString(
10909 startLureRequest.Info.Message),
10910 startLureRequest.TargetData[i].TargetID,
10911 this);
10912 }
10913 }
10790 return true; 10914 return true;
10791 } 10915 }
10792 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10916 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10900,10 +11024,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10900 } 11024 }
10901 #endregion 11025 #endregion
10902 11026
10903 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11027 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10904 if (handlerClassifiedGodDelete != null) 11028 if (handlerClassifiedGodDelete != null)
10905 handlerClassifiedGodDelete( 11029 handlerClassifiedGodDelete(
10906 classifiedGodDelete.Data.ClassifiedID, 11030 classifiedGodDelete.Data.ClassifiedID,
11031 classifiedGodDelete.Data.QueryID,
10907 this); 11032 this);
10908 return true; 11033 return true;
10909 } 11034 }
@@ -11947,7 +12072,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11947 12072
11948// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12073// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11949 12074
12075
12076 //Note, the bool returned from the below function is useless since it is always false.
11950 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12077 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12078
11951 } 12079 }
11952 12080
11953 /// <summary> 12081 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..ae72175 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -439,6 +440,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
439 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
440 { 441 {
441 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
443
444 if (m_deliverPackets == false)
445 {
446 queue.Enqueue(packet);
447 return true;
448 }
449
442 TokenBucket bucket = m_throttleCategories[category]; 450 TokenBucket bucket = m_throttleCategories[category];
443 451
444 // Don't send this packet if there is already a packet waiting in the queue 452 // Don't send this packet if there is already a packet waiting in the queue
@@ -488,7 +496,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 /// <returns>True if any packets were sent, otherwise false</returns> 496 /// <returns>True if any packets were sent, otherwise false</returns>
489 public bool DequeueOutgoing() 497 public bool DequeueOutgoing()
490 { 498 {
491 OutgoingPacket packet; 499 if (m_deliverPackets == false) return false;
500
501 OutgoingPacket packet = null;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
494 bool packetSent = false; 504 bool packetSent = false;
@@ -520,32 +530,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 // No dequeued packet waiting to be sent, try to pull one off 530 // No dequeued packet waiting to be sent, try to pull one off
521 // this queue 531 // this queue
522 queue = m_packetOutboxes[i]; 532 queue = m_packetOutboxes[i];
523 if (queue.Dequeue(out packet)) 533 if (queue != null)
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 bool success = false;
526 // enough tokens in the bucket to send it out 536 try
527 if (bucket.RemoveTokens(packet.Buffer.DataLength))
528 { 537 {
529 // Send the packet 538 success = queue.Dequeue(out packet);
530 m_udpServer.SendPacketFinal(packet);
531 packetSent = true;
532 } 539 }
533 else 540 catch
534 { 541 {
535 // Save the dequeued packet for the next iteration 542 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
536 m_nextPackets[i] = packet;
537 } 543 }
538 544 if (success)
539 // If the queue is empty after this dequeue, fire the queue 545 {
540 // empty callback now so it has a chance to fill before we 546 // A packet was pulled off the queue. See if we have
541 // get back here 547 // enough tokens in the bucket to send it out
542 if (queue.Count == 0) 548 if (bucket.RemoveTokens(packet.Buffer.DataLength))
549 {
550 // Send the packet
551 m_udpServer.SendPacketFinal(packet);
552 packetSent = true;
553 }
554 else
555 {
556 // Save the dequeued packet for the next iteration
557 m_nextPackets[i] = packet;
558 }
559
560 // If the queue is empty after this dequeue, fire the queue
561 // empty callback now so it has a chance to fill before we
562 // get back here
563 if (queue.Count == 0)
564 emptyCategories |= CategoryToFlag(i);
565 }
566 else
567 {
568 // No packets in this queue. Fire the queue empty callback
569 // if it has not been called recently
543 emptyCategories |= CategoryToFlag(i); 570 emptyCategories |= CategoryToFlag(i);
571 }
544 } 572 }
545 else 573 else
546 { 574 {
547 // No packets in this queue. Fire the queue empty callback 575 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
548 // if it has not been called recently
549 emptyCategories |= CategoryToFlag(i); 576 emptyCategories |= CategoryToFlag(i);
550 } 577 }
551 } 578 }
@@ -703,4 +730,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
703 } 730 }
704 } 731 }
705 } 732 }
706} \ No newline at end of file 733}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 5610c09..bf5b85a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1030,7 +1030,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1030 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1030 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1031 { 1031 {
1032 client.IsLoggingOut = true; 1032 client.IsLoggingOut = true;
1033 client.Close(); 1033 client.Close(false);
1034 } 1034 }
1035 } 1035 }
1036 1036
@@ -1042,6 +1042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1042 1042
1043 while (base.IsRunning) 1043 while (base.IsRunning)
1044 { 1044 {
1045 m_scene.ThreadAlive(1);
1045 try 1046 try
1046 { 1047 {
1047 IncomingPacket incomingPacket = null; 1048 IncomingPacket incomingPacket = null;
@@ -1084,6 +1085,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1084 1085
1085 while (base.IsRunning) 1086 while (base.IsRunning)
1086 { 1087 {
1088 m_scene.ThreadAlive(2);
1087 try 1089 try
1088 { 1090 {
1089 m_packetSent = false; 1091 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..cfe7c9d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,