aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1156
1 files changed, 691 insertions, 465 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 85d83f8..18602f7 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -98,6 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 public event AvatarPickerRequest OnAvatarPickerRequest; 98 public event AvatarPickerRequest OnAvatarPickerRequest;
99 public event StartAnim OnStartAnim; 99 public event StartAnim OnStartAnim;
100 public event StopAnim OnStopAnim; 100 public event StopAnim OnStopAnim;
101 public event ChangeAnim OnChangeAnim;
101 public event Action<IClientAPI> OnRequestAvatarsData; 102 public event Action<IClientAPI> OnRequestAvatarsData;
102 public event LinkObjects OnLinkObjects; 103 public event LinkObjects OnLinkObjects;
103 public event DelinkObjects OnDelinkObjects; 104 public event DelinkObjects OnDelinkObjects;
@@ -125,6 +126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 127 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 128 public event UpdatePrimTexture OnUpdatePrimTexture;
129 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 130 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 131 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 160 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 161 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 162 public event CopyInventoryItem OnCopyInventoryItem;
163 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 164 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 165 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 166 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +259,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 259 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 261 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 262 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 263 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 265 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 291 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 292 public event SendPostcard OnSendPostcard;
293 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 294 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 295 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 296 public event GodlikeMessage onGodlikeMessage;
@@ -325,6 +329,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 private Prioritizer m_prioritizer; 329 private Prioritizer m_prioritizer;
326 private bool m_disableFacelights = false; 330 private bool m_disableFacelights = false;
327 331
332 private const uint MaxTransferBytesPerPacket = 600;
333
334
328 /// <value> 335 /// <value>
329 /// List used in construction of data blocks for an object update packet. This is to stop us having to 336 /// List used in construction of data blocks for an object update packet. This is to stop us having to
330 /// continually recreate it. 337 /// continually recreate it.
@@ -336,14 +343,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 343 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 344 /// ownerless phantom.
338 /// 345 ///
339 /// All manipulation of this set has to occur under a lock 346 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 347 ///
341 /// </value> 348 /// </value>
342 protected HashSet<uint> m_killRecord; 349// protected HashSet<uint> m_killRecord;
343 350
344// protected HashSet<uint> m_attachmentsSent; 351// protected HashSet<uint> m_attachmentsSent;
345 352
346 private int m_moneyBalance; 353 private int m_moneyBalance;
354 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 355 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 356 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 357 private AgentUpdateArgs lastarg;
@@ -383,6 +391,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
383 get { return m_startpos; } 391 get { return m_startpos; }
384 set { m_startpos = value; } 392 set { m_startpos = value; }
385 } 393 }
394 public bool DeliverPackets
395 {
396 get { return m_deliverPackets; }
397 set {
398 m_deliverPackets = value;
399 m_udpClient.m_deliverPackets = value;
400 }
401 }
386 public UUID AgentId { get { return m_agentId; } } 402 public UUID AgentId { get { return m_agentId; } }
387 public ISceneAgent SceneAgent { get; set; } 403 public ISceneAgent SceneAgent { get; set; }
388 public UUID ActiveGroupId { get { return m_activeGroupID; } } 404 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -456,7 +472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
456 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 472 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
457 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 473 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
458 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 474 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
459 m_killRecord = new HashSet<uint>(); 475// m_killRecord = new HashSet<uint>();
460// m_attachmentsSent = new HashSet<uint>(); 476// m_attachmentsSent = new HashSet<uint>();
461 477
462 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 478 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -485,17 +501,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
485 501
486 #region Client Methods 502 #region Client Methods
487 503
504
488 /// <summary> 505 /// <summary>
489 /// Shut down the client view 506 /// Shut down the client view
490 /// </summary> 507 /// </summary>
491 public void Close() 508 public void Close()
492 { 509 {
510 Close(true);
511 }
512
513 /// <summary>
514 /// Shut down the client view
515 /// </summary>
516 public void Close(bool sendStop)
517 {
493 IsActive = false; 518 IsActive = false;
494 519
495 m_log.DebugFormat( 520 m_log.DebugFormat(
496 "[CLIENT]: Close has been called for {0} attached to scene {1}", 521 "[CLIENT]: Close has been called for {0} attached to scene {1}",
497 Name, m_scene.RegionInfo.RegionName); 522 Name, m_scene.RegionInfo.RegionName);
498 523
524 if (sendStop)
525 {
526 // Send the STOP packet
527 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
528 OutPacket(disable, ThrottleOutPacketType.Unknown);
529 }
530
531 IsActive = false;
532
499 // Shutdown the image manager 533 // Shutdown the image manager
500 ImageManager.Close(); 534 ImageManager.Close();
501 535
@@ -792,7 +826,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
792 reply.ChatData.OwnerID = fromAgentID; 826 reply.ChatData.OwnerID = fromAgentID;
793 reply.ChatData.SourceID = fromAgentID; 827 reply.ChatData.SourceID = fromAgentID;
794 828
795 OutPacket(reply, ThrottleOutPacketType.Task); 829 OutPacket(reply, ThrottleOutPacketType.Unknown);
796 } 830 }
797 831
798 /// <summary> 832 /// <summary>
@@ -1078,6 +1112,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1078 public virtual void SendLayerData(float[] map) 1112 public virtual void SendLayerData(float[] map)
1079 { 1113 {
1080 Util.FireAndForget(DoSendLayerData, map); 1114 Util.FireAndForget(DoSendLayerData, map);
1115
1116 // Send it sync, and async. It's not that much data
1117 // and it improves user experience just so much!
1118 DoSendLayerData(map);
1081 } 1119 }
1082 1120
1083 /// <summary> 1121 /// <summary>
@@ -1090,16 +1128,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1090 1128
1091 try 1129 try
1092 { 1130 {
1093 //for (int y = 0; y < 16; y++) 1131 for (int y = 0; y < 16; y++)
1094 //{ 1132 {
1095 // for (int x = 0; x < 16; x++) 1133 for (int x = 0; x < 16; x+=4)
1096 // { 1134 {
1097 // SendLayerData(x, y, map); 1135 SendLayerPacket(x, y, map);
1098 // } 1136 }
1099 //} 1137 }
1100
1101 // Send LayerData in a spiral pattern. Fun!
1102 SendLayerTopRight(map, 0, 0, 15, 15);
1103 } 1138 }
1104 catch (Exception e) 1139 catch (Exception e)
1105 { 1140 {
@@ -1107,51 +1142,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1107 } 1142 }
1108 } 1143 }
1109 1144
1110 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1111 {
1112 // Row
1113 for (int i = x1; i <= x2; i++)
1114 SendLayerData(i, y1, map);
1115
1116 // Column
1117 for (int j = y1 + 1; j <= y2; j++)
1118 SendLayerData(x2, j, map);
1119
1120 if (x2 - x1 > 0)
1121 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1122 }
1123
1124 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1125 {
1126 // Row in reverse
1127 for (int i = x2; i >= x1; i--)
1128 SendLayerData(i, y2, map);
1129
1130 // Column in reverse
1131 for (int j = y2 - 1; j >= y1; j--)
1132 SendLayerData(x1, j, map);
1133
1134 if (x2 - x1 > 0)
1135 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1136 }
1137
1138 /// <summary> 1145 /// <summary>
1139 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1146 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1140 /// </summary> 1147 /// </summary>
1141 /// <param name="map">heightmap</param> 1148 /// <param name="map">heightmap</param>
1142 /// <param name="px">X coordinate for patches 0..12</param> 1149 /// <param name="px">X coordinate for patches 0..12</param>
1143 /// <param name="py">Y coordinate for patches 0..15</param> 1150 /// <param name="py">Y coordinate for patches 0..15</param>
1144 // private void SendLayerPacket(float[] map, int y, int x) 1151 private void SendLayerPacket(int x, int y, float[] map)
1145 // { 1152 {
1146 // int[] patches = new int[4]; 1153 int[] patches = new int[4];
1147 // patches[0] = x + 0 + y * 16; 1154 patches[0] = x + 0 + y * 16;
1148 // patches[1] = x + 1 + y * 16; 1155 patches[1] = x + 1 + y * 16;
1149 // patches[2] = x + 2 + y * 16; 1156 patches[2] = x + 2 + y * 16;
1150 // patches[3] = x + 3 + y * 16; 1157 patches[3] = x + 3 + y * 16;
1151 1158
1152 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1159 float[] heightmap = (map.Length == 65536) ?
1153 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1160 map :
1154 // } 1161 LLHeightFieldMoronize(map);
1162
1163 try
1164 {
1165 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1166 OutPacket(layerpack, ThrottleOutPacketType.Land);
1167 }
1168 catch
1169 {
1170 for (int px = x ; px < x + 4 ; px++)
1171 SendLayerData(px, y, map);
1172 }
1173 }
1155 1174
1156 /// <summary> 1175 /// <summary>
1157 /// Sends a specified patch to a client 1176 /// Sends a specified patch to a client
@@ -1171,7 +1190,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1171 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1190 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1172 layerpack.Header.Reliable = true; 1191 layerpack.Header.Reliable = true;
1173 1192
1174 OutPacket(layerpack, ThrottleOutPacketType.Land); 1193 OutPacket(layerpack, ThrottleOutPacketType.Task);
1175 } 1194 }
1176 catch (Exception e) 1195 catch (Exception e)
1177 { 1196 {
@@ -1534,7 +1553,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1534 1553
1535 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1554 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1536 { 1555 {
1537// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1556// foreach (uint id in localIDs)
1557// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1538 1558
1539 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1559 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1540 // TODO: don't create new blocks if recycling an old packet 1560 // TODO: don't create new blocks if recycling an old packet
@@ -1556,17 +1576,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1556 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1576 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1557 // condition where a kill can be processed before an out-of-date update for the same object. 1577 // condition where a kill can be processed before an out-of-date update for the same object.
1558 // ProcessEntityUpdates() also takes the m_killRecord lock. 1578 // ProcessEntityUpdates() also takes the m_killRecord lock.
1559 lock (m_killRecord) 1579// lock (m_killRecord)
1560 { 1580// {
1561 foreach (uint localID in localIDs) 1581// foreach (uint localID in localIDs)
1562 m_killRecord.Add(localID); 1582// m_killRecord.Add(localID);
1563 1583
1564 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1584 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1565 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1585 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1566 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1586 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1567 // scene objects in a viewer until that viewer is relogged in. 1587 // scene objects in a viewer until that viewer is relogged in.
1568 OutPacket(kill, ThrottleOutPacketType.Task); 1588 OutPacket(kill, ThrottleOutPacketType.Task);
1569 } 1589// }
1570 } 1590 }
1571 } 1591 }
1572 1592
@@ -2296,6 +2316,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2296 OutPacket(sound, ThrottleOutPacketType.Task); 2316 OutPacket(sound, ThrottleOutPacketType.Task);
2297 } 2317 }
2298 2318
2319 public void SendTransferAbort(TransferRequestPacket transferRequest)
2320 {
2321 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2322 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2323 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2324 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2325 OutPacket(abort, ThrottleOutPacketType.Task);
2326 }
2327
2299 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2328 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2300 { 2329 {
2301 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2330 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2588,6 +2617,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2588 } 2617 }
2589 } 2618 }
2590 2619
2620 public void SendPartPhysicsProprieties(ISceneEntity entity)
2621 {
2622 SceneObjectPart part = (SceneObjectPart)entity;
2623 if (part != null && AgentId != UUID.Zero)
2624 {
2625 try
2626 {
2627 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2628 if (eq != null)
2629 {
2630 uint localid = part.LocalId;
2631 byte physshapetype = part.PhysicsShapeType;
2632 float density = part.Density;
2633 float friction = part.Friction;
2634 float bounce = part.Bounciness;
2635 float gravmod = part.GravityModifier;
2636
2637 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2638 }
2639 }
2640 catch (Exception ex)
2641 {
2642 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2643 }
2644 part.UpdatePhysRequired = false;
2645 }
2646 }
2647
2648
2591 2649
2592 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2650 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2593 { 2651 {
@@ -2685,7 +2743,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2685 else 2743 else
2686 { 2744 {
2687 int processedLength = 0; 2745 int processedLength = 0;
2688 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2746// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2747
2748 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2689 int packetNumber = 0; 2749 int packetNumber = 0;
2690 2750
2691 while (processedLength < req.AssetInf.Data.Length) 2751 while (processedLength < req.AssetInf.Data.Length)
@@ -2719,6 +2779,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2719 } 2779 }
2720 } 2780 }
2721 2781
2782 public void SendAssetNotFound(AssetRequestToClient req)
2783 {
2784 TransferInfoPacket Transfer = new TransferInfoPacket();
2785 Transfer.TransferInfo.ChannelType = 2;
2786 Transfer.TransferInfo.Status = -2;
2787 Transfer.TransferInfo.TargetType = 0;
2788 Transfer.TransferInfo.Params = req.Params;
2789 Transfer.TransferInfo.Size = 0;
2790 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2791 Transfer.Header.Zerocoded = true;
2792 OutPacket(Transfer, ThrottleOutPacketType.Asset);
2793 }
2794
2722 public void SendTexture(AssetBase TextureAsset) 2795 public void SendTexture(AssetBase TextureAsset)
2723 { 2796 {
2724 2797
@@ -2743,7 +2816,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2743 reply.Data.ParcelID = parcelID; 2816 reply.Data.ParcelID = parcelID;
2744 reply.Data.OwnerID = land.OwnerID; 2817 reply.Data.OwnerID = land.OwnerID;
2745 reply.Data.Name = Utils.StringToBytes(land.Name); 2818 reply.Data.Name = Utils.StringToBytes(land.Name);
2746 reply.Data.Desc = Utils.StringToBytes(land.Description); 2819 if (land != null && land.Description != null && land.Description != String.Empty)
2820 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2821 else
2822 reply.Data.Desc = new Byte[0];
2747 reply.Data.ActualArea = land.Area; 2823 reply.Data.ActualArea = land.Area;
2748 reply.Data.BillableArea = land.Area; // TODO: what is this? 2824 reply.Data.BillableArea = land.Area; // TODO: what is this?
2749 2825
@@ -3478,7 +3554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3478 3554
3479 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3555 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3480 // TODO: don't create new blocks if recycling an old packet 3556 // TODO: don't create new blocks if recycling an old packet
3481 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3557 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3482 avp.ObjectData.TextureEntry = textureEntry; 3558 avp.ObjectData.TextureEntry = textureEntry;
3483 3559
3484 AvatarAppearancePacket.VisualParamBlock avblock = null; 3560 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3606,7 +3682,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3606 /// </summary> 3682 /// </summary>
3607 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3683 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3608 { 3684 {
3609 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3685 if (entity is SceneObjectPart)
3686 {
3687 SceneObjectPart e = (SceneObjectPart)entity;
3688 SceneObjectGroup g = e.ParentGroup;
3689 if (g.RootPart.Shape.State > 30) // HUD
3690 if (g.OwnerID != AgentId)
3691 return; // Don't send updates for other people's HUDs
3692 }
3693
3610 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3694 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3611 3695
3612 lock (m_entityUpdates.SyncRoot) 3696 lock (m_entityUpdates.SyncRoot)
@@ -3673,27 +3757,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3673 3757
3674 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3758 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3675 // condition where a kill can be processed before an out-of-date update for the same object. 3759 // condition where a kill can be processed before an out-of-date update for the same object.
3676 lock (m_killRecord) 3760 float avgTimeDilation = 1.0f;
3761 IEntityUpdate iupdate;
3762 Int32 timeinqueue; // this is just debugging code & can be dropped later
3763
3764 while (updatesThisCall < maxUpdates)
3677 { 3765 {
3678 float avgTimeDilation = 1.0f; 3766 lock (m_entityUpdates.SyncRoot)
3679 IEntityUpdate iupdate; 3767 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3680 Int32 timeinqueue; // this is just debugging code & can be dropped later 3768 break;
3681 3769
3682 while (updatesThisCall < maxUpdates) 3770 EntityUpdate update = (EntityUpdate)iupdate;
3771
3772 avgTimeDilation += update.TimeDilation;
3773 avgTimeDilation *= 0.5f;
3774
3775 if (update.Entity is SceneObjectPart)
3683 { 3776 {
3684 lock (m_entityUpdates.SyncRoot) 3777 SceneObjectPart part = (SceneObjectPart)update.Entity;
3685 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3686 break;
3687 3778
3688 EntityUpdate update = (EntityUpdate)iupdate; 3779 if (part.ParentGroup.IsDeleted)
3689 3780 continue;
3690 avgTimeDilation += update.TimeDilation;
3691 avgTimeDilation *= 0.5f;
3692 3781
3693 if (update.Entity is SceneObjectPart) 3782 if (part.ParentGroup.IsAttachment)
3783 { // Someone else's HUD, why are we getting these?
3784 if (part.ParentGroup.OwnerID != AgentId &&
3785 part.ParentGroup.RootPart.Shape.State >= 30)
3786 continue;
3787 ScenePresence sp;
3788 // Owner is not in the sim, don't update it to
3789 // anyone
3790 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3791 continue;
3792
3793 List<SceneObjectGroup> atts = sp.GetAttachments();
3794 bool found = false;
3795 foreach (SceneObjectGroup att in atts)
3796 {
3797 if (att == part.ParentGroup)
3798 {
3799 found = true;
3800 break;
3801 }
3802 }
3803
3804 // It's an attachment of a valid avatar, but
3805 // doesn't seem to be attached, skip
3806 if (!found)
3807 continue;
3808
3809 // On vehicle crossing, the attachments are received
3810 // while the avatar is still a child. Don't send
3811 // updates here because the LocalId has not yet
3812 // been updated and the viewer will derender the
3813 // attachments until the avatar becomes root.
3814 if (sp.IsChildAgent)
3815 continue;
3816
3817 // If the object is an attachment we don't want it to be in the kill
3818 // record. Else attaching from inworld and subsequently dropping
3819 // it will no longer work.
3820// lock (m_killRecord)
3821// {
3822// m_killRecord.Remove(part.LocalId);
3823// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3824// }
3825 }
3826 else
3694 { 3827 {
3695 SceneObjectPart part = (SceneObjectPart)update.Entity;
3696
3697 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3828 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3698 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3829 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3699 // safety measure. 3830 // safety measure.
@@ -3704,182 +3835,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3704 // 3835 //
3705 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3836 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3706 // after the root prim has been deleted. 3837 // after the root prim has been deleted.
3707 if (m_killRecord.Contains(part.LocalId)) 3838 //
3708 { 3839 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3709 // m_log.WarnFormat( 3840// lock (m_killRecord)
3710 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3841// {
3711 // part.LocalId, Name); 3842// if (m_killRecord.Contains(part.LocalId))
3712 continue; 3843// continue;
3713 } 3844// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3714 3845// continue;
3715 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3846// }
3847 }
3848
3849 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3850 {
3851 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3852 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3716 { 3853 {
3717 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3854 part.Shape.LightEntry = false;
3718 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3719 {
3720 part.Shape.LightEntry = false;
3721 }
3722 } 3855 }
3723 } 3856 }
3724 3857 }
3725 ++updatesThisCall; 3858
3726 3859 ++updatesThisCall;
3727 #region UpdateFlags to packet type conversion 3860
3728 3861 #region UpdateFlags to packet type conversion
3729 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3862
3730 3863 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3731 bool canUseCompressed = true; 3864
3732 bool canUseImproved = true; 3865 bool canUseCompressed = true;
3733 3866 bool canUseImproved = true;
3734 // Compressed object updates only make sense for LL primitives 3867
3735 if (!(update.Entity is SceneObjectPart)) 3868 // Compressed object updates only make sense for LL primitives
3869 if (!(update.Entity is SceneObjectPart))
3870 {
3871 canUseCompressed = false;
3872 }
3873
3874 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3875 {
3876 canUseCompressed = false;
3877 canUseImproved = false;
3878 }
3879 else
3880 {
3881 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3882 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3883 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3884 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3736 { 3885 {
3737 canUseCompressed = false; 3886 canUseCompressed = false;
3738 } 3887 }
3739 3888
3740 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3889 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3890 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3891 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3892 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3893 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3894 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3895 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3896 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3897 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3898 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3899 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3900 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3901 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3902 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3741 { 3903 {
3742 canUseCompressed = false;
3743 canUseImproved = false; 3904 canUseImproved = false;
3744 } 3905 }
3745 else 3906 }
3746 {
3747 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3748 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3749 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3750 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3751 {
3752 canUseCompressed = false;
3753 }
3754
3755 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3769 {
3770 canUseImproved = false;
3771 }
3772 }
3773
3774 #endregion UpdateFlags to packet type conversion
3775
3776 #region Block Construction
3777
3778 // TODO: Remove this once we can build compressed updates
3779 canUseCompressed = false;
3780 3907
3781 if (!canUseImproved && !canUseCompressed) 3908 #endregion UpdateFlags to packet type conversion
3782 {
3783 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3784 3909
3785 if (update.Entity is ScenePresence) 3910 #region Block Construction
3786 {
3787 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3788 }
3789 else
3790 {
3791 updateBlock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, AgentId);
3792 }
3793 3911
3794 objectUpdateBlocks.Value.Add(updateBlock); 3912 // TODO: Remove this once we can build compressed updates
3795 objectUpdates.Value.Add(update); 3913 canUseCompressed = false;
3796 } 3914
3797 else if (!canUseImproved) 3915 if (!canUseImproved && !canUseCompressed)
3916 {
3917 if (update.Entity is ScenePresence)
3798 { 3918 {
3799 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3919 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3800 compressedUpdates.Value.Add(update);
3801 } 3920 }
3802 else 3921 else
3803 { 3922 {
3804 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3923 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
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 } 3924 }
3817
3818 #endregion Block Construction
3819 } 3925 }
3926 else if (!canUseImproved)
3927 {
3928 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3929 }
3930 else
3931 {
3932 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3933 // Self updates go into a special list
3934 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3935 else
3936 // Everything else goes here
3937 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3938 }
3939
3940 #endregion Block Construction
3941 }
3942
3943 #region Packet Sending
3944
3945 const float TIME_DILATION = 1.0f;
3946 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3820 3947
3821 #region Packet Sending 3948 if (terseAgentUpdateBlocks.IsValueCreated)
3822 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3949 {
3950 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3823 3951
3824 if (terseAgentUpdateBlocks.IsValueCreated) 3952 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3825 { 3953 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3826 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3954 packet.RegionData.TimeDilation = timeDilation;
3955 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3827 3956
3828 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3957 for (int i = 0; i < blocks.Count; i++)
3829 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3958 packet.ObjectData[i] = blocks[i];
3830 packet.RegionData.TimeDilation = timeDilation;
3831 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3832 3959
3833 for (int i = 0; i < blocks.Count; i++) 3960 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3834 packet.ObjectData[i] = blocks[i]; 3961 }
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 3962
3839 if (objectUpdateBlocks.IsValueCreated) 3963 if (objectUpdateBlocks.IsValueCreated)
3840 { 3964 {
3841 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3965 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3842 3966
3843 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3967 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3844 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3968 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3845 packet.RegionData.TimeDilation = timeDilation; 3969 packet.RegionData.TimeDilation = timeDilation;
3846 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3970 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3847 3971
3848 for (int i = 0; i < blocks.Count; i++) 3972 for (int i = 0; i < blocks.Count; i++)
3849 packet.ObjectData[i] = blocks[i]; 3973 packet.ObjectData[i] = blocks[i];
3850 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 3974
3851 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 3975 OutPacket(packet, ThrottleOutPacketType.Task, true);
3852 } 3976 }
3853 3977
3854 if (compressedUpdateBlocks.IsValueCreated) 3978 if (compressedUpdateBlocks.IsValueCreated)
3855 { 3979 {
3856 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3980 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3857 3981
3858 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 3982 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3859 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3983 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3860 packet.RegionData.TimeDilation = timeDilation; 3984 packet.RegionData.TimeDilation = timeDilation;
3861 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 3985 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 }
3868 3986
3869 if (terseUpdateBlocks.IsValueCreated) 3987 for (int i = 0; i < blocks.Count; i++)
3870 { 3988 packet.ObjectData[i] = blocks[i];
3871 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3989
3872 3990 OutPacket(packet, ThrottleOutPacketType.Task, true);
3873 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3991 }
3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3992
3875 packet.RegionData.TimeDilation = timeDilation; 3993 if (terseUpdateBlocks.IsValueCreated)
3876 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3994 {
3877 3995 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3878 for (int i = 0; i < blocks.Count; i++) 3996
3879 packet.ObjectData[i] = blocks[i]; 3997 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3880 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 3998 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3881 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 3999 packet.RegionData.TimeDilation = timeDilation;
3882 } 4000 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4001
4002 for (int i = 0; i < blocks.Count; i++)
4003 packet.ObjectData[i] = blocks[i];
4004
4005 OutPacket(packet, ThrottleOutPacketType.Task, true);
3883 } 4006 }
3884 4007
3885 #endregion Packet Sending 4008 #endregion Packet Sending
@@ -4172,11 +4295,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4172 4295
4173 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4296 // 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 4297 // of the object rather than the properties when the packet was created
4175 OutPacket(packet, ThrottleOutPacketType.Task, true, 4298 // HACK : Remove intelligent resending until it's fixed in core
4176 delegate(OutgoingPacket oPacket) 4299 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4177 { 4300 // delegate(OutgoingPacket oPacket)
4178 ResendPropertyUpdates(updates, oPacket); 4301 // {
4179 }); 4302 // ResendPropertyUpdates(updates, oPacket);
4303 // });
4304 OutPacket(packet, ThrottleOutPacketType.Task, true);
4180 4305
4181 // pbcnt += blocks.Count; 4306 // pbcnt += blocks.Count;
4182 // ppcnt++; 4307 // ppcnt++;
@@ -4202,11 +4327,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4202 // of the object rather than the properties when the packet was created 4327 // of the object rather than the properties when the packet was created
4203 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4328 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4204 updates.Add(familyUpdates.Value[i]); 4329 updates.Add(familyUpdates.Value[i]);
4205 OutPacket(packet, ThrottleOutPacketType.Task, true, 4330 // HACK : Remove intelligent resending until it's fixed in core
4206 delegate(OutgoingPacket oPacket) 4331 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4207 { 4332 // delegate(OutgoingPacket oPacket)
4208 ResendPropertyUpdates(updates, oPacket); 4333 // {
4209 }); 4334 // ResendPropertyUpdates(updates, oPacket);
4335 // });
4336 OutPacket(packet, ThrottleOutPacketType.Task, true);
4210 4337
4211 // fpcnt++; 4338 // fpcnt++;
4212 // fbcnt++; 4339 // fbcnt++;
@@ -4355,37 +4482,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4355 if (bl[i].BannedUserID == UUID.Zero) 4482 if (bl[i].BannedUserID == UUID.Zero)
4356 continue; 4483 continue;
4357 BannedUsers.Add(bl[i].BannedUserID); 4484 BannedUsers.Add(bl[i].BannedUserID);
4358 }
4359 4485
4360 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4486 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4361 packet.AgentData.TransactionID = UUID.Random(); 4487 {
4362 packet.AgentData.AgentID = AgentId; 4488 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4363 packet.AgentData.SessionID = SessionId; 4489 packet.AgentData.TransactionID = UUID.Random();
4364 packet.MethodData.Invoice = invoice; 4490 packet.AgentData.AgentID = AgentId;
4365 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4491 packet.AgentData.SessionID = SessionId;
4492 packet.MethodData.Invoice = invoice;
4493 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4366 4494
4367 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4495 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4368 4496
4369 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4497 int j;
4370 { 4498 for (j = 0; j < (6 + BannedUsers.Count); j++)
4371 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4499 {
4372 } 4500 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4373 int j = 0; 4501 }
4502 j = 0;
4374 4503
4375 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4504 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4505 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4506 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4507 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4508 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4509 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 4510
4382 foreach (UUID banned in BannedUsers) 4511 foreach (UUID banned in BannedUsers)
4383 { 4512 {
4384 returnblock[j].Parameter = banned.GetBytes(); j++; 4513 returnblock[j].Parameter = banned.GetBytes(); j++;
4514 }
4515 packet.ParamList = returnblock;
4516 packet.Header.Reliable = true;
4517 OutPacket(packet, ThrottleOutPacketType.Task);
4518
4519 BannedUsers.Clear();
4520 }
4385 } 4521 }
4386 packet.ParamList = returnblock; 4522
4387 packet.Header.Reliable = false;
4388 OutPacket(packet, ThrottleOutPacketType.Task);
4389 } 4523 }
4390 4524
4391 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4525 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4571,7 +4705,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4571 4705
4572 if (landData.SimwideArea > 0) 4706 if (landData.SimwideArea > 0)
4573 { 4707 {
4574 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4708 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4709 // Never report more than sim total capacity
4710 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4711 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4575 updateMessage.SimWideMaxPrims = simulatorCapacity; 4712 updateMessage.SimWideMaxPrims = simulatorCapacity;
4576 } 4713 }
4577 else 4714 else
@@ -4700,14 +4837,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4700 4837
4701 if (notifyCount > 0) 4838 if (notifyCount > 0)
4702 { 4839 {
4703 if (notifyCount > 32) 4840// if (notifyCount > 32)
4704 { 4841// {
4705 m_log.InfoFormat( 4842// m_log.InfoFormat(
4706 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4843// "[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); 4844// + " - a developer might want to investigate whether this is a hard limit", 32);
4708 4845//
4709 notifyCount = 32; 4846// notifyCount = 32;
4710 } 4847// }
4711 4848
4712 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4849 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4713 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4850 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4762,9 +4899,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4762 { 4899 {
4763 ScenePresence presence = (ScenePresence)entity; 4900 ScenePresence presence = (ScenePresence)entity;
4764 4901
4902 position = presence.OffsetPosition;
4903 rotation = presence.Rotation;
4904
4905 if (presence.ParentID != 0)
4906 {
4907 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4908 if (part != null && part != part.ParentGroup.RootPart)
4909 {
4910 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4911 rotation = part.RotationOffset * presence.Rotation;
4912 }
4913 }
4914
4765 attachPoint = 0; 4915 attachPoint = 0;
4766 collisionPlane = presence.CollisionPlane; 4916 collisionPlane = presence.CollisionPlane;
4767 position = presence.OffsetPosition;
4768 velocity = presence.Velocity; 4917 velocity = presence.Velocity;
4769 acceleration = Vector3.Zero; 4918 acceleration = Vector3.Zero;
4770 4919
@@ -4774,7 +4923,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4774// acceleration = new Vector3(1, 0, 0); 4923// acceleration = new Vector3(1, 0, 0);
4775 4924
4776 angularVelocity = Vector3.Zero; 4925 angularVelocity = Vector3.Zero;
4777 rotation = presence.Rotation;
4778 4926
4779 if (sendTexture) 4927 if (sendTexture)
4780 textureEntry = presence.Appearance.Texture.GetBytes(); 4928 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4879,13 +5027,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4879 5027
4880 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5028 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4881 { 5029 {
5030 Vector3 offsetPosition = data.OffsetPosition;
5031 Quaternion rotation = data.Rotation;
5032 uint parentID = data.ParentID;
5033
5034 if (parentID != 0)
5035 {
5036 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5037 if (part != null && part != part.ParentGroup.RootPart)
5038 {
5039 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5040 rotation = part.RotationOffset * data.Rotation;
5041 parentID = part.ParentGroup.RootPart.LocalId;
5042 }
5043 }
5044
4882 byte[] objectData = new byte[76]; 5045 byte[] objectData = new byte[76];
4883 5046
4884 data.CollisionPlane.ToBytes(objectData, 0); 5047 data.CollisionPlane.ToBytes(objectData, 0);
4885 data.OffsetPosition.ToBytes(objectData, 16); 5048 offsetPosition.ToBytes(objectData, 16);
4886// data.Velocity.ToBytes(objectData, 28); 5049// data.Velocity.ToBytes(objectData, 28);
4887// data.Acceleration.ToBytes(objectData, 40); 5050// data.Acceleration.ToBytes(objectData, 40);
4888 data.Rotation.ToBytes(objectData, 52); 5051 rotation.ToBytes(objectData, 52);
4889 //data.AngularVelocity.ToBytes(objectData, 64); 5052 //data.AngularVelocity.ToBytes(objectData, 64);
4890 5053
4891 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5054 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4899,7 +5062,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4899 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5062 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4900 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5063 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4901 update.ObjectData = objectData; 5064 update.ObjectData = objectData;
4902 update.ParentID = data.ParentID; 5065 update.ParentID = parentID;
4903 update.PathCurve = 16; 5066 update.PathCurve = 16;
4904 update.PathScaleX = 100; 5067 update.PathScaleX = 100;
4905 update.PathScaleY = 100; 5068 update.PathScaleY = 100;
@@ -5240,6 +5403,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5240 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5403 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5241 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5404 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5242 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5405 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5406 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5243 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5407 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5244 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5408 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5245 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5409 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5306,6 +5470,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5306 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5470 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5307 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5471 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5308 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5472 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5473 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5309 5474
5310 AddGenericPacketHandler("autopilot", HandleAutopilot); 5475 AddGenericPacketHandler("autopilot", HandleAutopilot);
5311 } 5476 }
@@ -5341,6 +5506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5341 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5506 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5342 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5507 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5343 (x.ControlFlags != lastarg.ControlFlags) || 5508 (x.ControlFlags != lastarg.ControlFlags) ||
5509 (x.ControlFlags != 0) ||
5344 (x.Far != lastarg.Far) || 5510 (x.Far != lastarg.Far) ||
5345 (x.Flags != lastarg.Flags) || 5511 (x.Flags != lastarg.Flags) ||
5346 (x.State != lastarg.State) || 5512 (x.State != lastarg.State) ||
@@ -5718,7 +5884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5718 args.Channel = ch; 5884 args.Channel = ch;
5719 args.From = String.Empty; 5885 args.From = String.Empty;
5720 args.Message = Utils.BytesToString(msg); 5886 args.Message = Utils.BytesToString(msg);
5721 args.Type = ChatTypeEnum.Shout; 5887 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5722 args.Position = new Vector3(); 5888 args.Position = new Vector3();
5723 args.Scene = Scene; 5889 args.Scene = Scene;
5724 args.Sender = this; 5890 args.Sender = this;
@@ -6255,7 +6421,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6255 return true; 6421 return true;
6256 } 6422 }
6257 #endregion 6423 #endregion
6258 6424/*
6259 StartAnim handlerStartAnim = null; 6425 StartAnim handlerStartAnim = null;
6260 StopAnim handlerStopAnim = null; 6426 StopAnim handlerStopAnim = null;
6261 6427
@@ -6279,6 +6445,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6279 } 6445 }
6280 } 6446 }
6281 return true; 6447 return true;
6448*/
6449 ChangeAnim handlerChangeAnim = null;
6450
6451 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6452 {
6453 handlerChangeAnim = OnChangeAnim;
6454 if (handlerChangeAnim != null)
6455 {
6456 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6457 }
6458 }
6459
6460 handlerChangeAnim = OnChangeAnim;
6461 if (handlerChangeAnim != null)
6462 {
6463 handlerChangeAnim(UUID.Zero, false, true);
6464 }
6465
6466 return true;
6282 } 6467 }
6283 6468
6284 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6469 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6904,10 +7089,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6904 // 46,47,48 are special positions within the packet 7089 // 46,47,48 are special positions within the packet
6905 // This may change so perhaps we need a better way 7090 // This may change so perhaps we need a better way
6906 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7091 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6907 bool UsePhysics = (data[46] != 0) ? true : false; 7092 /*
6908 bool IsTemporary = (data[47] != 0) ? true : false; 7093 bool UsePhysics = (data[46] != 0) ? true : false;
6909 bool IsPhantom = (data[48] != 0) ? true : false; 7094 bool IsTemporary = (data[47] != 0) ? true : false;
6910 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7095 bool IsPhantom = (data[48] != 0) ? true : false;
7096 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7097 */
7098 bool UsePhysics = flags.AgentData.UsePhysics;
7099 bool IsPhantom = flags.AgentData.IsPhantom;
7100 bool IsTemporary = flags.AgentData.IsTemporary;
7101 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7102 ExtraPhysicsData physdata = new ExtraPhysicsData();
7103
7104 if (blocks == null || blocks.Length == 0)
7105 {
7106 physdata.PhysShapeType = PhysShapeType.invalid;
7107 }
7108 else
7109 {
7110 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7111 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7112 physdata.Bounce = phsblock.Restitution;
7113 physdata.Density = phsblock.Density;
7114 physdata.Friction = phsblock.Friction;
7115 physdata.GravitationModifier = phsblock.GravityMultiplier;
7116 }
7117
7118 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6911 } 7119 }
6912 return true; 7120 return true;
6913 } 7121 }
@@ -9761,7 +9969,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9761 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9969 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9762 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9970 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9763 UpdateMuteListEntry.MuteData.MuteType, 9971 UpdateMuteListEntry.MuteData.MuteType,
9764 UpdateMuteListEntry.AgentData.AgentID); 9972 UpdateMuteListEntry.MuteData.MuteFlags);
9765 return true; 9973 return true;
9766 } 9974 }
9767 return false; 9975 return false;
@@ -9776,8 +9984,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9776 { 9984 {
9777 handlerRemoveMuteListEntry(this, 9985 handlerRemoveMuteListEntry(this,
9778 RemoveMuteListEntry.MuteData.MuteID, 9986 RemoveMuteListEntry.MuteData.MuteID,
9779 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9987 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9780 RemoveMuteListEntry.AgentData.AgentID);
9781 return true; 9988 return true;
9782 } 9989 }
9783 return false; 9990 return false;
@@ -9821,10 +10028,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9821 return false; 10028 return false;
9822 } 10029 }
9823 10030
10031 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10032 {
10033 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10034 (ChangeInventoryItemFlagsPacket)packet;
10035 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10036 if (handlerChangeInventoryItemFlags != null)
10037 {
10038 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10039 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10040 return true;
10041 }
10042 return false;
10043 }
10044
9824 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10045 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9825 { 10046 {
9826 return true; 10047 return true;
9827 } 10048 }
10049
10050 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10051 {
10052 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10053
10054 #region Packet Session and User Check
10055 if (m_checkPackets)
10056 {
10057 if (packet.AgentData.SessionID != SessionId ||
10058 packet.AgentData.AgentID != AgentId)
10059 return true;
10060 }
10061 #endregion
10062 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10063 List<InventoryItemBase> items = new List<InventoryItemBase>();
10064 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10065 {
10066 InventoryItemBase b = new InventoryItemBase();
10067 b.ID = n.OldItemID;
10068 b.Folder = n.OldFolderID;
10069 items.Add(b);
10070 }
10071
10072 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10073 if (handlerMoveItemsAndLeaveCopy != null)
10074 {
10075 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10076 }
10077
10078 return true;
10079 }
9828 10080
9829 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10081 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9830 { 10082 {
@@ -10251,6 +10503,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10251 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10503 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10252 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10504 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10253 10505
10506 Scene scene = (Scene)m_scene;
10507 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10508 {
10509 ScenePresence p;
10510 if (scene.TryGetScenePresence(sender.AgentId, out p))
10511 {
10512 if (p.GodLevel >= 200)
10513 {
10514 groupProfileReply.GroupData.OpenEnrollment = true;
10515 groupProfileReply.GroupData.MembershipFee = 0;
10516 }
10517 }
10518 }
10519
10254 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10520 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10255 } 10521 }
10256 return true; 10522 return true;
@@ -10824,11 +11090,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10824 11090
10825 StartLure handlerStartLure = OnStartLure; 11091 StartLure handlerStartLure = OnStartLure;
10826 if (handlerStartLure != null) 11092 if (handlerStartLure != null)
10827 handlerStartLure(startLureRequest.Info.LureType, 11093 {
10828 Utils.BytesToString( 11094 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10829 startLureRequest.Info.Message), 11095 {
10830 startLureRequest.TargetData[0].TargetID, 11096 handlerStartLure(startLureRequest.Info.LureType,
10831 this); 11097 Utils.BytesToString(
11098 startLureRequest.Info.Message),
11099 startLureRequest.TargetData[i].TargetID,
11100 this);
11101 }
11102 }
10832 return true; 11103 return true;
10833 } 11104 }
10834 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11105 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10942,10 +11213,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10942 } 11213 }
10943 #endregion 11214 #endregion
10944 11215
10945 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11216 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10946 if (handlerClassifiedGodDelete != null) 11217 if (handlerClassifiedGodDelete != null)
10947 handlerClassifiedGodDelete( 11218 handlerClassifiedGodDelete(
10948 classifiedGodDelete.Data.ClassifiedID, 11219 classifiedGodDelete.Data.ClassifiedID,
11220 classifiedGodDelete.Data.QueryID,
10949 this); 11221 this);
10950 return true; 11222 return true;
10951 } 11223 }
@@ -11311,209 +11583,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11311 } 11583 }
11312 else 11584 else
11313 { 11585 {
11314// m_log.DebugFormat( 11586 ClientChangeObject updatehandler = onClientChangeObject;
11315// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11316// i, block.Type, part.Name, part.LocalId);
11317 11587
11318// // Do this once since fetch parts creates a new array. 11588 if (updatehandler != null)
11319// SceneObjectPart[] parts = part.ParentGroup.Parts; 11589 {
11320// for (int j = 0; j < parts.Length; j++) 11590 ObjectChangeData udata = new ObjectChangeData();
11321// {
11322// part.StoreUndoState();
11323// parts[j].IgnoreUndoUpdate = true;
11324// }
11325 11591
11326 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11592 /*ubit from ll JIRA:
11593 * 0x01 position
11594 * 0x02 rotation
11595 * 0x04 scale
11596
11597 * 0x08 LINK_SET
11598 * 0x10 UNIFORM for scale
11599 */
11327 11600
11328 switch (block.Type) 11601 // translate to internal changes
11329 { 11602 // not all cases .. just the ones older code did
11330 case 1:
11331 Vector3 pos1 = new Vector3(block.Data, 0);
11332 11603
11333 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11604 switch (block.Type)
11334 if (handlerUpdatePrimSinglePosition != null) 11605 {
11335 { 11606 case 1: //change position sp
11336 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11607 udata.position = new Vector3(block.Data, 0);
11337 handlerUpdatePrimSinglePosition(localId, pos1, this);
11338 }
11339 break;
11340 11608
11341 case 2: 11609 udata.change = ObjectChangeType.primP;
11342 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11610 updatehandler(localId, udata, this);
11611 break;
11343 11612
11344 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11613 case 2: // rotation sp
11345 if (handlerUpdatePrimSingleRotation != null) 11614 udata.rotation = new Quaternion(block.Data, 0, true);
11346 {
11347 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11348 handlerUpdatePrimSingleRotation(localId, rot1, this);
11349 }
11350 break;
11351 11615
11352 case 3: 11616 udata.change = ObjectChangeType.primR;
11353 Vector3 rotPos = new Vector3(block.Data, 0); 11617 updatehandler(localId, udata, this);
11354 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11618 break;
11355 11619
11356 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11620 case 3: // position plus rotation
11357 if (handlerUpdatePrimSingleRotationPosition != null) 11621 udata.position = new Vector3(block.Data, 0);
11358 { 11622 udata.rotation = new Quaternion(block.Data, 12, true);
11359 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11360 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11361 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11362 }
11363 break;
11364 11623
11365 case 4: 11624 udata.change = ObjectChangeType.primPR;
11366 case 20: 11625 updatehandler(localId, udata, this);
11367 Vector3 scale4 = new Vector3(block.Data, 0); 11626 break;
11368 11627
11369 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11628 case 4: // scale sp
11370 if (handlerUpdatePrimScale != null) 11629 udata.scale = new Vector3(block.Data, 0);
11371 { 11630 udata.change = ObjectChangeType.primS;
11372 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11373 handlerUpdatePrimScale(localId, scale4, this);
11374 }
11375 break;
11376 11631
11377 case 5: 11632 updatehandler(localId, udata, this);
11378 Vector3 scale1 = new Vector3(block.Data, 12); 11633 break;
11379 Vector3 pos11 = new Vector3(block.Data, 0);
11380 11634
11381 handlerUpdatePrimScale = OnUpdatePrimScale; 11635 case 0x14: // uniform scale sp
11382 if (handlerUpdatePrimScale != null) 11636 udata.scale = new Vector3(block.Data, 0);
11383 {
11384 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11385 handlerUpdatePrimScale(localId, scale1, this);
11386 11637
11387 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11638 udata.change = ObjectChangeType.primUS;
11388 if (handlerUpdatePrimSinglePosition != null) 11639 updatehandler(localId, udata, this);
11389 { 11640 break;
11390 handlerUpdatePrimSinglePosition(localId, pos11, this);
11391 }
11392 }
11393 break;
11394 11641
11395 case 9: 11642 case 5: // scale and position sp
11396 Vector3 pos2 = new Vector3(block.Data, 0); 11643 udata.position = new Vector3(block.Data, 0);
11644 udata.scale = new Vector3(block.Data, 12);
11397 11645
11398 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11646 udata.change = ObjectChangeType.primPS;
11647 updatehandler(localId, udata, this);
11648 break;
11399 11649
11400 if (handlerUpdateVector != null) 11650 case 0x15: //uniform scale and position
11401 { 11651 udata.position = new Vector3(block.Data, 0);
11402 handlerUpdateVector(localId, pos2, this); 11652 udata.scale = new Vector3(block.Data, 12);
11403 }
11404 break;
11405 11653
11406 case 10: 11654 udata.change = ObjectChangeType.primPUS;
11407 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11655 updatehandler(localId, udata, this);
11656 break;
11408 11657
11409 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11658 // now group related (bit 4)
11410 if (handlerUpdatePrimRotation != null) 11659 case 9: //( 8 + 1 )group position
11411 { 11660 udata.position = new Vector3(block.Data, 0);
11412 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11413 handlerUpdatePrimRotation(localId, rot3, this);
11414 }
11415 break;
11416 11661
11417 case 11: 11662 udata.change = ObjectChangeType.groupP;
11418 Vector3 pos3 = new Vector3(block.Data, 0); 11663 updatehandler(localId, udata, this);
11419 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11664 break;
11420 11665
11421 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11666 case 0x0A: // (8 + 2) group rotation
11422 if (handlerUpdatePrimGroupRotation != null) 11667 udata.rotation = new Quaternion(block.Data, 0, true);
11423 {
11424 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11425 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11426 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11427 }
11428 break;
11429 case 12:
11430 case 28:
11431 Vector3 scale7 = new Vector3(block.Data, 0);
11432 11668
11433 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11669 udata.change = ObjectChangeType.groupR;
11434 if (handlerUpdatePrimGroupScale != null) 11670 updatehandler(localId, udata, this);
11435 { 11671 break;
11436 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11437 handlerUpdatePrimGroupScale(localId, scale7, this);
11438 }
11439 break;
11440 11672
11441 case 13: 11673 case 0x0B: //( 8 + 2 + 1) group rotation and position
11442 Vector3 scale2 = new Vector3(block.Data, 12); 11674 udata.position = new Vector3(block.Data, 0);
11443 Vector3 pos4 = new Vector3(block.Data, 0); 11675 udata.rotation = new Quaternion(block.Data, 12, true);
11444 11676
11445 handlerUpdatePrimScale = OnUpdatePrimScale; 11677 udata.change = ObjectChangeType.groupPR;
11446 if (handlerUpdatePrimScale != null) 11678 updatehandler(localId, udata, this);
11447 { 11679 break;
11448 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11449 handlerUpdatePrimScale(localId, scale2, this);
11450 11680
11451 // Change the position based on scale (for bug number 246) 11681 case 0x0C: // (8 + 4) group scale
11452 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11682 // only afects root prim and only sent by viewer editor object tab scaling
11453 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11683 // mouse edition only allows uniform scaling
11454 if (handlerUpdatePrimSinglePosition != null) 11684 // SL MAY CHANGE THIS in viewers
11455 {
11456 handlerUpdatePrimSinglePosition(localId, pos4, this);
11457 }
11458 }
11459 break;
11460 11685
11461 case 29: 11686 udata.scale = new Vector3(block.Data, 0);
11462 Vector3 scale5 = new Vector3(block.Data, 12);
11463 Vector3 pos5 = new Vector3(block.Data, 0);
11464 11687
11465 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11688 udata.change = ObjectChangeType.groupS;
11466 if (handlerUpdatePrimGroupScale != null) 11689 updatehandler(localId, udata, this);
11467 {
11468 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11469 part.StoreUndoState(true);
11470 part.IgnoreUndoUpdate = true;
11471 handlerUpdatePrimGroupScale(localId, scale5, this);
11472 handlerUpdateVector = OnUpdatePrimGroupPosition;
11473 11690
11474 if (handlerUpdateVector != null) 11691 break;
11475 {
11476 handlerUpdateVector(localId, pos5, this);
11477 }
11478 11692
11479 part.IgnoreUndoUpdate = false; 11693 case 0x0D: //(8 + 4 + 1) group scale and position
11480 } 11694 // exception as above
11481 11695
11482 break; 11696 udata.position = new Vector3(block.Data, 0);
11697 udata.scale = new Vector3(block.Data, 12);
11483 11698
11484 case 21: 11699 udata.change = ObjectChangeType.groupPS;
11485 Vector3 scale6 = new Vector3(block.Data, 12); 11700 updatehandler(localId, udata, this);
11486 Vector3 pos6 = new Vector3(block.Data, 0); 11701 break;
11487 11702
11488 handlerUpdatePrimScale = OnUpdatePrimScale; 11703 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11489 if (handlerUpdatePrimScale != null) 11704 udata.scale = new Vector3(block.Data, 0);
11490 {
11491 part.StoreUndoState(false);
11492 part.IgnoreUndoUpdate = true;
11493 11705
11494 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11706 udata.change = ObjectChangeType.groupUS;
11495 handlerUpdatePrimScale(localId, scale6, this); 11707 updatehandler(localId, udata, this);
11496 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11708 break;
11497 if (handlerUpdatePrimSinglePosition != null)
11498 {
11499 handlerUpdatePrimSinglePosition(localId, pos6, this);
11500 }
11501 11709
11502 part.IgnoreUndoUpdate = false; 11710 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11503 } 11711 udata.position = new Vector3(block.Data, 0);
11504 break; 11712 udata.scale = new Vector3(block.Data, 12);
11505 11713
11506 default: 11714 udata.change = ObjectChangeType.groupPUS;
11507 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11715 updatehandler(localId, udata, this);
11508 break; 11716 break;
11717
11718 default:
11719 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11720 break;
11721 }
11509 } 11722 }
11510 11723
11511// for (int j = 0; j < parts.Length; j++)
11512// parts[j].IgnoreUndoUpdate = false;
11513 } 11724 }
11514 } 11725 }
11515 } 11726 }
11516
11517 return true; 11727 return true;
11518 } 11728 }
11519 11729
@@ -11969,7 +12179,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11969// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12179// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
11970// requestID, taskID, (SourceType)sourceType, Name); 12180// requestID, taskID, (SourceType)sourceType, Name);
11971 12181
12182
12183 //Note, the bool returned from the below function is useless since it is always false.
11972 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12184 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12185
11973 } 12186 }
11974 12187
11975 /// <summary> 12188 /// <summary>
@@ -11980,14 +12193,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11980 /// <param name="asset"></param> 12193 /// <param name="asset"></param>
11981 protected void AssetReceived(string id, Object sender, AssetBase asset) 12194 protected void AssetReceived(string id, Object sender, AssetBase asset)
11982 { 12195 {
11983 if (asset == null)
11984 return;
11985
11986 TransferRequestPacket transferRequest = (TransferRequestPacket)sender; 12196 TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
11987 12197
11988 UUID requestID = UUID.Zero; 12198 UUID requestID = UUID.Zero;
11989 byte source = (byte)SourceType.Asset; 12199 byte source = (byte)SourceType.Asset;
11990 12200
12201 AssetRequestToClient req = new AssetRequestToClient();
12202
12203 if (asset == null)
12204 {
12205 req.AssetInf = null;
12206 req.AssetRequestSource = source;
12207 req.IsTextureRequest = false;
12208 req.NumPackets = 0;
12209 req.Params = transferRequest.TransferInfo.Params;
12210 req.RequestAssetID = requestID;
12211 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
12212
12213 SendAssetNotFound(req);
12214 return;
12215 }
12216
11991 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) 12217 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
11992 { 12218 {
11993 requestID = new UUID(transferRequest.TransferInfo.Params, 0); 12219 requestID = new UUID(transferRequest.TransferInfo.Params, 0);
@@ -12004,7 +12230,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12004 return; 12230 return;
12005 12231
12006 // The asset is known to exist and is in our cache, so add it to the AssetRequests list 12232 // The asset is known to exist and is in our cache, so add it to the AssetRequests list
12007 AssetRequestToClient req = new AssetRequestToClient();
12008 req.AssetInf = asset; 12233 req.AssetInf = asset;
12009 req.AssetRequestSource = source; 12234 req.AssetRequestSource = source;
12010 req.IsTextureRequest = false; 12235 req.IsTextureRequest = false;
@@ -12023,7 +12248,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12023 /// <returns></returns> 12248 /// <returns></returns>
12024 private static int CalculateNumPackets(byte[] data) 12249 private static int CalculateNumPackets(byte[] data)
12025 { 12250 {
12026 const uint m_maxPacketSize = 600; 12251// const uint m_maxPacketSize = 600;
12252 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12027 int numPackets = 1; 12253 int numPackets = 1;
12028 12254
12029 if (data == null) 12255 if (data == null)