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.cs1079
-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, 671 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 68aae14..c40c0ec 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);
@@ -2590,6 +2609,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2590 } 2609 }
2591 } 2610 }
2592 2611
2612 public void SendPartPhysicsProprieties(ISceneEntity entity)
2613 {
2614 SceneObjectPart part = (SceneObjectPart)entity;
2615 if (part != null && AgentId != UUID.Zero)
2616 {
2617 try
2618 {
2619 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2620 if (eq != null)
2621 {
2622 uint localid = part.LocalId;
2623 byte physshapetype = part.PhysicsShapeType;
2624 float density = part.Density;
2625 float friction = part.Friction;
2626 float bounce = part.Bounciness;
2627 float gravmod = part.GravityModifier;
2628
2629 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2630 }
2631 }
2632 catch (Exception ex)
2633 {
2634 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2635 }
2636 part.UpdatePhysRequired = false;
2637 }
2638 }
2639
2640
2593 2641
2594 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2642 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2595 { 2643 {
@@ -2745,7 +2793,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2745 reply.Data.ParcelID = parcelID; 2793 reply.Data.ParcelID = parcelID;
2746 reply.Data.OwnerID = land.OwnerID; 2794 reply.Data.OwnerID = land.OwnerID;
2747 reply.Data.Name = Utils.StringToBytes(land.Name); 2795 reply.Data.Name = Utils.StringToBytes(land.Name);
2748 reply.Data.Desc = Utils.StringToBytes(land.Description); 2796 if (land != null && land.Description != null && land.Description != String.Empty)
2797 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2798 else
2799 reply.Data.Desc = new Byte[0];
2749 reply.Data.ActualArea = land.Area; 2800 reply.Data.ActualArea = land.Area;
2750 reply.Data.BillableArea = land.Area; // TODO: what is this? 2801 reply.Data.BillableArea = land.Area; // TODO: what is this?
2751 2802
@@ -3608,7 +3659,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3608 /// </summary> 3659 /// </summary>
3609 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3660 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3610 { 3661 {
3611 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3662 if (entity is SceneObjectPart)
3663 {
3664 SceneObjectPart e = (SceneObjectPart)entity;
3665 SceneObjectGroup g = e.ParentGroup;
3666 if (g.RootPart.Shape.State > 30) // HUD
3667 if (g.OwnerID != AgentId)
3668 return; // Don't send updates for other people's HUDs
3669 }
3670
3612 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3671 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3613 3672
3614 lock (m_entityUpdates.SyncRoot) 3673 lock (m_entityUpdates.SyncRoot)
@@ -3675,211 +3734,238 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3675 3734
3676 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3735 // 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. 3736 // condition where a kill can be processed before an out-of-date update for the same object.
3678 lock (m_killRecord) 3737 float avgTimeDilation = 1.0f;
3738 IEntityUpdate iupdate;
3739 Int32 timeinqueue; // this is just debugging code & can be dropped later
3740
3741 while (updatesThisCall < maxUpdates)
3679 { 3742 {
3680 float avgTimeDilation = 1.0f; 3743 lock (m_entityUpdates.SyncRoot)
3681 IEntityUpdate iupdate; 3744 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3682 Int32 timeinqueue; // this is just debugging code & can be dropped later 3745 break;
3683
3684 while (updatesThisCall < maxUpdates)
3685 {
3686 lock (m_entityUpdates.SyncRoot)
3687 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3688 break;
3689 3746
3690 EntityUpdate update = (EntityUpdate)iupdate; 3747 EntityUpdate update = (EntityUpdate)iupdate;
3691 3748
3692 avgTimeDilation += update.TimeDilation; 3749 avgTimeDilation += update.TimeDilation;
3693 avgTimeDilation *= 0.5f; 3750 avgTimeDilation *= 0.5f;
3694 3751
3695 if (update.Entity is SceneObjectPart) 3752 if (update.Entity is SceneObjectPart)
3753 {
3754 SceneObjectPart part = (SceneObjectPart)update.Entity;
3755
3756 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3757 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3758 // safety measure.
3759 //
3760 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3761 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3762 // updates and kills on different threads with different scheduling strategies, hence this protection.
3763 //
3764 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3765 // after the root prim has been deleted.
3766 lock (m_killRecord)
3696 { 3767 {
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)) 3768 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; 3769 continue;
3715 } 3770 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3716 3771 continue;
3717 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3772 }
3773
3774 if (part.ParentGroup.IsDeleted)
3775 continue;
3776
3777 if (part.ParentGroup.IsAttachment)
3778 { // Someone else's HUD, why are we getting these?
3779 if (part.ParentGroup.OwnerID != AgentId &&
3780 part.ParentGroup.RootPart.Shape.State >= 30)
3781 continue;
3782 ScenePresence sp;
3783 // Owner is not in the sim, don't update it to
3784 // anyone
3785 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3786 continue;
3787
3788 List<SceneObjectGroup> atts = sp.GetAttachments();
3789 bool found = false;
3790 foreach (SceneObjectGroup att in atts)
3718 { 3791 {
3719 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3792 if (att == part.ParentGroup)
3720 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3721 { 3793 {
3722 part.Shape.LightEntry = false; 3794 found = true;
3795 break;
3723 } 3796 }
3724 } 3797 }
3798
3799 // It's an attachment of a valid avatar, but
3800 // doesn't seem to be attached, skip
3801 if (!found)
3802 continue;
3803
3804 // On vehicle crossing, the attachments are received
3805 // while the avatar is still a child. Don't send
3806 // updates here because the LocalId has not yet
3807 // been updated and the viewer will derender the
3808 // attachments until the avatar becomes root.
3809 if (sp.IsChildAgent)
3810 continue;
3725 } 3811 }
3726 3812 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 { 3813 {
3749 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3814 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3750 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3815 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3751 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3752 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3753 {
3754 canUseCompressed = 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 { 3816 {
3772 canUseImproved = false; 3817 part.Shape.LightEntry = false;
3773 } 3818 }
3774 } 3819 }
3775 3820 }
3776 #endregion UpdateFlags to packet type conversion 3821
3777 3822 ++updatesThisCall;
3778 #region Block Construction 3823
3779 3824 #region UpdateFlags to packet type conversion
3780 // TODO: Remove this once we can build compressed updates 3825
3826 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3827
3828 bool canUseCompressed = true;
3829 bool canUseImproved = true;
3830
3831 // Compressed object updates only make sense for LL primitives
3832 if (!(update.Entity is SceneObjectPart))
3833 {
3781 canUseCompressed = false; 3834 canUseCompressed = false;
3782 3835 }
3783 if (!canUseImproved && !canUseCompressed) 3836
3784 { 3837 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3785 if (update.Entity is ScenePresence) 3838 {
3786 { 3839 canUseCompressed = false;
3787 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3840 canUseImproved = false;
3788 objectUpdates.Value.Add(update); 3841 }
3789 } 3842 else
3790 else 3843 {
3791 { 3844 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3792 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3845 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3793 objectUpdates.Value.Add(update); 3846 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3794 } 3847 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3795 }
3796 else if (!canUseImproved)
3797 { 3848 {
3798 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3849 canUseCompressed = false;
3799 compressedUpdates.Value.Add(update);
3800 } 3850 }
3801 else 3851
3852 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3853 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3854 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3855 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3858 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3859 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3860 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3861 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3862 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3863 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3864 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3802 { 3866 {
3803 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3867 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 } 3868 }
3816
3817 #endregion Block Construction
3818 } 3869 }
3819
3820
3821 #region Packet Sending
3822 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3823 3870
3824 if (terseAgentUpdateBlocks.IsValueCreated) 3871 #endregion UpdateFlags to packet type conversion
3825 {
3826 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3827 3872
3828 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3873 #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 3874
3833 for (int i = 0; i < blocks.Count; i++) 3875 // TODO: Remove this once we can build compressed updates
3834 packet.ObjectData[i] = blocks[i]; 3876 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 3877
3839 if (objectUpdateBlocks.IsValueCreated) 3878 if (!canUseImproved && !canUseCompressed)
3840 { 3879 {
3841 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3880 if (update.Entity is ScenePresence)
3842 3881 {
3843 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3882 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3844 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3883 }
3845 packet.RegionData.TimeDilation = timeDilation; 3884 else
3846 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3885 {
3847 3886 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3848 for (int i = 0; i < blocks.Count; i++) 3887 }
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 } 3888 }
3853 3889 else if (!canUseImproved)
3854 if (compressedUpdateBlocks.IsValueCreated)
3855 { 3890 {
3856 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3891 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 } 3892 }
3868 3893 else
3869 if (terseUpdateBlocks.IsValueCreated)
3870 { 3894 {
3871 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3895 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3872 3896 // Self updates go into a special list
3873 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3897 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3898 else
3875 packet.RegionData.TimeDilation = timeDilation; 3899 // Everything else goes here
3876 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3900 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 } 3901 }
3902
3903 #endregion Block Construction
3904 }
3905
3906 #region Packet Sending
3907
3908 const float TIME_DILATION = 1.0f;
3909 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3910
3911 if (terseAgentUpdateBlocks.IsValueCreated)
3912 {
3913 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3914
3915 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3916 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3917 packet.RegionData.TimeDilation = timeDilation;
3918 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3919
3920 for (int i = 0; i < blocks.Count; i++)
3921 packet.ObjectData[i] = blocks[i];
3922
3923 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3924 }
3925
3926 if (objectUpdateBlocks.IsValueCreated)
3927 {
3928 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3929
3930 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3931 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3932 packet.RegionData.TimeDilation = timeDilation;
3933 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3934
3935 for (int i = 0; i < blocks.Count; i++)
3936 packet.ObjectData[i] = blocks[i];
3937
3938 OutPacket(packet, ThrottleOutPacketType.Task, true);
3939 }
3940
3941 if (compressedUpdateBlocks.IsValueCreated)
3942 {
3943 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3944
3945 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3946 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3947 packet.RegionData.TimeDilation = timeDilation;
3948 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3949
3950 for (int i = 0; i < blocks.Count; i++)
3951 packet.ObjectData[i] = blocks[i];
3952
3953 OutPacket(packet, ThrottleOutPacketType.Task, true);
3954 }
3955
3956 if (terseUpdateBlocks.IsValueCreated)
3957 {
3958 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3959
3960 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3961 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3962 packet.RegionData.TimeDilation = timeDilation;
3963 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3964
3965 for (int i = 0; i < blocks.Count; i++)
3966 packet.ObjectData[i] = blocks[i];
3967
3968 OutPacket(packet, ThrottleOutPacketType.Task, true);
3883 } 3969 }
3884 3970
3885 #endregion Packet Sending 3971 #endregion Packet Sending
@@ -4172,11 +4258,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4172 4258
4173 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4259 // 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 4260 // of the object rather than the properties when the packet was created
4175 OutPacket(packet, ThrottleOutPacketType.Task, true, 4261 // HACK : Remove intelligent resending until it's fixed in core
4176 delegate(OutgoingPacket oPacket) 4262 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4177 { 4263 // delegate(OutgoingPacket oPacket)
4178 ResendPropertyUpdates(updates, oPacket); 4264 // {
4179 }); 4265 // ResendPropertyUpdates(updates, oPacket);
4266 // });
4267 OutPacket(packet, ThrottleOutPacketType.Task, true);
4180 4268
4181 // pbcnt += blocks.Count; 4269 // pbcnt += blocks.Count;
4182 // ppcnt++; 4270 // ppcnt++;
@@ -4202,11 +4290,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4202 // of the object rather than the properties when the packet was created 4290 // of the object rather than the properties when the packet was created
4203 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4291 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4204 updates.Add(familyUpdates.Value[i]); 4292 updates.Add(familyUpdates.Value[i]);
4205 OutPacket(packet, ThrottleOutPacketType.Task, true, 4293 // HACK : Remove intelligent resending until it's fixed in core
4206 delegate(OutgoingPacket oPacket) 4294 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4207 { 4295 // delegate(OutgoingPacket oPacket)
4208 ResendPropertyUpdates(updates, oPacket); 4296 // {
4209 }); 4297 // ResendPropertyUpdates(updates, oPacket);
4298 // });
4299 OutPacket(packet, ThrottleOutPacketType.Task, true);
4210 4300
4211 // fpcnt++; 4301 // fpcnt++;
4212 // fbcnt++; 4302 // fbcnt++;
@@ -4355,37 +4445,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4355 if (bl[i].BannedUserID == UUID.Zero) 4445 if (bl[i].BannedUserID == UUID.Zero)
4356 continue; 4446 continue;
4357 BannedUsers.Add(bl[i].BannedUserID); 4447 BannedUsers.Add(bl[i].BannedUserID);
4358 }
4359 4448
4360 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4449 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4361 packet.AgentData.TransactionID = UUID.Random(); 4450 {
4362 packet.AgentData.AgentID = AgentId; 4451 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4363 packet.AgentData.SessionID = SessionId; 4452 packet.AgentData.TransactionID = UUID.Random();
4364 packet.MethodData.Invoice = invoice; 4453 packet.AgentData.AgentID = AgentId;
4365 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4454 packet.AgentData.SessionID = SessionId;
4455 packet.MethodData.Invoice = invoice;
4456 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4366 4457
4367 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4458 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4368 4459
4369 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4460 int j;
4370 { 4461 for (j = 0; j < (6 + BannedUsers.Count); j++)
4371 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4462 {
4372 } 4463 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4373 int j = 0; 4464 }
4465 j = 0;
4374 4466
4375 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4467 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4468 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4469 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4470 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4471 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4472 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 4473
4382 foreach (UUID banned in BannedUsers) 4474 foreach (UUID banned in BannedUsers)
4383 { 4475 {
4384 returnblock[j].Parameter = banned.GetBytes(); j++; 4476 returnblock[j].Parameter = banned.GetBytes(); j++;
4477 }
4478 packet.ParamList = returnblock;
4479 packet.Header.Reliable = true;
4480 OutPacket(packet, ThrottleOutPacketType.Task);
4481
4482 BannedUsers.Clear();
4483 }
4385 } 4484 }
4386 packet.ParamList = returnblock; 4485
4387 packet.Header.Reliable = false;
4388 OutPacket(packet, ThrottleOutPacketType.Task);
4389 } 4486 }
4390 4487
4391 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4488 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4571,7 +4668,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4571 4668
4572 if (landData.SimwideArea > 0) 4669 if (landData.SimwideArea > 0)
4573 { 4670 {
4574 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4671 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4672 // Never report more than sim total capacity
4673 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4674 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4575 updateMessage.SimWideMaxPrims = simulatorCapacity; 4675 updateMessage.SimWideMaxPrims = simulatorCapacity;
4576 } 4676 }
4577 else 4677 else
@@ -4700,14 +4800,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4700 4800
4701 if (notifyCount > 0) 4801 if (notifyCount > 0)
4702 { 4802 {
4703 if (notifyCount > 32) 4803// if (notifyCount > 32)
4704 { 4804// {
4705 m_log.InfoFormat( 4805// m_log.InfoFormat(
4706 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4806// "[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); 4807// + " - a developer might want to investigate whether this is a hard limit", 32);
4708 4808//
4709 notifyCount = 32; 4809// notifyCount = 32;
4710 } 4810// }
4711 4811
4712 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4812 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4713 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4813 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4762,9 +4862,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4762 { 4862 {
4763 ScenePresence presence = (ScenePresence)entity; 4863 ScenePresence presence = (ScenePresence)entity;
4764 4864
4865 position = presence.OffsetPosition;
4866 rotation = presence.Rotation;
4867
4868 if (presence.ParentID != 0)
4869 {
4870 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4871 if (part != null && part != part.ParentGroup.RootPart)
4872 {
4873 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4874 rotation = part.RotationOffset * presence.Rotation;
4875 }
4876 }
4877
4765 attachPoint = 0; 4878 attachPoint = 0;
4766 collisionPlane = presence.CollisionPlane; 4879 collisionPlane = presence.CollisionPlane;
4767 position = presence.OffsetPosition;
4768 velocity = presence.Velocity; 4880 velocity = presence.Velocity;
4769 acceleration = Vector3.Zero; 4881 acceleration = Vector3.Zero;
4770 4882
@@ -4774,7 +4886,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4774// acceleration = new Vector3(1, 0, 0); 4886// acceleration = new Vector3(1, 0, 0);
4775 4887
4776 angularVelocity = Vector3.Zero; 4888 angularVelocity = Vector3.Zero;
4777 rotation = presence.Rotation;
4778 4889
4779 if (sendTexture) 4890 if (sendTexture)
4780 textureEntry = presence.Appearance.Texture.GetBytes(); 4891 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4879,13 +4990,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4879 4990
4880 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 4991 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4881 { 4992 {
4993 Vector3 offsetPosition = data.OffsetPosition;
4994 Quaternion rotation = data.Rotation;
4995 uint parentID = data.ParentID;
4996
4997 if (parentID != 0)
4998 {
4999 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5000 if (part != null && part != part.ParentGroup.RootPart)
5001 {
5002 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5003 rotation = part.RotationOffset * data.Rotation;
5004 parentID = part.ParentGroup.RootPart.LocalId;
5005 }
5006 }
5007
4882 byte[] objectData = new byte[76]; 5008 byte[] objectData = new byte[76];
4883 5009
4884 data.CollisionPlane.ToBytes(objectData, 0); 5010 data.CollisionPlane.ToBytes(objectData, 0);
4885 data.OffsetPosition.ToBytes(objectData, 16); 5011 offsetPosition.ToBytes(objectData, 16);
4886// data.Velocity.ToBytes(objectData, 28); 5012// data.Velocity.ToBytes(objectData, 28);
4887// data.Acceleration.ToBytes(objectData, 40); 5013// data.Acceleration.ToBytes(objectData, 40);
4888 data.Rotation.ToBytes(objectData, 52); 5014 rotation.ToBytes(objectData, 52);
4889 //data.AngularVelocity.ToBytes(objectData, 64); 5015 //data.AngularVelocity.ToBytes(objectData, 64);
4890 5016
4891 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5017 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4899,7 +5025,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4899 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5025 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4900 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5026 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4901 update.ObjectData = objectData; 5027 update.ObjectData = objectData;
4902 update.ParentID = data.ParentID; 5028 update.ParentID = parentID;
4903 update.PathCurve = 16; 5029 update.PathCurve = 16;
4904 update.PathScaleX = 100; 5030 update.PathScaleX = 100;
4905 update.PathScaleY = 100; 5031 update.PathScaleY = 100;
@@ -5240,6 +5366,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5240 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5366 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5241 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5367 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5242 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5368 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5369 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5243 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5370 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5244 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5371 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5245 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5372 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5306,6 +5433,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5306 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5433 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5307 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5434 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5308 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5435 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5436 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5309 5437
5310 AddGenericPacketHandler("autopilot", HandleAutopilot); 5438 AddGenericPacketHandler("autopilot", HandleAutopilot);
5311 } 5439 }
@@ -5341,6 +5469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5341 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5469 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5342 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5470 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5343 (x.ControlFlags != lastarg.ControlFlags) || 5471 (x.ControlFlags != lastarg.ControlFlags) ||
5472 (x.ControlFlags != 0) ||
5344 (x.Far != lastarg.Far) || 5473 (x.Far != lastarg.Far) ||
5345 (x.Flags != lastarg.Flags) || 5474 (x.Flags != lastarg.Flags) ||
5346 (x.State != lastarg.State) || 5475 (x.State != lastarg.State) ||
@@ -5718,7 +5847,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5718 args.Channel = ch; 5847 args.Channel = ch;
5719 args.From = String.Empty; 5848 args.From = String.Empty;
5720 args.Message = Utils.BytesToString(msg); 5849 args.Message = Utils.BytesToString(msg);
5721 args.Type = ChatTypeEnum.Shout; 5850 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5722 args.Position = new Vector3(); 5851 args.Position = new Vector3();
5723 args.Scene = Scene; 5852 args.Scene = Scene;
5724 args.Sender = this; 5853 args.Sender = this;
@@ -6906,10 +7035,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6906 // 46,47,48 are special positions within the packet 7035 // 46,47,48 are special positions within the packet
6907 // This may change so perhaps we need a better way 7036 // This may change so perhaps we need a better way
6908 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7037 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6909 bool UsePhysics = (data[46] != 0) ? true : false; 7038 /*
6910 bool IsTemporary = (data[47] != 0) ? true : false; 7039 bool UsePhysics = (data[46] != 0) ? true : false;
6911 bool IsPhantom = (data[48] != 0) ? true : false; 7040 bool IsTemporary = (data[47] != 0) ? true : false;
6912 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7041 bool IsPhantom = (data[48] != 0) ? true : false;
7042 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7043 */
7044 bool UsePhysics = flags.AgentData.UsePhysics;
7045 bool IsPhantom = flags.AgentData.IsPhantom;
7046 bool IsTemporary = flags.AgentData.IsTemporary;
7047 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7048 ExtraPhysicsData physdata = new ExtraPhysicsData();
7049
7050 if (blocks == null || blocks.Length == 0)
7051 {
7052 physdata.PhysShapeType = PhysShapeType.invalid;
7053 }
7054 else
7055 {
7056 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7057 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7058 physdata.Bounce = phsblock.Restitution;
7059 physdata.Density = phsblock.Density;
7060 physdata.Friction = phsblock.Friction;
7061 physdata.GravitationModifier = phsblock.GravityMultiplier;
7062 }
7063
7064 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6913 } 7065 }
6914 return true; 7066 return true;
6915 } 7067 }
@@ -9763,7 +9915,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9763 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9915 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9764 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9916 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9765 UpdateMuteListEntry.MuteData.MuteType, 9917 UpdateMuteListEntry.MuteData.MuteType,
9766 UpdateMuteListEntry.AgentData.AgentID); 9918 UpdateMuteListEntry.MuteData.MuteFlags);
9767 return true; 9919 return true;
9768 } 9920 }
9769 return false; 9921 return false;
@@ -9778,8 +9930,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9778 { 9930 {
9779 handlerRemoveMuteListEntry(this, 9931 handlerRemoveMuteListEntry(this,
9780 RemoveMuteListEntry.MuteData.MuteID, 9932 RemoveMuteListEntry.MuteData.MuteID,
9781 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9933 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9782 RemoveMuteListEntry.AgentData.AgentID);
9783 return true; 9934 return true;
9784 } 9935 }
9785 return false; 9936 return false;
@@ -9823,10 +9974,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9823 return false; 9974 return false;
9824 } 9975 }
9825 9976
9977 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9978 {
9979 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9980 (ChangeInventoryItemFlagsPacket)packet;
9981 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9982 if (handlerChangeInventoryItemFlags != null)
9983 {
9984 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9985 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9986 return true;
9987 }
9988 return false;
9989 }
9990
9826 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9991 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9827 { 9992 {
9828 return true; 9993 return true;
9829 } 9994 }
9995
9996 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9997 {
9998 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9999
10000 #region Packet Session and User Check
10001 if (m_checkPackets)
10002 {
10003 if (packet.AgentData.SessionID != SessionId ||
10004 packet.AgentData.AgentID != AgentId)
10005 return true;
10006 }
10007 #endregion
10008 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10009 List<InventoryItemBase> items = new List<InventoryItemBase>();
10010 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10011 {
10012 InventoryItemBase b = new InventoryItemBase();
10013 b.ID = n.OldItemID;
10014 b.Folder = n.OldFolderID;
10015 items.Add(b);
10016 }
10017
10018 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10019 if (handlerMoveItemsAndLeaveCopy != null)
10020 {
10021 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10022 }
10023
10024 return true;
10025 }
9830 10026
9831 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10027 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9832 { 10028 {
@@ -10253,6 +10449,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10253 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10449 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10254 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10450 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10255 10451
10452 Scene scene = (Scene)m_scene;
10453 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10454 {
10455 ScenePresence p;
10456 if (scene.TryGetScenePresence(sender.AgentId, out p))
10457 {
10458 if (p.GodLevel >= 200)
10459 {
10460 groupProfileReply.GroupData.OpenEnrollment = true;
10461 groupProfileReply.GroupData.MembershipFee = 0;
10462 }
10463 }
10464 }
10465
10256 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10466 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10257 } 10467 }
10258 return true; 10468 return true;
@@ -10826,11 +11036,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10826 11036
10827 StartLure handlerStartLure = OnStartLure; 11037 StartLure handlerStartLure = OnStartLure;
10828 if (handlerStartLure != null) 11038 if (handlerStartLure != null)
10829 handlerStartLure(startLureRequest.Info.LureType, 11039 {
10830 Utils.BytesToString( 11040 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10831 startLureRequest.Info.Message), 11041 {
10832 startLureRequest.TargetData[0].TargetID, 11042 handlerStartLure(startLureRequest.Info.LureType,
10833 this); 11043 Utils.BytesToString(
11044 startLureRequest.Info.Message),
11045 startLureRequest.TargetData[i].TargetID,
11046 this);
11047 }
11048 }
10834 return true; 11049 return true;
10835 } 11050 }
10836 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11051 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10944,10 +11159,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10944 } 11159 }
10945 #endregion 11160 #endregion
10946 11161
10947 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11162 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10948 if (handlerClassifiedGodDelete != null) 11163 if (handlerClassifiedGodDelete != null)
10949 handlerClassifiedGodDelete( 11164 handlerClassifiedGodDelete(
10950 classifiedGodDelete.Data.ClassifiedID, 11165 classifiedGodDelete.Data.ClassifiedID,
11166 classifiedGodDelete.Data.QueryID,
10951 this); 11167 this);
10952 return true; 11168 return true;
10953 } 11169 }
@@ -11312,209 +11528,149 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11312 } 11528 }
11313 else 11529 else
11314 { 11530 {
11315// m_log.DebugFormat( 11531 ClientChangeObject updatehandler = onClientChangeObject;
11316// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11317// i, block.Type, part.Name, part.LocalId);
11318 11532
11319// // Do this once since fetch parts creates a new array. 11533 if (updatehandler != null)
11320// SceneObjectPart[] parts = part.ParentGroup.Parts; 11534 {
11321// for (int j = 0; j < parts.Length; j++) 11535 ObjectChangeData udata = new ObjectChangeData();
11322// {
11323// part.StoreUndoState();
11324// parts[j].IgnoreUndoUpdate = true;
11325// }
11326 11536
11327 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11537 /*ubit from ll JIRA:
11538 * 0x01 position
11539 * 0x02 rotation
11540 * 0x04 scale
11541
11542 * 0x08 LINK_SET
11543 * 0x10 UNIFORM for scale
11544 */
11328 11545
11329 switch (block.Type) 11546 // translate to internal changes
11330 { 11547 // not all cases .. just the ones older code did
11331 case 1:
11332 Vector3 pos1 = new Vector3(block.Data, 0);
11333 11548
11334 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11549 switch (block.Type)
11335 if (handlerUpdatePrimSinglePosition != null) 11550 {
11336 { 11551 case 1: //change position sp
11337 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11552 udata.position = new Vector3(block.Data, 0);
11338 handlerUpdatePrimSinglePosition(localId, pos1, this);
11339 }
11340 break;
11341 11553
11342 case 2: 11554 udata.change = ObjectChangeType.primP;
11343 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11555 updatehandler(localId, udata, this);
11556 break;
11344 11557
11345 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11558 case 2: // rotation sp
11346 if (handlerUpdatePrimSingleRotation != null) 11559 udata.rotation = new Quaternion(block.Data, 0, true);
11347 {
11348 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11349 handlerUpdatePrimSingleRotation(localId, rot1, this);
11350 }
11351 break;
11352 11560
11353 case 3: 11561 udata.change = ObjectChangeType.primR;
11354 Vector3 rotPos = new Vector3(block.Data, 0); 11562 updatehandler(localId, udata, this);
11355 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11563 break;
11356 11564
11357 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11565 case 3: // position plus rotation
11358 if (handlerUpdatePrimSingleRotationPosition != null) 11566 udata.position = new Vector3(block.Data, 0);
11359 { 11567 udata.rotation = new Quaternion(block.Data, 12, true);
11360 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11361 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11362 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11363 }
11364 break;
11365 11568
11366 case 4: 11569 udata.change = ObjectChangeType.primPR;
11367 case 20: 11570 updatehandler(localId, udata, this);
11368 Vector3 scale4 = new Vector3(block.Data, 0); 11571 break;
11369 11572
11370 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11573 case 4: // scale sp
11371 if (handlerUpdatePrimScale != null) 11574 udata.scale = new Vector3(block.Data, 0);
11372 { 11575 udata.change = ObjectChangeType.primS;
11373 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11374 handlerUpdatePrimScale(localId, scale4, this);
11375 }
11376 break;
11377 11576
11378 case 5: 11577 updatehandler(localId, udata, this);
11379 Vector3 scale1 = new Vector3(block.Data, 12); 11578 break;
11380 Vector3 pos11 = new Vector3(block.Data, 0);
11381 11579
11382 handlerUpdatePrimScale = OnUpdatePrimScale; 11580 case 0x14: // uniform scale sp
11383 if (handlerUpdatePrimScale != null) 11581 udata.scale = new Vector3(block.Data, 0);
11384 {
11385 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11386 handlerUpdatePrimScale(localId, scale1, this);
11387 11582
11388 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11583 udata.change = ObjectChangeType.primUS;
11389 if (handlerUpdatePrimSinglePosition != null) 11584 updatehandler(localId, udata, this);
11390 { 11585 break;
11391 handlerUpdatePrimSinglePosition(localId, pos11, this);
11392 }
11393 }
11394 break;
11395 11586
11396 case 9: 11587 case 5: // scale and position sp
11397 Vector3 pos2 = new Vector3(block.Data, 0); 11588 udata.position = new Vector3(block.Data, 0);
11589 udata.scale = new Vector3(block.Data, 12);
11398 11590
11399 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11591 udata.change = ObjectChangeType.primPS;
11592 updatehandler(localId, udata, this);
11593 break;
11400 11594
11401 if (handlerUpdateVector != null) 11595 case 0x15: //uniform scale and position
11402 { 11596 udata.position = new Vector3(block.Data, 0);
11403 handlerUpdateVector(localId, pos2, this); 11597 udata.scale = new Vector3(block.Data, 12);
11404 }
11405 break;
11406 11598
11407 case 10: 11599 udata.change = ObjectChangeType.primPUS;
11408 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11600 updatehandler(localId, udata, this);
11601 break;
11409 11602
11410 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11603 // now group related (bit 4)
11411 if (handlerUpdatePrimRotation != null) 11604 case 9: //( 8 + 1 )group position
11412 { 11605 udata.position = new Vector3(block.Data, 0);
11413 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11414 handlerUpdatePrimRotation(localId, rot3, this);
11415 }
11416 break;
11417 11606
11418 case 11: 11607 udata.change = ObjectChangeType.groupP;
11419 Vector3 pos3 = new Vector3(block.Data, 0); 11608 updatehandler(localId, udata, this);
11420 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11609 break;
11421 11610
11422 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11611 case 0x0A: // (8 + 2) group rotation
11423 if (handlerUpdatePrimGroupRotation != null) 11612 udata.rotation = new Quaternion(block.Data, 0, true);
11424 {
11425 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11426 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11427 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11428 }
11429 break;
11430 case 12:
11431 case 28:
11432 Vector3 scale7 = new Vector3(block.Data, 0);
11433 11613
11434 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11614 udata.change = ObjectChangeType.groupR;
11435 if (handlerUpdatePrimGroupScale != null) 11615 updatehandler(localId, udata, this);
11436 { 11616 break;
11437 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11438 handlerUpdatePrimGroupScale(localId, scale7, this);
11439 }
11440 break;
11441 11617
11442 case 13: 11618 case 0x0B: //( 8 + 2 + 1) group rotation and position
11443 Vector3 scale2 = new Vector3(block.Data, 12); 11619 udata.position = new Vector3(block.Data, 0);
11444 Vector3 pos4 = new Vector3(block.Data, 0); 11620 udata.rotation = new Quaternion(block.Data, 12, true);
11445 11621
11446 handlerUpdatePrimScale = OnUpdatePrimScale; 11622 udata.change = ObjectChangeType.groupPR;
11447 if (handlerUpdatePrimScale != null) 11623 updatehandler(localId, udata, this);
11448 { 11624 break;
11449 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11450 handlerUpdatePrimScale(localId, scale2, this);
11451 11625
11452 // Change the position based on scale (for bug number 246) 11626 case 0x0C: // (8 + 4) group scale
11453 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11627 // only afects root prim and only sent by viewer editor object tab scaling
11454 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11628 // mouse edition only allows uniform scaling
11455 if (handlerUpdatePrimSinglePosition != null) 11629 // SL MAY CHANGE THIS in viewers
11456 {
11457 handlerUpdatePrimSinglePosition(localId, pos4, this);
11458 }
11459 }
11460 break;
11461 11630
11462 case 29: 11631 udata.scale = new Vector3(block.Data, 0);
11463 Vector3 scale5 = new Vector3(block.Data, 12);
11464 Vector3 pos5 = new Vector3(block.Data, 0);
11465 11632
11466 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11633 // udata.change = ObjectChangeType.groupS;
11467 if (handlerUpdatePrimGroupScale != null) 11634 udata.change = ObjectChangeType.primS; // to conform to current SL
11468 { 11635 updatehandler(localId, udata, this);
11469 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11470 part.StoreUndoState(true);
11471 part.IgnoreUndoUpdate = true;
11472 handlerUpdatePrimGroupScale(localId, scale5, this);
11473 handlerUpdateVector = OnUpdatePrimGroupPosition;
11474 11636
11475 if (handlerUpdateVector != null) 11637 break;
11476 {
11477 handlerUpdateVector(localId, pos5, this);
11478 }
11479 11638
11480 part.IgnoreUndoUpdate = false; 11639 case 0x0D: //(8 + 4 + 1) group scale and position
11481 } 11640 // exception as above
11482 11641
11483 break; 11642 udata.position = new Vector3(block.Data, 0);
11643 udata.scale = new Vector3(block.Data, 12);
11484 11644
11485 case 21: 11645 // udata.change = ObjectChangeType.groupPS;
11486 Vector3 scale6 = new Vector3(block.Data, 12); 11646 udata.change = ObjectChangeType.primPS; // to conform to current SL
11487 Vector3 pos6 = new Vector3(block.Data, 0); 11647 updatehandler(localId, udata, this);
11648 break;
11488 11649
11489 handlerUpdatePrimScale = OnUpdatePrimScale; 11650 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11490 if (handlerUpdatePrimScale != null) 11651 udata.scale = new Vector3(block.Data, 0);
11491 {
11492 part.StoreUndoState(false);
11493 part.IgnoreUndoUpdate = true;
11494 11652
11495 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11653 udata.change = ObjectChangeType.groupUS;
11496 handlerUpdatePrimScale(localId, scale6, this); 11654 updatehandler(localId, udata, this);
11497 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11655 break;
11498 if (handlerUpdatePrimSinglePosition != null)
11499 {
11500 handlerUpdatePrimSinglePosition(localId, pos6, this);
11501 }
11502 11656
11503 part.IgnoreUndoUpdate = false; 11657 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11504 } 11658 udata.position = new Vector3(block.Data, 0);
11505 break; 11659 udata.scale = new Vector3(block.Data, 12);
11506 11660
11507 default: 11661 udata.change = ObjectChangeType.groupPUS;
11508 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11662 updatehandler(localId, udata, this);
11509 break; 11663 break;
11664
11665 default:
11666 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11667 break;
11668 }
11510 } 11669 }
11511 11670
11512// for (int j = 0; j < parts.Length; j++)
11513// parts[j].IgnoreUndoUpdate = false;
11514 } 11671 }
11515 } 11672 }
11516 } 11673 }
11517
11518 return true; 11674 return true;
11519 } 11675 }
11520 11676
@@ -11970,7 +12126,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11970 12126
11971// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12127// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11972 12128
12129
12130 //Note, the bool returned from the below function is useless since it is always false.
11973 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12131 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12132
11974 } 12133 }
11975 12134
11976 /// <summary> 12135 /// <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,