aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1048
-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, 640 insertions, 484 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 b388b10..23beaec 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -125,6 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 126 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 127 public event UpdatePrimTexture OnUpdatePrimTexture;
128 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 129 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 130 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 131 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 159 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 160 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 161 public event CopyInventoryItem OnCopyInventoryItem;
162 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 163 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 164 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 165 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 258 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 259 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 260 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 261 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 262 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 263 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 264 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +289,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 289 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 290 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 291 public event SendPostcard OnSendPostcard;
292 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 293 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 294 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 295 public event GodlikeMessage onGodlikeMessage;
@@ -336,7 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// 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
337 /// ownerless phantom. 340 /// ownerless phantom.
338 /// 341 ///
339 /// 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
340 /// 343 ///
341 /// </value> 344 /// </value>
342 protected HashSet<uint> m_killRecord; 345 protected HashSet<uint> m_killRecord;
@@ -344,6 +347,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
344// protected HashSet<uint> m_attachmentsSent; 347// protected HashSet<uint> m_attachmentsSent;
345 348
346 private int m_moneyBalance; 349 private int m_moneyBalance;
350 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 351 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 352 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 353 private AgentUpdateArgs lastarg;
@@ -383,6 +387,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
383 get { return m_startpos; } 387 get { return m_startpos; }
384 set { m_startpos = value; } 388 set { m_startpos = value; }
385 } 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 }
386 public UUID AgentId { get { return m_agentId; } } 398 public UUID AgentId { get { return m_agentId; } }
387 public ISceneAgent SceneAgent { get; private set; } 399 public ISceneAgent SceneAgent { get; private set; }
388 public UUID ActiveGroupId { get { return m_activeGroupID; } } 400 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -484,18 +496,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
484 496
485 #region Client Methods 497 #region Client Methods
486 498
499
487 /// <summary> 500 /// <summary>
488 /// Shut down the client view 501 /// Shut down the client view
489 /// </summary> 502 /// </summary>
490 public void Close() 503 public void Close()
491 { 504 {
505 Close(true);
506 }
507
508 /// <summary>
509 /// Shut down the client view
510 /// </summary>
511 public void Close(bool sendStop)
512 {
492 m_log.DebugFormat( 513 m_log.DebugFormat(
493 "[CLIENT]: Close has been called for {0} attached to scene {1}", 514 "[CLIENT]: Close has been called for {0} attached to scene {1}",
494 Name, m_scene.RegionInfo.RegionName); 515 Name, m_scene.RegionInfo.RegionName);
495 516
496 // Send the STOP packet 517 if (sendStop)
497 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 518 {
498 OutPacket(disable, ThrottleOutPacketType.Unknown); 519 // Send the STOP packet
520 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
521 OutPacket(disable, ThrottleOutPacketType.Unknown);
522 }
499 523
500 IsActive = false; 524 IsActive = false;
501 525
@@ -795,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
795 reply.ChatData.OwnerID = fromAgentID; 819 reply.ChatData.OwnerID = fromAgentID;
796 reply.ChatData.SourceID = fromAgentID; 820 reply.ChatData.SourceID = fromAgentID;
797 821
798 OutPacket(reply, ThrottleOutPacketType.Task); 822 OutPacket(reply, ThrottleOutPacketType.Unknown);
799 } 823 }
800 824
801 /// <summary> 825 /// <summary>
@@ -1081,6 +1105,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1081 public virtual void SendLayerData(float[] map) 1105 public virtual void SendLayerData(float[] map)
1082 { 1106 {
1083 Util.FireAndForget(DoSendLayerData, map); 1107 Util.FireAndForget(DoSendLayerData, map);
1108
1109 // Send it sync, and async. It's not that much data
1110 // and it improves user experience just so much!
1111 DoSendLayerData(map);
1084 } 1112 }
1085 1113
1086 /// <summary> 1114 /// <summary>
@@ -1093,16 +1121,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1093 1121
1094 try 1122 try
1095 { 1123 {
1096 //for (int y = 0; y < 16; y++) 1124 for (int y = 0; y < 16; y++)
1097 //{ 1125 {
1098 // for (int x = 0; x < 16; x++) 1126 for (int x = 0; x < 16; x+=4)
1099 // { 1127 {
1100 // SendLayerData(x, y, map); 1128 SendLayerPacket(x, y, map);
1101 // } 1129 }
1102 //} 1130 }
1103
1104 // Send LayerData in a spiral pattern. Fun!
1105 SendLayerTopRight(map, 0, 0, 15, 15);
1106 } 1131 }
1107 catch (Exception e) 1132 catch (Exception e)
1108 { 1133 {
@@ -1110,51 +1135,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1110 } 1135 }
1111 } 1136 }
1112 1137
1113 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1114 {
1115 // Row
1116 for (int i = x1; i <= x2; i++)
1117 SendLayerData(i, y1, map);
1118
1119 // Column
1120 for (int j = y1 + 1; j <= y2; j++)
1121 SendLayerData(x2, j, map);
1122
1123 if (x2 - x1 > 0)
1124 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1125 }
1126
1127 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1128 {
1129 // Row in reverse
1130 for (int i = x2; i >= x1; i--)
1131 SendLayerData(i, y2, map);
1132
1133 // Column in reverse
1134 for (int j = y2 - 1; j >= y1; j--)
1135 SendLayerData(x1, j, map);
1136
1137 if (x2 - x1 > 0)
1138 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1139 }
1140
1141 /// <summary> 1138 /// <summary>
1142 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1139 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1143 /// </summary> 1140 /// </summary>
1144 /// <param name="map">heightmap</param> 1141 /// <param name="map">heightmap</param>
1145 /// <param name="px">X coordinate for patches 0..12</param> 1142 /// <param name="px">X coordinate for patches 0..12</param>
1146 /// <param name="py">Y coordinate for patches 0..15</param> 1143 /// <param name="py">Y coordinate for patches 0..15</param>
1147 // private void SendLayerPacket(float[] map, int y, int x) 1144 private void SendLayerPacket(int x, int y, float[] map)
1148 // { 1145 {
1149 // int[] patches = new int[4]; 1146 int[] patches = new int[4];
1150 // patches[0] = x + 0 + y * 16; 1147 patches[0] = x + 0 + y * 16;
1151 // patches[1] = x + 1 + y * 16; 1148 patches[1] = x + 1 + y * 16;
1152 // patches[2] = x + 2 + y * 16; 1149 patches[2] = x + 2 + y * 16;
1153 // patches[3] = x + 3 + y * 16; 1150 patches[3] = x + 3 + y * 16;
1154 1151
1155 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1152 float[] heightmap = (map.Length == 65536) ?
1156 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1153 map :
1157 // } 1154 LLHeightFieldMoronize(map);
1155
1156 try
1157 {
1158 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1159 OutPacket(layerpack, ThrottleOutPacketType.Land);
1160 }
1161 catch
1162 {
1163 for (int px = x ; px < x + 4 ; px++)
1164 SendLayerData(px, y, map);
1165 }
1166 }
1158 1167
1159 /// <summary> 1168 /// <summary>
1160 /// Sends a specified patch to a client 1169 /// Sends a specified patch to a client
@@ -1174,7 +1183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1174 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1183 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1175 layerpack.Header.Reliable = true; 1184 layerpack.Header.Reliable = true;
1176 1185
1177 OutPacket(layerpack, ThrottleOutPacketType.Land); 1186 OutPacket(layerpack, ThrottleOutPacketType.Task);
1178 } 1187 }
1179 catch (Exception e) 1188 catch (Exception e)
1180 { 1189 {
@@ -1537,7 +1546,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1537 1546
1538 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1547 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1539 { 1548 {
1540// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1549// foreach (uint id in localIDs)
1550// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1541 1551
1542 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1552 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1543 // TODO: don't create new blocks if recycling an old packet 1553 // TODO: don't create new blocks if recycling an old packet
@@ -2298,6 +2308,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2298 OutPacket(sound, ThrottleOutPacketType.Task); 2308 OutPacket(sound, ThrottleOutPacketType.Task);
2299 } 2309 }
2300 2310
2311 public void SendTransferAbort(TransferRequestPacket transferRequest)
2312 {
2313 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2314 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2315 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2316 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2317 OutPacket(abort, ThrottleOutPacketType.Task);
2318 }
2319
2301 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2320 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2302 { 2321 {
2303 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2322 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2745,7 +2764,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2745 reply.Data.ParcelID = parcelID; 2764 reply.Data.ParcelID = parcelID;
2746 reply.Data.OwnerID = land.OwnerID; 2765 reply.Data.OwnerID = land.OwnerID;
2747 reply.Data.Name = Utils.StringToBytes(land.Name); 2766 reply.Data.Name = Utils.StringToBytes(land.Name);
2748 reply.Data.Desc = Utils.StringToBytes(land.Description); 2767 if (land != null && land.Description != null && land.Description != String.Empty)
2768 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2769 else
2770 reply.Data.Desc = new Byte[0];
2749 reply.Data.ActualArea = land.Area; 2771 reply.Data.ActualArea = land.Area;
2750 reply.Data.BillableArea = land.Area; // TODO: what is this? 2772 reply.Data.BillableArea = land.Area; // TODO: what is this?
2751 2773
@@ -3608,7 +3630,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3608 /// </summary> 3630 /// </summary>
3609 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3631 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3610 { 3632 {
3611 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3633 if (entity is SceneObjectPart)
3634 {
3635 SceneObjectPart e = (SceneObjectPart)entity;
3636 SceneObjectGroup g = e.ParentGroup;
3637 if (g.RootPart.Shape.State > 30) // HUD
3638 if (g.OwnerID != AgentId)
3639 return; // Don't send updates for other people's HUDs
3640 }
3641
3612 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3642 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3613 3643
3614 lock (m_entityUpdates.SyncRoot) 3644 lock (m_entityUpdates.SyncRoot)
@@ -3675,211 +3705,238 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3675 3705
3676 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3706 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3677 // condition where a kill can be processed before an out-of-date update for the same object. 3707 // condition where a kill can be processed before an out-of-date update for the same object.
3678 lock (m_killRecord) 3708 float avgTimeDilation = 1.0f;
3709 IEntityUpdate iupdate;
3710 Int32 timeinqueue; // this is just debugging code & can be dropped later
3711
3712 while (updatesThisCall < maxUpdates)
3679 { 3713 {
3680 float avgTimeDilation = 1.0f; 3714 lock (m_entityUpdates.SyncRoot)
3681 IEntityUpdate iupdate; 3715 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3682 Int32 timeinqueue; // this is just debugging code & can be dropped later 3716 break;
3683
3684 while (updatesThisCall < maxUpdates)
3685 {
3686 lock (m_entityUpdates.SyncRoot)
3687 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3688 break;
3689 3717
3690 EntityUpdate update = (EntityUpdate)iupdate; 3718 EntityUpdate update = (EntityUpdate)iupdate;
3691 3719
3692 avgTimeDilation += update.TimeDilation; 3720 avgTimeDilation += update.TimeDilation;
3693 avgTimeDilation *= 0.5f; 3721 avgTimeDilation *= 0.5f;
3694 3722
3695 if (update.Entity is SceneObjectPart) 3723 if (update.Entity is SceneObjectPart)
3724 {
3725 SceneObjectPart part = (SceneObjectPart)update.Entity;
3726
3727 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3728 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3729 // safety measure.
3730 //
3731 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3732 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3733 // updates and kills on different threads with different scheduling strategies, hence this protection.
3734 //
3735 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3736 // after the root prim has been deleted.
3737 lock (m_killRecord)
3696 { 3738 {
3697 SceneObjectPart part = (SceneObjectPart)update.Entity;
3698
3699 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3700 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3701 // safety measure.
3702 //
3703 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3704 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3705 // updates and kills on different threads with different scheduling strategies, hence this protection.
3706 //
3707 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3708 // after the root prim has been deleted.
3709 if (m_killRecord.Contains(part.LocalId)) 3739 if (m_killRecord.Contains(part.LocalId))
3710 {
3711 // m_log.WarnFormat(
3712 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3713 // part.LocalId, Name);
3714 continue; 3740 continue;
3715 } 3741 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3716 3742 continue;
3717 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3743 }
3744
3745 if (part.ParentGroup.IsDeleted)
3746 continue;
3747
3748 if (part.ParentGroup.IsAttachment)
3749 { // Someone else's HUD, why are we getting these?
3750 if (part.ParentGroup.OwnerID != AgentId &&
3751 part.ParentGroup.RootPart.Shape.State >= 30)
3752 continue;
3753 ScenePresence sp;
3754 // Owner is not in the sim, don't update it to
3755 // anyone
3756 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3757 continue;
3758
3759 List<SceneObjectGroup> atts = sp.GetAttachments();
3760 bool found = false;
3761 foreach (SceneObjectGroup att in atts)
3718 { 3762 {
3719 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3763 if (att == part.ParentGroup)
3720 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3721 { 3764 {
3722 part.Shape.LightEntry = false; 3765 found = true;
3766 break;
3723 } 3767 }
3724 } 3768 }
3769
3770 // It's an attachment of a valid avatar, but
3771 // doesn't seem to be attached, skip
3772 if (!found)
3773 continue;
3774
3775 // On vehicle crossing, the attachments are received
3776 // while the avatar is still a child. Don't send
3777 // updates here because the LocalId has not yet
3778 // been updated and the viewer will derender the
3779 // attachments until the avatar becomes root.
3780 if (sp.IsChildAgent)
3781 continue;
3725 } 3782 }
3726 3783 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3727 ++updatesThisCall;
3728
3729 #region UpdateFlags to packet type conversion
3730
3731 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3732
3733 bool canUseCompressed = true;
3734 bool canUseImproved = true;
3735
3736 // Compressed object updates only make sense for LL primitives
3737 if (!(update.Entity is SceneObjectPart))
3738 {
3739 canUseCompressed = false;
3740 }
3741
3742 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3743 {
3744 canUseCompressed = false;
3745 canUseImproved = false;
3746 }
3747 else
3748 { 3784 {
3749 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3785 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3750 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3786 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3751 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3753 { 3787 {
3754 canUseCompressed = false; 3788 part.Shape.LightEntry = false;
3755 }
3756
3757 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3771 {
3772 canUseImproved = false;
3773 } 3789 }
3774 } 3790 }
3775 3791 }
3776 #endregion UpdateFlags to packet type conversion 3792
3777 3793 ++updatesThisCall;
3778 #region Block Construction 3794
3779 3795 #region UpdateFlags to packet type conversion
3780 // TODO: Remove this once we can build compressed updates 3796
3797 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3798
3799 bool canUseCompressed = true;
3800 bool canUseImproved = true;
3801
3802 // Compressed object updates only make sense for LL primitives
3803 if (!(update.Entity is SceneObjectPart))
3804 {
3781 canUseCompressed = false; 3805 canUseCompressed = false;
3782 3806 }
3783 if (!canUseImproved && !canUseCompressed) 3807
3784 { 3808 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3785 if (update.Entity is ScenePresence) 3809 {
3786 { 3810 canUseCompressed = false;
3787 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3811 canUseImproved = false;
3788 objectUpdates.Value.Add(update); 3812 }
3789 } 3813 else
3790 else 3814 {
3791 { 3815 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3792 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3816 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3793 objectUpdates.Value.Add(update); 3817 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3794 } 3818 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3795 }
3796 else if (!canUseImproved)
3797 { 3819 {
3798 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3820 canUseCompressed = false;
3799 compressedUpdates.Value.Add(update);
3800 } 3821 }
3801 else 3822
3823 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3824 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3825 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3826 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3827 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3828 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3829 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3830 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3831 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3832 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3833 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3834 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3835 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3836 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3802 { 3837 {
3803 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3838 canUseImproved = false;
3804 {
3805 // Self updates go into a special list
3806 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3807 terseAgentUpdates.Value.Add(update);
3808 }
3809 else
3810 {
3811 // Everything else goes here
3812 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3813 terseUpdates.Value.Add(update);
3814 }
3815 } 3839 }
3816
3817 #endregion Block Construction
3818 } 3840 }
3819
3820
3821 #region Packet Sending
3822 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3823 3841
3824 if (terseAgentUpdateBlocks.IsValueCreated) 3842 #endregion UpdateFlags to packet type conversion
3825 {
3826 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3827 3843
3828 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3844 #region Block Construction
3829 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3830 packet.RegionData.TimeDilation = timeDilation;
3831 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3832 3845
3833 for (int i = 0; i < blocks.Count; i++) 3846 // TODO: Remove this once we can build compressed updates
3834 packet.ObjectData[i] = blocks[i]; 3847 canUseCompressed = false;
3835 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3836 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3837 }
3838 3848
3839 if (objectUpdateBlocks.IsValueCreated) 3849 if (!canUseImproved && !canUseCompressed)
3840 { 3850 {
3841 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3851 if (update.Entity is ScenePresence)
3842 3852 {
3843 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3853 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3844 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3854 }
3845 packet.RegionData.TimeDilation = timeDilation; 3855 else
3846 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3856 {
3847 3857 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3848 for (int i = 0; i < blocks.Count; i++) 3858 }
3849 packet.ObjectData[i] = blocks[i];
3850 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3851 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3852 } 3859 }
3853 3860 else if (!canUseImproved)
3854 if (compressedUpdateBlocks.IsValueCreated)
3855 { 3861 {
3856 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3862 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3857
3858 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3859 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3860 packet.RegionData.TimeDilation = timeDilation;
3861 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3862
3863 for (int i = 0; i < blocks.Count; i++)
3864 packet.ObjectData[i] = blocks[i];
3865 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3866 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3867 } 3863 }
3868 3864 else
3869 if (terseUpdateBlocks.IsValueCreated)
3870 { 3865 {
3871 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3866 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3872 3867 // Self updates go into a special list
3873 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3868 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3869 else
3875 packet.RegionData.TimeDilation = timeDilation; 3870 // Everything else goes here
3876 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3871 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3877
3878 for (int i = 0; i < blocks.Count; i++)
3879 packet.ObjectData[i] = blocks[i];
3880 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3881 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3882 } 3872 }
3873
3874 #endregion Block Construction
3875 }
3876
3877 #region Packet Sending
3878
3879 const float TIME_DILATION = 1.0f;
3880 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3881
3882 if (terseAgentUpdateBlocks.IsValueCreated)
3883 {
3884 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3885
3886 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3887 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3888 packet.RegionData.TimeDilation = timeDilation;
3889 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3890
3891 for (int i = 0; i < blocks.Count; i++)
3892 packet.ObjectData[i] = blocks[i];
3893
3894 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3895 }
3896
3897 if (objectUpdateBlocks.IsValueCreated)
3898 {
3899 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3900
3901 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3902 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3903 packet.RegionData.TimeDilation = timeDilation;
3904 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3905
3906 for (int i = 0; i < blocks.Count; i++)
3907 packet.ObjectData[i] = blocks[i];
3908
3909 OutPacket(packet, ThrottleOutPacketType.Task, true);
3910 }
3911
3912 if (compressedUpdateBlocks.IsValueCreated)
3913 {
3914 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3915
3916 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3917 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3918 packet.RegionData.TimeDilation = timeDilation;
3919 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3920
3921 for (int i = 0; i < blocks.Count; i++)
3922 packet.ObjectData[i] = blocks[i];
3923
3924 OutPacket(packet, ThrottleOutPacketType.Task, true);
3925 }
3926
3927 if (terseUpdateBlocks.IsValueCreated)
3928 {
3929 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3930
3931 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3932 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3933 packet.RegionData.TimeDilation = timeDilation;
3934 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3935
3936 for (int i = 0; i < blocks.Count; i++)
3937 packet.ObjectData[i] = blocks[i];
3938
3939 OutPacket(packet, ThrottleOutPacketType.Task, true);
3883 } 3940 }
3884 3941
3885 #endregion Packet Sending 3942 #endregion Packet Sending
@@ -4172,11 +4229,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4172 4229
4173 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4230 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4174 // of the object rather than the properties when the packet was created 4231 // of the object rather than the properties when the packet was created
4175 OutPacket(packet, ThrottleOutPacketType.Task, true, 4232 // HACK : Remove intelligent resending until it's fixed in core
4176 delegate(OutgoingPacket oPacket) 4233 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4177 { 4234 // delegate(OutgoingPacket oPacket)
4178 ResendPropertyUpdates(updates, oPacket); 4235 // {
4179 }); 4236 // ResendPropertyUpdates(updates, oPacket);
4237 // });
4238 OutPacket(packet, ThrottleOutPacketType.Task, true);
4180 4239
4181 // pbcnt += blocks.Count; 4240 // pbcnt += blocks.Count;
4182 // ppcnt++; 4241 // ppcnt++;
@@ -4202,11 +4261,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4202 // of the object rather than the properties when the packet was created 4261 // of the object rather than the properties when the packet was created
4203 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4262 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4204 updates.Add(familyUpdates.Value[i]); 4263 updates.Add(familyUpdates.Value[i]);
4205 OutPacket(packet, ThrottleOutPacketType.Task, true, 4264 // HACK : Remove intelligent resending until it's fixed in core
4206 delegate(OutgoingPacket oPacket) 4265 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4207 { 4266 // delegate(OutgoingPacket oPacket)
4208 ResendPropertyUpdates(updates, oPacket); 4267 // {
4209 }); 4268 // ResendPropertyUpdates(updates, oPacket);
4269 // });
4270 OutPacket(packet, ThrottleOutPacketType.Task, true);
4210 4271
4211 // fpcnt++; 4272 // fpcnt++;
4212 // fbcnt++; 4273 // fbcnt++;
@@ -4355,37 +4416,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4355 if (bl[i].BannedUserID == UUID.Zero) 4416 if (bl[i].BannedUserID == UUID.Zero)
4356 continue; 4417 continue;
4357 BannedUsers.Add(bl[i].BannedUserID); 4418 BannedUsers.Add(bl[i].BannedUserID);
4358 }
4359 4419
4360 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4420 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4361 packet.AgentData.TransactionID = UUID.Random(); 4421 {
4362 packet.AgentData.AgentID = AgentId; 4422 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4363 packet.AgentData.SessionID = SessionId; 4423 packet.AgentData.TransactionID = UUID.Random();
4364 packet.MethodData.Invoice = invoice; 4424 packet.AgentData.AgentID = AgentId;
4365 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4425 packet.AgentData.SessionID = SessionId;
4426 packet.MethodData.Invoice = invoice;
4427 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4366 4428
4367 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4429 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4368 4430
4369 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4431 int j;
4370 { 4432 for (j = 0; j < (6 + BannedUsers.Count); j++)
4371 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4433 {
4372 } 4434 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4373 int j = 0; 4435 }
4436 j = 0;
4374 4437
4375 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4438 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4439 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4440 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4441 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4442 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4443 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 4444
4382 foreach (UUID banned in BannedUsers) 4445 foreach (UUID banned in BannedUsers)
4383 { 4446 {
4384 returnblock[j].Parameter = banned.GetBytes(); j++; 4447 returnblock[j].Parameter = banned.GetBytes(); j++;
4448 }
4449 packet.ParamList = returnblock;
4450 packet.Header.Reliable = true;
4451 OutPacket(packet, ThrottleOutPacketType.Task);
4452
4453 BannedUsers.Clear();
4454 }
4385 } 4455 }
4386 packet.ParamList = returnblock; 4456
4387 packet.Header.Reliable = false;
4388 OutPacket(packet, ThrottleOutPacketType.Task);
4389 } 4457 }
4390 4458
4391 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4459 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4571,7 +4639,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4571 4639
4572 if (landData.SimwideArea > 0) 4640 if (landData.SimwideArea > 0)
4573 { 4641 {
4574 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4642 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4643 // Never report more than sim total capacity
4644 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4645 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4575 updateMessage.SimWideMaxPrims = simulatorCapacity; 4646 updateMessage.SimWideMaxPrims = simulatorCapacity;
4576 } 4647 }
4577 else 4648 else
@@ -4700,14 +4771,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4700 4771
4701 if (notifyCount > 0) 4772 if (notifyCount > 0)
4702 { 4773 {
4703 if (notifyCount > 32) 4774// if (notifyCount > 32)
4704 { 4775// {
4705 m_log.InfoFormat( 4776// m_log.InfoFormat(
4706 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4777// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4707 + " - a developer might want to investigate whether this is a hard limit", 32); 4778// + " - a developer might want to investigate whether this is a hard limit", 32);
4708 4779//
4709 notifyCount = 32; 4780// notifyCount = 32;
4710 } 4781// }
4711 4782
4712 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4783 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4713 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4784 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4762,9 +4833,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4762 { 4833 {
4763 ScenePresence presence = (ScenePresence)entity; 4834 ScenePresence presence = (ScenePresence)entity;
4764 4835
4836 position = presence.OffsetPosition;
4837 rotation = presence.Rotation;
4838
4839 if (presence.ParentID != 0)
4840 {
4841 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4842 if (part != null && part != part.ParentGroup.RootPart)
4843 {
4844 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4845 rotation = part.RotationOffset * presence.Rotation;
4846 }
4847 }
4848
4765 attachPoint = 0; 4849 attachPoint = 0;
4766 collisionPlane = presence.CollisionPlane; 4850 collisionPlane = presence.CollisionPlane;
4767 position = presence.OffsetPosition;
4768 velocity = presence.Velocity; 4851 velocity = presence.Velocity;
4769 acceleration = Vector3.Zero; 4852 acceleration = Vector3.Zero;
4770 4853
@@ -4774,7 +4857,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4774// acceleration = new Vector3(1, 0, 0); 4857// acceleration = new Vector3(1, 0, 0);
4775 4858
4776 angularVelocity = Vector3.Zero; 4859 angularVelocity = Vector3.Zero;
4777 rotation = presence.Rotation;
4778 4860
4779 if (sendTexture) 4861 if (sendTexture)
4780 textureEntry = presence.Appearance.Texture.GetBytes(); 4862 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4879,13 +4961,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4879 4961
4880 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 4962 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4881 { 4963 {
4964 Vector3 offsetPosition = data.OffsetPosition;
4965 Quaternion rotation = data.Rotation;
4966 uint parentID = data.ParentID;
4967
4968 if (parentID != 0)
4969 {
4970 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
4971 if (part != null && part != part.ParentGroup.RootPart)
4972 {
4973 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
4974 rotation = part.RotationOffset * data.Rotation;
4975 parentID = part.ParentGroup.RootPart.LocalId;
4976 }
4977 }
4978
4882 byte[] objectData = new byte[76]; 4979 byte[] objectData = new byte[76];
4883 4980
4884 data.CollisionPlane.ToBytes(objectData, 0); 4981 data.CollisionPlane.ToBytes(objectData, 0);
4885 data.OffsetPosition.ToBytes(objectData, 16); 4982 offsetPosition.ToBytes(objectData, 16);
4886// data.Velocity.ToBytes(objectData, 28); 4983// data.Velocity.ToBytes(objectData, 28);
4887// data.Acceleration.ToBytes(objectData, 40); 4984// data.Acceleration.ToBytes(objectData, 40);
4888 data.Rotation.ToBytes(objectData, 52); 4985 rotation.ToBytes(objectData, 52);
4889 //data.AngularVelocity.ToBytes(objectData, 64); 4986 //data.AngularVelocity.ToBytes(objectData, 64);
4890 4987
4891 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 4988 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4899,7 +4996,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4899 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 4996 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4900 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 4997 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4901 update.ObjectData = objectData; 4998 update.ObjectData = objectData;
4902 update.ParentID = data.ParentID; 4999 update.ParentID = parentID;
4903 update.PathCurve = 16; 5000 update.PathCurve = 16;
4904 update.PathScaleX = 100; 5001 update.PathScaleX = 100;
4905 update.PathScaleY = 100; 5002 update.PathScaleY = 100;
@@ -5240,6 +5337,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5240 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5337 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5241 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5338 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5242 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5339 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5340 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5243 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5341 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5244 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5342 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5245 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5343 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5306,6 +5404,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5306 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5404 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5307 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5405 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5308 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5406 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5407 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5309 5408
5310 AddGenericPacketHandler("autopilot", HandleAutopilot); 5409 AddGenericPacketHandler("autopilot", HandleAutopilot);
5311 } 5410 }
@@ -5341,6 +5440,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5341 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5440 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5342 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5441 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5343 (x.ControlFlags != lastarg.ControlFlags) || 5442 (x.ControlFlags != lastarg.ControlFlags) ||
5443 (x.ControlFlags != 0) ||
5344 (x.Far != lastarg.Far) || 5444 (x.Far != lastarg.Far) ||
5345 (x.Flags != lastarg.Flags) || 5445 (x.Flags != lastarg.Flags) ||
5346 (x.State != lastarg.State) || 5446 (x.State != lastarg.State) ||
@@ -5718,7 +5818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5718 args.Channel = ch; 5818 args.Channel = ch;
5719 args.From = String.Empty; 5819 args.From = String.Empty;
5720 args.Message = Utils.BytesToString(msg); 5820 args.Message = Utils.BytesToString(msg);
5721 args.Type = ChatTypeEnum.Shout; 5821 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5722 args.Position = new Vector3(); 5822 args.Position = new Vector3();
5723 args.Scene = Scene; 5823 args.Scene = Scene;
5724 args.Sender = this; 5824 args.Sender = this;
@@ -6906,10 +7006,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6906 // 46,47,48 are special positions within the packet 7006 // 46,47,48 are special positions within the packet
6907 // This may change so perhaps we need a better way 7007 // This may change so perhaps we need a better way
6908 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7008 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6909 bool UsePhysics = (data[46] != 0) ? true : false; 7009 /*
6910 bool IsTemporary = (data[47] != 0) ? true : false; 7010 bool UsePhysics = (data[46] != 0) ? true : false;
6911 bool IsPhantom = (data[48] != 0) ? true : false; 7011 bool IsTemporary = (data[47] != 0) ? true : false;
6912 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7012 bool IsPhantom = (data[48] != 0) ? true : false;
7013 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7014 */
7015 bool UsePhysics = flags.AgentData.UsePhysics;
7016 bool IsPhantom = flags.AgentData.IsPhantom;
7017 bool IsTemporary = flags.AgentData.IsTemporary;
7018 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7019 ExtraPhysicsData physdata = new ExtraPhysicsData();
7020
7021 if (blocks == null || blocks.Length == 0)
7022 {
7023 physdata.PhysShapeType = PhysShapeType.invalid;
7024 }
7025 else
7026 {
7027 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7028 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7029 physdata.Bounce = phsblock.Restitution;
7030 physdata.Density = phsblock.Density;
7031 physdata.Friction = phsblock.Friction;
7032 }
7033 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6913 } 7034 }
6914 return true; 7035 return true;
6915 } 7036 }
@@ -9763,7 +9884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9763 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9884 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9764 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9885 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9765 UpdateMuteListEntry.MuteData.MuteType, 9886 UpdateMuteListEntry.MuteData.MuteType,
9766 UpdateMuteListEntry.AgentData.AgentID); 9887 UpdateMuteListEntry.MuteData.MuteFlags);
9767 return true; 9888 return true;
9768 } 9889 }
9769 return false; 9890 return false;
@@ -9778,8 +9899,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9778 { 9899 {
9779 handlerRemoveMuteListEntry(this, 9900 handlerRemoveMuteListEntry(this,
9780 RemoveMuteListEntry.MuteData.MuteID, 9901 RemoveMuteListEntry.MuteData.MuteID,
9781 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9902 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9782 RemoveMuteListEntry.AgentData.AgentID);
9783 return true; 9903 return true;
9784 } 9904 }
9785 return false; 9905 return false;
@@ -9823,10 +9943,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9823 return false; 9943 return false;
9824 } 9944 }
9825 9945
9946 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9947 {
9948 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9949 (ChangeInventoryItemFlagsPacket)packet;
9950 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9951 if (handlerChangeInventoryItemFlags != null)
9952 {
9953 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9954 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9955 return true;
9956 }
9957 return false;
9958 }
9959
9826 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9960 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9827 { 9961 {
9828 return true; 9962 return true;
9829 } 9963 }
9964
9965 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9966 {
9967 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9968
9969 #region Packet Session and User Check
9970 if (m_checkPackets)
9971 {
9972 if (packet.AgentData.SessionID != SessionId ||
9973 packet.AgentData.AgentID != AgentId)
9974 return true;
9975 }
9976 #endregion
9977 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9978 List<InventoryItemBase> items = new List<InventoryItemBase>();
9979 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9980 {
9981 InventoryItemBase b = new InventoryItemBase();
9982 b.ID = n.OldItemID;
9983 b.Folder = n.OldFolderID;
9984 items.Add(b);
9985 }
9986
9987 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9988 if (handlerMoveItemsAndLeaveCopy != null)
9989 {
9990 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9991 }
9992
9993 return true;
9994 }
9830 9995
9831 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9996 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9832 { 9997 {
@@ -10253,6 +10418,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10253 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10418 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10254 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10419 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10255 10420
10421 Scene scene = (Scene)m_scene;
10422 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10423 {
10424 ScenePresence p;
10425 if (scene.TryGetScenePresence(sender.AgentId, out p))
10426 {
10427 if (p.GodLevel >= 200)
10428 {
10429 groupProfileReply.GroupData.OpenEnrollment = true;
10430 groupProfileReply.GroupData.MembershipFee = 0;
10431 }
10432 }
10433 }
10434
10256 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10435 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10257 } 10436 }
10258 return true; 10437 return true;
@@ -10826,11 +11005,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10826 11005
10827 StartLure handlerStartLure = OnStartLure; 11006 StartLure handlerStartLure = OnStartLure;
10828 if (handlerStartLure != null) 11007 if (handlerStartLure != null)
10829 handlerStartLure(startLureRequest.Info.LureType, 11008 {
10830 Utils.BytesToString( 11009 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10831 startLureRequest.Info.Message), 11010 {
10832 startLureRequest.TargetData[0].TargetID, 11011 handlerStartLure(startLureRequest.Info.LureType,
10833 this); 11012 Utils.BytesToString(
11013 startLureRequest.Info.Message),
11014 startLureRequest.TargetData[i].TargetID,
11015 this);
11016 }
11017 }
10834 return true; 11018 return true;
10835 } 11019 }
10836 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11020 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10944,10 +11128,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10944 } 11128 }
10945 #endregion 11129 #endregion
10946 11130
10947 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11131 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10948 if (handlerClassifiedGodDelete != null) 11132 if (handlerClassifiedGodDelete != null)
10949 handlerClassifiedGodDelete( 11133 handlerClassifiedGodDelete(
10950 classifiedGodDelete.Data.ClassifiedID, 11134 classifiedGodDelete.Data.ClassifiedID,
11135 classifiedGodDelete.Data.QueryID,
10951 this); 11136 this);
10952 return true; 11137 return true;
10953 } 11138 }
@@ -11317,209 +11502,149 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11317 } 11502 }
11318 else 11503 else
11319 { 11504 {
11320// m_log.DebugFormat( 11505 ClientChangeObject updatehandler = onClientChangeObject;
11321// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11322// i, block.Type, part.Name, part.LocalId);
11323 11506
11324// // Do this once since fetch parts creates a new array. 11507 if (updatehandler != null)
11325// SceneObjectPart[] parts = part.ParentGroup.Parts; 11508 {
11326// for (int j = 0; j < parts.Length; j++) 11509 ObjectChangeData udata = new ObjectChangeData();
11327// {
11328// part.StoreUndoState();
11329// parts[j].IgnoreUndoUpdate = true;
11330// }
11331 11510
11332 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11511 /*ubit from ll JIRA:
11512 * 0x01 position
11513 * 0x02 rotation
11514 * 0x04 scale
11515
11516 * 0x08 LINK_SET
11517 * 0x10 UNIFORM for scale
11518 */
11333 11519
11334 switch (block.Type) 11520 // translate to internal changes
11335 { 11521 // not all cases .. just the ones older code did
11336 case 1:
11337 Vector3 pos1 = new Vector3(block.Data, 0);
11338 11522
11339 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11523 switch (block.Type)
11340 if (handlerUpdatePrimSinglePosition != null) 11524 {
11341 { 11525 case 1: //change position sp
11342 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11526 udata.position = new Vector3(block.Data, 0);
11343 handlerUpdatePrimSinglePosition(localId, pos1, this);
11344 }
11345 break;
11346 11527
11347 case 2: 11528 udata.change = ObjectChangeType.primP;
11348 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11529 updatehandler(localId, udata, this);
11530 break;
11349 11531
11350 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11532 case 2: // rotation sp
11351 if (handlerUpdatePrimSingleRotation != null) 11533 udata.rotation = new Quaternion(block.Data, 0, true);
11352 {
11353 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11354 handlerUpdatePrimSingleRotation(localId, rot1, this);
11355 }
11356 break;
11357 11534
11358 case 3: 11535 udata.change = ObjectChangeType.primR;
11359 Vector3 rotPos = new Vector3(block.Data, 0); 11536 updatehandler(localId, udata, this);
11360 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11537 break;
11361 11538
11362 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11539 case 3: // position plus rotation
11363 if (handlerUpdatePrimSingleRotationPosition != null) 11540 udata.position = new Vector3(block.Data, 0);
11364 { 11541 udata.rotation = new Quaternion(block.Data, 12, true);
11365 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11366 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11367 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11368 }
11369 break;
11370 11542
11371 case 4: 11543 udata.change = ObjectChangeType.primPR;
11372 case 20: 11544 updatehandler(localId, udata, this);
11373 Vector3 scale4 = new Vector3(block.Data, 0); 11545 break;
11374 11546
11375 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11547 case 4: // scale sp
11376 if (handlerUpdatePrimScale != null) 11548 udata.scale = new Vector3(block.Data, 0);
11377 { 11549 udata.change = ObjectChangeType.primS;
11378 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11379 handlerUpdatePrimScale(localId, scale4, this);
11380 }
11381 break;
11382 11550
11383 case 5: 11551 updatehandler(localId, udata, this);
11384 Vector3 scale1 = new Vector3(block.Data, 12); 11552 break;
11385 Vector3 pos11 = new Vector3(block.Data, 0);
11386 11553
11387 handlerUpdatePrimScale = OnUpdatePrimScale; 11554 case 0x14: // uniform scale sp
11388 if (handlerUpdatePrimScale != null) 11555 udata.scale = new Vector3(block.Data, 0);
11389 {
11390 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11391 handlerUpdatePrimScale(localId, scale1, this);
11392 11556
11393 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11557 udata.change = ObjectChangeType.primUS;
11394 if (handlerUpdatePrimSinglePosition != null) 11558 updatehandler(localId, udata, this);
11395 { 11559 break;
11396 handlerUpdatePrimSinglePosition(localId, pos11, this);
11397 }
11398 }
11399 break;
11400 11560
11401 case 9: 11561 case 5: // scale and position sp
11402 Vector3 pos2 = new Vector3(block.Data, 0); 11562 udata.position = new Vector3(block.Data, 0);
11563 udata.scale = new Vector3(block.Data, 12);
11403 11564
11404 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11565 udata.change = ObjectChangeType.primPS;
11566 updatehandler(localId, udata, this);
11567 break;
11405 11568
11406 if (handlerUpdateVector != null) 11569 case 0x15: //uniform scale and position
11407 { 11570 udata.position = new Vector3(block.Data, 0);
11408 handlerUpdateVector(localId, pos2, this); 11571 udata.scale = new Vector3(block.Data, 12);
11409 }
11410 break;
11411 11572
11412 case 10: 11573 udata.change = ObjectChangeType.primPUS;
11413 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11574 updatehandler(localId, udata, this);
11575 break;
11414 11576
11415 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11577 // now group related (bit 4)
11416 if (handlerUpdatePrimRotation != null) 11578 case 9: //( 8 + 1 )group position
11417 { 11579 udata.position = new Vector3(block.Data, 0);
11418 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11419 handlerUpdatePrimRotation(localId, rot3, this);
11420 }
11421 break;
11422 11580
11423 case 11: 11581 udata.change = ObjectChangeType.groupP;
11424 Vector3 pos3 = new Vector3(block.Data, 0); 11582 updatehandler(localId, udata, this);
11425 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11583 break;
11426 11584
11427 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11585 case 0x0A: // (8 + 2) group rotation
11428 if (handlerUpdatePrimGroupRotation != null) 11586 udata.rotation = new Quaternion(block.Data, 0, true);
11429 {
11430 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11431 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11432 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11433 }
11434 break;
11435 case 12:
11436 case 28:
11437 Vector3 scale7 = new Vector3(block.Data, 0);
11438 11587
11439 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11588 udata.change = ObjectChangeType.groupR;
11440 if (handlerUpdatePrimGroupScale != null) 11589 updatehandler(localId, udata, this);
11441 { 11590 break;
11442 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11443 handlerUpdatePrimGroupScale(localId, scale7, this);
11444 }
11445 break;
11446 11591
11447 case 13: 11592 case 0x0B: //( 8 + 2 + 1) group rotation and position
11448 Vector3 scale2 = new Vector3(block.Data, 12); 11593 udata.position = new Vector3(block.Data, 0);
11449 Vector3 pos4 = new Vector3(block.Data, 0); 11594 udata.rotation = new Quaternion(block.Data, 12, true);
11450 11595
11451 handlerUpdatePrimScale = OnUpdatePrimScale; 11596 udata.change = ObjectChangeType.groupPR;
11452 if (handlerUpdatePrimScale != null) 11597 updatehandler(localId, udata, this);
11453 { 11598 break;
11454 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11455 handlerUpdatePrimScale(localId, scale2, this);
11456 11599
11457 // Change the position based on scale (for bug number 246) 11600 case 0x0C: // (8 + 4) group scale
11458 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11601 // only afects root prim and only sent by viewer editor object tab scaling
11459 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11602 // mouse edition only allows uniform scaling
11460 if (handlerUpdatePrimSinglePosition != null) 11603 // SL MAY CHANGE THIS in viewers
11461 {
11462 handlerUpdatePrimSinglePosition(localId, pos4, this);
11463 }
11464 }
11465 break;
11466 11604
11467 case 29: 11605 udata.scale = new Vector3(block.Data, 0);
11468 Vector3 scale5 = new Vector3(block.Data, 12);
11469 Vector3 pos5 = new Vector3(block.Data, 0);
11470 11606
11471 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11607 // udata.change = ObjectChangeType.groupS;
11472 if (handlerUpdatePrimGroupScale != null) 11608 udata.change = ObjectChangeType.primS; // to conform to current SL
11473 { 11609 updatehandler(localId, udata, this);
11474 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11475 part.StoreUndoState(true);
11476 part.IgnoreUndoUpdate = true;
11477 handlerUpdatePrimGroupScale(localId, scale5, this);
11478 handlerUpdateVector = OnUpdatePrimGroupPosition;
11479 11610
11480 if (handlerUpdateVector != null) 11611 break;
11481 {
11482 handlerUpdateVector(localId, pos5, this);
11483 }
11484 11612
11485 part.IgnoreUndoUpdate = false; 11613 case 0x0D: //(8 + 4 + 1) group scale and position
11486 } 11614 // exception as above
11487 11615
11488 break; 11616 udata.position = new Vector3(block.Data, 0);
11617 udata.scale = new Vector3(block.Data, 12);
11489 11618
11490 case 21: 11619 // udata.change = ObjectChangeType.groupPS;
11491 Vector3 scale6 = new Vector3(block.Data, 12); 11620 udata.change = ObjectChangeType.primPS; // to conform to current SL
11492 Vector3 pos6 = new Vector3(block.Data, 0); 11621 updatehandler(localId, udata, this);
11622 break;
11493 11623
11494 handlerUpdatePrimScale = OnUpdatePrimScale; 11624 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11495 if (handlerUpdatePrimScale != null) 11625 udata.scale = new Vector3(block.Data, 0);
11496 {
11497 part.StoreUndoState(false);
11498 part.IgnoreUndoUpdate = true;
11499 11626
11500 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11627 udata.change = ObjectChangeType.groupUS;
11501 handlerUpdatePrimScale(localId, scale6, this); 11628 updatehandler(localId, udata, this);
11502 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11629 break;
11503 if (handlerUpdatePrimSinglePosition != null)
11504 {
11505 handlerUpdatePrimSinglePosition(localId, pos6, this);
11506 }
11507 11630
11508 part.IgnoreUndoUpdate = false; 11631 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11509 } 11632 udata.position = new Vector3(block.Data, 0);
11510 break; 11633 udata.scale = new Vector3(block.Data, 12);
11511 11634
11512 default: 11635 udata.change = ObjectChangeType.groupPUS;
11513 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11636 updatehandler(localId, udata, this);
11514 break; 11637 break;
11638
11639 default:
11640 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11641 break;
11642 }
11515 } 11643 }
11516 11644
11517// for (int j = 0; j < parts.Length; j++)
11518// parts[j].IgnoreUndoUpdate = false;
11519 } 11645 }
11520 } 11646 }
11521 } 11647 }
11522
11523 return true; 11648 return true;
11524 } 11649 }
11525 11650
@@ -11975,7 +12100,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11975 12100
11976// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12101// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11977 12102
12103
12104 //Note, the bool returned from the below function is useless since it is always false.
11978 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12105 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12106
11979 } 12107 }
11980 12108
11981 /// <summary> 12109 /// <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,