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.cs1518
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs115
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs134
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 1138 insertions, 636 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index 4d0568d..15d6f7f 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 6b58fb7..51cc2bf 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -102,6 +102,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
102 public event AvatarPickerRequest OnAvatarPickerRequest; 102 public event AvatarPickerRequest OnAvatarPickerRequest;
103 public event StartAnim OnStartAnim; 103 public event StartAnim OnStartAnim;
104 public event StopAnim OnStopAnim; 104 public event StopAnim OnStopAnim;
105 public event ChangeAnim OnChangeAnim;
105 public event Action<IClientAPI> OnRequestAvatarsData; 106 public event Action<IClientAPI> OnRequestAvatarsData;
106 public event LinkObjects OnLinkObjects; 107 public event LinkObjects OnLinkObjects;
107 public event DelinkObjects OnDelinkObjects; 108 public event DelinkObjects OnDelinkObjects;
@@ -129,6 +130,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
129 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 130 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
130 public event UpdatePrimFlags OnUpdatePrimFlags; 131 public event UpdatePrimFlags OnUpdatePrimFlags;
131 public event UpdatePrimTexture OnUpdatePrimTexture; 132 public event UpdatePrimTexture OnUpdatePrimTexture;
133 public event ClientChangeObject onClientChangeObject;
132 public event UpdateVector OnUpdatePrimGroupPosition; 134 public event UpdateVector OnUpdatePrimGroupPosition;
133 public event UpdateVector OnUpdatePrimSinglePosition; 135 public event UpdateVector OnUpdatePrimSinglePosition;
134 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 136 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -162,6 +164,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
162 public event RequestTaskInventory OnRequestTaskInventory; 164 public event RequestTaskInventory OnRequestTaskInventory;
163 public event UpdateInventoryItem OnUpdateInventoryItem; 165 public event UpdateInventoryItem OnUpdateInventoryItem;
164 public event CopyInventoryItem OnCopyInventoryItem; 166 public event CopyInventoryItem OnCopyInventoryItem;
167 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
165 public event MoveInventoryItem OnMoveInventoryItem; 168 public event MoveInventoryItem OnMoveInventoryItem;
166 public event RemoveInventoryItem OnRemoveInventoryItem; 169 public event RemoveInventoryItem OnRemoveInventoryItem;
167 public event RemoveInventoryFolder OnRemoveInventoryFolder; 170 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -260,7 +263,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
260 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 263 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
261 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 264 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
262 public event ClassifiedDelete OnClassifiedDelete; 265 public event ClassifiedDelete OnClassifiedDelete;
263 public event ClassifiedDelete OnClassifiedGodDelete; 266 public event ClassifiedGodDelete OnClassifiedGodDelete;
264 public event EventNotificationAddRequest OnEventNotificationAddRequest; 267 public event EventNotificationAddRequest OnEventNotificationAddRequest;
265 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 268 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
266 public event EventGodDelete OnEventGodDelete; 269 public event EventGodDelete OnEventGodDelete;
@@ -291,10 +294,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
291 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 294 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
292 public event SimWideDeletesDelegate OnSimWideDeletes; 295 public event SimWideDeletesDelegate OnSimWideDeletes;
293 public event SendPostcard OnSendPostcard; 296 public event SendPostcard OnSendPostcard;
297 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
294 public event MuteListEntryUpdate OnUpdateMuteListEntry; 298 public event MuteListEntryUpdate OnUpdateMuteListEntry;
295 public event MuteListEntryRemove OnRemoveMuteListEntry; 299 public event MuteListEntryRemove OnRemoveMuteListEntry;
296 public event GodlikeMessage onGodlikeMessage; 300 public event GodlikeMessage onGodlikeMessage;
297 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 301 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
302 public event GenericCall2 OnUpdateThrottles;
298 303
299 #endregion Events 304 #endregion Events
300 305
@@ -323,11 +328,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
323 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 328 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
324 private readonly IGroupsModule m_GroupsModule; 329 private readonly IGroupsModule m_GroupsModule;
325 330
331 private int m_cachedTextureSerial;
326 private PriorityQueue m_entityUpdates; 332 private PriorityQueue m_entityUpdates;
327 private PriorityQueue m_entityProps; 333 private PriorityQueue m_entityProps;
328 private Prioritizer m_prioritizer; 334 private Prioritizer m_prioritizer;
329 private bool m_disableFacelights = false; 335 private bool m_disableFacelights = false;
336
337 private bool m_VelocityInterpolate = false;
338 private const uint MaxTransferBytesPerPacket = 600;
339
330 private volatile bool m_justEditedTerrain = false; 340 private volatile bool m_justEditedTerrain = false;
341
331 /// <value> 342 /// <value>
332 /// List used in construction of data blocks for an object update packet. This is to stop us having to 343 /// List used in construction of data blocks for an object update packet. This is to stop us having to
333 /// continually recreate it. 344 /// continually recreate it.
@@ -339,13 +350,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 350 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
340 /// ownerless phantom. 351 /// ownerless phantom.
341 /// 352 ///
342 /// All manipulation of this set has to occur under a lock 353 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
343 /// 354 ///
344 /// </value> 355 /// </value>
345 protected HashSet<uint> m_killRecord; 356// protected HashSet<uint> m_killRecord;
346 357
347// protected HashSet<uint> m_attachmentsSent; 358// protected HashSet<uint> m_attachmentsSent;
348 359
360 private bool m_deliverPackets = true;
349 private int m_animationSequenceNumber = 1; 361 private int m_animationSequenceNumber = 1;
350 private bool m_SendLogoutPacketWhenClosing = true; 362 private bool m_SendLogoutPacketWhenClosing = true;
351 363
@@ -392,6 +404,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
392 get { return m_startpos; } 404 get { return m_startpos; }
393 set { m_startpos = value; } 405 set { m_startpos = value; }
394 } 406 }
407 public bool DeliverPackets
408 {
409 get { return m_deliverPackets; }
410 set {
411 m_deliverPackets = value;
412 m_udpClient.m_deliverPackets = value;
413 }
414 }
395 public UUID AgentId { get { return m_agentId; } } 415 public UUID AgentId { get { return m_agentId; } }
396 public ISceneAgent SceneAgent { get; set; } 416 public ISceneAgent SceneAgent { get; set; }
397 public UUID ActiveGroupId { get { return m_activeGroupID; } } 417 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -442,6 +462,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
442 } 462 }
443 463
444 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 464 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
465
445 466
446 #endregion Properties 467 #endregion Properties
447 468
@@ -468,7 +489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 489 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 490 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 491 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 492// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 493// m_attachmentsSent = new HashSet<uint>();
473 494
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 495 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +519,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 519
499 #region Client Methods 520 #region Client Methods
500 521
522
523 /// <summary>
524 /// Close down the client view
525 /// </summary>
501 public void Close() 526 public void Close()
502 { 527 {
503 Close(false); 528 Close(true, false);
504 } 529 }
505 530
506 public void Close(bool force) 531 public void Close(bool sendStop, bool force)
507 { 532 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 533 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
509 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 534 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -521,7 +546,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 } 546 }
522 547
523 IsActive = false; 548 IsActive = false;
524 CloseWithoutChecks(); 549 CloseWithoutChecks(sendStop);
525 } 550 }
526 } 551 }
527 552
@@ -534,12 +559,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
534 /// 559 ///
535 /// Callers must lock ClosingSyncLock before calling. 560 /// Callers must lock ClosingSyncLock before calling.
536 /// </remarks> 561 /// </remarks>
537 public void CloseWithoutChecks() 562 public void CloseWithoutChecks(bool sendStop)
538 { 563 {
539 m_log.DebugFormat( 564 m_log.DebugFormat(
540 "[CLIENT]: Close has been called for {0} attached to scene {1}", 565 "[CLIENT]: Close has been called for {0} attached to scene {1}",
541 Name, m_scene.RegionInfo.RegionName); 566 Name, m_scene.RegionInfo.RegionName);
542 567
568 if (sendStop)
569 {
570 // Send the STOP packet
571 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
572 OutPacket(disable, ThrottleOutPacketType.Unknown);
573 }
574
543 // Shutdown the image manager 575 // Shutdown the image manager
544 ImageManager.Close(); 576 ImageManager.Close();
545 577
@@ -562,6 +594,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
562 // Disable UDP handling for this client 594 // Disable UDP handling for this client
563 m_udpClient.Shutdown(); 595 m_udpClient.Shutdown();
564 596
597
565 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 598 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
566 //GC.Collect(); 599 //GC.Collect();
567 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 600 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -858,7 +891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
858 reply.ChatData.OwnerID = ownerID; 891 reply.ChatData.OwnerID = ownerID;
859 reply.ChatData.SourceID = fromAgentID; 892 reply.ChatData.SourceID = fromAgentID;
860 893
861 OutPacket(reply, ThrottleOutPacketType.Task); 894 OutPacket(reply, ThrottleOutPacketType.Unknown);
862 } 895 }
863 896
864 /// <summary> 897 /// <summary>
@@ -891,32 +924,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
891 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 924 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
892 msg.MessageBlock.BinaryBucket = im.binaryBucket; 925 msg.MessageBlock.BinaryBucket = im.binaryBucket;
893 926
894 if (im.message.StartsWith("[grouptest]")) 927 OutPacket(msg, ThrottleOutPacketType.Task);
895 { // this block is test code for implementing group IM - delete when group IM is finished
896 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
897 if (eq != null)
898 {
899 im.dialog = 17;
900
901 //eq.ChatterboxInvitation(
902 // new UUID("00000000-68f9-1111-024e-222222111123"),
903 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
904 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
905
906 eq.ChatterboxInvitation(
907 new UUID("00000000-68f9-1111-024e-222222111123"),
908 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
909 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
910
911 eq.ChatterBoxSessionAgentListUpdates(
912 new UUID("00000000-68f9-1111-024e-222222111123"),
913 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
914 }
915
916 Console.WriteLine("SendInstantMessage: " + msg);
917 }
918 else
919 OutPacket(msg, ThrottleOutPacketType.Task);
920 } 928 }
921 } 929 }
922 930
@@ -1154,6 +1162,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1154 public virtual void SendLayerData(float[] map) 1162 public virtual void SendLayerData(float[] map)
1155 { 1163 {
1156 Util.FireAndForget(DoSendLayerData, map); 1164 Util.FireAndForget(DoSendLayerData, map);
1165
1166 // Send it sync, and async. It's not that much data
1167 // and it improves user experience just so much!
1168 DoSendLayerData(map);
1157 } 1169 }
1158 1170
1159 /// <summary> 1171 /// <summary>
@@ -1166,16 +1178,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1166 1178
1167 try 1179 try
1168 { 1180 {
1169 //for (int y = 0; y < 16; y++) 1181 for (int y = 0; y < 16; y++)
1170 //{ 1182 {
1171 // for (int x = 0; x < 16; x++) 1183 for (int x = 0; x < 16; x+=4)
1172 // { 1184 {
1173 // SendLayerData(x, y, map); 1185 SendLayerPacket(x, y, map);
1174 // } 1186 }
1175 //} 1187 }
1176
1177 // Send LayerData in a spiral pattern. Fun!
1178 SendLayerTopRight(map, 0, 0, 15, 15);
1179 } 1188 }
1180 catch (Exception e) 1189 catch (Exception e)
1181 { 1190 {
@@ -1183,51 +1192,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1183 } 1192 }
1184 } 1193 }
1185 1194
1186 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1187 {
1188 // Row
1189 for (int i = x1; i <= x2; i++)
1190 SendLayerData(i, y1, map);
1191
1192 // Column
1193 for (int j = y1 + 1; j <= y2; j++)
1194 SendLayerData(x2, j, map);
1195
1196 if (x2 - x1 > 0)
1197 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1198 }
1199
1200 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1201 {
1202 // Row in reverse
1203 for (int i = x2; i >= x1; i--)
1204 SendLayerData(i, y2, map);
1205
1206 // Column in reverse
1207 for (int j = y2 - 1; j >= y1; j--)
1208 SendLayerData(x1, j, map);
1209
1210 if (x2 - x1 > 0)
1211 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1212 }
1213
1214 /// <summary> 1195 /// <summary>
1215 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1196 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1216 /// </summary> 1197 /// </summary>
1217 /// <param name="map">heightmap</param> 1198 /// <param name="map">heightmap</param>
1218 /// <param name="px">X coordinate for patches 0..12</param> 1199 /// <param name="px">X coordinate for patches 0..12</param>
1219 /// <param name="py">Y coordinate for patches 0..15</param> 1200 /// <param name="py">Y coordinate for patches 0..15</param>
1220 // private void SendLayerPacket(float[] map, int y, int x) 1201 private void SendLayerPacket(int x, int y, float[] map)
1221 // { 1202 {
1222 // int[] patches = new int[4]; 1203 int[] patches = new int[4];
1223 // patches[0] = x + 0 + y * 16; 1204 patches[0] = x + 0 + y * 16;
1224 // patches[1] = x + 1 + y * 16; 1205 patches[1] = x + 1 + y * 16;
1225 // patches[2] = x + 2 + y * 16; 1206 patches[2] = x + 2 + y * 16;
1226 // patches[3] = x + 3 + y * 16; 1207 patches[3] = x + 3 + y * 16;
1227 1208
1228 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1209 float[] heightmap = (map.Length == 65536) ?
1229 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1210 map :
1230 // } 1211 LLHeightFieldMoronize(map);
1212
1213 try
1214 {
1215 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1216 OutPacket(layerpack, ThrottleOutPacketType.Land);
1217 }
1218 catch
1219 {
1220 for (int px = x ; px < x + 4 ; px++)
1221 SendLayerData(px, y, map);
1222 }
1223 }
1231 1224
1232 /// <summary> 1225 /// <summary>
1233 /// Sends a specified patch to a client 1226 /// Sends a specified patch to a client
@@ -1269,7 +1262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1269 { 1262 {
1270 layerpack.Header.Reliable = true; 1263 layerpack.Header.Reliable = true;
1271 OutPacket(layerpack, 1264 OutPacket(layerpack,
1272 ThrottleOutPacketType.Land); 1265 ThrottleOutPacketType.Task);
1273 } 1266 }
1274 } 1267 }
1275 catch (Exception e) 1268 catch (Exception e)
@@ -1640,7 +1633,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1640 1633
1641 public void SendKillObject(List<uint> localIDs) 1634 public void SendKillObject(List<uint> localIDs)
1642 { 1635 {
1643// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1636// foreach (uint id in localIDs)
1637// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1644 1638
1645 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1639 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1646 // TODO: don't create new blocks if recycling an old packet 1640 // TODO: don't create new blocks if recycling an old packet
@@ -1662,17 +1656,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1662 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1656 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1663 // condition where a kill can be processed before an out-of-date update for the same object. 1657 // condition where a kill can be processed before an out-of-date update for the same object.
1664 // ProcessEntityUpdates() also takes the m_killRecord lock. 1658 // ProcessEntityUpdates() also takes the m_killRecord lock.
1665 lock (m_killRecord) 1659// lock (m_killRecord)
1666 { 1660// {
1667 foreach (uint localID in localIDs) 1661// foreach (uint localID in localIDs)
1668 m_killRecord.Add(localID); 1662// m_killRecord.Add(localID);
1669 1663
1670 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1664 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1671 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1665 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1672 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1666 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1673 // scene objects in a viewer until that viewer is relogged in. 1667 // scene objects in a viewer until that viewer is relogged in.
1674 OutPacket(kill, ThrottleOutPacketType.Task); 1668 OutPacket(kill, ThrottleOutPacketType.Task);
1675 } 1669// }
1676 } 1670 }
1677 } 1671 }
1678 1672
@@ -1794,7 +1788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1794 newBlock.CreationDate = item.CreationDate; 1788 newBlock.CreationDate = item.CreationDate;
1795 newBlock.SalePrice = item.SalePrice; 1789 newBlock.SalePrice = item.SalePrice;
1796 newBlock.SaleType = item.SaleType; 1790 newBlock.SaleType = item.SaleType;
1797 newBlock.Flags = item.Flags; 1791 newBlock.Flags = item.Flags & 0xff;
1798 1792
1799 newBlock.CRC = 1793 newBlock.CRC =
1800 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, 1794 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
@@ -2048,7 +2042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2048 itemBlock.GroupID = item.GroupID; 2042 itemBlock.GroupID = item.GroupID;
2049 itemBlock.GroupOwned = item.GroupOwned; 2043 itemBlock.GroupOwned = item.GroupOwned;
2050 itemBlock.GroupMask = item.GroupPermissions; 2044 itemBlock.GroupMask = item.GroupPermissions;
2051 itemBlock.Flags = item.Flags; 2045 itemBlock.Flags = item.Flags & 0xff;
2052 itemBlock.SalePrice = item.SalePrice; 2046 itemBlock.SalePrice = item.SalePrice;
2053 itemBlock.SaleType = item.SaleType; 2047 itemBlock.SaleType = item.SaleType;
2054 itemBlock.CreationDate = item.CreationDate; 2048 itemBlock.CreationDate = item.CreationDate;
@@ -2115,7 +2109,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2115 bulkUpdate.ItemData[0].GroupID = item.GroupID; 2109 bulkUpdate.ItemData[0].GroupID = item.GroupID;
2116 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned; 2110 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned;
2117 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions; 2111 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions;
2118 bulkUpdate.ItemData[0].Flags = item.Flags; 2112 bulkUpdate.ItemData[0].Flags = item.Flags & 0xff;
2119 bulkUpdate.ItemData[0].SalePrice = item.SalePrice; 2113 bulkUpdate.ItemData[0].SalePrice = item.SalePrice;
2120 bulkUpdate.ItemData[0].SaleType = item.SaleType; 2114 bulkUpdate.ItemData[0].SaleType = item.SaleType;
2121 2115
@@ -2131,9 +2125,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2131 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2125 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2132 } 2126 }
2133 2127
2134 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2135 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2128 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2136 { 2129 {
2130 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2131 }
2132
2133 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2134 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2135 {
2137 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2136 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2138 2137
2139 UpdateCreateInventoryItemPacket InventoryReply 2138 UpdateCreateInventoryItemPacket InventoryReply
@@ -2143,6 +2142,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2143 // TODO: don't create new blocks if recycling an old packet 2142 // TODO: don't create new blocks if recycling an old packet
2144 InventoryReply.AgentData.AgentID = AgentId; 2143 InventoryReply.AgentData.AgentID = AgentId;
2145 InventoryReply.AgentData.SimApproved = true; 2144 InventoryReply.AgentData.SimApproved = true;
2145 InventoryReply.AgentData.TransactionID = transactionID;
2146 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2146 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2147 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2147 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2148 InventoryReply.InventoryData[0].ItemID = Item.ID; 2148 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2163,7 +2163,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2163 InventoryReply.InventoryData[0].GroupID = Item.GroupID; 2163 InventoryReply.InventoryData[0].GroupID = Item.GroupID;
2164 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned; 2164 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned;
2165 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions; 2165 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions;
2166 InventoryReply.InventoryData[0].Flags = Item.Flags; 2166 InventoryReply.InventoryData[0].Flags = Item.Flags & 0xff;
2167 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice; 2167 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice;
2168 InventoryReply.InventoryData[0].SaleType = Item.SaleType; 2168 InventoryReply.InventoryData[0].SaleType = Item.SaleType;
2169 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate; 2169 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate;
@@ -2212,16 +2212,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2212 replytask.InventoryData.TaskID = taskID; 2212 replytask.InventoryData.TaskID = taskID;
2213 replytask.InventoryData.Serial = serial; 2213 replytask.InventoryData.Serial = serial;
2214 replytask.InventoryData.Filename = fileName; 2214 replytask.InventoryData.Filename = fileName;
2215 OutPacket(replytask, ThrottleOutPacketType.Asset); 2215 OutPacket(replytask, ThrottleOutPacketType.Task);
2216 } 2216 }
2217 2217
2218 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2218 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2219 { 2219 {
2220 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2221 if (isTaskInventory)
2222 type = ThrottleOutPacketType.Task;
2223
2220 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2224 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2221 sendXfer.XferID.ID = xferID; 2225 sendXfer.XferID.ID = xferID;
2222 sendXfer.XferID.Packet = packet; 2226 sendXfer.XferID.Packet = packet;
2223 sendXfer.DataPacket.Data = data; 2227 sendXfer.DataPacket.Data = data;
2224 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2228 OutPacket(sendXfer, type);
2225 } 2229 }
2226 2230
2227 public void SendAbortXferPacket(ulong xferID) 2231 public void SendAbortXferPacket(ulong xferID)
@@ -2408,6 +2412,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2408 OutPacket(sound, ThrottleOutPacketType.Task); 2412 OutPacket(sound, ThrottleOutPacketType.Task);
2409 } 2413 }
2410 2414
2415 public void SendTransferAbort(TransferRequestPacket transferRequest)
2416 {
2417 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2418 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2419 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2420 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2421 OutPacket(abort, ThrottleOutPacketType.Task);
2422 }
2423
2411 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2424 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2412 { 2425 {
2413 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2426 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2716,6 +2729,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2716 float friction = part.Friction; 2729 float friction = part.Friction;
2717 float bounce = part.Restitution; 2730 float bounce = part.Restitution;
2718 float gravmod = part.GravityModifier; 2731 float gravmod = part.GravityModifier;
2732
2719 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2733 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2720 } 2734 }
2721 } 2735 }
@@ -2786,8 +2800,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2786 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2800 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2787 return; 2801 return;
2788 } 2802 }
2803 int WearableOut = 0;
2804 bool isWearable = false;
2789 2805
2790 //m_log.Debug("sending asset " + req.RequestAssetID); 2806 if (req.AssetInf != null)
2807 isWearable =
2808 ((AssetType) req.AssetInf.Type ==
2809 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2810
2811
2812 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2813
2814
2815 //if (isWearable)
2816 // m_log.Debug((AssetType)req.AssetInf.Type);
2817
2791 TransferInfoPacket Transfer = new TransferInfoPacket(); 2818 TransferInfoPacket Transfer = new TransferInfoPacket();
2792 Transfer.TransferInfo.ChannelType = 2; 2819 Transfer.TransferInfo.ChannelType = 2;
2793 Transfer.TransferInfo.Status = 0; 2820 Transfer.TransferInfo.Status = 0;
@@ -2809,7 +2836,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2809 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2836 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2810 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2837 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2811 Transfer.Header.Zerocoded = true; 2838 Transfer.Header.Zerocoded = true;
2812 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2839 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2813 2840
2814 if (req.NumPackets == 1) 2841 if (req.NumPackets == 1)
2815 { 2842 {
@@ -2820,12 +2847,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2820 TransferPacket.TransferData.Data = req.AssetInf.Data; 2847 TransferPacket.TransferData.Data = req.AssetInf.Data;
2821 TransferPacket.TransferData.Status = 1; 2848 TransferPacket.TransferData.Status = 1;
2822 TransferPacket.Header.Zerocoded = true; 2849 TransferPacket.Header.Zerocoded = true;
2823 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2850 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2824 } 2851 }
2825 else 2852 else
2826 { 2853 {
2827 int processedLength = 0; 2854 int processedLength = 0;
2828 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2855// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2856
2857 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2829 int packetNumber = 0; 2858 int packetNumber = 0;
2830 2859
2831 while (processedLength < req.AssetInf.Data.Length) 2860 while (processedLength < req.AssetInf.Data.Length)
@@ -2851,7 +2880,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2851 TransferPacket.TransferData.Status = 1; 2880 TransferPacket.TransferData.Status = 1;
2852 } 2881 }
2853 TransferPacket.Header.Zerocoded = true; 2882 TransferPacket.Header.Zerocoded = true;
2854 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2883 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2855 2884
2856 processedLength += chunkSize; 2885 processedLength += chunkSize;
2857 packetNumber++; 2886 packetNumber++;
@@ -2896,7 +2925,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2896 reply.Data.ParcelID = parcelID; 2925 reply.Data.ParcelID = parcelID;
2897 reply.Data.OwnerID = land.OwnerID; 2926 reply.Data.OwnerID = land.OwnerID;
2898 reply.Data.Name = Utils.StringToBytes(land.Name); 2927 reply.Data.Name = Utils.StringToBytes(land.Name);
2899 reply.Data.Desc = Utils.StringToBytes(land.Description); 2928 if (land != null && land.Description != null && land.Description != String.Empty)
2929 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2930 else
2931 reply.Data.Desc = new Byte[0];
2900 reply.Data.ActualArea = land.Area; 2932 reply.Data.ActualArea = land.Area;
2901 reply.Data.BillableArea = land.Area; // TODO: what is this? 2933 reply.Data.BillableArea = land.Area; // TODO: what is this?
2902 2934
@@ -3603,24 +3635,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3603 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3635 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3604 AgentWearablesUpdatePacket.WearableDataBlock awb; 3636 AgentWearablesUpdatePacket.WearableDataBlock awb;
3605 int idx = 0; 3637 int idx = 0;
3606 for (int i = 0; i < wearables.Length; i++) 3638
3607 { 3639 for (int i = 0; i < wearables.Length; i++)
3608 for (int j = 0; j < wearables[i].Count; j++) 3640 {
3609 { 3641 for (int j = 0; j < wearables[i].Count; j++)
3610 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3642 {
3611 awb.WearableType = (byte)i; 3643 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3612 awb.AssetID = wearables[i][j].AssetID; 3644 awb.WearableType = (byte) i;
3613 awb.ItemID = wearables[i][j].ItemID; 3645 awb.AssetID = wearables[i][j].AssetID;
3614 aw.WearableData[idx] = awb; 3646 awb.ItemID = wearables[i][j].ItemID;
3615 idx++; 3647 aw.WearableData[idx] = awb;
3616 3648 idx++;
3617// m_log.DebugFormat( 3649
3618// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3650 // m_log.DebugFormat(
3619// awb.ItemID, awb.AssetID, i, Name); 3651 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3620 } 3652 // awb.ItemID, awb.AssetID, i, Name);
3621 } 3653 }
3654 }
3622 3655
3623 OutPacket(aw, ThrottleOutPacketType.Task); 3656 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3624 } 3657 }
3625 3658
3626 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3659 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3631,7 +3664,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3631 3664
3632 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3665 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3633 // TODO: don't create new blocks if recycling an old packet 3666 // TODO: don't create new blocks if recycling an old packet
3634 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3667 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3635 avp.ObjectData.TextureEntry = textureEntry; 3668 avp.ObjectData.TextureEntry = textureEntry;
3636 3669
3637 AvatarAppearancePacket.VisualParamBlock avblock = null; 3670 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3762,7 +3795,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3762 /// </summary> 3795 /// </summary>
3763 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3796 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3764 { 3797 {
3765 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3798 if (entity is SceneObjectPart)
3799 {
3800 SceneObjectPart e = (SceneObjectPart)entity;
3801 SceneObjectGroup g = e.ParentGroup;
3802 if (g.RootPart.Shape.State > 30) // HUD
3803 if (g.OwnerID != AgentId)
3804 return; // Don't send updates for other people's HUDs
3805 }
3806
3766 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3807 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3767 3808
3768 lock (m_entityUpdates.SyncRoot) 3809 lock (m_entityUpdates.SyncRoot)
@@ -3849,27 +3890,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3849 3890
3850 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3891 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3851 // condition where a kill can be processed before an out-of-date update for the same object. 3892 // condition where a kill can be processed before an out-of-date update for the same object.
3852 lock (m_killRecord) 3893 float avgTimeDilation = 1.0f;
3894 IEntityUpdate iupdate;
3895 Int32 timeinqueue; // this is just debugging code & can be dropped later
3896
3897 while (updatesThisCall < maxUpdates)
3853 { 3898 {
3854 float avgTimeDilation = 1.0f; 3899 lock (m_entityUpdates.SyncRoot)
3855 IEntityUpdate iupdate; 3900 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3856 Int32 timeinqueue; // this is just debugging code & can be dropped later 3901 break;
3902
3903 EntityUpdate update = (EntityUpdate)iupdate;
3904
3905 avgTimeDilation += update.TimeDilation;
3906 avgTimeDilation *= 0.5f;
3857 3907
3858 while (updatesThisCall < maxUpdates) 3908 if (update.Entity is SceneObjectPart)
3859 { 3909 {
3860 lock (m_entityUpdates.SyncRoot) 3910 SceneObjectPart part = (SceneObjectPart)update.Entity;
3861 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3862 break;
3863 3911
3864 EntityUpdate update = (EntityUpdate)iupdate; 3912 if (part.ParentGroup.IsDeleted)
3865 3913 continue;
3866 avgTimeDilation += update.TimeDilation;
3867 avgTimeDilation *= 0.5f;
3868 3914
3869 if (update.Entity is SceneObjectPart) 3915 if (part.ParentGroup.IsAttachment)
3916 { // Someone else's HUD, why are we getting these?
3917 if (part.ParentGroup.OwnerID != AgentId &&
3918 part.ParentGroup.RootPart.Shape.State > 30)
3919 continue;
3920 ScenePresence sp;
3921 // Owner is not in the sim, don't update it to
3922 // anyone
3923 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3924 continue;
3925
3926 List<SceneObjectGroup> atts = sp.GetAttachments();
3927 bool found = false;
3928 foreach (SceneObjectGroup att in atts)
3929 {
3930 if (att == part.ParentGroup)
3931 {
3932 found = true;
3933 break;
3934 }
3935 }
3936
3937 // It's an attachment of a valid avatar, but
3938 // doesn't seem to be attached, skip
3939 if (!found)
3940 continue;
3941
3942 // On vehicle crossing, the attachments are received
3943 // while the avatar is still a child. Don't send
3944 // updates here because the LocalId has not yet
3945 // been updated and the viewer will derender the
3946 // attachments until the avatar becomes root.
3947 if (sp.IsChildAgent)
3948 continue;
3949
3950 // If the object is an attachment we don't want it to be in the kill
3951 // record. Else attaching from inworld and subsequently dropping
3952 // it will no longer work.
3953// lock (m_killRecord)
3954// {
3955// m_killRecord.Remove(part.LocalId);
3956// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3957// }
3958 }
3959 else
3870 { 3960 {
3871 SceneObjectPart part = (SceneObjectPart)update.Entity;
3872
3873 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3961 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3874 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3962 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3875 // safety measure. 3963 // safety measure.
@@ -3880,21 +3968,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3880 // 3968 //
3881 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3969 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3882 // after the root prim has been deleted. 3970 // after the root prim has been deleted.
3883 if (m_killRecord.Contains(part.LocalId)) 3971 //
3884 { 3972 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3885 // m_log.WarnFormat( 3973// lock (m_killRecord)
3886 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3974// {
3887 // part.LocalId, Name); 3975// if (m_killRecord.Contains(part.LocalId))
3888 continue; 3976// continue;
3889 } 3977// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3890 3978// continue;
3891 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3979// }
3980 }
3981
3982 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3983 {
3984 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3985 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3892 { 3986 {
3893 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3987 part.Shape.LightEntry = false;
3894 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3895 {
3896 part.Shape.LightEntry = false;
3897 }
3898 } 3988 }
3899 3989
3900 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3990 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3905,224 +3995,178 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3905 part.Shape.ProfileHollow = 27500; 3995 part.Shape.ProfileHollow = 27500;
3906 } 3996 }
3907 } 3997 }
3908 3998
3909 #region UpdateFlags to packet type conversion 3999 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3910
3911 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3912
3913 bool canUseCompressed = true;
3914 bool canUseImproved = true;
3915
3916 // Compressed object updates only make sense for LL primitives
3917 if (!(update.Entity is SceneObjectPart))
3918 { 4000 {
3919 canUseCompressed = false; 4001 // Ensure that mesh has at least 8 valid faces
4002 part.Shape.ProfileBegin = 12500;
4003 part.Shape.ProfileEnd = 0;
4004 part.Shape.ProfileHollow = 27500;
3920 } 4005 }
3921 4006 }
3922 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 4007 else if (update.Entity is ScenePresence)
4008 {
4009 ScenePresence presence = (ScenePresence)update.Entity;
4010
4011 // If ParentUUID is not UUID.Zero and ParentID is 0, this
4012 // avatar is in the process of crossing regions while
4013 // sat on an object. In this state, we don't want any
4014 // updates because they will visually orbit the avatar.
4015 // Update will be forced once crossing is completed anyway.
4016 if (presence.ParentUUID != UUID.Zero && presence.ParentID == 0)
4017 continue;
4018 }
4019
4020 ++updatesThisCall;
4021
4022 #region UpdateFlags to packet type conversion
4023
4024 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
4025
4026 bool canUseCompressed = true;
4027 bool canUseImproved = true;
4028
4029 // Compressed object updates only make sense for LL primitives
4030 if (!(update.Entity is SceneObjectPart))
4031 {
4032 canUseCompressed = false;
4033 }
4034
4035 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
4036 {
4037 canUseCompressed = false;
4038 canUseImproved = false;
4039 }
4040 else
4041 {
4042 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
4043 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
4044 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
4045 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3923 { 4046 {
3924 canUseCompressed = false; 4047 canUseCompressed = false;
3925 canUseImproved = false;
3926 } 4048 }
3927 else 4049
4050 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
4051 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
4052 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
4053 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
4054 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
4055 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
4056 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
4057 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
4058 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
4059 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
4060 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
4061 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
4062 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
4063 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3928 { 4064 {
3929 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 4065 canUseImproved = false;
3930 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3932 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3933 {
3934 canUseCompressed = false;
3935 }
3936
3937 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3938 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3939 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3940 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3941 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3942 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3943 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3944 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3945 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3950 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3951 {
3952 canUseImproved = false;
3953 }
3954 } 4066 }
4067 }
3955 4068
3956 #endregion UpdateFlags to packet type conversion 4069 #endregion UpdateFlags to packet type conversion
3957
3958 #region Block Construction
3959
3960 // TODO: Remove this once we can build compressed updates
3961 canUseCompressed = false;
3962
3963 if (!canUseImproved && !canUseCompressed)
3964 {
3965 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3966 4070
3967 if (update.Entity is ScenePresence) 4071 #region Block Construction
3968 {
3969 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3970 }
3971 else
3972 {
3973 SceneObjectPart part = (SceneObjectPart)update.Entity;
3974 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3975
3976 // If the part has become a private hud since the update was scheduled then we do not
3977 // want to send it to other avatars.
3978 if (part.ParentGroup.IsAttachment
3979 && part.ParentGroup.HasPrivateAttachmentPoint
3980 && part.ParentGroup.AttachedAvatar != AgentId)
3981 continue;
3982
3983 // If the part has since been deleted, then drop the update. In the case of attachments,
3984 // this is to avoid spurious updates to other viewers since post-processing of attachments
3985 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3986 // of the test above).
3987 //
3988 // Actual deletions (kills) happen in another method.
3989 if (part.ParentGroup.IsDeleted)
3990 continue;
3991 }
3992 4072
3993 objectUpdateBlocks.Value.Add(updateBlock); 4073 // TODO: Remove this once we can build compressed updates
3994 objectUpdates.Value.Add(update); 4074 canUseCompressed = false;
3995 }
3996 else if (!canUseImproved)
3997 {
3998 SceneObjectPart part = (SceneObjectPart)update.Entity;
3999 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
4000 = CreateCompressedUpdateBlock(part, updateFlags);
4001
4002 // If the part has since been deleted, then drop the update. In the case of attachments,
4003 // this is to avoid spurious updates to other viewers since post-processing of attachments
4004 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4005 // of the test above).
4006 //
4007 // Actual deletions (kills) happen in another method.
4008 if (part.ParentGroup.IsDeleted)
4009 continue;
4010 4075
4011 compressedUpdateBlocks.Value.Add(compressedBlock); 4076 if (!canUseImproved && !canUseCompressed)
4012 compressedUpdates.Value.Add(update); 4077 {
4078 if (update.Entity is ScenePresence)
4079 {
4080 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
4013 } 4081 }
4014 else 4082 else
4015 { 4083 {
4016 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 4084 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
4017 {
4018 // Self updates go into a special list
4019 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4020 terseAgentUpdates.Value.Add(update);
4021 }
4022 else
4023 {
4024 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
4025 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4026
4027 // Everything else goes here
4028 if (update.Entity is SceneObjectPart)
4029 {
4030 SceneObjectPart part = (SceneObjectPart)update.Entity;
4031
4032 // If the part has become a private hud since the update was scheduled then we do not
4033 // want to send it to other avatars.
4034 if (part.ParentGroup.IsAttachment
4035 && part.ParentGroup.HasPrivateAttachmentPoint
4036 && part.ParentGroup.AttachedAvatar != AgentId)
4037 continue;
4038
4039 // If the part has since been deleted, then drop the update. In the case of attachments,
4040 // this is to avoid spurious updates to other viewers since post-processing of attachments
4041 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4042 // of the test above).
4043 //
4044 // Actual deletions (kills) happen in another method.
4045 if (part.ParentGroup.IsDeleted)
4046 continue;
4047 }
4048
4049 terseUpdateBlocks.Value.Add(terseUpdateBlock);
4050 terseUpdates.Value.Add(update);
4051 }
4052 } 4085 }
4053
4054 ++updatesThisCall;
4055
4056 #endregion Block Construction
4057 } 4086 }
4058 4087 else if (!canUseImproved)
4059 #region Packet Sending
4060 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4061
4062 if (terseAgentUpdateBlocks.IsValueCreated)
4063 { 4088 {
4064 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4089 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
4090 }
4091 else
4092 {
4093 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4094 // Self updates go into a special list
4095 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4096 else
4097 // Everything else goes here
4098 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4099 }
4065 4100
4066 ImprovedTerseObjectUpdatePacket packet 4101 #endregion Block Construction
4067 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4102 }
4068 4103
4069 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4104 #region Packet Sending
4070 packet.RegionData.TimeDilation = timeDilation; 4105
4071 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4106 const float TIME_DILATION = 1.0f;
4107 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4108
4109 if (terseAgentUpdateBlocks.IsValueCreated)
4110 {
4111 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4072 4112
4073 for (int i = 0; i < blocks.Count; i++) 4113 ImprovedTerseObjectUpdatePacket packet
4074 packet.ObjectData[i] = blocks[i]; 4114 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4075 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4115 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4076 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4116 packet.RegionData.TimeDilation = timeDilation;
4077 } 4117 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4078 4118
4079 if (objectUpdateBlocks.IsValueCreated) 4119 for (int i = 0; i < blocks.Count; i++)
4080 { 4120 packet.ObjectData[i] = blocks[i];
4081 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4082
4083 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4084 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4085 packet.RegionData.TimeDilation = timeDilation;
4086 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4087
4088 for (int i = 0; i < blocks.Count; i++)
4089 packet.ObjectData[i] = blocks[i];
4090 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4091 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4092 }
4093
4094 if (compressedUpdateBlocks.IsValueCreated)
4095 {
4096 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4097
4098 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4099 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4100 packet.RegionData.TimeDilation = timeDilation;
4101 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4102
4103 for (int i = 0; i < blocks.Count; i++)
4104 packet.ObjectData[i] = blocks[i];
4105 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4106 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4107 }
4108 4121
4109 if (terseUpdateBlocks.IsValueCreated) 4122 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4110 { 4123 }
4111 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4112
4113 ImprovedTerseObjectUpdatePacket packet
4114 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4115 PacketType.ImprovedTerseObjectUpdate);
4116 4124
4117 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4125 if (objectUpdateBlocks.IsValueCreated)
4118 packet.RegionData.TimeDilation = timeDilation; 4126 {
4119 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4127 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4120 4128
4121 for (int i = 0; i < blocks.Count; i++) 4129 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4122 packet.ObjectData[i] = blocks[i]; 4130 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4123 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4131 packet.RegionData.TimeDilation = timeDilation;
4124 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4132 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4125 } 4133
4134 for (int i = 0; i < blocks.Count; i++)
4135 packet.ObjectData[i] = blocks[i];
4136
4137 OutPacket(packet, ThrottleOutPacketType.Task, true);
4138 }
4139
4140 if (compressedUpdateBlocks.IsValueCreated)
4141 {
4142 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4143
4144 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4145 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4146 packet.RegionData.TimeDilation = timeDilation;
4147 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4148
4149 for (int i = 0; i < blocks.Count; i++)
4150 packet.ObjectData[i] = blocks[i];
4151
4152 OutPacket(packet, ThrottleOutPacketType.Task, true);
4153 }
4154
4155 if (terseUpdateBlocks.IsValueCreated)
4156 {
4157 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4158
4159 ImprovedTerseObjectUpdatePacket packet
4160 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4161 PacketType.ImprovedTerseObjectUpdate);
4162 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4163 packet.RegionData.TimeDilation = timeDilation;
4164 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4165
4166 for (int i = 0; i < blocks.Count; i++)
4167 packet.ObjectData[i] = blocks[i];
4168
4169 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4126 } 4170 }
4127 4171
4128 #endregion Packet Sending 4172 #endregion Packet Sending
@@ -4442,11 +4486,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4442 4486
4443 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4487 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4444 // of the object rather than the properties when the packet was created 4488 // of the object rather than the properties when the packet was created
4445 OutPacket(packet, ThrottleOutPacketType.Task, true, 4489 // HACK : Remove intelligent resending until it's fixed in core
4446 delegate(OutgoingPacket oPacket) 4490 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4447 { 4491 // delegate(OutgoingPacket oPacket)
4448 ResendPropertyUpdates(updates, oPacket); 4492 // {
4449 }); 4493 // ResendPropertyUpdates(updates, oPacket);
4494 // });
4495 OutPacket(packet, ThrottleOutPacketType.Task, true);
4450 4496
4451 // pbcnt += blocks.Count; 4497 // pbcnt += blocks.Count;
4452 // ppcnt++; 4498 // ppcnt++;
@@ -4472,11 +4518,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4472 // of the object rather than the properties when the packet was created 4518 // of the object rather than the properties when the packet was created
4473 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4519 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4474 updates.Add(familyUpdates.Value[i]); 4520 updates.Add(familyUpdates.Value[i]);
4475 OutPacket(packet, ThrottleOutPacketType.Task, true, 4521 // HACK : Remove intelligent resending until it's fixed in core
4476 delegate(OutgoingPacket oPacket) 4522 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4477 { 4523 // delegate(OutgoingPacket oPacket)
4478 ResendPropertyUpdates(updates, oPacket); 4524 // {
4479 }); 4525 // ResendPropertyUpdates(updates, oPacket);
4526 // });
4527 OutPacket(packet, ThrottleOutPacketType.Task, true);
4480 4528
4481 // fpcnt++; 4529 // fpcnt++;
4482 // fbcnt++; 4530 // fbcnt++;
@@ -4848,7 +4896,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4848 4896
4849 if (landData.SimwideArea > 0) 4897 if (landData.SimwideArea > 0)
4850 { 4898 {
4851 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4899 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4900 // Never report more than sim total capacity
4901 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4902 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4852 updateMessage.SimWideMaxPrims = simulatorCapacity; 4903 updateMessage.SimWideMaxPrims = simulatorCapacity;
4853 } 4904 }
4854 else 4905 else
@@ -4977,14 +5028,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4977 5028
4978 if (notifyCount > 0) 5029 if (notifyCount > 0)
4979 { 5030 {
4980 if (notifyCount > 32) 5031// if (notifyCount > 32)
4981 { 5032// {
4982 m_log.InfoFormat( 5033// m_log.InfoFormat(
4983 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 5034// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4984 + " - a developer might want to investigate whether this is a hard limit", 32); 5035// + " - a developer might want to investigate whether this is a hard limit", 32);
4985 5036//
4986 notifyCount = 32; 5037// notifyCount = 32;
4987 } 5038// }
4988 5039
4989 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 5040 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4990 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 5041 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5039,9 +5090,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 { 5090 {
5040 ScenePresence presence = (ScenePresence)entity; 5091 ScenePresence presence = (ScenePresence)entity;
5041 5092
5042 attachPoint = presence.State;
5043 collisionPlane = presence.CollisionPlane;
5044 position = presence.OffsetPosition; 5093 position = presence.OffsetPosition;
5094 rotation = presence.Rotation;
5095
5096 if (presence.ParentID != 0)
5097 {
5098 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
5099 if (part != null && part != part.ParentGroup.RootPart)
5100 {
5101 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
5102 rotation = part.RotationOffset * presence.Rotation;
5103 }
5104 angularVelocity = Vector3.Zero;
5105 }
5106 else
5107 {
5108 angularVelocity = presence.AngularVelocity;
5109 rotation = presence.Rotation;
5110 }
5111
5112 attachPoint = 0;
5113 collisionPlane = presence.CollisionPlane;
5045 velocity = presence.Velocity; 5114 velocity = presence.Velocity;
5046 acceleration = Vector3.Zero; 5115 acceleration = Vector3.Zero;
5047 5116
@@ -5050,9 +5119,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5050 // may improve movement smoothness. 5119 // may improve movement smoothness.
5051// acceleration = new Vector3(1, 0, 0); 5120// acceleration = new Vector3(1, 0, 0);
5052 5121
5053 angularVelocity = presence.AngularVelocity;
5054 rotation = presence.Rotation;
5055
5056 if (sendTexture) 5122 if (sendTexture)
5057 textureEntry = presence.Appearance.Texture.GetBytes(); 5123 textureEntry = presence.Appearance.Texture.GetBytes();
5058 else 5124 else
@@ -5158,13 +5224,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5158 5224
5159 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5225 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5160 { 5226 {
5227 Vector3 offsetPosition = data.OffsetPosition;
5228 Quaternion rotation = data.Rotation;
5229 uint parentID = data.ParentID;
5230
5231 if (parentID != 0)
5232 {
5233 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5234 if (part != null && part != part.ParentGroup.RootPart)
5235 {
5236 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5237 rotation = part.RotationOffset * data.Rotation;
5238 parentID = part.ParentGroup.RootPart.LocalId;
5239 }
5240 }
5241
5161 byte[] objectData = new byte[76]; 5242 byte[] objectData = new byte[76];
5162 5243
5163 data.CollisionPlane.ToBytes(objectData, 0); 5244 data.CollisionPlane.ToBytes(objectData, 0);
5164 data.OffsetPosition.ToBytes(objectData, 16); 5245 offsetPosition.ToBytes(objectData, 16);
5246 Vector3 velocity = new Vector3(0, 0, 0);
5247 Vector3 acceleration = new Vector3(0, 0, 0);
5248 velocity.ToBytes(objectData, 28);
5249 acceleration.ToBytes(objectData, 40);
5165// data.Velocity.ToBytes(objectData, 28); 5250// data.Velocity.ToBytes(objectData, 28);
5166// data.Acceleration.ToBytes(objectData, 40); 5251// data.Acceleration.ToBytes(objectData, 40);
5167 data.Rotation.ToBytes(objectData, 52); 5252 rotation.ToBytes(objectData, 52);
5168 //data.AngularVelocity.ToBytes(objectData, 64); 5253 //data.AngularVelocity.ToBytes(objectData, 64);
5169 5254
5170 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5255 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5178,14 +5263,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5178 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5263 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5179 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5264 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5180 update.ObjectData = objectData; 5265 update.ObjectData = objectData;
5181 update.ParentID = data.ParentID; 5266 update.ParentID = parentID;
5182 update.PathCurve = 16; 5267 update.PathCurve = 16;
5183 update.PathScaleX = 100; 5268 update.PathScaleX = 100;
5184 update.PathScaleY = 100; 5269 update.PathScaleY = 100;
5185 update.PCode = (byte)PCode.Avatar; 5270 update.PCode = (byte)PCode.Avatar;
5186 update.ProfileCurve = 1; 5271 update.ProfileCurve = 1;
5187 update.PSBlock = Utils.EmptyBytes; 5272 update.PSBlock = Utils.EmptyBytes;
5188 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5273 update.Scale = data.Appearance.AvatarSize;
5274// update.Scale.Z -= 0.2f;
5275
5189 update.Text = Utils.EmptyBytes; 5276 update.Text = Utils.EmptyBytes;
5190 update.TextColor = new byte[4]; 5277 update.TextColor = new byte[4];
5191 5278
@@ -5196,10 +5283,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5196 update.TextureEntry = Utils.EmptyBytes; 5283 update.TextureEntry = Utils.EmptyBytes;
5197// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5284// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5198 5285
5286/* all this flags seem related to prims and not avatars. This allow for wrong viewer side move of a avatar in prim edition mode (anv mantis 854)
5199 update.UpdateFlags = (uint)( 5287 update.UpdateFlags = (uint)(
5200 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5288 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5201 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5289 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5202 PrimFlags.ObjectOwnerModify); 5290 PrimFlags.ObjectOwnerModify);
5291*/
5292 update.UpdateFlags = 0;
5203 5293
5204 return update; 5294 return update;
5205 } 5295 }
@@ -5370,8 +5460,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5370 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5460 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5371 // for each AgentUpdate packet. 5461 // for each AgentUpdate packet.
5372 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5462 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5373 5463
5374 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5464 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5465 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5466 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5375 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5467 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5376 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5468 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5377 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5469 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5523,6 +5615,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5523 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5615 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5524 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5616 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5525 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5617 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5618 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5526 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5619 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5527 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5620 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5528 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5621 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5589,6 +5682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5589 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5682 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5590 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5683 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5591 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5684 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5685 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5592 5686
5593 AddGenericPacketHandler("autopilot", HandleAutopilot); 5687 AddGenericPacketHandler("autopilot", HandleAutopilot);
5594 } 5688 }
@@ -5941,6 +6035,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5941 return true; 6035 return true;
5942 } 6036 }
5943 6037
6038 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
6039 {
6040 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
6041 if (p.AgentData.SessionID != SessionId ||
6042 p.AgentData.AgentID != AgentId)
6043 return true;
6044
6045 m_VelocityInterpolate = false;
6046 return true;
6047 }
6048
6049 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
6050 {
6051 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
6052 if (p.AgentData.SessionID != SessionId ||
6053 p.AgentData.AgentID != AgentId)
6054 return true;
6055
6056 m_VelocityInterpolate = true;
6057 return true;
6058 }
6059
6060
5944 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 6061 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5945 { 6062 {
5946 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 6063 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6365,26 +6482,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6365 // Temporarily protect ourselves from the mantis #951 failure. 6482 // Temporarily protect ourselves from the mantis #951 failure.
6366 // However, we could do this for several other handlers where a failure isn't terminal 6483 // However, we could do this for several other handlers where a failure isn't terminal
6367 // for the client session anyway, in order to protect ourselves against bad code in plugins 6484 // for the client session anyway, in order to protect ourselves against bad code in plugins
6485 Vector3 avSize = appear.AgentData.Size;
6368 try 6486 try
6369 { 6487 {
6370 byte[] visualparams = new byte[appear.VisualParam.Length]; 6488 byte[] visualparams = new byte[appear.VisualParam.Length];
6371 for (int i = 0; i < appear.VisualParam.Length; i++) 6489 for (int i = 0; i < appear.VisualParam.Length; i++)
6372 visualparams[i] = appear.VisualParam[i].ParamValue; 6490 visualparams[i] = appear.VisualParam[i].ParamValue;
6373 6491 //var b = appear.WearableData[0];
6492
6374 Primitive.TextureEntry te = null; 6493 Primitive.TextureEntry te = null;
6375 if (appear.ObjectData.TextureEntry.Length > 1) 6494 if (appear.ObjectData.TextureEntry.Length > 1)
6376 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6495 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6496
6497 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6498 for (int i=0; i<appear.WearableData.Length;i++)
6499 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6377 6500
6378 List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); 6501
6379 for (int i = 0; i < appear.WearableData.Length; i++)
6380 {
6381 CachedTextureRequestArg arg = new CachedTextureRequestArg();
6382 arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
6383 arg.WearableHashID = appear.WearableData[i].CacheID;
6384 hashes.Add(arg);
6385 }
6386 6502
6387 handlerSetAppearance(sender, te, visualparams, hashes); 6503 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6388 } 6504 }
6389 catch (Exception e) 6505 catch (Exception e)
6390 { 6506 {
@@ -6593,6 +6709,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6593 { 6709 {
6594 handlerCompleteMovementToRegion(sender, true); 6710 handlerCompleteMovementToRegion(sender, true);
6595 } 6711 }
6712 else
6713 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6714
6596 handlerCompleteMovementToRegion = null; 6715 handlerCompleteMovementToRegion = null;
6597 6716
6598 return true; 6717 return true;
@@ -6610,7 +6729,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6610 return true; 6729 return true;
6611 } 6730 }
6612 #endregion 6731 #endregion
6613 6732/*
6614 StartAnim handlerStartAnim = null; 6733 StartAnim handlerStartAnim = null;
6615 StopAnim handlerStopAnim = null; 6734 StopAnim handlerStopAnim = null;
6616 6735
@@ -6634,6 +6753,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6634 } 6753 }
6635 } 6754 }
6636 return true; 6755 return true;
6756*/
6757 ChangeAnim handlerChangeAnim = null;
6758
6759 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6760 {
6761 handlerChangeAnim = OnChangeAnim;
6762 if (handlerChangeAnim != null)
6763 {
6764 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6765 }
6766 }
6767
6768 handlerChangeAnim = OnChangeAnim;
6769 if (handlerChangeAnim != null)
6770 {
6771 handlerChangeAnim(UUID.Zero, false, true);
6772 }
6773
6774 return true;
6637 } 6775 }
6638 6776
6639 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6777 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6879,6 +7017,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6879 #endregion 7017 #endregion
6880 7018
6881 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 7019 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
7020 GenericCall2 handler = OnUpdateThrottles;
7021 if (handler != null)
7022 {
7023 handler();
7024 }
6882 return true; 7025 return true;
6883 } 7026 }
6884 7027
@@ -7303,7 +7446,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7303 physdata.Bounce = phsblock.Restitution; 7446 physdata.Bounce = phsblock.Restitution;
7304 physdata.Density = phsblock.Density; 7447 physdata.Density = phsblock.Density;
7305 physdata.Friction = phsblock.Friction; 7448 physdata.Friction = phsblock.Friction;
7306 physdata.GravitationModifier = phsblock.GravityMultiplier; 7449 physdata.GravitationModifier = phsblock.GravityMultiplier;
7307 } 7450 }
7308 7451
7309 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7452 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7889,6 +8032,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7889 // surrounding scene 8032 // surrounding scene
7890 if ((ImageType)block.Type == ImageType.Baked) 8033 if ((ImageType)block.Type == ImageType.Baked)
7891 args.Priority *= 2.0f; 8034 args.Priority *= 2.0f;
8035 int wearableout = 0;
7892 8036
7893 ImageManager.EnqueueReq(args); 8037 ImageManager.EnqueueReq(args);
7894 } 8038 }
@@ -8923,16 +9067,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8923 9067
8924 #region Parcel related packets 9068 #region Parcel related packets
8925 9069
9070 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
9071 // to be done with minimal resources as possible
9072 // variables temporary here while in test
9073
9074 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
9075 bool RegionHandleRequestsInService = false;
9076
8926 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 9077 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8927 { 9078 {
8928 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 9079 UUID currentUUID;
8929 9080
8930 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 9081 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8931 if (handlerRegionHandleRequest != null) 9082
9083 if (handlerRegionHandleRequest == null)
9084 return true;
9085
9086 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
9087
9088 lock (RegionHandleRequests)
8932 { 9089 {
8933 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 9090 if (RegionHandleRequestsInService)
9091 {
9092 // we are already busy doing a previus request
9093 // so enqueue it
9094 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
9095 return true;
9096 }
9097
9098 // else do it
9099 currentUUID = rhrPack.RequestBlock.RegionID;
9100 RegionHandleRequestsInService = true;
8934 } 9101 }
8935 return true; 9102
9103 while (true)
9104 {
9105 handlerRegionHandleRequest(this, currentUUID);
9106
9107 lock (RegionHandleRequests)
9108 {
9109 // exit condition, nothing to do or closed
9110 // current code seems to assume we may loose the handler at anytime,
9111 // so keep checking it
9112 handlerRegionHandleRequest = OnRegionHandleRequest;
9113
9114 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
9115 {
9116 RegionHandleRequests.Clear();
9117 RegionHandleRequestsInService = false;
9118 return true;
9119 }
9120 currentUUID = RegionHandleRequests.Dequeue();
9121 }
9122 }
9123
9124 return true; // actually unreached
8936 } 9125 }
8937 9126
8938 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 9127 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -10188,7 +10377,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10188 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10377 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10189 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10378 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10190 UpdateMuteListEntry.MuteData.MuteType, 10379 UpdateMuteListEntry.MuteData.MuteType,
10191 UpdateMuteListEntry.AgentData.AgentID); 10380 UpdateMuteListEntry.MuteData.MuteFlags);
10192 return true; 10381 return true;
10193 } 10382 }
10194 return false; 10383 return false;
@@ -10203,8 +10392,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10203 { 10392 {
10204 handlerRemoveMuteListEntry(this, 10393 handlerRemoveMuteListEntry(this,
10205 RemoveMuteListEntry.MuteData.MuteID, 10394 RemoveMuteListEntry.MuteData.MuteID,
10206 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10395 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10207 RemoveMuteListEntry.AgentData.AgentID);
10208 return true; 10396 return true;
10209 } 10397 }
10210 return false; 10398 return false;
@@ -10248,10 +10436,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10248 return false; 10436 return false;
10249 } 10437 }
10250 10438
10439 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10440 {
10441 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10442 (ChangeInventoryItemFlagsPacket)packet;
10443 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10444 if (handlerChangeInventoryItemFlags != null)
10445 {
10446 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10447 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10448 return true;
10449 }
10450 return false;
10451 }
10452
10251 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10453 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10252 { 10454 {
10253 return true; 10455 return true;
10254 } 10456 }
10457
10458 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10459 {
10460 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10461
10462 #region Packet Session and User Check
10463 if (m_checkPackets)
10464 {
10465 if (packet.AgentData.SessionID != SessionId ||
10466 packet.AgentData.AgentID != AgentId)
10467 return true;
10468 }
10469 #endregion
10470 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10471 List<InventoryItemBase> items = new List<InventoryItemBase>();
10472 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10473 {
10474 InventoryItemBase b = new InventoryItemBase();
10475 b.ID = n.OldItemID;
10476 b.Folder = n.OldFolderID;
10477 items.Add(b);
10478 }
10479
10480 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10481 if (handlerMoveItemsAndLeaveCopy != null)
10482 {
10483 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10484 }
10485
10486 return true;
10487 }
10255 10488
10256 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10489 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10257 { 10490 {
@@ -10678,6 +10911,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10678 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10911 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10679 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10912 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10680 10913
10914 Scene scene = (Scene)m_scene;
10915 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10916 {
10917 ScenePresence p;
10918 if (scene.TryGetScenePresence(sender.AgentId, out p))
10919 {
10920 if (p.GodLevel >= 200)
10921 {
10922 groupProfileReply.GroupData.OpenEnrollment = true;
10923 groupProfileReply.GroupData.MembershipFee = 0;
10924 }
10925 }
10926 }
10927
10681 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10928 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10682 } 10929 }
10683 return true; 10930 return true;
@@ -11251,11 +11498,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11251 11498
11252 StartLure handlerStartLure = OnStartLure; 11499 StartLure handlerStartLure = OnStartLure;
11253 if (handlerStartLure != null) 11500 if (handlerStartLure != null)
11254 handlerStartLure(startLureRequest.Info.LureType, 11501 {
11255 Utils.BytesToString( 11502 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11256 startLureRequest.Info.Message), 11503 {
11257 startLureRequest.TargetData[0].TargetID, 11504 handlerStartLure(startLureRequest.Info.LureType,
11258 this); 11505 Utils.BytesToString(
11506 startLureRequest.Info.Message),
11507 startLureRequest.TargetData[i].TargetID,
11508 this);
11509 }
11510 }
11259 return true; 11511 return true;
11260 } 11512 }
11261 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11513 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11369,10 +11621,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11369 } 11621 }
11370 #endregion 11622 #endregion
11371 11623
11372 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11624 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11373 if (handlerClassifiedGodDelete != null) 11625 if (handlerClassifiedGodDelete != null)
11374 handlerClassifiedGodDelete( 11626 handlerClassifiedGodDelete(
11375 classifiedGodDelete.Data.ClassifiedID, 11627 classifiedGodDelete.Data.ClassifiedID,
11628 classifiedGodDelete.Data.QueryID,
11376 this); 11629 this);
11377 return true; 11630 return true;
11378 } 11631 }
@@ -11675,12 +11928,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11675 /// <param name="simclient"></param> 11928 /// <param name="simclient"></param>
11676 /// <param name="packet"></param> 11929 /// <param name="packet"></param>
11677 /// <returns></returns> 11930 /// <returns></returns>
11678 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11931 // TODO: Convert old handler to use new method
11932 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11679 { 11933 {
11680 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11934 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11681 11935
11682 if (cachedtex.AgentData.SessionID != SessionId) 11936 if (cachedtex.AgentData.SessionID != SessionId)
11683 return false; 11937 return false;
11938
11684 11939
11685 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); 11940 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11686 11941
@@ -11693,23 +11948,173 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11693 requestArgs.Add(arg); 11948 requestArgs.Add(arg);
11694 } 11949 }
11695 11950
11696 try 11951 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11952 if (handlerCachedTextureRequest != null)
11697 { 11953 {
11698 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11954 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11699 if (handlerCachedTextureRequest != null) 11955 }
11956
11957 return true;
11958 }*/
11959
11960 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11961 {
11962 //m_log.Debug("texture cached: " + packet.ToString());
11963 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11964 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
11965
11966 if (cachedtex.AgentData.SessionID != SessionId)
11967 return false;
11968
11969
11970 // TODO: don't create new blocks if recycling an old packet
11971 cachedresp.AgentData.AgentID = AgentId;
11972 cachedresp.AgentData.SessionID = m_sessionId;
11973 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
11974 m_cachedTextureSerial++;
11975 cachedresp.WearableData =
11976 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11977
11978 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11979 // var item = fac.GetBakedTextureFaces(AgentId);
11980 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11981
11982 IAssetService cache = m_scene.AssetService;
11983 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11984 //bakedTextureModule = null;
11985 int maxWearablesLoop = cachedtex.WearableData.Length;
11986 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11987 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11988
11989 if (bakedTextureModule != null && cache != null)
11990 {
11991 // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
11992
11993 WearableCacheItem[] cacheItems = null;
11994 ScenePresence p = m_scene.GetScenePresence(AgentId);
11995 if (p.Appearance != null)
11996 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11997 {
11998 try
11999 {
12000 cacheItems = bakedTextureModule.Get(AgentId);
12001 p.Appearance.WearableCacheItems = cacheItems;
12002 p.Appearance.WearableCacheItemsDirty = false;
12003 }
12004
12005 /*
12006 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
12007 *
12008 catch (System.Net.Sockets.SocketException)
12009 {
12010 cacheItems = null;
12011 }
12012 catch (WebException)
12013 {
12014 cacheItems = null;
12015 }
12016 catch (InvalidOperationException)
12017 {
12018 cacheItems = null;
12019 } */
12020 catch (Exception)
12021 {
12022 cacheItems = null;
12023 }
12024
12025 }
12026 else if (p.Appearance.WearableCacheItems != null)
12027 {
12028 cacheItems = p.Appearance.WearableCacheItems;
12029 }
12030
12031 if (cache != null && cacheItems != null)
12032 {
12033 foreach (WearableCacheItem item in cacheItems)
12034 {
12035
12036 if (cache.GetCached(item.TextureID.ToString()) == null)
12037 {
12038 item.TextureAsset.Temporary = true;
12039 cache.Store(item.TextureAsset);
12040 }
12041
12042
12043 }
12044 }
12045
12046 if (cacheItems != null)
12047 {
12048
12049 for (int i = 0; i < maxWearablesLoop; i++)
12050 {
12051 WearableCacheItem item =
12052 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
12053
12054 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12055 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
12056 cachedresp.WearableData[i].HostName = new byte[0];
12057 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
12058 {
12059
12060 cachedresp.WearableData[i].TextureID = item.TextureID;
12061 }
12062 else
12063 {
12064 cachedresp.WearableData[i].TextureID = UUID.Zero;
12065 }
12066 }
12067 }
12068 else
11700 { 12069 {
11701 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 12070 for (int i = 0; i < maxWearablesLoop; i++)
12071 {
12072 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12073 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12074 cachedresp.WearableData[i].TextureID = UUID.Zero;
12075 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12076 cachedresp.WearableData[i].HostName = new byte[0];
12077 }
11702 } 12078 }
11703 } 12079 }
11704 catch (Exception e) 12080 else
11705 { 12081 {
11706 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); 12082 if (cache == null)
11707 return false; 12083 {
12084 for (int i = 0; i < maxWearablesLoop; i++)
12085 {
12086 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12087 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12088 cachedresp.WearableData[i].TextureID = UUID.Zero;
12089 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12090 cachedresp.WearableData[i].HostName = new byte[0];
12091 }
12092 }
12093 else
12094 {
12095 for (int i = 0; i < maxWearablesLoop; i++)
12096 {
12097 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12098 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12099
12100
12101
12102 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
12103 cachedresp.WearableData[i].TextureID = UUID.Zero;
12104 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12105 else
12106 cachedresp.WearableData[i].TextureID = UUID.Zero;
12107 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12108 cachedresp.WearableData[i].HostName = new byte[0];
12109 }
12110 }
11708 } 12111 }
11709 12112 cachedresp.Header.Zerocoded = true;
12113 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12114
11710 return true; 12115 return true;
11711 } 12116 }
11712 12117
11713 /// <summary> 12118 /// <summary>
11714 /// Send a response back to a client when it asks the asset server (via the region server) if it has 12119 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11715 /// its appearance texture cached. 12120 /// its appearance texture cached.
@@ -11773,209 +12178,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11773 } 12178 }
11774 else 12179 else
11775 { 12180 {
11776// m_log.DebugFormat( 12181 ClientChangeObject updatehandler = onClientChangeObject;
11777// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11778// i, block.Type, part.Name, part.LocalId);
11779 12182
11780// // Do this once since fetch parts creates a new array. 12183 if (updatehandler != null)
11781// SceneObjectPart[] parts = part.ParentGroup.Parts; 12184 {
11782// for (int j = 0; j < parts.Length; j++) 12185 ObjectChangeData udata = new ObjectChangeData();
11783// {
11784// part.StoreUndoState();
11785// parts[j].IgnoreUndoUpdate = true;
11786// }
11787 12186
11788 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 12187 /*ubit from ll JIRA:
12188 * 0x01 position
12189 * 0x02 rotation
12190 * 0x04 scale
12191
12192 * 0x08 LINK_SET
12193 * 0x10 UNIFORM for scale
12194 */
11789 12195
11790 switch (block.Type) 12196 // translate to internal changes
11791 { 12197 // not all cases .. just the ones older code did
11792 case 1:
11793 Vector3 pos1 = new Vector3(block.Data, 0);
11794 12198
11795 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12199 switch (block.Type)
11796 if (handlerUpdatePrimSinglePosition != null) 12200 {
11797 { 12201 case 1: //change position sp
11798 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12202 udata.position = new Vector3(block.Data, 0);
11799 handlerUpdatePrimSinglePosition(localId, pos1, this);
11800 }
11801 break;
11802 12203
11803 case 2: 12204 udata.change = ObjectChangeType.primP;
11804 Quaternion rot1 = new Quaternion(block.Data, 0, true); 12205 updatehandler(localId, udata, this);
12206 break;
11805 12207
11806 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 12208 case 2: // rotation sp
11807 if (handlerUpdatePrimSingleRotation != null) 12209 udata.rotation = new Quaternion(block.Data, 0, true);
11808 {
11809 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11810 handlerUpdatePrimSingleRotation(localId, rot1, this);
11811 }
11812 break;
11813 12210
11814 case 3: 12211 udata.change = ObjectChangeType.primR;
11815 Vector3 rotPos = new Vector3(block.Data, 0); 12212 updatehandler(localId, udata, this);
11816 Quaternion rot2 = new Quaternion(block.Data, 12, true); 12213 break;
11817 12214
11818 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 12215 case 3: // position plus rotation
11819 if (handlerUpdatePrimSingleRotationPosition != null) 12216 udata.position = new Vector3(block.Data, 0);
11820 { 12217 udata.rotation = new Quaternion(block.Data, 12, true);
11821 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11822 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11823 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11824 }
11825 break;
11826 12218
11827 case 4: 12219 udata.change = ObjectChangeType.primPR;
11828 case 20: 12220 updatehandler(localId, udata, this);
11829 Vector3 scale4 = new Vector3(block.Data, 0); 12221 break;
11830 12222
11831 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 12223 case 4: // scale sp
11832 if (handlerUpdatePrimScale != null) 12224 udata.scale = new Vector3(block.Data, 0);
11833 { 12225 udata.change = ObjectChangeType.primS;
11834 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11835 handlerUpdatePrimScale(localId, scale4, this);
11836 }
11837 break;
11838 12226
11839 case 5: 12227 updatehandler(localId, udata, this);
11840 Vector3 scale1 = new Vector3(block.Data, 12); 12228 break;
11841 Vector3 pos11 = new Vector3(block.Data, 0);
11842 12229
11843 handlerUpdatePrimScale = OnUpdatePrimScale; 12230 case 0x14: // uniform scale sp
11844 if (handlerUpdatePrimScale != null) 12231 udata.scale = new Vector3(block.Data, 0);
11845 {
11846 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11847 handlerUpdatePrimScale(localId, scale1, this);
11848 12232
11849 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12233 udata.change = ObjectChangeType.primUS;
11850 if (handlerUpdatePrimSinglePosition != null) 12234 updatehandler(localId, udata, this);
11851 { 12235 break;
11852 handlerUpdatePrimSinglePosition(localId, pos11, this);
11853 }
11854 }
11855 break;
11856 12236
11857 case 9: 12237 case 5: // scale and position sp
11858 Vector3 pos2 = new Vector3(block.Data, 0); 12238 udata.position = new Vector3(block.Data, 0);
12239 udata.scale = new Vector3(block.Data, 12);
11859 12240
11860 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 12241 udata.change = ObjectChangeType.primPS;
12242 updatehandler(localId, udata, this);
12243 break;
11861 12244
11862 if (handlerUpdateVector != null) 12245 case 0x15: //uniform scale and position
11863 { 12246 udata.position = new Vector3(block.Data, 0);
11864 handlerUpdateVector(localId, pos2, this); 12247 udata.scale = new Vector3(block.Data, 12);
11865 }
11866 break;
11867 12248
11868 case 10: 12249 udata.change = ObjectChangeType.primPUS;
11869 Quaternion rot3 = new Quaternion(block.Data, 0, true); 12250 updatehandler(localId, udata, this);
12251 break;
11870 12252
11871 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 12253 // now group related (bit 4)
11872 if (handlerUpdatePrimRotation != null) 12254 case 9: //( 8 + 1 )group position
11873 { 12255 udata.position = new Vector3(block.Data, 0);
11874 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11875 handlerUpdatePrimRotation(localId, rot3, this);
11876 }
11877 break;
11878 12256
11879 case 11: 12257 udata.change = ObjectChangeType.groupP;
11880 Vector3 pos3 = new Vector3(block.Data, 0); 12258 updatehandler(localId, udata, this);
11881 Quaternion rot4 = new Quaternion(block.Data, 12, true); 12259 break;
11882 12260
11883 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 12261 case 0x0A: // (8 + 2) group rotation
11884 if (handlerUpdatePrimGroupRotation != null) 12262 udata.rotation = new Quaternion(block.Data, 0, true);
11885 {
11886 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11887 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11888 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11889 }
11890 break;
11891 case 12:
11892 case 28:
11893 Vector3 scale7 = new Vector3(block.Data, 0);
11894 12263
11895 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12264 udata.change = ObjectChangeType.groupR;
11896 if (handlerUpdatePrimGroupScale != null) 12265 updatehandler(localId, udata, this);
11897 { 12266 break;
11898 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11899 handlerUpdatePrimGroupScale(localId, scale7, this);
11900 }
11901 break;
11902 12267
11903 case 13: 12268 case 0x0B: //( 8 + 2 + 1) group rotation and position
11904 Vector3 scale2 = new Vector3(block.Data, 12); 12269 udata.position = new Vector3(block.Data, 0);
11905 Vector3 pos4 = new Vector3(block.Data, 0); 12270 udata.rotation = new Quaternion(block.Data, 12, true);
11906 12271
11907 handlerUpdatePrimScale = OnUpdatePrimScale; 12272 udata.change = ObjectChangeType.groupPR;
11908 if (handlerUpdatePrimScale != null) 12273 updatehandler(localId, udata, this);
11909 { 12274 break;
11910 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11911 handlerUpdatePrimScale(localId, scale2, this);
11912 12275
11913 // Change the position based on scale (for bug number 246) 12276 case 0x0C: // (8 + 4) group scale
11914 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12277 // only afects root prim and only sent by viewer editor object tab scaling
11915 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12278 // mouse edition only allows uniform scaling
11916 if (handlerUpdatePrimSinglePosition != null) 12279 // SL MAY CHANGE THIS in viewers
11917 {
11918 handlerUpdatePrimSinglePosition(localId, pos4, this);
11919 }
11920 }
11921 break;
11922 12280
11923 case 29: 12281 udata.scale = new Vector3(block.Data, 0);
11924 Vector3 scale5 = new Vector3(block.Data, 12);
11925 Vector3 pos5 = new Vector3(block.Data, 0);
11926 12282
11927 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12283 udata.change = ObjectChangeType.groupS;
11928 if (handlerUpdatePrimGroupScale != null) 12284 updatehandler(localId, udata, this);
11929 {
11930 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11931 part.StoreUndoState(true);
11932 part.IgnoreUndoUpdate = true;
11933 handlerUpdatePrimGroupScale(localId, scale5, this);
11934 handlerUpdateVector = OnUpdatePrimGroupPosition;
11935 12285
11936 if (handlerUpdateVector != null) 12286 break;
11937 {
11938 handlerUpdateVector(localId, pos5, this);
11939 }
11940 12287
11941 part.IgnoreUndoUpdate = false; 12288 case 0x0D: //(8 + 4 + 1) group scale and position
11942 } 12289 // exception as above
11943 12290
11944 break; 12291 udata.position = new Vector3(block.Data, 0);
12292 udata.scale = new Vector3(block.Data, 12);
11945 12293
11946 case 21: 12294 udata.change = ObjectChangeType.groupPS;
11947 Vector3 scale6 = new Vector3(block.Data, 12); 12295 updatehandler(localId, udata, this);
11948 Vector3 pos6 = new Vector3(block.Data, 0); 12296 break;
11949 12297
11950 handlerUpdatePrimScale = OnUpdatePrimScale; 12298 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11951 if (handlerUpdatePrimScale != null) 12299 udata.scale = new Vector3(block.Data, 0);
11952 {
11953 part.StoreUndoState(false);
11954 part.IgnoreUndoUpdate = true;
11955 12300
11956 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12301 udata.change = ObjectChangeType.groupUS;
11957 handlerUpdatePrimScale(localId, scale6, this); 12302 updatehandler(localId, udata, this);
11958 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12303 break;
11959 if (handlerUpdatePrimSinglePosition != null)
11960 {
11961 handlerUpdatePrimSinglePosition(localId, pos6, this);
11962 }
11963 12304
11964 part.IgnoreUndoUpdate = false; 12305 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11965 } 12306 udata.position = new Vector3(block.Data, 0);
11966 break; 12307 udata.scale = new Vector3(block.Data, 12);
11967 12308
11968 default: 12309 udata.change = ObjectChangeType.groupPUS;
11969 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12310 updatehandler(localId, udata, this);
11970 break; 12311 break;
12312
12313 default:
12314 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12315 break;
12316 }
11971 } 12317 }
11972 12318
11973// for (int j = 0; j < parts.Length; j++)
11974// parts[j].IgnoreUndoUpdate = false;
11975 } 12319 }
11976 } 12320 }
11977 } 12321 }
11978
11979 return true; 12322 return true;
11980 } 12323 }
11981 12324
@@ -12036,9 +12379,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12036 public void SetChildAgentThrottle(byte[] throttles) 12379 public void SetChildAgentThrottle(byte[] throttles)
12037 { 12380 {
12038 m_udpClient.SetThrottles(throttles); 12381 m_udpClient.SetThrottles(throttles);
12382 GenericCall2 handler = OnUpdateThrottles;
12383 if (handler != null)
12384 {
12385 handler();
12386 }
12039 } 12387 }
12040 12388
12041 /// <summary> 12389 /// <summary>
12390 /// Sets the throttles from values supplied by the client
12391 /// </summary>
12392 /// <param name="throttles"></param>
12393 public void SetAgentThrottleSilent(int throttle, int setting)
12394 {
12395 m_udpClient.ForceThrottleSetting(throttle,setting);
12396 //m_udpClient.SetThrottles(throttles);
12397
12398 }
12399
12400
12401 /// <summary>
12042 /// Get the current throttles for this client as a packed byte array 12402 /// Get the current throttles for this client as a packed byte array
12043 /// </summary> 12403 /// </summary>
12044 /// <param name="multiplier">Unused</param> 12404 /// <param name="multiplier">Unused</param>
@@ -12421,7 +12781,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12421// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12781// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12422// requestID, taskID, (SourceType)sourceType, Name); 12782// requestID, taskID, (SourceType)sourceType, Name);
12423 12783
12784
12785 //Note, the bool returned from the below function is useless since it is always false.
12424 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12786 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12787
12425 } 12788 }
12426 12789
12427 /// <summary> 12790 /// <summary>
@@ -12487,7 +12850,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12487 /// <returns></returns> 12850 /// <returns></returns>
12488 private static int CalculateNumPackets(byte[] data) 12851 private static int CalculateNumPackets(byte[] data)
12489 { 12852 {
12490 const uint m_maxPacketSize = 600; 12853// const uint m_maxPacketSize = 600;
12854 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12491 int numPackets = 1; 12855 int numPackets = 1;
12492 12856
12493 if (data == null) 12857 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 202cc62..d52ad7e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -95,7 +95,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
95 /// <summary>Packets we have sent that need to be ACKed by the client</summary> 95 /// <summary>Packets we have sent that need to be ACKed by the client</summary>
96 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); 96 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
97 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary> 97 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
98 public readonly OpenSim.Framework.LocklessQueue<uint> PendingAcks = new OpenSim.Framework.LocklessQueue<uint>(); 98 public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
99 99
100 /// <summary>Current packet sequence number</summary> 100 /// <summary>Current packet sequence number</summary>
101 public int CurrentSequence; 101 public int CurrentSequence;
@@ -149,7 +149,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
149 /// <summary>Throttle buckets for each packet category</summary> 149 /// <summary>Throttle buckets for each packet category</summary>
150 private readonly TokenBucket[] m_throttleCategories; 150 private readonly TokenBucket[] m_throttleCategories;
151 /// <summary>Outgoing queues for throttled packets</summary> 151 /// <summary>Outgoing queues for throttled packets</summary>
152 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 152 private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
153 /// <summary>A container that can hold one packet for each outbox, used to store 153 /// <summary>A container that can hold one packet for each outbox, used to store
154 /// dequeued packets that are being held for throttling</summary> 154 /// dequeued packets that are being held for throttling</summary>
155 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; 155 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
@@ -161,6 +161,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
161 161
162 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 162 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
163 private int m_maxRTO = 60000; 163 private int m_maxRTO = 60000;
164 public bool m_deliverPackets = true;
164 165
165 private ClientInfo m_info = new ClientInfo(); 166 private ClientInfo m_info = new ClientInfo();
166 167
@@ -206,7 +207,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
206 ThrottleOutPacketType type = (ThrottleOutPacketType)i; 207 ThrottleOutPacketType type = (ThrottleOutPacketType)i;
207 208
208 // Initialize the packet outboxes, where packets sit while they are waiting for tokens 209 // Initialize the packet outboxes, where packets sit while they are waiting for tokens
209 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 210 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
210 // Initialize the token buckets that control the throttling for each category 211 // Initialize the token buckets that control the throttling for each category
211 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); 212 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
212 } 213 }
@@ -431,11 +432,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
431 /// </returns> 432 /// </returns>
432 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) 433 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
433 { 434 {
435 return EnqueueOutgoing(packet, forceQueue, false);
436 }
437
438 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue, bool highPriority)
439 {
434 int category = (int)packet.Category; 440 int category = (int)packet.Category;
435 441
436 if (category >= 0 && category < m_packetOutboxes.Length) 442 if (category >= 0 && category < m_packetOutboxes.Length)
437 { 443 {
438 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 444 DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
445
446 if (m_deliverPackets == false)
447 {
448 queue.Enqueue(packet, highPriority);
449 return true;
450 }
451
439 TokenBucket bucket = m_throttleCategories[category]; 452 TokenBucket bucket = m_throttleCategories[category];
440 453
441 // Don't send this packet if there is already a packet waiting in the queue 454 // Don't send this packet if there is already a packet waiting in the queue
@@ -443,7 +456,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
443 // queued packets 456 // queued packets
444 if (queue.Count > 0) 457 if (queue.Count > 0)
445 { 458 {
446 queue.Enqueue(packet); 459 queue.Enqueue(packet, highPriority);
447 return true; 460 return true;
448 } 461 }
449 462
@@ -456,7 +469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
456 else 469 else
457 { 470 {
458 // Force queue specified or not enough tokens in the bucket, queue this packet 471 // Force queue specified or not enough tokens in the bucket, queue this packet
459 queue.Enqueue(packet); 472 queue.Enqueue(packet, highPriority);
460 return true; 473 return true;
461 } 474 }
462 } 475 }
@@ -485,8 +498,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
485 /// <returns>True if any packets were sent, otherwise false</returns> 498 /// <returns>True if any packets were sent, otherwise false</returns>
486 public bool DequeueOutgoing() 499 public bool DequeueOutgoing()
487 { 500 {
488 OutgoingPacket packet; 501 if (m_deliverPackets == false) return false;
489 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502
503 OutgoingPacket packet = null;
504 DoubleLocklessQueue<OutgoingPacket> queue;
490 TokenBucket bucket; 505 TokenBucket bucket;
491 bool packetSent = false; 506 bool packetSent = false;
492 ThrottleOutPacketTypeFlags emptyCategories = 0; 507 ThrottleOutPacketTypeFlags emptyCategories = 0;
@@ -517,32 +532,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
517 // No dequeued packet waiting to be sent, try to pull one off 532 // No dequeued packet waiting to be sent, try to pull one off
518 // this queue 533 // this queue
519 queue = m_packetOutboxes[i]; 534 queue = m_packetOutboxes[i];
520 if (queue.Dequeue(out packet)) 535 if (queue != null)
521 { 536 {
522 // A packet was pulled off the queue. See if we have 537 bool success = false;
523 // enough tokens in the bucket to send it out 538 try
524 if (bucket.RemoveTokens(packet.Buffer.DataLength))
525 { 539 {
526 // Send the packet 540 success = queue.Dequeue(out packet);
527 m_udpServer.SendPacketFinal(packet);
528 packetSent = true;
529 } 541 }
530 else 542 catch
531 { 543 {
532 // Save the dequeued packet for the next iteration 544 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
533 m_nextPackets[i] = packet;
534 } 545 }
535 546 if (success)
536 // If the queue is empty after this dequeue, fire the queue 547 {
537 // empty callback now so it has a chance to fill before we 548 // A packet was pulled off the queue. See if we have
538 // get back here 549 // enough tokens in the bucket to send it out
539 if (queue.Count == 0) 550 if (bucket.RemoveTokens(packet.Buffer.DataLength))
551 {
552 // Send the packet
553 m_udpServer.SendPacketFinal(packet);
554 packetSent = true;
555 }
556 else
557 {
558 // Save the dequeued packet for the next iteration
559 m_nextPackets[i] = packet;
560 }
561
562 // If the queue is empty after this dequeue, fire the queue
563 // empty callback now so it has a chance to fill before we
564 // get back here
565 if (queue.Count == 0)
566 emptyCategories |= CategoryToFlag(i);
567 }
568 else
569 {
570 // No packets in this queue. Fire the queue empty callback
571 // if it has not been called recently
540 emptyCategories |= CategoryToFlag(i); 572 emptyCategories |= CategoryToFlag(i);
573 }
541 } 574 }
542 else 575 else
543 { 576 {
544 // No packets in this queue. Fire the queue empty callback 577 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
545 // if it has not been called recently
546 emptyCategories |= CategoryToFlag(i); 578 emptyCategories |= CategoryToFlag(i);
547 } 579 }
548 } 580 }
@@ -683,6 +715,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
683 715
684 m_isQueueEmptyRunning = false; 716 m_isQueueEmptyRunning = false;
685 } 717 }
718 internal void ForceThrottleSetting(int throttle, int setting)
719 {
720 m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
721 }
686 722
687 /// <summary> 723 /// <summary>
688 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a 724 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
@@ -727,4 +763,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
727 } 763 }
728 } 764 }
729 } 765 }
766
767 public class DoubleLocklessQueue<T> : OpenSim.Framework.LocklessQueue<T>
768 {
769 OpenSim.Framework.LocklessQueue<T> highQueue = new OpenSim.Framework.LocklessQueue<T>();
770
771 public override int Count
772 {
773 get
774 {
775 return base.Count + highQueue.Count;
776 }
777 }
778
779 public override bool Dequeue(out T item)
780 {
781 if (highQueue.Dequeue(out item))
782 return true;
783
784 return base.Dequeue(out item);
785 }
786
787 public void Enqueue(T item, bool highPriority)
788 {
789 if (highPriority)
790 highQueue.Enqueue(item);
791 else
792 Enqueue(item);
793 }
794 }
730} 795}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 8d957dc..01981dd 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -210,7 +210,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
210 /// <summary>Handlers for incoming packets</summary> 210 /// <summary>Handlers for incoming packets</summary>
211 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 211 //PacketEventDictionary packetEvents = new PacketEventDictionary();
212 /// <summary>Incoming packets that are awaiting handling</summary> 212 /// <summary>Incoming packets that are awaiting handling</summary>
213 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 213 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
214
215 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
214 216
215 /// <summary></summary> 217 /// <summary></summary>
216 //private UDPClientCollection m_clients = new UDPClientCollection(); 218 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -265,6 +267,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
265 /// <summary>Flag to signal when clients should send pings</summary> 267 /// <summary>Flag to signal when clients should send pings</summary>
266 protected bool m_sendPing; 268 protected bool m_sendPing;
267 269
270 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
271
268 /// <summary> 272 /// <summary>
269 /// Event used to signal when queued packets are available for sending. 273 /// Event used to signal when queued packets are available for sending.
270 /// </summary> 274 /// </summary>
@@ -1011,6 +1015,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1011 1015
1012 #region Queue or Send 1016 #region Queue or Send
1013 1017
1018 bool highPriority = false;
1019
1020 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
1021 {
1022 category = (ThrottleOutPacketType)((int)category & 127);
1023 highPriority = true;
1024 }
1025
1014 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 1026 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
1015 // If we were not provided a method for handling unacked, use the UDPServer default method 1027 // If we were not provided a method for handling unacked, use the UDPServer default method
1016 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 1028 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -1019,7 +1031,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1019 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 1031 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
1020 // packet so that it isn't sent before a queued update packet. 1032 // packet so that it isn't sent before a queued update packet.
1021 bool requestQueue = type == PacketType.KillObject; 1033 bool requestQueue = type == PacketType.KillObject;
1022 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 1034 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
1023 SendPacketFinal(outgoingPacket); 1035 SendPacketFinal(outgoingPacket);
1024 1036
1025 #endregion Queue or Send 1037 #endregion Queue or Send
@@ -1310,34 +1322,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1310 1322
1311 #region Packet to Client Mapping 1323 #region Packet to Client Mapping
1312 1324
1313 // UseCircuitCode handling 1325 // If there is already a client for this endpoint, don't process UseCircuitCode
1314 if (packet.Type == PacketType.UseCircuitCode) 1326 IClientAPI client = null;
1327 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1315 { 1328 {
1316 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1329 // UseCircuitCode handling
1317 // buffer. 1330 if (packet.Type == PacketType.UseCircuitCode)
1318 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1331 {
1332 // And if there is a UseCircuitCode pending, also drop it
1333 lock (m_pendingCache)
1334 {
1335 if (m_pendingCache.Contains(endPoint))
1336 return;
1319 1337
1320 Util.FireAndForget(HandleUseCircuitCode, array); 1338 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1339 }
1321 1340
1322 return; 1341 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1342 // buffer.
1343 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1344
1345 Util.FireAndForget(HandleUseCircuitCode, array);
1346
1347 return;
1348 }
1323 } 1349 }
1324 else if (packet.Type == PacketType.CompleteAgentMovement) 1350
1351 // If this is a pending connection, enqueue, don't process yet
1352 lock (m_pendingCache)
1325 { 1353 {
1326 // Send ack straight away to let the viewer know that we got it. 1354 Queue<UDPPacketBuffer> queue;
1327 SendAckImmediate(endPoint, packet.Header.Sequence); 1355 if (m_pendingCache.TryGetValue(endPoint, out queue))
1356 {
1357 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1358 queue.Enqueue(buffer);
1359 return;
1360 }
1361 else if (packet.Type == PacketType.CompleteAgentMovement)
1362 {
1363 // Send ack straight away to let the viewer know that we got it.
1364 SendAckImmediate(endPoint, packet.Header.Sequence);
1328 1365
1329 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1366 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1330 // buffer. 1367 // buffer.
1331 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1368 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1332 1369
1333 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1370 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1334 1371
1335 return; 1372 return;
1373 }
1336 } 1374 }
1337 1375
1338 // Determine which agent this packet came from 1376 // Determine which agent this packet came from
1339 IClientAPI client; 1377 if (client == null || !(client is LLClientView))
1340 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1341 { 1378 {
1342 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1379 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1343 1380
@@ -1354,7 +1391,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1354 udpClient = ((LLClientView)client).UDPClient; 1391 udpClient = ((LLClientView)client).UDPClient;
1355 1392
1356 if (!udpClient.IsConnected) 1393 if (!udpClient.IsConnected)
1394 {
1395 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1357 return; 1396 return;
1397 }
1358 1398
1359 #endregion Packet to Client Mapping 1399 #endregion Packet to Client Mapping
1360 1400
@@ -1503,7 +1543,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1503 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1543 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1504 } 1544 }
1505 1545
1506 packetInbox.Enqueue(incomingPacket); 1546 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1547 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1548 packetInbox.EnqueueHigh(incomingPacket);
1549 else
1550 packetInbox.EnqueueLow(incomingPacket);
1507 } 1551 }
1508 1552
1509 #region BinaryStats 1553 #region BinaryStats
@@ -1655,6 +1699,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1655 if (!tp) 1699 if (!tp)
1656 client.SceneAgent.SendInitialDataToMe(); 1700 client.SceneAgent.SendInitialDataToMe();
1657 } 1701 }
1702
1703 // Now we know we can handle more data
1704 Thread.Sleep(200);
1705
1706 // Obtain the queue and remove it from the cache
1707 Queue<UDPPacketBuffer> queue = null;
1708
1709 lock (m_pendingCache)
1710 {
1711 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1712 {
1713 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1714 return;
1715 }
1716 m_pendingCache.Remove(endPoint);
1717 }
1718
1719 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1720
1721 // Reinject queued packets
1722 while(queue.Count > 0)
1723 {
1724 UDPPacketBuffer buf = queue.Dequeue();
1725 PacketReceived(buf);
1726 }
1727 queue = null;
1658 } 1728 }
1659 else 1729 else
1660 { 1730 {
@@ -1662,6 +1732,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1662 m_log.WarnFormat( 1732 m_log.WarnFormat(
1663 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1733 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1664 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1734 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1735 lock (m_pendingCache)
1736 m_pendingCache.Remove(endPoint);
1665 } 1737 }
1666 1738
1667 // m_log.DebugFormat( 1739 // m_log.DebugFormat(
@@ -1904,6 +1976,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1904 1976
1905 while (IsRunningInbound) 1977 while (IsRunningInbound)
1906 { 1978 {
1979 m_scene.ThreadAlive(1);
1907 try 1980 try
1908 { 1981 {
1909 IncomingPacket incomingPacket = null; 1982 IncomingPacket incomingPacket = null;
@@ -1953,6 +2026,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1953 2026
1954 while (base.IsRunningOutbound) 2027 while (base.IsRunningOutbound)
1955 { 2028 {
2029 m_scene.ThreadAlive(2);
1956 try 2030 try
1957 { 2031 {
1958 m_packetSent = false; 2032 m_packetSent = false;
@@ -2188,8 +2262,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2188 Packet packet = incomingPacket.Packet; 2262 Packet packet = incomingPacket.Packet;
2189 LLClientView client = incomingPacket.Client; 2263 LLClientView client = incomingPacket.Client;
2190 2264
2191 if (client.IsActive) 2265// if (client.IsActive)
2192 { 2266// {
2193 m_currentIncomingClient = client; 2267 m_currentIncomingClient = client;
2194 2268
2195 try 2269 try
@@ -2216,13 +2290,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2216 { 2290 {
2217 m_currentIncomingClient = null; 2291 m_currentIncomingClient = null;
2218 } 2292 }
2219 } 2293// }
2220 else 2294// else
2221 { 2295// {
2222 m_log.DebugFormat( 2296// m_log.DebugFormat(
2223 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2297// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2224 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2298// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2225 } 2299// }
2226 2300
2227 IncomingPacketsProcessed++; 2301 IncomingPacketsProcessed++;
2228 } 2302 }
@@ -2238,4 +2312,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2238 } 2312 }
2239 } 2313 }
2240 } 2314 }
2241} \ No newline at end of file 2315}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 88494be..881e768 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -146,10 +146,6 @@ namespace OpenMetaverse
146 const int SIO_UDP_CONNRESET = -1744830452; 146 const int SIO_UDP_CONNRESET = -1744830452;
147 147
148 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 148 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
149
150 m_log.DebugFormat(
151 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
152 ipep.Address, ipep.Port);
153 149
154 m_udpSocket = new Socket( 150 m_udpSocket = new Socket(
155 AddressFamily.InterNetwork, 151 AddressFamily.InterNetwork,