aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs750
-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, 510 insertions, 316 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index afbe56b..3995620 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -234,6 +234,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_stopPacket = TexturePacketCount(); 234 m_stopPacket = TexturePacketCount();
235 } 235 }
236 236
237 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
238 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
239
237 m_currentPacket = StartPacket; 240 m_currentPacket = StartPacket;
238 } 241 }
239 } 242 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index d98ff68..f835e56 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 {
@@ -1541,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1541 1549
1542 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1550 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1543 { 1551 {
1544// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1552// foreach (uint id in localIDs)
1553// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1545 1554
1546 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1555 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1547 // TODO: don't create new blocks if recycling an old packet 1556 // TODO: don't create new blocks if recycling an old packet
@@ -2302,6 +2311,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2302 OutPacket(sound, ThrottleOutPacketType.Task); 2311 OutPacket(sound, ThrottleOutPacketType.Task);
2303 } 2312 }
2304 2313
2314 public void SendTransferAbort(TransferRequestPacket transferRequest)
2315 {
2316 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2317 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2318 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2319 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2320 OutPacket(abort, ThrottleOutPacketType.Task);
2321 }
2322
2305 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2323 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2306 { 2324 {
2307 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2325 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2749,7 +2767,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2749 reply.Data.ParcelID = parcelID; 2767 reply.Data.ParcelID = parcelID;
2750 reply.Data.OwnerID = land.OwnerID; 2768 reply.Data.OwnerID = land.OwnerID;
2751 reply.Data.Name = Utils.StringToBytes(land.Name); 2769 reply.Data.Name = Utils.StringToBytes(land.Name);
2752 reply.Data.Desc = Utils.StringToBytes(land.Description); 2770 if (land != null && land.Description != null && land.Description != String.Empty)
2771 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2772 else
2773 reply.Data.Desc = new Byte[0];
2753 reply.Data.ActualArea = land.Area; 2774 reply.Data.ActualArea = land.Area;
2754 reply.Data.BillableArea = land.Area; // TODO: what is this? 2775 reply.Data.BillableArea = land.Area; // TODO: what is this?
2755 2776
@@ -3612,7 +3633,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3612 /// </summary> 3633 /// </summary>
3613 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3634 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3614 { 3635 {
3615 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3636 if (entity is SceneObjectPart)
3637 {
3638 SceneObjectPart e = (SceneObjectPart)entity;
3639 SceneObjectGroup g = e.ParentGroup;
3640 if (g.RootPart.Shape.State > 30) // HUD
3641 if (g.OwnerID != AgentId)
3642 return; // Don't send updates for other people's HUDs
3643 }
3644
3616 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3645 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3617 3646
3618 lock (m_entityUpdates.SyncRoot) 3647 lock (m_entityUpdates.SyncRoot)
@@ -3679,211 +3708,238 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3679 3708
3680 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3709 // 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. 3710 // condition where a kill can be processed before an out-of-date update for the same object.
3682 lock (m_killRecord) 3711 float avgTimeDilation = 1.0f;
3712 IEntityUpdate iupdate;
3713 Int32 timeinqueue; // this is just debugging code & can be dropped later
3714
3715 while (updatesThisCall < maxUpdates)
3683 { 3716 {
3684 float avgTimeDilation = 1.0f; 3717 lock (m_entityUpdates.SyncRoot)
3685 IEntityUpdate iupdate; 3718 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3686 Int32 timeinqueue; // this is just debugging code & can be dropped later 3719 break;
3687
3688 while (updatesThisCall < maxUpdates)
3689 {
3690 lock (m_entityUpdates.SyncRoot)
3691 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3692 break;
3693 3720
3694 EntityUpdate update = (EntityUpdate)iupdate; 3721 EntityUpdate update = (EntityUpdate)iupdate;
3695 3722
3696 avgTimeDilation += update.TimeDilation; 3723 avgTimeDilation += update.TimeDilation;
3697 avgTimeDilation *= 0.5f; 3724 avgTimeDilation *= 0.5f;
3698 3725
3699 if (update.Entity is SceneObjectPart) 3726 if (update.Entity is SceneObjectPart)
3727 {
3728 SceneObjectPart part = (SceneObjectPart)update.Entity;
3729
3730 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3731 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3732 // safety measure.
3733 //
3734 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3735 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3736 // updates and kills on different threads with different scheduling strategies, hence this protection.
3737 //
3738 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3739 // after the root prim has been deleted.
3740 lock (m_killRecord)
3700 { 3741 {
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)) 3742 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; 3743 continue;
3719 } 3744 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3720 3745 continue;
3721 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3746 }
3747
3748 if (part.ParentGroup.IsDeleted)
3749 continue;
3750
3751 if (part.ParentGroup.IsAttachment)
3752 { // Someone else's HUD, why are we getting these?
3753 if (part.ParentGroup.OwnerID != AgentId &&
3754 part.ParentGroup.RootPart.Shape.State >= 30)
3755 continue;
3756 ScenePresence sp;
3757 // Owner is not in the sim, don't update it to
3758 // anyone
3759 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3760 continue;
3761
3762 List<SceneObjectGroup> atts = sp.GetAttachments();
3763 bool found = false;
3764 foreach (SceneObjectGroup att in atts)
3722 { 3765 {
3723 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3766 if (att == part.ParentGroup)
3724 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3725 { 3767 {
3726 part.Shape.LightEntry = false; 3768 found = true;
3769 break;
3727 } 3770 }
3728 } 3771 }
3772
3773 // It's an attachment of a valid avatar, but
3774 // doesn't seem to be attached, skip
3775 if (!found)
3776 continue;
3777
3778 // On vehicle crossing, the attachments are received
3779 // while the avatar is still a child. Don't send
3780 // updates here because the LocalId has not yet
3781 // been updated and the viewer will derender the
3782 // attachments until the avatar becomes root.
3783 if (sp.IsChildAgent)
3784 continue;
3729 } 3785 }
3730 3786 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 { 3787 {
3753 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3788 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3754 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3789 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3755 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3757 { 3790 {
3758 canUseCompressed = false; 3791 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 } 3792 }
3778 } 3793 }
3779 3794 }
3780 #endregion UpdateFlags to packet type conversion 3795
3781 3796 ++updatesThisCall;
3782 #region Block Construction 3797
3783 3798 #region UpdateFlags to packet type conversion
3784 // TODO: Remove this once we can build compressed updates 3799
3800 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3801
3802 bool canUseCompressed = true;
3803 bool canUseImproved = true;
3804
3805 // Compressed object updates only make sense for LL primitives
3806 if (!(update.Entity is SceneObjectPart))
3807 {
3785 canUseCompressed = false; 3808 canUseCompressed = false;
3786 3809 }
3787 if (!canUseImproved && !canUseCompressed) 3810
3788 { 3811 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3789 if (update.Entity is ScenePresence) 3812 {
3790 { 3813 canUseCompressed = false;
3791 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3814 canUseImproved = false;
3792 objectUpdates.Value.Add(update); 3815 }
3793 } 3816 else
3794 else 3817 {
3795 { 3818 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3796 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3819 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3797 objectUpdates.Value.Add(update); 3820 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3798 } 3821 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3799 }
3800 else if (!canUseImproved)
3801 { 3822 {
3802 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3823 canUseCompressed = false;
3803 compressedUpdates.Value.Add(update);
3804 } 3824 }
3805 else 3825
3826 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3827 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3828 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3829 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3830 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3831 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3832 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3833 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3834 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3835 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3836 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3837 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3838 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3839 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3806 { 3840 {
3807 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3841 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 } 3842 }
3820
3821 #endregion Block Construction
3822 } 3843 }
3823
3824
3825 #region Packet Sending
3826 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3827 3844
3828 if (terseAgentUpdateBlocks.IsValueCreated) 3845 #endregion UpdateFlags to packet type conversion
3829 {
3830 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3831 3846
3832 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3847 #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 3848
3837 for (int i = 0; i < blocks.Count; i++) 3849 // TODO: Remove this once we can build compressed updates
3838 packet.ObjectData[i] = blocks[i]; 3850 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 3851
3843 if (objectUpdateBlocks.IsValueCreated) 3852 if (!canUseImproved && !canUseCompressed)
3844 { 3853 {
3845 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3854 if (update.Entity is ScenePresence)
3846 3855 {
3847 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3856 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3848 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3857 }
3849 packet.RegionData.TimeDilation = timeDilation; 3858 else
3850 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3859 {
3851 3860 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3852 for (int i = 0; i < blocks.Count; i++) 3861 }
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 } 3862 }
3857 3863 else if (!canUseImproved)
3858 if (compressedUpdateBlocks.IsValueCreated)
3859 { 3864 {
3860 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3865 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 } 3866 }
3872 3867 else
3873 if (terseUpdateBlocks.IsValueCreated)
3874 { 3868 {
3875 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3869 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3876 3870 // Self updates go into a special list
3877 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3871 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3872 else
3879 packet.RegionData.TimeDilation = timeDilation; 3873 // Everything else goes here
3880 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3874 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 } 3875 }
3876
3877 #endregion Block Construction
3878 }
3879
3880 #region Packet Sending
3881
3882 const float TIME_DILATION = 1.0f;
3883 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3884
3885 if (terseAgentUpdateBlocks.IsValueCreated)
3886 {
3887 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3888
3889 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3890 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3891 packet.RegionData.TimeDilation = timeDilation;
3892 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3893
3894 for (int i = 0; i < blocks.Count; i++)
3895 packet.ObjectData[i] = blocks[i];
3896
3897 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3898 }
3899
3900 if (objectUpdateBlocks.IsValueCreated)
3901 {
3902 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3903
3904 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3905 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3906 packet.RegionData.TimeDilation = timeDilation;
3907 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3908
3909 for (int i = 0; i < blocks.Count; i++)
3910 packet.ObjectData[i] = blocks[i];
3911
3912 OutPacket(packet, ThrottleOutPacketType.Task, true);
3913 }
3914
3915 if (compressedUpdateBlocks.IsValueCreated)
3916 {
3917 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3918
3919 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3920 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3921 packet.RegionData.TimeDilation = timeDilation;
3922 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3923
3924 for (int i = 0; i < blocks.Count; i++)
3925 packet.ObjectData[i] = blocks[i];
3926
3927 OutPacket(packet, ThrottleOutPacketType.Task, true);
3928 }
3929
3930 if (terseUpdateBlocks.IsValueCreated)
3931 {
3932 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3933
3934 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3935 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3936 packet.RegionData.TimeDilation = timeDilation;
3937 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3938
3939 for (int i = 0; i < blocks.Count; i++)
3940 packet.ObjectData[i] = blocks[i];
3941
3942 OutPacket(packet, ThrottleOutPacketType.Task, true);
3887 } 3943 }
3888 3944
3889 #endregion Packet Sending 3945 #endregion Packet Sending
@@ -4176,11 +4232,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4176 4232
4177 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4233 // 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 4234 // of the object rather than the properties when the packet was created
4179 OutPacket(packet, ThrottleOutPacketType.Task, true, 4235 // HACK : Remove intelligent resending until it's fixed in core
4180 delegate(OutgoingPacket oPacket) 4236 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4181 { 4237 // delegate(OutgoingPacket oPacket)
4182 ResendPropertyUpdates(updates, oPacket); 4238 // {
4183 }); 4239 // ResendPropertyUpdates(updates, oPacket);
4240 // });
4241 OutPacket(packet, ThrottleOutPacketType.Task, true);
4184 4242
4185 // pbcnt += blocks.Count; 4243 // pbcnt += blocks.Count;
4186 // ppcnt++; 4244 // ppcnt++;
@@ -4206,11 +4264,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4206 // of the object rather than the properties when the packet was created 4264 // of the object rather than the properties when the packet was created
4207 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4265 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4208 updates.Add(familyUpdates.Value[i]); 4266 updates.Add(familyUpdates.Value[i]);
4209 OutPacket(packet, ThrottleOutPacketType.Task, true, 4267 // HACK : Remove intelligent resending until it's fixed in core
4210 delegate(OutgoingPacket oPacket) 4268 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4211 { 4269 // delegate(OutgoingPacket oPacket)
4212 ResendPropertyUpdates(updates, oPacket); 4270 // {
4213 }); 4271 // ResendPropertyUpdates(updates, oPacket);
4272 // });
4273 OutPacket(packet, ThrottleOutPacketType.Task, true);
4214 4274
4215 // fpcnt++; 4275 // fpcnt++;
4216 // fbcnt++; 4276 // fbcnt++;
@@ -4359,37 +4419,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4359 if (bl[i].BannedUserID == UUID.Zero) 4419 if (bl[i].BannedUserID == UUID.Zero)
4360 continue; 4420 continue;
4361 BannedUsers.Add(bl[i].BannedUserID); 4421 BannedUsers.Add(bl[i].BannedUserID);
4362 }
4363 4422
4364 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4423 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4365 packet.AgentData.TransactionID = UUID.Random(); 4424 {
4366 packet.AgentData.AgentID = AgentId; 4425 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4367 packet.AgentData.SessionID = SessionId; 4426 packet.AgentData.TransactionID = UUID.Random();
4368 packet.MethodData.Invoice = invoice; 4427 packet.AgentData.AgentID = AgentId;
4369 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4428 packet.AgentData.SessionID = SessionId;
4429 packet.MethodData.Invoice = invoice;
4430 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4370 4431
4371 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4432 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4372 4433
4373 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4434 int j;
4374 { 4435 for (j = 0; j < (6 + BannedUsers.Count); j++)
4375 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4436 {
4376 } 4437 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4377 int j = 0; 4438 }
4439 j = 0;
4378 4440
4379 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4441 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4442 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4443 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4444 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4383 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4445 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4384 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4446 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4385 4447
4386 foreach (UUID banned in BannedUsers) 4448 foreach (UUID banned in BannedUsers)
4387 { 4449 {
4388 returnblock[j].Parameter = banned.GetBytes(); j++; 4450 returnblock[j].Parameter = banned.GetBytes(); j++;
4451 }
4452 packet.ParamList = returnblock;
4453 packet.Header.Reliable = true;
4454 OutPacket(packet, ThrottleOutPacketType.Task);
4455
4456 BannedUsers.Clear();
4457 }
4389 } 4458 }
4390 packet.ParamList = returnblock; 4459
4391 packet.Header.Reliable = false;
4392 OutPacket(packet, ThrottleOutPacketType.Task);
4393 } 4460 }
4394 4461
4395 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4462 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4575,7 +4642,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4575 4642
4576 if (landData.SimwideArea > 0) 4643 if (landData.SimwideArea > 0)
4577 { 4644 {
4578 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4645 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4646 // Never report more than sim total capacity
4647 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4648 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4579 updateMessage.SimWideMaxPrims = simulatorCapacity; 4649 updateMessage.SimWideMaxPrims = simulatorCapacity;
4580 } 4650 }
4581 else 4651 else
@@ -4704,14 +4774,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4704 4774
4705 if (notifyCount > 0) 4775 if (notifyCount > 0)
4706 { 4776 {
4707 if (notifyCount > 32) 4777// if (notifyCount > 32)
4708 { 4778// {
4709 m_log.InfoFormat( 4779// m_log.InfoFormat(
4710 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4780// "[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); 4781// + " - a developer might want to investigate whether this is a hard limit", 32);
4712 4782//
4713 notifyCount = 32; 4783// notifyCount = 32;
4714 } 4784// }
4715 4785
4716 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4786 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4717 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4787 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4766,9 +4836,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4766 { 4836 {
4767 ScenePresence presence = (ScenePresence)entity; 4837 ScenePresence presence = (ScenePresence)entity;
4768 4838
4839 position = presence.OffsetPosition;
4840 rotation = presence.Rotation;
4841
4842 if (presence.ParentID != 0)
4843 {
4844 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4845 if (part != null && part != part.ParentGroup.RootPart)
4846 {
4847 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4848 rotation = part.RotationOffset * presence.Rotation;
4849 }
4850 }
4851
4769 attachPoint = 0; 4852 attachPoint = 0;
4770 collisionPlane = presence.CollisionPlane; 4853 collisionPlane = presence.CollisionPlane;
4771 position = presence.OffsetPosition;
4772 velocity = presence.Velocity; 4854 velocity = presence.Velocity;
4773 acceleration = Vector3.Zero; 4855 acceleration = Vector3.Zero;
4774 4856
@@ -4778,7 +4860,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4778// acceleration = new Vector3(1, 0, 0); 4860// acceleration = new Vector3(1, 0, 0);
4779 4861
4780 angularVelocity = Vector3.Zero; 4862 angularVelocity = Vector3.Zero;
4781 rotation = presence.Rotation;
4782 4863
4783 if (sendTexture) 4864 if (sendTexture)
4784 textureEntry = presence.Appearance.Texture.GetBytes(); 4865 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4883,13 +4964,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4883 4964
4884 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 4965 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4885 { 4966 {
4967 Vector3 offsetPosition = data.OffsetPosition;
4968 Quaternion rotation = data.Rotation;
4969 uint parentID = data.ParentID;
4970
4971 if (parentID != 0)
4972 {
4973 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
4974 if (part != null && part != part.ParentGroup.RootPart)
4975 {
4976 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
4977 rotation = part.RotationOffset * data.Rotation;
4978 parentID = part.ParentGroup.RootPart.LocalId;
4979 }
4980 }
4981
4886 byte[] objectData = new byte[76]; 4982 byte[] objectData = new byte[76];
4887 4983
4888 data.CollisionPlane.ToBytes(objectData, 0); 4984 data.CollisionPlane.ToBytes(objectData, 0);
4889 data.OffsetPosition.ToBytes(objectData, 16); 4985 offsetPosition.ToBytes(objectData, 16);
4890// data.Velocity.ToBytes(objectData, 28); 4986// data.Velocity.ToBytes(objectData, 28);
4891// data.Acceleration.ToBytes(objectData, 40); 4987// data.Acceleration.ToBytes(objectData, 40);
4892 data.Rotation.ToBytes(objectData, 52); 4988 rotation.ToBytes(objectData, 52);
4893 //data.AngularVelocity.ToBytes(objectData, 64); 4989 //data.AngularVelocity.ToBytes(objectData, 64);
4894 4990
4895 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 4991 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4903,7 +4999,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4903 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 4999 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4904 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5000 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4905 update.ObjectData = objectData; 5001 update.ObjectData = objectData;
4906 update.ParentID = data.ParentID; 5002 update.ParentID = parentID;
4907 update.PathCurve = 16; 5003 update.PathCurve = 16;
4908 update.PathScaleX = 100; 5004 update.PathScaleX = 100;
4909 update.PathScaleY = 100; 5005 update.PathScaleY = 100;
@@ -5244,6 +5340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5244 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5340 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5245 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5341 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5246 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5342 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5343 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5247 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5344 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5248 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5345 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5249 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5346 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5310,6 +5407,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5310 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5407 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5311 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5408 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5312 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5409 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5410 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5313 5411
5314 AddGenericPacketHandler("autopilot", HandleAutopilot); 5412 AddGenericPacketHandler("autopilot", HandleAutopilot);
5315 } 5413 }
@@ -5345,6 +5443,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5345 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5443 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5346 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5444 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5347 (x.ControlFlags != lastarg.ControlFlags) || 5445 (x.ControlFlags != lastarg.ControlFlags) ||
5446 (x.ControlFlags != 0) ||
5348 (x.Far != lastarg.Far) || 5447 (x.Far != lastarg.Far) ||
5349 (x.Flags != lastarg.Flags) || 5448 (x.Flags != lastarg.Flags) ||
5350 (x.State != lastarg.State) || 5449 (x.State != lastarg.State) ||
@@ -5722,7 +5821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5722 args.Channel = ch; 5821 args.Channel = ch;
5723 args.From = String.Empty; 5822 args.From = String.Empty;
5724 args.Message = Utils.BytesToString(msg); 5823 args.Message = Utils.BytesToString(msg);
5725 args.Type = ChatTypeEnum.Shout; 5824 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5726 args.Position = new Vector3(); 5825 args.Position = new Vector3();
5727 args.Scene = Scene; 5826 args.Scene = Scene;
5728 args.Sender = this; 5827 args.Sender = this;
@@ -9767,7 +9866,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9767 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9866 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9768 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9867 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9769 UpdateMuteListEntry.MuteData.MuteType, 9868 UpdateMuteListEntry.MuteData.MuteType,
9770 UpdateMuteListEntry.AgentData.AgentID); 9869 UpdateMuteListEntry.MuteData.MuteFlags);
9771 return true; 9870 return true;
9772 } 9871 }
9773 return false; 9872 return false;
@@ -9782,8 +9881,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9782 { 9881 {
9783 handlerRemoveMuteListEntry(this, 9882 handlerRemoveMuteListEntry(this,
9784 RemoveMuteListEntry.MuteData.MuteID, 9883 RemoveMuteListEntry.MuteData.MuteID,
9785 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9884 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9786 RemoveMuteListEntry.AgentData.AgentID);
9787 return true; 9885 return true;
9788 } 9886 }
9789 return false; 9887 return false;
@@ -9827,10 +9925,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9827 return false; 9925 return false;
9828 } 9926 }
9829 9927
9928 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9929 {
9930 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9931 (ChangeInventoryItemFlagsPacket)packet;
9932 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9933 if (handlerChangeInventoryItemFlags != null)
9934 {
9935 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9936 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9937 return true;
9938 }
9939 return false;
9940 }
9941
9830 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9942 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9831 { 9943 {
9832 return true; 9944 return true;
9833 } 9945 }
9946
9947 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9948 {
9949 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9950
9951 #region Packet Session and User Check
9952 if (m_checkPackets)
9953 {
9954 if (packet.AgentData.SessionID != SessionId ||
9955 packet.AgentData.AgentID != AgentId)
9956 return true;
9957 }
9958 #endregion
9959 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9960 List<InventoryItemBase> items = new List<InventoryItemBase>();
9961 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9962 {
9963 InventoryItemBase b = new InventoryItemBase();
9964 b.ID = n.OldItemID;
9965 b.Folder = n.OldFolderID;
9966 items.Add(b);
9967 }
9968
9969 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9970 if (handlerMoveItemsAndLeaveCopy != null)
9971 {
9972 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9973 }
9974
9975 return true;
9976 }
9834 9977
9835 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9978 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9836 { 9979 {
@@ -10257,6 +10400,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10257 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10400 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10258 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10401 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10259 10402
10403 Scene scene = (Scene)m_scene;
10404 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10405 {
10406 ScenePresence p;
10407 if (scene.TryGetScenePresence(sender.AgentId, out p))
10408 {
10409 if (p.GodLevel >= 200)
10410 {
10411 groupProfileReply.GroupData.OpenEnrollment = true;
10412 groupProfileReply.GroupData.MembershipFee = 0;
10413 }
10414 }
10415 }
10416
10260 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10417 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10261 } 10418 }
10262 return true; 10419 return true;
@@ -10830,11 +10987,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10830 10987
10831 StartLure handlerStartLure = OnStartLure; 10988 StartLure handlerStartLure = OnStartLure;
10832 if (handlerStartLure != null) 10989 if (handlerStartLure != null)
10833 handlerStartLure(startLureRequest.Info.LureType, 10990 {
10834 Utils.BytesToString( 10991 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10835 startLureRequest.Info.Message), 10992 {
10836 startLureRequest.TargetData[0].TargetID, 10993 handlerStartLure(startLureRequest.Info.LureType,
10837 this); 10994 Utils.BytesToString(
10995 startLureRequest.Info.Message),
10996 startLureRequest.TargetData[i].TargetID,
10997 this);
10998 }
10999 }
10838 return true; 11000 return true;
10839 } 11001 }
10840 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11002 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10948,10 +11110,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10948 } 11110 }
10949 #endregion 11111 #endregion
10950 11112
10951 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11113 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10952 if (handlerClassifiedGodDelete != null) 11114 if (handlerClassifiedGodDelete != null)
10953 handlerClassifiedGodDelete( 11115 handlerClassifiedGodDelete(
10954 classifiedGodDelete.Data.ClassifiedID, 11116 classifiedGodDelete.Data.ClassifiedID,
11117 classifiedGodDelete.Data.QueryID,
10955 this); 11118 this);
10956 return true; 11119 return true;
10957 } 11120 }
@@ -12000,7 +12163,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12000 12163
12001// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12164// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
12002 12165
12166
12167 //Note, the bool returned from the below function is useless since it is always false.
12003 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12168 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12169
12004 } 12170 }
12005 12171
12006 /// <summary> 12172 /// <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 fb6b11e..75f783b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1051,7 +1051,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1051 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1051 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1052 { 1052 {
1053 client.IsLoggingOut = true; 1053 client.IsLoggingOut = true;
1054 client.Close(); 1054 client.Close(false);
1055 } 1055 }
1056 } 1056 }
1057 1057
@@ -1063,6 +1063,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1063 1063
1064 while (base.IsRunning) 1064 while (base.IsRunning)
1065 { 1065 {
1066 m_scene.ThreadAlive(1);
1066 try 1067 try
1067 { 1068 {
1068 IncomingPacket incomingPacket = null; 1069 IncomingPacket incomingPacket = null;
@@ -1105,6 +1106,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1105 1106
1106 while (base.IsRunning) 1107 while (base.IsRunning)
1107 { 1108 {
1109 m_scene.ThreadAlive(2);
1108 try 1110 try
1109 { 1111 {
1110 m_packetSent = false; 1112 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,