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