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