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.cs1505
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs115
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs138
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 1127 insertions, 638 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 8b2440a..0e20e38 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,16 @@ 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;
330 336
337 private bool m_VelocityInterpolate = false;
338 private const uint MaxTransferBytesPerPacket = 600;
339
340
331 /// <value> 341 /// <value>
332 /// List used in construction of data blocks for an object update packet. This is to stop us having to 342 /// List used in construction of data blocks for an object update packet. This is to stop us having to
333 /// continually recreate it. 343 /// continually recreate it.
@@ -339,13 +349,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 349 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
340 /// ownerless phantom. 350 /// ownerless phantom.
341 /// 351 ///
342 /// All manipulation of this set has to occur under a lock 352 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
343 /// 353 ///
344 /// </value> 354 /// </value>
345 protected HashSet<uint> m_killRecord; 355// protected HashSet<uint> m_killRecord;
346 356
347// protected HashSet<uint> m_attachmentsSent; 357// protected HashSet<uint> m_attachmentsSent;
348 358
359 private bool m_deliverPackets = true;
349 private int m_animationSequenceNumber = 1; 360 private int m_animationSequenceNumber = 1;
350 private bool m_SendLogoutPacketWhenClosing = true; 361 private bool m_SendLogoutPacketWhenClosing = true;
351 362
@@ -392,6 +403,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
392 get { return m_startpos; } 403 get { return m_startpos; }
393 set { m_startpos = value; } 404 set { m_startpos = value; }
394 } 405 }
406 public bool DeliverPackets
407 {
408 get { return m_deliverPackets; }
409 set {
410 m_deliverPackets = value;
411 m_udpClient.m_deliverPackets = value;
412 }
413 }
395 public UUID AgentId { get { return m_agentId; } } 414 public UUID AgentId { get { return m_agentId; } }
396 public ISceneAgent SceneAgent { get; set; } 415 public ISceneAgent SceneAgent { get; set; }
397 public UUID ActiveGroupId { get { return m_activeGroupID; } } 416 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -442,6 +461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
442 } 461 }
443 462
444 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 463 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
464
445 465
446 #endregion Properties 466 #endregion Properties
447 467
@@ -468,7 +488,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 488 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 489 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 490 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 491// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 492// m_attachmentsSent = new HashSet<uint>();
473 493
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 494 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +518,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 518
499 #region Client Methods 519 #region Client Methods
500 520
521
522 /// <summary>
523 /// Close down the client view
524 /// </summary>
501 public void Close() 525 public void Close()
502 { 526 {
503 Close(false); 527 Close(true, false);
504 } 528 }
505 529
506 public void Close(bool force) 530 public void Close(bool sendStop, bool force)
507 { 531 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 532 // 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. 533 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -515,7 +539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return; 539 return;
516 540
517 IsActive = false; 541 IsActive = false;
518 CloseWithoutChecks(); 542 CloseWithoutChecks(sendStop);
519 } 543 }
520 } 544 }
521 545
@@ -528,12 +552,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
528 /// 552 ///
529 /// Callers must lock ClosingSyncLock before calling. 553 /// Callers must lock ClosingSyncLock before calling.
530 /// </remarks> 554 /// </remarks>
531 public void CloseWithoutChecks() 555 public void CloseWithoutChecks(bool sendStop)
532 { 556 {
533 m_log.DebugFormat( 557 m_log.DebugFormat(
534 "[CLIENT]: Close has been called for {0} attached to scene {1}", 558 "[CLIENT]: Close has been called for {0} attached to scene {1}",
535 Name, m_scene.RegionInfo.RegionName); 559 Name, m_scene.RegionInfo.RegionName);
536 560
561 if (sendStop)
562 {
563 // Send the STOP packet
564 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
565 OutPacket(disable, ThrottleOutPacketType.Unknown);
566 }
567
537 // Shutdown the image manager 568 // Shutdown the image manager
538 ImageManager.Close(); 569 ImageManager.Close();
539 570
@@ -556,6 +587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
556 // Disable UDP handling for this client 587 // Disable UDP handling for this client
557 m_udpClient.Shutdown(); 588 m_udpClient.Shutdown();
558 589
590
559 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 591 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
560 //GC.Collect(); 592 //GC.Collect();
561 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 593 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -852,7 +884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
852 reply.ChatData.OwnerID = ownerID; 884 reply.ChatData.OwnerID = ownerID;
853 reply.ChatData.SourceID = fromAgentID; 885 reply.ChatData.SourceID = fromAgentID;
854 886
855 OutPacket(reply, ThrottleOutPacketType.Task); 887 OutPacket(reply, ThrottleOutPacketType.Unknown);
856 } 888 }
857 889
858 /// <summary> 890 /// <summary>
@@ -885,32 +917,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
885 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 917 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
886 msg.MessageBlock.BinaryBucket = im.binaryBucket; 918 msg.MessageBlock.BinaryBucket = im.binaryBucket;
887 919
888 if (im.message.StartsWith("[grouptest]")) 920 OutPacket(msg, ThrottleOutPacketType.Task);
889 { // this block is test code for implementing group IM - delete when group IM is finished
890 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
891 if (eq != null)
892 {
893 im.dialog = 17;
894
895 //eq.ChatterboxInvitation(
896 // new UUID("00000000-68f9-1111-024e-222222111123"),
897 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
898 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
899
900 eq.ChatterboxInvitation(
901 new UUID("00000000-68f9-1111-024e-222222111123"),
902 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
903 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
904
905 eq.ChatterBoxSessionAgentListUpdates(
906 new UUID("00000000-68f9-1111-024e-222222111123"),
907 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
908 }
909
910 Console.WriteLine("SendInstantMessage: " + msg);
911 }
912 else
913 OutPacket(msg, ThrottleOutPacketType.Task);
914 } 921 }
915 } 922 }
916 923
@@ -1148,6 +1155,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1148 public virtual void SendLayerData(float[] map) 1155 public virtual void SendLayerData(float[] map)
1149 { 1156 {
1150 Util.FireAndForget(DoSendLayerData, map); 1157 Util.FireAndForget(DoSendLayerData, map);
1158
1159 // Send it sync, and async. It's not that much data
1160 // and it improves user experience just so much!
1161 DoSendLayerData(map);
1151 } 1162 }
1152 1163
1153 /// <summary> 1164 /// <summary>
@@ -1160,16 +1171,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1160 1171
1161 try 1172 try
1162 { 1173 {
1163 //for (int y = 0; y < 16; y++) 1174 for (int y = 0; y < 16; y++)
1164 //{ 1175 {
1165 // for (int x = 0; x < 16; x++) 1176 for (int x = 0; x < 16; x+=4)
1166 // { 1177 {
1167 // SendLayerData(x, y, map); 1178 SendLayerPacket(x, y, map);
1168 // } 1179 }
1169 //} 1180 }
1170
1171 // Send LayerData in a spiral pattern. Fun!
1172 SendLayerTopRight(map, 0, 0, 15, 15);
1173 } 1181 }
1174 catch (Exception e) 1182 catch (Exception e)
1175 { 1183 {
@@ -1177,51 +1185,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1177 } 1185 }
1178 } 1186 }
1179 1187
1180 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1181 {
1182 // Row
1183 for (int i = x1; i <= x2; i++)
1184 SendLayerData(i, y1, map);
1185
1186 // Column
1187 for (int j = y1 + 1; j <= y2; j++)
1188 SendLayerData(x2, j, map);
1189
1190 if (x2 - x1 > 0)
1191 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1192 }
1193
1194 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1195 {
1196 // Row in reverse
1197 for (int i = x2; i >= x1; i--)
1198 SendLayerData(i, y2, map);
1199
1200 // Column in reverse
1201 for (int j = y2 - 1; j >= y1; j--)
1202 SendLayerData(x1, j, map);
1203
1204 if (x2 - x1 > 0)
1205 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1206 }
1207
1208 /// <summary> 1188 /// <summary>
1209 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1189 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1210 /// </summary> 1190 /// </summary>
1211 /// <param name="map">heightmap</param> 1191 /// <param name="map">heightmap</param>
1212 /// <param name="px">X coordinate for patches 0..12</param> 1192 /// <param name="px">X coordinate for patches 0..12</param>
1213 /// <param name="py">Y coordinate for patches 0..15</param> 1193 /// <param name="py">Y coordinate for patches 0..15</param>
1214 // private void SendLayerPacket(float[] map, int y, int x) 1194 private void SendLayerPacket(int x, int y, float[] map)
1215 // { 1195 {
1216 // int[] patches = new int[4]; 1196 int[] patches = new int[4];
1217 // patches[0] = x + 0 + y * 16; 1197 patches[0] = x + 0 + y * 16;
1218 // patches[1] = x + 1 + y * 16; 1198 patches[1] = x + 1 + y * 16;
1219 // patches[2] = x + 2 + y * 16; 1199 patches[2] = x + 2 + y * 16;
1220 // patches[3] = x + 3 + y * 16; 1200 patches[3] = x + 3 + y * 16;
1221 1201
1222 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1202 float[] heightmap = (map.Length == 65536) ?
1223 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1203 map :
1224 // } 1204 LLHeightFieldMoronize(map);
1205
1206 try
1207 {
1208 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1209 OutPacket(layerpack, ThrottleOutPacketType.Land);
1210 }
1211 catch
1212 {
1213 for (int px = x ; px < x + 4 ; px++)
1214 SendLayerData(px, y, map);
1215 }
1216 }
1225 1217
1226 /// <summary> 1218 /// <summary>
1227 /// Sends a specified patch to a client 1219 /// Sends a specified patch to a client
@@ -1241,7 +1233,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1241 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1233 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1242 layerpack.Header.Reliable = true; 1234 layerpack.Header.Reliable = true;
1243 1235
1244 OutPacket(layerpack, ThrottleOutPacketType.Land); 1236 OutPacket(layerpack, ThrottleOutPacketType.Task);
1245 } 1237 }
1246 catch (Exception e) 1238 catch (Exception e)
1247 { 1239 {
@@ -1611,7 +1603,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1611 1603
1612 public void SendKillObject(List<uint> localIDs) 1604 public void SendKillObject(List<uint> localIDs)
1613 { 1605 {
1614// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1606// foreach (uint id in localIDs)
1607// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1615 1608
1616 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1609 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1617 // TODO: don't create new blocks if recycling an old packet 1610 // TODO: don't create new blocks if recycling an old packet
@@ -1633,17 +1626,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1633 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1626 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1634 // condition where a kill can be processed before an out-of-date update for the same object. 1627 // condition where a kill can be processed before an out-of-date update for the same object.
1635 // ProcessEntityUpdates() also takes the m_killRecord lock. 1628 // ProcessEntityUpdates() also takes the m_killRecord lock.
1636 lock (m_killRecord) 1629// lock (m_killRecord)
1637 { 1630// {
1638 foreach (uint localID in localIDs) 1631// foreach (uint localID in localIDs)
1639 m_killRecord.Add(localID); 1632// m_killRecord.Add(localID);
1640 1633
1641 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1634 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1642 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1635 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1643 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1636 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1644 // scene objects in a viewer until that viewer is relogged in. 1637 // scene objects in a viewer until that viewer is relogged in.
1645 OutPacket(kill, ThrottleOutPacketType.Task); 1638 OutPacket(kill, ThrottleOutPacketType.Task);
1646 } 1639// }
1647 } 1640 }
1648 } 1641 }
1649 1642
@@ -1765,7 +1758,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1765 newBlock.CreationDate = item.CreationDate; 1758 newBlock.CreationDate = item.CreationDate;
1766 newBlock.SalePrice = item.SalePrice; 1759 newBlock.SalePrice = item.SalePrice;
1767 newBlock.SaleType = item.SaleType; 1760 newBlock.SaleType = item.SaleType;
1768 newBlock.Flags = item.Flags; 1761 newBlock.Flags = item.Flags & 0xff;
1769 1762
1770 newBlock.CRC = 1763 newBlock.CRC =
1771 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, 1764 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
@@ -2019,7 +2012,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2019 itemBlock.GroupID = item.GroupID; 2012 itemBlock.GroupID = item.GroupID;
2020 itemBlock.GroupOwned = item.GroupOwned; 2013 itemBlock.GroupOwned = item.GroupOwned;
2021 itemBlock.GroupMask = item.GroupPermissions; 2014 itemBlock.GroupMask = item.GroupPermissions;
2022 itemBlock.Flags = item.Flags; 2015 itemBlock.Flags = item.Flags & 0xff;
2023 itemBlock.SalePrice = item.SalePrice; 2016 itemBlock.SalePrice = item.SalePrice;
2024 itemBlock.SaleType = item.SaleType; 2017 itemBlock.SaleType = item.SaleType;
2025 itemBlock.CreationDate = item.CreationDate; 2018 itemBlock.CreationDate = item.CreationDate;
@@ -2086,7 +2079,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2086 bulkUpdate.ItemData[0].GroupID = item.GroupID; 2079 bulkUpdate.ItemData[0].GroupID = item.GroupID;
2087 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned; 2080 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned;
2088 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions; 2081 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions;
2089 bulkUpdate.ItemData[0].Flags = item.Flags; 2082 bulkUpdate.ItemData[0].Flags = item.Flags & 0xff;
2090 bulkUpdate.ItemData[0].SalePrice = item.SalePrice; 2083 bulkUpdate.ItemData[0].SalePrice = item.SalePrice;
2091 bulkUpdate.ItemData[0].SaleType = item.SaleType; 2084 bulkUpdate.ItemData[0].SaleType = item.SaleType;
2092 2085
@@ -2102,9 +2095,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2102 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2095 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2103 } 2096 }
2104 2097
2105 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2106 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2098 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2107 { 2099 {
2100 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2101 }
2102
2103 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2104 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2105 {
2108 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2106 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2109 2107
2110 UpdateCreateInventoryItemPacket InventoryReply 2108 UpdateCreateInventoryItemPacket InventoryReply
@@ -2114,6 +2112,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2114 // TODO: don't create new blocks if recycling an old packet 2112 // TODO: don't create new blocks if recycling an old packet
2115 InventoryReply.AgentData.AgentID = AgentId; 2113 InventoryReply.AgentData.AgentID = AgentId;
2116 InventoryReply.AgentData.SimApproved = true; 2114 InventoryReply.AgentData.SimApproved = true;
2115 InventoryReply.AgentData.TransactionID = transactionID;
2117 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2116 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2118 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2117 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2119 InventoryReply.InventoryData[0].ItemID = Item.ID; 2118 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2134,7 +2133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2134 InventoryReply.InventoryData[0].GroupID = Item.GroupID; 2133 InventoryReply.InventoryData[0].GroupID = Item.GroupID;
2135 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned; 2134 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned;
2136 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions; 2135 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions;
2137 InventoryReply.InventoryData[0].Flags = Item.Flags; 2136 InventoryReply.InventoryData[0].Flags = Item.Flags & 0xff;
2138 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice; 2137 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice;
2139 InventoryReply.InventoryData[0].SaleType = Item.SaleType; 2138 InventoryReply.InventoryData[0].SaleType = Item.SaleType;
2140 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate; 2139 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate;
@@ -2183,16 +2182,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2183 replytask.InventoryData.TaskID = taskID; 2182 replytask.InventoryData.TaskID = taskID;
2184 replytask.InventoryData.Serial = serial; 2183 replytask.InventoryData.Serial = serial;
2185 replytask.InventoryData.Filename = fileName; 2184 replytask.InventoryData.Filename = fileName;
2186 OutPacket(replytask, ThrottleOutPacketType.Asset); 2185 OutPacket(replytask, ThrottleOutPacketType.Task);
2187 } 2186 }
2188 2187
2189 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2188 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2190 { 2189 {
2190 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2191 if (isTaskInventory)
2192 type = ThrottleOutPacketType.Task;
2193
2191 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2194 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2192 sendXfer.XferID.ID = xferID; 2195 sendXfer.XferID.ID = xferID;
2193 sendXfer.XferID.Packet = packet; 2196 sendXfer.XferID.Packet = packet;
2194 sendXfer.DataPacket.Data = data; 2197 sendXfer.DataPacket.Data = data;
2195 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2198 OutPacket(sendXfer, type);
2196 } 2199 }
2197 2200
2198 public void SendAbortXferPacket(ulong xferID) 2201 public void SendAbortXferPacket(ulong xferID)
@@ -2379,6 +2382,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2379 OutPacket(sound, ThrottleOutPacketType.Task); 2382 OutPacket(sound, ThrottleOutPacketType.Task);
2380 } 2383 }
2381 2384
2385 public void SendTransferAbort(TransferRequestPacket transferRequest)
2386 {
2387 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2388 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2389 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2390 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2391 OutPacket(abort, ThrottleOutPacketType.Task);
2392 }
2393
2382 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2394 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2383 { 2395 {
2384 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2396 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2687,6 +2699,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2687 float friction = part.Friction; 2699 float friction = part.Friction;
2688 float bounce = part.Restitution; 2700 float bounce = part.Restitution;
2689 float gravmod = part.GravityModifier; 2701 float gravmod = part.GravityModifier;
2702
2690 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2703 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2691 } 2704 }
2692 } 2705 }
@@ -2757,8 +2770,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2757 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2770 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2758 return; 2771 return;
2759 } 2772 }
2773 int WearableOut = 0;
2774 bool isWearable = false;
2775
2776 if (req.AssetInf != null)
2777 isWearable =
2778 ((AssetType) req.AssetInf.Type ==
2779 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2760 2780
2761 //m_log.Debug("sending asset " + req.RequestAssetID); 2781
2782 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2783
2784
2785 //if (isWearable)
2786 // m_log.Debug((AssetType)req.AssetInf.Type);
2787
2762 TransferInfoPacket Transfer = new TransferInfoPacket(); 2788 TransferInfoPacket Transfer = new TransferInfoPacket();
2763 Transfer.TransferInfo.ChannelType = 2; 2789 Transfer.TransferInfo.ChannelType = 2;
2764 Transfer.TransferInfo.Status = 0; 2790 Transfer.TransferInfo.Status = 0;
@@ -2780,7 +2806,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2780 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2806 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2781 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2807 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2782 Transfer.Header.Zerocoded = true; 2808 Transfer.Header.Zerocoded = true;
2783 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2809 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2784 2810
2785 if (req.NumPackets == 1) 2811 if (req.NumPackets == 1)
2786 { 2812 {
@@ -2791,12 +2817,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2791 TransferPacket.TransferData.Data = req.AssetInf.Data; 2817 TransferPacket.TransferData.Data = req.AssetInf.Data;
2792 TransferPacket.TransferData.Status = 1; 2818 TransferPacket.TransferData.Status = 1;
2793 TransferPacket.Header.Zerocoded = true; 2819 TransferPacket.Header.Zerocoded = true;
2794 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2820 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2795 } 2821 }
2796 else 2822 else
2797 { 2823 {
2798 int processedLength = 0; 2824 int processedLength = 0;
2799 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2825// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2826
2827 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2800 int packetNumber = 0; 2828 int packetNumber = 0;
2801 2829
2802 while (processedLength < req.AssetInf.Data.Length) 2830 while (processedLength < req.AssetInf.Data.Length)
@@ -2822,7 +2850,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2822 TransferPacket.TransferData.Status = 1; 2850 TransferPacket.TransferData.Status = 1;
2823 } 2851 }
2824 TransferPacket.Header.Zerocoded = true; 2852 TransferPacket.Header.Zerocoded = true;
2825 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2853 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2826 2854
2827 processedLength += chunkSize; 2855 processedLength += chunkSize;
2828 packetNumber++; 2856 packetNumber++;
@@ -2867,7 +2895,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2867 reply.Data.ParcelID = parcelID; 2895 reply.Data.ParcelID = parcelID;
2868 reply.Data.OwnerID = land.OwnerID; 2896 reply.Data.OwnerID = land.OwnerID;
2869 reply.Data.Name = Utils.StringToBytes(land.Name); 2897 reply.Data.Name = Utils.StringToBytes(land.Name);
2870 reply.Data.Desc = Utils.StringToBytes(land.Description); 2898 if (land != null && land.Description != null && land.Description != String.Empty)
2899 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2900 else
2901 reply.Data.Desc = new Byte[0];
2871 reply.Data.ActualArea = land.Area; 2902 reply.Data.ActualArea = land.Area;
2872 reply.Data.BillableArea = land.Area; // TODO: what is this? 2903 reply.Data.BillableArea = land.Area; // TODO: what is this?
2873 2904
@@ -3574,24 +3605,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3574 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3605 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3575 AgentWearablesUpdatePacket.WearableDataBlock awb; 3606 AgentWearablesUpdatePacket.WearableDataBlock awb;
3576 int idx = 0; 3607 int idx = 0;
3577 for (int i = 0; i < wearables.Length; i++) 3608
3578 { 3609 for (int i = 0; i < wearables.Length; i++)
3579 for (int j = 0; j < wearables[i].Count; j++) 3610 {
3580 { 3611 for (int j = 0; j < wearables[i].Count; j++)
3581 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3612 {
3582 awb.WearableType = (byte)i; 3613 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3583 awb.AssetID = wearables[i][j].AssetID; 3614 awb.WearableType = (byte) i;
3584 awb.ItemID = wearables[i][j].ItemID; 3615 awb.AssetID = wearables[i][j].AssetID;
3585 aw.WearableData[idx] = awb; 3616 awb.ItemID = wearables[i][j].ItemID;
3586 idx++; 3617 aw.WearableData[idx] = awb;
3587 3618 idx++;
3588// m_log.DebugFormat( 3619
3589// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3620 // m_log.DebugFormat(
3590// awb.ItemID, awb.AssetID, i, Name); 3621 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3591 } 3622 // awb.ItemID, awb.AssetID, i, Name);
3592 } 3623 }
3624 }
3593 3625
3594 OutPacket(aw, ThrottleOutPacketType.Task); 3626 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3595 } 3627 }
3596 3628
3597 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3629 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3602,7 +3634,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3602 3634
3603 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3635 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3604 // TODO: don't create new blocks if recycling an old packet 3636 // TODO: don't create new blocks if recycling an old packet
3605 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3637 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3606 avp.ObjectData.TextureEntry = textureEntry; 3638 avp.ObjectData.TextureEntry = textureEntry;
3607 3639
3608 AvatarAppearancePacket.VisualParamBlock avblock = null; 3640 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3733,7 +3765,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3733 /// </summary> 3765 /// </summary>
3734 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3766 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3735 { 3767 {
3736 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3768 if (entity is SceneObjectPart)
3769 {
3770 SceneObjectPart e = (SceneObjectPart)entity;
3771 SceneObjectGroup g = e.ParentGroup;
3772 if (g.RootPart.Shape.State > 30) // HUD
3773 if (g.OwnerID != AgentId)
3774 return; // Don't send updates for other people's HUDs
3775 }
3776
3737 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3777 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3738 3778
3739 lock (m_entityUpdates.SyncRoot) 3779 lock (m_entityUpdates.SyncRoot)
@@ -3820,27 +3860,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3820 3860
3821 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3861 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3822 // condition where a kill can be processed before an out-of-date update for the same object. 3862 // condition where a kill can be processed before an out-of-date update for the same object.
3823 lock (m_killRecord) 3863 float avgTimeDilation = 1.0f;
3864 IEntityUpdate iupdate;
3865 Int32 timeinqueue; // this is just debugging code & can be dropped later
3866
3867 while (updatesThisCall < maxUpdates)
3824 { 3868 {
3825 float avgTimeDilation = 1.0f; 3869 lock (m_entityUpdates.SyncRoot)
3826 IEntityUpdate iupdate; 3870 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3827 Int32 timeinqueue; // this is just debugging code & can be dropped later 3871 break;
3828 3872
3829 while (updatesThisCall < maxUpdates) 3873 EntityUpdate update = (EntityUpdate)iupdate;
3874
3875 avgTimeDilation += update.TimeDilation;
3876 avgTimeDilation *= 0.5f;
3877
3878 if (update.Entity is SceneObjectPart)
3830 { 3879 {
3831 lock (m_entityUpdates.SyncRoot) 3880 SceneObjectPart part = (SceneObjectPart)update.Entity;
3832 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3833 break;
3834 3881
3835 EntityUpdate update = (EntityUpdate)iupdate; 3882 if (part.ParentGroup.IsDeleted)
3836 3883 continue;
3837 avgTimeDilation += update.TimeDilation;
3838 avgTimeDilation *= 0.5f;
3839 3884
3840 if (update.Entity is SceneObjectPart) 3885 if (part.ParentGroup.IsAttachment)
3886 { // Someone else's HUD, why are we getting these?
3887 if (part.ParentGroup.OwnerID != AgentId &&
3888 part.ParentGroup.RootPart.Shape.State > 30)
3889 continue;
3890 ScenePresence sp;
3891 // Owner is not in the sim, don't update it to
3892 // anyone
3893 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3894 continue;
3895
3896 List<SceneObjectGroup> atts = sp.GetAttachments();
3897 bool found = false;
3898 foreach (SceneObjectGroup att in atts)
3899 {
3900 if (att == part.ParentGroup)
3901 {
3902 found = true;
3903 break;
3904 }
3905 }
3906
3907 // It's an attachment of a valid avatar, but
3908 // doesn't seem to be attached, skip
3909 if (!found)
3910 continue;
3911
3912 // On vehicle crossing, the attachments are received
3913 // while the avatar is still a child. Don't send
3914 // updates here because the LocalId has not yet
3915 // been updated and the viewer will derender the
3916 // attachments until the avatar becomes root.
3917 if (sp.IsChildAgent)
3918 continue;
3919
3920 // If the object is an attachment we don't want it to be in the kill
3921 // record. Else attaching from inworld and subsequently dropping
3922 // it will no longer work.
3923// lock (m_killRecord)
3924// {
3925// m_killRecord.Remove(part.LocalId);
3926// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3927// }
3928 }
3929 else
3841 { 3930 {
3842 SceneObjectPart part = (SceneObjectPart)update.Entity;
3843
3844 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3931 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3845 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3932 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3846 // safety measure. 3933 // safety measure.
@@ -3851,21 +3938,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3851 // 3938 //
3852 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3939 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3853 // after the root prim has been deleted. 3940 // after the root prim has been deleted.
3854 if (m_killRecord.Contains(part.LocalId)) 3941 //
3855 { 3942 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3856 // m_log.WarnFormat( 3943// lock (m_killRecord)
3857 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3944// {
3858 // part.LocalId, Name); 3945// if (m_killRecord.Contains(part.LocalId))
3859 continue; 3946// continue;
3860 } 3947// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3861 3948// continue;
3862 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3949// }
3950 }
3951
3952 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3953 {
3954 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3955 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3863 { 3956 {
3864 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3957 part.Shape.LightEntry = false;
3865 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3866 {
3867 part.Shape.LightEntry = false;
3868 }
3869 } 3958 }
3870 3959
3871 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3960 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3876,224 +3965,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3876 part.Shape.ProfileHollow = 27500; 3965 part.Shape.ProfileHollow = 27500;
3877 } 3966 }
3878 } 3967 }
3879 3968
3880 #region UpdateFlags to packet type conversion 3969 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3881
3882 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3883
3884 bool canUseCompressed = true;
3885 bool canUseImproved = true;
3886
3887 // Compressed object updates only make sense for LL primitives
3888 if (!(update.Entity is SceneObjectPart))
3889 { 3970 {
3890 canUseCompressed = false; 3971 // Ensure that mesh has at least 8 valid faces
3972 part.Shape.ProfileBegin = 12500;
3973 part.Shape.ProfileEnd = 0;
3974 part.Shape.ProfileHollow = 27500;
3891 } 3975 }
3892 3976 }
3893 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3977
3978 ++updatesThisCall;
3979
3980 #region UpdateFlags to packet type conversion
3981
3982 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3983
3984 bool canUseCompressed = true;
3985 bool canUseImproved = true;
3986
3987 // Compressed object updates only make sense for LL primitives
3988 if (!(update.Entity is SceneObjectPart))
3989 {
3990 canUseCompressed = false;
3991 }
3992
3993 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3994 {
3995 canUseCompressed = false;
3996 canUseImproved = false;
3997 }
3998 else
3999 {
4000 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
4001 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
4002 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
4003 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3894 { 4004 {
3895 canUseCompressed = false; 4005 canUseCompressed = false;
3896 canUseImproved = false;
3897 } 4006 }
3898 else 4007
4008 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
4009 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
4010 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
4011 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
4012 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
4013 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
4014 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
4015 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
4016 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
4017 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
4018 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
4019 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
4020 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
4021 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3899 { 4022 {
3900 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 4023 canUseImproved = false;
3901 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3902 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3903 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3904 {
3905 canUseCompressed = false;
3906 }
3907
3908 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3909 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3910 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3911 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3912 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3913 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3914 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3915 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3916 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3917 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3918 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3919 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3920 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3921 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3922 {
3923 canUseImproved = false;
3924 }
3925 } 4024 }
4025 }
3926 4026
3927 #endregion UpdateFlags to packet type conversion 4027 #endregion UpdateFlags to packet type conversion
3928
3929 #region Block Construction
3930
3931 // TODO: Remove this once we can build compressed updates
3932 canUseCompressed = false;
3933
3934 if (!canUseImproved && !canUseCompressed)
3935 {
3936 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3937 4028
3938 if (update.Entity is ScenePresence) 4029 #region Block Construction
3939 {
3940 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3941 }
3942 else
3943 {
3944 SceneObjectPart part = (SceneObjectPart)update.Entity;
3945 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3946
3947 // If the part has become a private hud since the update was scheduled then we do not
3948 // want to send it to other avatars.
3949 if (part.ParentGroup.IsAttachment
3950 && part.ParentGroup.HasPrivateAttachmentPoint
3951 && part.ParentGroup.AttachedAvatar != AgentId)
3952 continue;
3953
3954 // If the part has since been deleted, then drop the update. In the case of attachments,
3955 // this is to avoid spurious updates to other viewers since post-processing of attachments
3956 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3957 // of the test above).
3958 //
3959 // Actual deletions (kills) happen in another method.
3960 if (part.ParentGroup.IsDeleted)
3961 continue;
3962 }
3963 4030
3964 objectUpdateBlocks.Value.Add(updateBlock); 4031 // TODO: Remove this once we can build compressed updates
3965 objectUpdates.Value.Add(update); 4032 canUseCompressed = false;
3966 }
3967 else if (!canUseImproved)
3968 {
3969 SceneObjectPart part = (SceneObjectPart)update.Entity;
3970 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3971 = CreateCompressedUpdateBlock(part, updateFlags);
3972
3973 // If the part has since been deleted, then drop the update. In the case of attachments,
3974 // this is to avoid spurious updates to other viewers since post-processing of attachments
3975 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3976 // of the test above).
3977 //
3978 // Actual deletions (kills) happen in another method.
3979 if (part.ParentGroup.IsDeleted)
3980 continue;
3981 4033
3982 compressedUpdateBlocks.Value.Add(compressedBlock); 4034 if (!canUseImproved && !canUseCompressed)
3983 compressedUpdates.Value.Add(update); 4035 {
4036 if (update.Entity is ScenePresence)
4037 {
4038 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3984 } 4039 }
3985 else 4040 else
3986 { 4041 {
3987 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 4042 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3988 {
3989 // Self updates go into a special list
3990 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3991 terseAgentUpdates.Value.Add(update);
3992 }
3993 else
3994 {
3995 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3996 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3997
3998 // Everything else goes here
3999 if (update.Entity is SceneObjectPart)
4000 {
4001 SceneObjectPart part = (SceneObjectPart)update.Entity;
4002
4003 // If the part has become a private hud since the update was scheduled then we do not
4004 // want to send it to other avatars.
4005 if (part.ParentGroup.IsAttachment
4006 && part.ParentGroup.HasPrivateAttachmentPoint
4007 && part.ParentGroup.AttachedAvatar != AgentId)
4008 continue;
4009
4010 // If the part has since been deleted, then drop the update. In the case of attachments,
4011 // this is to avoid spurious updates to other viewers since post-processing of attachments
4012 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4013 // of the test above).
4014 //
4015 // Actual deletions (kills) happen in another method.
4016 if (part.ParentGroup.IsDeleted)
4017 continue;
4018 }
4019
4020 terseUpdateBlocks.Value.Add(terseUpdateBlock);
4021 terseUpdates.Value.Add(update);
4022 }
4023 } 4043 }
4024
4025 ++updatesThisCall;
4026
4027 #endregion Block Construction
4028 } 4044 }
4029 4045 else if (!canUseImproved)
4030 #region Packet Sending 4046 {
4031 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 4047 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
4032 4048 }
4033 if (terseAgentUpdateBlocks.IsValueCreated) 4049 else
4034 { 4050 {
4035 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4051 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4052 // Self updates go into a special list
4053 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4054 else
4055 // Everything else goes here
4056 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4057 }
4036 4058
4037 ImprovedTerseObjectUpdatePacket packet 4059 #endregion Block Construction
4038 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4060 }
4039 4061
4040 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4062 #region Packet Sending
4041 packet.RegionData.TimeDilation = timeDilation; 4063
4042 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4064 const float TIME_DILATION = 1.0f;
4065 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4066
4067 if (terseAgentUpdateBlocks.IsValueCreated)
4068 {
4069 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4043 4070
4044 for (int i = 0; i < blocks.Count; i++) 4071 ImprovedTerseObjectUpdatePacket packet
4045 packet.ObjectData[i] = blocks[i]; 4072 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4046 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4073 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4047 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4074 packet.RegionData.TimeDilation = timeDilation;
4048 } 4075 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4049 4076
4050 if (objectUpdateBlocks.IsValueCreated) 4077 for (int i = 0; i < blocks.Count; i++)
4051 { 4078 packet.ObjectData[i] = blocks[i];
4052 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4053
4054 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4055 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4056 packet.RegionData.TimeDilation = timeDilation;
4057 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4058
4059 for (int i = 0; i < blocks.Count; i++)
4060 packet.ObjectData[i] = blocks[i];
4061 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4062 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4063 }
4064
4065 if (compressedUpdateBlocks.IsValueCreated)
4066 {
4067 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4068
4069 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4070 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4071 packet.RegionData.TimeDilation = timeDilation;
4072 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4073
4074 for (int i = 0; i < blocks.Count; i++)
4075 packet.ObjectData[i] = blocks[i];
4076 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4077 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4078 }
4079 4079
4080 if (terseUpdateBlocks.IsValueCreated) 4080 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4081 { 4081 }
4082 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4083
4084 ImprovedTerseObjectUpdatePacket packet
4085 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4086 PacketType.ImprovedTerseObjectUpdate);
4087 4082
4088 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4083 if (objectUpdateBlocks.IsValueCreated)
4089 packet.RegionData.TimeDilation = timeDilation; 4084 {
4090 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4085 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4091 4086
4092 for (int i = 0; i < blocks.Count; i++) 4087 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4093 packet.ObjectData[i] = blocks[i]; 4088 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4094 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4089 packet.RegionData.TimeDilation = timeDilation;
4095 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4090 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4096 } 4091
4092 for (int i = 0; i < blocks.Count; i++)
4093 packet.ObjectData[i] = blocks[i];
4094
4095 OutPacket(packet, ThrottleOutPacketType.Task, true);
4096 }
4097
4098 if (compressedUpdateBlocks.IsValueCreated)
4099 {
4100 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4101
4102 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4103 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4104 packet.RegionData.TimeDilation = timeDilation;
4105 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4106
4107 for (int i = 0; i < blocks.Count; i++)
4108 packet.ObjectData[i] = blocks[i];
4109
4110 OutPacket(packet, ThrottleOutPacketType.Task, true);
4111 }
4112
4113 if (terseUpdateBlocks.IsValueCreated)
4114 {
4115 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4116
4117 ImprovedTerseObjectUpdatePacket packet
4118 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4119 PacketType.ImprovedTerseObjectUpdate);
4120 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4121 packet.RegionData.TimeDilation = timeDilation;
4122 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4123
4124 for (int i = 0; i < blocks.Count; i++)
4125 packet.ObjectData[i] = blocks[i];
4126
4127 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4097 } 4128 }
4098 4129
4099 #endregion Packet Sending 4130 #endregion Packet Sending
@@ -4413,11 +4444,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4413 4444
4414 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4445 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4415 // of the object rather than the properties when the packet was created 4446 // of the object rather than the properties when the packet was created
4416 OutPacket(packet, ThrottleOutPacketType.Task, true, 4447 // HACK : Remove intelligent resending until it's fixed in core
4417 delegate(OutgoingPacket oPacket) 4448 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4418 { 4449 // delegate(OutgoingPacket oPacket)
4419 ResendPropertyUpdates(updates, oPacket); 4450 // {
4420 }); 4451 // ResendPropertyUpdates(updates, oPacket);
4452 // });
4453 OutPacket(packet, ThrottleOutPacketType.Task, true);
4421 4454
4422 // pbcnt += blocks.Count; 4455 // pbcnt += blocks.Count;
4423 // ppcnt++; 4456 // ppcnt++;
@@ -4443,11 +4476,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4443 // of the object rather than the properties when the packet was created 4476 // of the object rather than the properties when the packet was created
4444 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4477 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4445 updates.Add(familyUpdates.Value[i]); 4478 updates.Add(familyUpdates.Value[i]);
4446 OutPacket(packet, ThrottleOutPacketType.Task, true, 4479 // HACK : Remove intelligent resending until it's fixed in core
4447 delegate(OutgoingPacket oPacket) 4480 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4448 { 4481 // delegate(OutgoingPacket oPacket)
4449 ResendPropertyUpdates(updates, oPacket); 4482 // {
4450 }); 4483 // ResendPropertyUpdates(updates, oPacket);
4484 // });
4485 OutPacket(packet, ThrottleOutPacketType.Task, true);
4451 4486
4452 // fpcnt++; 4487 // fpcnt++;
4453 // fbcnt++; 4488 // fbcnt++;
@@ -4819,7 +4854,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4819 4854
4820 if (landData.SimwideArea > 0) 4855 if (landData.SimwideArea > 0)
4821 { 4856 {
4822 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4857 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4858 // Never report more than sim total capacity
4859 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4860 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4823 updateMessage.SimWideMaxPrims = simulatorCapacity; 4861 updateMessage.SimWideMaxPrims = simulatorCapacity;
4824 } 4862 }
4825 else 4863 else
@@ -4948,14 +4986,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4948 4986
4949 if (notifyCount > 0) 4987 if (notifyCount > 0)
4950 { 4988 {
4951 if (notifyCount > 32) 4989// if (notifyCount > 32)
4952 { 4990// {
4953 m_log.InfoFormat( 4991// m_log.InfoFormat(
4954 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4992// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4955 + " - a developer might want to investigate whether this is a hard limit", 32); 4993// + " - a developer might want to investigate whether this is a hard limit", 32);
4956 4994//
4957 notifyCount = 32; 4995// notifyCount = 32;
4958 } 4996// }
4959 4997
4960 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4998 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4961 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4999 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5010,9 +5048,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5010 { 5048 {
5011 ScenePresence presence = (ScenePresence)entity; 5049 ScenePresence presence = (ScenePresence)entity;
5012 5050
5013 attachPoint = presence.State;
5014 collisionPlane = presence.CollisionPlane;
5015 position = presence.OffsetPosition; 5051 position = presence.OffsetPosition;
5052 rotation = presence.Rotation;
5053
5054 if (presence.ParentID != 0)
5055 {
5056 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
5057 if (part != null && part != part.ParentGroup.RootPart)
5058 {
5059 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
5060 rotation = part.RotationOffset * presence.Rotation;
5061 }
5062 angularVelocity = Vector3.Zero;
5063 }
5064 else
5065 {
5066 angularVelocity = presence.AngularVelocity;
5067 rotation = presence.Rotation;
5068 }
5069
5070 attachPoint = 0;
5071 collisionPlane = presence.CollisionPlane;
5016 velocity = presence.Velocity; 5072 velocity = presence.Velocity;
5017 acceleration = Vector3.Zero; 5073 acceleration = Vector3.Zero;
5018 5074
@@ -5021,9 +5077,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5021 // may improve movement smoothness. 5077 // may improve movement smoothness.
5022// acceleration = new Vector3(1, 0, 0); 5078// acceleration = new Vector3(1, 0, 0);
5023 5079
5024 angularVelocity = presence.AngularVelocity;
5025 rotation = presence.Rotation;
5026
5027 if (sendTexture) 5080 if (sendTexture)
5028 textureEntry = presence.Appearance.Texture.GetBytes(); 5081 textureEntry = presence.Appearance.Texture.GetBytes();
5029 else 5082 else
@@ -5129,13 +5182,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5129 5182
5130 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5183 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5131 { 5184 {
5185 Vector3 offsetPosition = data.OffsetPosition;
5186 Quaternion rotation = data.Rotation;
5187 uint parentID = data.ParentID;
5188
5189 if (parentID != 0)
5190 {
5191 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5192 if (part != null && part != part.ParentGroup.RootPart)
5193 {
5194 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5195 rotation = part.RotationOffset * data.Rotation;
5196 parentID = part.ParentGroup.RootPart.LocalId;
5197 }
5198 }
5199
5132 byte[] objectData = new byte[76]; 5200 byte[] objectData = new byte[76];
5133 5201
5134 data.CollisionPlane.ToBytes(objectData, 0); 5202 data.CollisionPlane.ToBytes(objectData, 0);
5135 data.OffsetPosition.ToBytes(objectData, 16); 5203 offsetPosition.ToBytes(objectData, 16);
5204 Vector3 velocity = new Vector3(0, 0, 0);
5205 Vector3 acceleration = new Vector3(0, 0, 0);
5206 velocity.ToBytes(objectData, 28);
5207 acceleration.ToBytes(objectData, 40);
5136// data.Velocity.ToBytes(objectData, 28); 5208// data.Velocity.ToBytes(objectData, 28);
5137// data.Acceleration.ToBytes(objectData, 40); 5209// data.Acceleration.ToBytes(objectData, 40);
5138 data.Rotation.ToBytes(objectData, 52); 5210 rotation.ToBytes(objectData, 52);
5139 //data.AngularVelocity.ToBytes(objectData, 64); 5211 //data.AngularVelocity.ToBytes(objectData, 64);
5140 5212
5141 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5213 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5149,14 +5221,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5149 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5221 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5150 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5222 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5151 update.ObjectData = objectData; 5223 update.ObjectData = objectData;
5152 update.ParentID = data.ParentID; 5224 update.ParentID = parentID;
5153 update.PathCurve = 16; 5225 update.PathCurve = 16;
5154 update.PathScaleX = 100; 5226 update.PathScaleX = 100;
5155 update.PathScaleY = 100; 5227 update.PathScaleY = 100;
5156 update.PCode = (byte)PCode.Avatar; 5228 update.PCode = (byte)PCode.Avatar;
5157 update.ProfileCurve = 1; 5229 update.ProfileCurve = 1;
5158 update.PSBlock = Utils.EmptyBytes; 5230 update.PSBlock = Utils.EmptyBytes;
5159 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5231 update.Scale = data.Appearance.AvatarSize;
5232// update.Scale.Z -= 0.2f;
5233
5160 update.Text = Utils.EmptyBytes; 5234 update.Text = Utils.EmptyBytes;
5161 update.TextColor = new byte[4]; 5235 update.TextColor = new byte[4];
5162 5236
@@ -5167,10 +5241,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5167 update.TextureEntry = Utils.EmptyBytes; 5241 update.TextureEntry = Utils.EmptyBytes;
5168// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5242// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5169 5243
5244/* 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)
5170 update.UpdateFlags = (uint)( 5245 update.UpdateFlags = (uint)(
5171 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5246 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5172 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5247 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5173 PrimFlags.ObjectOwnerModify); 5248 PrimFlags.ObjectOwnerModify);
5249*/
5250 update.UpdateFlags = 0;
5174 5251
5175 return update; 5252 return update;
5176 } 5253 }
@@ -5341,8 +5418,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5341 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5418 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5342 // for each AgentUpdate packet. 5419 // for each AgentUpdate packet.
5343 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5420 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5344 5421
5345 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5422 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5423 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5424 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5346 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5425 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5347 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5426 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5348 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5427 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5494,6 +5573,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5494 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5573 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5495 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5574 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5496 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5575 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5576 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5497 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5577 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5498 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5578 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5499 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5579 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5560,6 +5640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5560 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5640 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5561 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5641 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5562 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5642 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5643 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5563 5644
5564 AddGenericPacketHandler("autopilot", HandleAutopilot); 5645 AddGenericPacketHandler("autopilot", HandleAutopilot);
5565 } 5646 }
@@ -5912,6 +5993,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5912 return true; 5993 return true;
5913 } 5994 }
5914 5995
5996 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5997 {
5998 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5999 if (p.AgentData.SessionID != SessionId ||
6000 p.AgentData.AgentID != AgentId)
6001 return true;
6002
6003 m_VelocityInterpolate = false;
6004 return true;
6005 }
6006
6007 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
6008 {
6009 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
6010 if (p.AgentData.SessionID != SessionId ||
6011 p.AgentData.AgentID != AgentId)
6012 return true;
6013
6014 m_VelocityInterpolate = true;
6015 return true;
6016 }
6017
6018
5915 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 6019 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5916 { 6020 {
5917 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 6021 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6332,26 +6436,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6332 // Temporarily protect ourselves from the mantis #951 failure. 6436 // Temporarily protect ourselves from the mantis #951 failure.
6333 // However, we could do this for several other handlers where a failure isn't terminal 6437 // However, we could do this for several other handlers where a failure isn't terminal
6334 // for the client session anyway, in order to protect ourselves against bad code in plugins 6438 // for the client session anyway, in order to protect ourselves against bad code in plugins
6439 Vector3 avSize = appear.AgentData.Size;
6335 try 6440 try
6336 { 6441 {
6337 byte[] visualparams = new byte[appear.VisualParam.Length]; 6442 byte[] visualparams = new byte[appear.VisualParam.Length];
6338 for (int i = 0; i < appear.VisualParam.Length; i++) 6443 for (int i = 0; i < appear.VisualParam.Length; i++)
6339 visualparams[i] = appear.VisualParam[i].ParamValue; 6444 visualparams[i] = appear.VisualParam[i].ParamValue;
6340 6445 //var b = appear.WearableData[0];
6446
6341 Primitive.TextureEntry te = null; 6447 Primitive.TextureEntry te = null;
6342 if (appear.ObjectData.TextureEntry.Length > 1) 6448 if (appear.ObjectData.TextureEntry.Length > 1)
6343 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6449 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6450
6451 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6452 for (int i=0; i<appear.WearableData.Length;i++)
6453 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6344 6454
6345 List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); 6455
6346 for (int i = 0; i < appear.WearableData.Length; i++)
6347 {
6348 CachedTextureRequestArg arg = new CachedTextureRequestArg();
6349 arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
6350 arg.WearableHashID = appear.WearableData[i].CacheID;
6351 hashes.Add(arg);
6352 }
6353 6456
6354 handlerSetAppearance(sender, te, visualparams, hashes); 6457 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6355 } 6458 }
6356 catch (Exception e) 6459 catch (Exception e)
6357 { 6460 {
@@ -6560,6 +6663,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6560 { 6663 {
6561 handlerCompleteMovementToRegion(sender, true); 6664 handlerCompleteMovementToRegion(sender, true);
6562 } 6665 }
6666 else
6667 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6668
6563 handlerCompleteMovementToRegion = null; 6669 handlerCompleteMovementToRegion = null;
6564 6670
6565 return true; 6671 return true;
@@ -6577,7 +6683,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6577 return true; 6683 return true;
6578 } 6684 }
6579 #endregion 6685 #endregion
6580 6686/*
6581 StartAnim handlerStartAnim = null; 6687 StartAnim handlerStartAnim = null;
6582 StopAnim handlerStopAnim = null; 6688 StopAnim handlerStopAnim = null;
6583 6689
@@ -6601,6 +6707,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6601 } 6707 }
6602 } 6708 }
6603 return true; 6709 return true;
6710*/
6711 ChangeAnim handlerChangeAnim = null;
6712
6713 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6714 {
6715 handlerChangeAnim = OnChangeAnim;
6716 if (handlerChangeAnim != null)
6717 {
6718 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6719 }
6720 }
6721
6722 handlerChangeAnim = OnChangeAnim;
6723 if (handlerChangeAnim != null)
6724 {
6725 handlerChangeAnim(UUID.Zero, false, true);
6726 }
6727
6728 return true;
6604 } 6729 }
6605 6730
6606 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6731 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6826,6 +6951,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6826 #endregion 6951 #endregion
6827 6952
6828 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6953 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6954 GenericCall2 handler = OnUpdateThrottles;
6955 if (handler != null)
6956 {
6957 handler();
6958 }
6829 return true; 6959 return true;
6830 } 6960 }
6831 6961
@@ -7250,7 +7380,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7250 physdata.Bounce = phsblock.Restitution; 7380 physdata.Bounce = phsblock.Restitution;
7251 physdata.Density = phsblock.Density; 7381 physdata.Density = phsblock.Density;
7252 physdata.Friction = phsblock.Friction; 7382 physdata.Friction = phsblock.Friction;
7253 physdata.GravitationModifier = phsblock.GravityMultiplier; 7383 physdata.GravitationModifier = phsblock.GravityMultiplier;
7254 } 7384 }
7255 7385
7256 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7386 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7836,6 +7966,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7836 // surrounding scene 7966 // surrounding scene
7837 if ((ImageType)block.Type == ImageType.Baked) 7967 if ((ImageType)block.Type == ImageType.Baked)
7838 args.Priority *= 2.0f; 7968 args.Priority *= 2.0f;
7969 int wearableout = 0;
7839 7970
7840 ImageManager.EnqueueReq(args); 7971 ImageManager.EnqueueReq(args);
7841 } 7972 }
@@ -8870,16 +9001,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8870 9001
8871 #region Parcel related packets 9002 #region Parcel related packets
8872 9003
9004 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
9005 // to be done with minimal resources as possible
9006 // variables temporary here while in test
9007
9008 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
9009 bool RegionHandleRequestsInService = false;
9010
8873 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 9011 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8874 { 9012 {
8875 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 9013 UUID currentUUID;
8876 9014
8877 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 9015 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8878 if (handlerRegionHandleRequest != null) 9016
9017 if (handlerRegionHandleRequest == null)
9018 return true;
9019
9020 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
9021
9022 lock (RegionHandleRequests)
8879 { 9023 {
8880 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 9024 if (RegionHandleRequestsInService)
9025 {
9026 // we are already busy doing a previus request
9027 // so enqueue it
9028 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
9029 return true;
9030 }
9031
9032 // else do it
9033 currentUUID = rhrPack.RequestBlock.RegionID;
9034 RegionHandleRequestsInService = true;
8881 } 9035 }
8882 return true; 9036
9037 while (true)
9038 {
9039 handlerRegionHandleRequest(this, currentUUID);
9040
9041 lock (RegionHandleRequests)
9042 {
9043 // exit condition, nothing to do or closed
9044 // current code seems to assume we may loose the handler at anytime,
9045 // so keep checking it
9046 handlerRegionHandleRequest = OnRegionHandleRequest;
9047
9048 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
9049 {
9050 RegionHandleRequests.Clear();
9051 RegionHandleRequestsInService = false;
9052 return true;
9053 }
9054 currentUUID = RegionHandleRequests.Dequeue();
9055 }
9056 }
9057
9058 return true; // actually unreached
8883 } 9059 }
8884 9060
8885 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 9061 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -10135,7 +10311,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10135 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10311 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10136 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10312 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10137 UpdateMuteListEntry.MuteData.MuteType, 10313 UpdateMuteListEntry.MuteData.MuteType,
10138 UpdateMuteListEntry.AgentData.AgentID); 10314 UpdateMuteListEntry.MuteData.MuteFlags);
10139 return true; 10315 return true;
10140 } 10316 }
10141 return false; 10317 return false;
@@ -10150,8 +10326,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10150 { 10326 {
10151 handlerRemoveMuteListEntry(this, 10327 handlerRemoveMuteListEntry(this,
10152 RemoveMuteListEntry.MuteData.MuteID, 10328 RemoveMuteListEntry.MuteData.MuteID,
10153 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10329 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10154 RemoveMuteListEntry.AgentData.AgentID);
10155 return true; 10330 return true;
10156 } 10331 }
10157 return false; 10332 return false;
@@ -10195,10 +10370,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10195 return false; 10370 return false;
10196 } 10371 }
10197 10372
10373 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10374 {
10375 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10376 (ChangeInventoryItemFlagsPacket)packet;
10377 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10378 if (handlerChangeInventoryItemFlags != null)
10379 {
10380 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10381 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10382 return true;
10383 }
10384 return false;
10385 }
10386
10198 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10387 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10199 { 10388 {
10200 return true; 10389 return true;
10201 } 10390 }
10391
10392 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10393 {
10394 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10395
10396 #region Packet Session and User Check
10397 if (m_checkPackets)
10398 {
10399 if (packet.AgentData.SessionID != SessionId ||
10400 packet.AgentData.AgentID != AgentId)
10401 return true;
10402 }
10403 #endregion
10404 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10405 List<InventoryItemBase> items = new List<InventoryItemBase>();
10406 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10407 {
10408 InventoryItemBase b = new InventoryItemBase();
10409 b.ID = n.OldItemID;
10410 b.Folder = n.OldFolderID;
10411 items.Add(b);
10412 }
10413
10414 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10415 if (handlerMoveItemsAndLeaveCopy != null)
10416 {
10417 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10418 }
10419
10420 return true;
10421 }
10202 10422
10203 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10423 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10204 { 10424 {
@@ -10625,6 +10845,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10625 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10845 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10626 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10846 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10627 10847
10848 Scene scene = (Scene)m_scene;
10849 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10850 {
10851 ScenePresence p;
10852 if (scene.TryGetScenePresence(sender.AgentId, out p))
10853 {
10854 if (p.GodLevel >= 200)
10855 {
10856 groupProfileReply.GroupData.OpenEnrollment = true;
10857 groupProfileReply.GroupData.MembershipFee = 0;
10858 }
10859 }
10860 }
10861
10628 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10862 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10629 } 10863 }
10630 return true; 10864 return true;
@@ -11198,11 +11432,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11198 11432
11199 StartLure handlerStartLure = OnStartLure; 11433 StartLure handlerStartLure = OnStartLure;
11200 if (handlerStartLure != null) 11434 if (handlerStartLure != null)
11201 handlerStartLure(startLureRequest.Info.LureType, 11435 {
11202 Utils.BytesToString( 11436 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11203 startLureRequest.Info.Message), 11437 {
11204 startLureRequest.TargetData[0].TargetID, 11438 handlerStartLure(startLureRequest.Info.LureType,
11205 this); 11439 Utils.BytesToString(
11440 startLureRequest.Info.Message),
11441 startLureRequest.TargetData[i].TargetID,
11442 this);
11443 }
11444 }
11206 return true; 11445 return true;
11207 } 11446 }
11208 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11447 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11316,10 +11555,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11316 } 11555 }
11317 #endregion 11556 #endregion
11318 11557
11319 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11558 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11320 if (handlerClassifiedGodDelete != null) 11559 if (handlerClassifiedGodDelete != null)
11321 handlerClassifiedGodDelete( 11560 handlerClassifiedGodDelete(
11322 classifiedGodDelete.Data.ClassifiedID, 11561 classifiedGodDelete.Data.ClassifiedID,
11562 classifiedGodDelete.Data.QueryID,
11323 this); 11563 this);
11324 return true; 11564 return true;
11325 } 11565 }
@@ -11622,12 +11862,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11622 /// <param name="simclient"></param> 11862 /// <param name="simclient"></param>
11623 /// <param name="packet"></param> 11863 /// <param name="packet"></param>
11624 /// <returns></returns> 11864 /// <returns></returns>
11625 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11865 // TODO: Convert old handler to use new method
11866 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11626 { 11867 {
11627 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11868 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11628 11869
11629 if (cachedtex.AgentData.SessionID != SessionId) 11870 if (cachedtex.AgentData.SessionID != SessionId)
11630 return false; 11871 return false;
11872
11631 11873
11632 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); 11874 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11633 11875
@@ -11640,23 +11882,173 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11640 requestArgs.Add(arg); 11882 requestArgs.Add(arg);
11641 } 11883 }
11642 11884
11643 try 11885 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11886 if (handlerCachedTextureRequest != null)
11644 { 11887 {
11645 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11888 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11646 if (handlerCachedTextureRequest != null) 11889 }
11890
11891 return true;
11892 }*/
11893
11894 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11895 {
11896 //m_log.Debug("texture cached: " + packet.ToString());
11897 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11898 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
11899
11900 if (cachedtex.AgentData.SessionID != SessionId)
11901 return false;
11902
11903
11904 // TODO: don't create new blocks if recycling an old packet
11905 cachedresp.AgentData.AgentID = AgentId;
11906 cachedresp.AgentData.SessionID = m_sessionId;
11907 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
11908 m_cachedTextureSerial++;
11909 cachedresp.WearableData =
11910 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11911
11912 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11913 // var item = fac.GetBakedTextureFaces(AgentId);
11914 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11915
11916 IAssetService cache = m_scene.AssetService;
11917 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11918 //bakedTextureModule = null;
11919 int maxWearablesLoop = cachedtex.WearableData.Length;
11920 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11921 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11922
11923 if (bakedTextureModule != null && cache != null)
11924 {
11925 // 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
11926
11927 WearableCacheItem[] cacheItems = null;
11928 ScenePresence p = m_scene.GetScenePresence(AgentId);
11929 if (p.Appearance != null)
11930 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11931 {
11932 try
11933 {
11934 cacheItems = bakedTextureModule.Get(AgentId);
11935 p.Appearance.WearableCacheItems = cacheItems;
11936 p.Appearance.WearableCacheItemsDirty = false;
11937 }
11938
11939 /*
11940 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11941 *
11942 catch (System.Net.Sockets.SocketException)
11943 {
11944 cacheItems = null;
11945 }
11946 catch (WebException)
11947 {
11948 cacheItems = null;
11949 }
11950 catch (InvalidOperationException)
11951 {
11952 cacheItems = null;
11953 } */
11954 catch (Exception)
11955 {
11956 cacheItems = null;
11957 }
11958
11959 }
11960 else if (p.Appearance.WearableCacheItems != null)
11961 {
11962 cacheItems = p.Appearance.WearableCacheItems;
11963 }
11964
11965 if (cache != null && cacheItems != null)
11647 { 11966 {
11648 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 11967 foreach (WearableCacheItem item in cacheItems)
11968 {
11969
11970 if (cache.GetCached(item.TextureID.ToString()) == null)
11971 {
11972 item.TextureAsset.Temporary = true;
11973 cache.Store(item.TextureAsset);
11974 }
11975
11976
11977 }
11978 }
11979
11980 if (cacheItems != null)
11981 {
11982
11983 for (int i = 0; i < maxWearablesLoop; i++)
11984 {
11985 WearableCacheItem item =
11986 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11987
11988 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11989 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11990 cachedresp.WearableData[i].HostName = new byte[0];
11991 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11992 {
11993
11994 cachedresp.WearableData[i].TextureID = item.TextureID;
11995 }
11996 else
11997 {
11998 cachedresp.WearableData[i].TextureID = UUID.Zero;
11999 }
12000 }
12001 }
12002 else
12003 {
12004 for (int i = 0; i < maxWearablesLoop; i++)
12005 {
12006 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12007 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12008 cachedresp.WearableData[i].TextureID = UUID.Zero;
12009 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12010 cachedresp.WearableData[i].HostName = new byte[0];
12011 }
11649 } 12012 }
11650 } 12013 }
11651 catch (Exception e) 12014 else
11652 { 12015 {
11653 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); 12016 if (cache == null)
11654 return false; 12017 {
12018 for (int i = 0; i < maxWearablesLoop; i++)
12019 {
12020 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12021 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12022 cachedresp.WearableData[i].TextureID = UUID.Zero;
12023 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12024 cachedresp.WearableData[i].HostName = new byte[0];
12025 }
12026 }
12027 else
12028 {
12029 for (int i = 0; i < maxWearablesLoop; i++)
12030 {
12031 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12032 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12033
12034
12035
12036 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
12037 cachedresp.WearableData[i].TextureID = UUID.Zero;
12038 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12039 else
12040 cachedresp.WearableData[i].TextureID = UUID.Zero;
12041 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12042 cachedresp.WearableData[i].HostName = new byte[0];
12043 }
12044 }
11655 } 12045 }
11656 12046 cachedresp.Header.Zerocoded = true;
12047 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12048
11657 return true; 12049 return true;
11658 } 12050 }
11659 12051
11660 /// <summary> 12052 /// <summary>
11661 /// Send a response back to a client when it asks the asset server (via the region server) if it has 12053 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11662 /// its appearance texture cached. 12054 /// its appearance texture cached.
@@ -11720,209 +12112,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11720 } 12112 }
11721 else 12113 else
11722 { 12114 {
11723// m_log.DebugFormat( 12115 ClientChangeObject updatehandler = onClientChangeObject;
11724// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11725// i, block.Type, part.Name, part.LocalId);
11726 12116
11727// // Do this once since fetch parts creates a new array. 12117 if (updatehandler != null)
11728// SceneObjectPart[] parts = part.ParentGroup.Parts; 12118 {
11729// for (int j = 0; j < parts.Length; j++) 12119 ObjectChangeData udata = new ObjectChangeData();
11730// {
11731// part.StoreUndoState();
11732// parts[j].IgnoreUndoUpdate = true;
11733// }
11734 12120
11735 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 12121 /*ubit from ll JIRA:
12122 * 0x01 position
12123 * 0x02 rotation
12124 * 0x04 scale
12125
12126 * 0x08 LINK_SET
12127 * 0x10 UNIFORM for scale
12128 */
11736 12129
11737 switch (block.Type) 12130 // translate to internal changes
11738 { 12131 // not all cases .. just the ones older code did
11739 case 1:
11740 Vector3 pos1 = new Vector3(block.Data, 0);
11741 12132
11742 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12133 switch (block.Type)
11743 if (handlerUpdatePrimSinglePosition != null) 12134 {
11744 { 12135 case 1: //change position sp
11745 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12136 udata.position = new Vector3(block.Data, 0);
11746 handlerUpdatePrimSinglePosition(localId, pos1, this);
11747 }
11748 break;
11749 12137
11750 case 2: 12138 udata.change = ObjectChangeType.primP;
11751 Quaternion rot1 = new Quaternion(block.Data, 0, true); 12139 updatehandler(localId, udata, this);
12140 break;
11752 12141
11753 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 12142 case 2: // rotation sp
11754 if (handlerUpdatePrimSingleRotation != null) 12143 udata.rotation = new Quaternion(block.Data, 0, true);
11755 {
11756 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11757 handlerUpdatePrimSingleRotation(localId, rot1, this);
11758 }
11759 break;
11760 12144
11761 case 3: 12145 udata.change = ObjectChangeType.primR;
11762 Vector3 rotPos = new Vector3(block.Data, 0); 12146 updatehandler(localId, udata, this);
11763 Quaternion rot2 = new Quaternion(block.Data, 12, true); 12147 break;
11764 12148
11765 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 12149 case 3: // position plus rotation
11766 if (handlerUpdatePrimSingleRotationPosition != null) 12150 udata.position = new Vector3(block.Data, 0);
11767 { 12151 udata.rotation = new Quaternion(block.Data, 12, true);
11768 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11769 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11770 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11771 }
11772 break;
11773 12152
11774 case 4: 12153 udata.change = ObjectChangeType.primPR;
11775 case 20: 12154 updatehandler(localId, udata, this);
11776 Vector3 scale4 = new Vector3(block.Data, 0); 12155 break;
11777 12156
11778 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 12157 case 4: // scale sp
11779 if (handlerUpdatePrimScale != null) 12158 udata.scale = new Vector3(block.Data, 0);
11780 { 12159 udata.change = ObjectChangeType.primS;
11781 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11782 handlerUpdatePrimScale(localId, scale4, this);
11783 }
11784 break;
11785 12160
11786 case 5: 12161 updatehandler(localId, udata, this);
11787 Vector3 scale1 = new Vector3(block.Data, 12); 12162 break;
11788 Vector3 pos11 = new Vector3(block.Data, 0);
11789 12163
11790 handlerUpdatePrimScale = OnUpdatePrimScale; 12164 case 0x14: // uniform scale sp
11791 if (handlerUpdatePrimScale != null) 12165 udata.scale = new Vector3(block.Data, 0);
11792 {
11793 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11794 handlerUpdatePrimScale(localId, scale1, this);
11795 12166
11796 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12167 udata.change = ObjectChangeType.primUS;
11797 if (handlerUpdatePrimSinglePosition != null) 12168 updatehandler(localId, udata, this);
11798 { 12169 break;
11799 handlerUpdatePrimSinglePosition(localId, pos11, this);
11800 }
11801 }
11802 break;
11803 12170
11804 case 9: 12171 case 5: // scale and position sp
11805 Vector3 pos2 = new Vector3(block.Data, 0); 12172 udata.position = new Vector3(block.Data, 0);
12173 udata.scale = new Vector3(block.Data, 12);
11806 12174
11807 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 12175 udata.change = ObjectChangeType.primPS;
12176 updatehandler(localId, udata, this);
12177 break;
11808 12178
11809 if (handlerUpdateVector != null) 12179 case 0x15: //uniform scale and position
11810 { 12180 udata.position = new Vector3(block.Data, 0);
11811 handlerUpdateVector(localId, pos2, this); 12181 udata.scale = new Vector3(block.Data, 12);
11812 }
11813 break;
11814 12182
11815 case 10: 12183 udata.change = ObjectChangeType.primPUS;
11816 Quaternion rot3 = new Quaternion(block.Data, 0, true); 12184 updatehandler(localId, udata, this);
12185 break;
11817 12186
11818 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 12187 // now group related (bit 4)
11819 if (handlerUpdatePrimRotation != null) 12188 case 9: //( 8 + 1 )group position
11820 { 12189 udata.position = new Vector3(block.Data, 0);
11821 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11822 handlerUpdatePrimRotation(localId, rot3, this);
11823 }
11824 break;
11825 12190
11826 case 11: 12191 udata.change = ObjectChangeType.groupP;
11827 Vector3 pos3 = new Vector3(block.Data, 0); 12192 updatehandler(localId, udata, this);
11828 Quaternion rot4 = new Quaternion(block.Data, 12, true); 12193 break;
11829 12194
11830 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 12195 case 0x0A: // (8 + 2) group rotation
11831 if (handlerUpdatePrimGroupRotation != null) 12196 udata.rotation = new Quaternion(block.Data, 0, true);
11832 {
11833 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11834 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11835 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11836 }
11837 break;
11838 case 12:
11839 case 28:
11840 Vector3 scale7 = new Vector3(block.Data, 0);
11841 12197
11842 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12198 udata.change = ObjectChangeType.groupR;
11843 if (handlerUpdatePrimGroupScale != null) 12199 updatehandler(localId, udata, this);
11844 { 12200 break;
11845 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11846 handlerUpdatePrimGroupScale(localId, scale7, this);
11847 }
11848 break;
11849 12201
11850 case 13: 12202 case 0x0B: //( 8 + 2 + 1) group rotation and position
11851 Vector3 scale2 = new Vector3(block.Data, 12); 12203 udata.position = new Vector3(block.Data, 0);
11852 Vector3 pos4 = new Vector3(block.Data, 0); 12204 udata.rotation = new Quaternion(block.Data, 12, true);
11853 12205
11854 handlerUpdatePrimScale = OnUpdatePrimScale; 12206 udata.change = ObjectChangeType.groupPR;
11855 if (handlerUpdatePrimScale != null) 12207 updatehandler(localId, udata, this);
11856 { 12208 break;
11857 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11858 handlerUpdatePrimScale(localId, scale2, this);
11859 12209
11860 // Change the position based on scale (for bug number 246) 12210 case 0x0C: // (8 + 4) group scale
11861 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12211 // only afects root prim and only sent by viewer editor object tab scaling
11862 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12212 // mouse edition only allows uniform scaling
11863 if (handlerUpdatePrimSinglePosition != null) 12213 // SL MAY CHANGE THIS in viewers
11864 {
11865 handlerUpdatePrimSinglePosition(localId, pos4, this);
11866 }
11867 }
11868 break;
11869 12214
11870 case 29: 12215 udata.scale = new Vector3(block.Data, 0);
11871 Vector3 scale5 = new Vector3(block.Data, 12);
11872 Vector3 pos5 = new Vector3(block.Data, 0);
11873 12216
11874 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12217 udata.change = ObjectChangeType.groupS;
11875 if (handlerUpdatePrimGroupScale != null) 12218 updatehandler(localId, udata, this);
11876 {
11877 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11878 part.StoreUndoState(true);
11879 part.IgnoreUndoUpdate = true;
11880 handlerUpdatePrimGroupScale(localId, scale5, this);
11881 handlerUpdateVector = OnUpdatePrimGroupPosition;
11882 12219
11883 if (handlerUpdateVector != null) 12220 break;
11884 {
11885 handlerUpdateVector(localId, pos5, this);
11886 }
11887 12221
11888 part.IgnoreUndoUpdate = false; 12222 case 0x0D: //(8 + 4 + 1) group scale and position
11889 } 12223 // exception as above
11890 12224
11891 break; 12225 udata.position = new Vector3(block.Data, 0);
12226 udata.scale = new Vector3(block.Data, 12);
11892 12227
11893 case 21: 12228 udata.change = ObjectChangeType.groupPS;
11894 Vector3 scale6 = new Vector3(block.Data, 12); 12229 updatehandler(localId, udata, this);
11895 Vector3 pos6 = new Vector3(block.Data, 0); 12230 break;
11896 12231
11897 handlerUpdatePrimScale = OnUpdatePrimScale; 12232 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11898 if (handlerUpdatePrimScale != null) 12233 udata.scale = new Vector3(block.Data, 0);
11899 {
11900 part.StoreUndoState(false);
11901 part.IgnoreUndoUpdate = true;
11902 12234
11903 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12235 udata.change = ObjectChangeType.groupUS;
11904 handlerUpdatePrimScale(localId, scale6, this); 12236 updatehandler(localId, udata, this);
11905 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12237 break;
11906 if (handlerUpdatePrimSinglePosition != null)
11907 {
11908 handlerUpdatePrimSinglePosition(localId, pos6, this);
11909 }
11910 12238
11911 part.IgnoreUndoUpdate = false; 12239 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11912 } 12240 udata.position = new Vector3(block.Data, 0);
11913 break; 12241 udata.scale = new Vector3(block.Data, 12);
11914 12242
11915 default: 12243 udata.change = ObjectChangeType.groupPUS;
11916 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12244 updatehandler(localId, udata, this);
11917 break; 12245 break;
12246
12247 default:
12248 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12249 break;
12250 }
11918 } 12251 }
11919 12252
11920// for (int j = 0; j < parts.Length; j++)
11921// parts[j].IgnoreUndoUpdate = false;
11922 } 12253 }
11923 } 12254 }
11924 } 12255 }
11925
11926 return true; 12256 return true;
11927 } 12257 }
11928 12258
@@ -11983,9 +12313,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11983 public void SetChildAgentThrottle(byte[] throttles) 12313 public void SetChildAgentThrottle(byte[] throttles)
11984 { 12314 {
11985 m_udpClient.SetThrottles(throttles); 12315 m_udpClient.SetThrottles(throttles);
12316 GenericCall2 handler = OnUpdateThrottles;
12317 if (handler != null)
12318 {
12319 handler();
12320 }
11986 } 12321 }
11987 12322
11988 /// <summary> 12323 /// <summary>
12324 /// Sets the throttles from values supplied by the client
12325 /// </summary>
12326 /// <param name="throttles"></param>
12327 public void SetAgentThrottleSilent(int throttle, int setting)
12328 {
12329 m_udpClient.ForceThrottleSetting(throttle,setting);
12330 //m_udpClient.SetThrottles(throttles);
12331
12332 }
12333
12334
12335 /// <summary>
11989 /// Get the current throttles for this client as a packed byte array 12336 /// Get the current throttles for this client as a packed byte array
11990 /// </summary> 12337 /// </summary>
11991 /// <param name="multiplier">Unused</param> 12338 /// <param name="multiplier">Unused</param>
@@ -12367,7 +12714,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12367// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12714// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12368// requestID, taskID, (SourceType)sourceType, Name); 12715// requestID, taskID, (SourceType)sourceType, Name);
12369 12716
12717
12718 //Note, the bool returned from the below function is useless since it is always false.
12370 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12719 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12720
12371 } 12721 }
12372 12722
12373 /// <summary> 12723 /// <summary>
@@ -12433,7 +12783,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12433 /// <returns></returns> 12783 /// <returns></returns>
12434 private static int CalculateNumPackets(byte[] data) 12784 private static int CalculateNumPackets(byte[] data)
12435 { 12785 {
12436 const uint m_maxPacketSize = 600; 12786// const uint m_maxPacketSize = 600;
12787 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12437 int numPackets = 1; 12788 int numPackets = 1;
12438 12789
12439 if (data == null) 12790 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 25e10be..544b54b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -168,7 +168,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
168 /// <summary>Handlers for incoming packets</summary> 168 /// <summary>Handlers for incoming packets</summary>
169 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 169 //PacketEventDictionary packetEvents = new PacketEventDictionary();
170 /// <summary>Incoming packets that are awaiting handling</summary> 170 /// <summary>Incoming packets that are awaiting handling</summary>
171 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 171 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
172
173 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
172 174
173 /// <summary></summary> 175 /// <summary></summary>
174 //private UDPClientCollection m_clients = new UDPClientCollection(); 176 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -223,6 +225,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
223 /// <summary>Flag to signal when clients should send pings</summary> 225 /// <summary>Flag to signal when clients should send pings</summary>
224 protected bool m_sendPing; 226 protected bool m_sendPing;
225 227
228 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
229
226 /// <summary> 230 /// <summary>
227 /// Event used to signal when queued packets are available for sending. 231 /// Event used to signal when queued packets are available for sending.
228 /// </summary> 232 /// </summary>
@@ -961,6 +965,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
961 965
962 #region Queue or Send 966 #region Queue or Send
963 967
968 bool highPriority = false;
969
970 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
971 {
972 category = (ThrottleOutPacketType)((int)category & 127);
973 highPriority = true;
974 }
975
964 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 976 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
965 // If we were not provided a method for handling unacked, use the UDPServer default method 977 // If we were not provided a method for handling unacked, use the UDPServer default method
966 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 978 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -969,7 +981,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
969 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 981 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
970 // packet so that it isn't sent before a queued update packet. 982 // packet so that it isn't sent before a queued update packet.
971 bool requestQueue = type == PacketType.KillObject; 983 bool requestQueue = type == PacketType.KillObject;
972 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 984 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
973 SendPacketFinal(outgoingPacket); 985 SendPacketFinal(outgoingPacket);
974 986
975 #endregion Queue or Send 987 #endregion Queue or Send
@@ -1254,34 +1266,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1254 1266
1255 #region Packet to Client Mapping 1267 #region Packet to Client Mapping
1256 1268
1257 // UseCircuitCode handling 1269 // If there is already a client for this endpoint, don't process UseCircuitCode
1258 if (packet.Type == PacketType.UseCircuitCode) 1270 IClientAPI client = null;
1271 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1259 { 1272 {
1260 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1273 // UseCircuitCode handling
1261 // buffer. 1274 if (packet.Type == PacketType.UseCircuitCode)
1262 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1275 {
1276 // And if there is a UseCircuitCode pending, also drop it
1277 lock (m_pendingCache)
1278 {
1279 if (m_pendingCache.Contains(endPoint))
1280 return;
1263 1281
1264 Util.FireAndForget(HandleUseCircuitCode, array); 1282 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1283 }
1265 1284
1266 return; 1285 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1286 // buffer.
1287 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1288
1289 Util.FireAndForget(HandleUseCircuitCode, array);
1290
1291 return;
1292 }
1267 } 1293 }
1268 else if (packet.Type == PacketType.CompleteAgentMovement) 1294
1295 // If this is a pending connection, enqueue, don't process yet
1296 lock (m_pendingCache)
1269 { 1297 {
1270 // Send ack straight away to let the viewer know that we got it. 1298 Queue<UDPPacketBuffer> queue;
1271 SendAckImmediate(endPoint, packet.Header.Sequence); 1299 if (m_pendingCache.TryGetValue(endPoint, out queue))
1300 {
1301 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1302 queue.Enqueue(buffer);
1303 return;
1304 }
1305 else if (packet.Type == PacketType.CompleteAgentMovement)
1306 {
1307 // Send ack straight away to let the viewer know that we got it.
1308 SendAckImmediate(endPoint, packet.Header.Sequence);
1272 1309
1273 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1310 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1274 // buffer. 1311 // buffer.
1275 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1312 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1276 1313
1277 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1314 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1278 1315
1279 return; 1316 return;
1317 }
1280 } 1318 }
1281 1319
1282 // Determine which agent this packet came from 1320 // Determine which agent this packet came from
1283 IClientAPI client; 1321 if (client == null || !(client is LLClientView))
1284 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1285 { 1322 {
1286 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1323 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1287 return; 1324 return;
@@ -1290,7 +1327,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1290 udpClient = ((LLClientView)client).UDPClient; 1327 udpClient = ((LLClientView)client).UDPClient;
1291 1328
1292 if (!udpClient.IsConnected) 1329 if (!udpClient.IsConnected)
1330 {
1331 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1293 return; 1332 return;
1333 }
1294 1334
1295 #endregion Packet to Client Mapping 1335 #endregion Packet to Client Mapping
1296 1336
@@ -1439,7 +1479,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1439 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1479 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1440 } 1480 }
1441 1481
1442 packetInbox.Enqueue(incomingPacket); 1482 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1483 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1484 packetInbox.EnqueueHigh(incomingPacket);
1485 else
1486 packetInbox.EnqueueLow(incomingPacket);
1443 } 1487 }
1444 1488
1445 #region BinaryStats 1489 #region BinaryStats
@@ -1591,6 +1635,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1591 if (!tp) 1635 if (!tp)
1592 client.SceneAgent.SendInitialDataToMe(); 1636 client.SceneAgent.SendInitialDataToMe();
1593 } 1637 }
1638
1639 // Now we know we can handle more data
1640 Thread.Sleep(200);
1641
1642 // Obtain the queue and remove it from the cache
1643 Queue<UDPPacketBuffer> queue = null;
1644
1645 lock (m_pendingCache)
1646 {
1647 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1648 {
1649 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1650 return;
1651 }
1652 m_pendingCache.Remove(endPoint);
1653 }
1654
1655 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1656
1657 // Reinject queued packets
1658 while(queue.Count > 0)
1659 {
1660 UDPPacketBuffer buf = queue.Dequeue();
1661 PacketReceived(buf);
1662 }
1663 queue = null;
1594 } 1664 }
1595 else 1665 else
1596 { 1666 {
@@ -1598,6 +1668,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1598 m_log.WarnFormat( 1668 m_log.WarnFormat(
1599 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1669 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1600 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1670 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1671 lock (m_pendingCache)
1672 m_pendingCache.Remove(endPoint);
1601 } 1673 }
1602 1674
1603 // m_log.DebugFormat( 1675 // m_log.DebugFormat(
@@ -1783,7 +1855,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1783 if (!client.SceneAgent.IsChildAgent) 1855 if (!client.SceneAgent.IsChildAgent)
1784 client.Kick("Simulator logged you out due to connection timeout"); 1856 client.Kick("Simulator logged you out due to connection timeout");
1785 1857
1786 client.CloseWithoutChecks(); 1858 client.CloseWithoutChecks(true);
1787 } 1859 }
1788 } 1860 }
1789 1861
@@ -1795,6 +1867,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1795 1867
1796 while (IsRunningInbound) 1868 while (IsRunningInbound)
1797 { 1869 {
1870 m_scene.ThreadAlive(1);
1798 try 1871 try
1799 { 1872 {
1800 IncomingPacket incomingPacket = null; 1873 IncomingPacket incomingPacket = null;
@@ -1844,6 +1917,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1844 1917
1845 while (base.IsRunningOutbound) 1918 while (base.IsRunningOutbound)
1846 { 1919 {
1920 m_scene.ThreadAlive(2);
1847 try 1921 try
1848 { 1922 {
1849 m_packetSent = false; 1923 m_packetSent = false;
@@ -2078,8 +2152,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2078 Packet packet = incomingPacket.Packet; 2152 Packet packet = incomingPacket.Packet;
2079 LLClientView client = incomingPacket.Client; 2153 LLClientView client = incomingPacket.Client;
2080 2154
2081 if (client.IsActive) 2155// if (client.IsActive)
2082 { 2156// {
2083 m_currentIncomingClient = client; 2157 m_currentIncomingClient = client;
2084 2158
2085 try 2159 try
@@ -2106,13 +2180,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2106 { 2180 {
2107 m_currentIncomingClient = null; 2181 m_currentIncomingClient = null;
2108 } 2182 }
2109 } 2183// }
2110 else 2184// else
2111 { 2185// {
2112 m_log.DebugFormat( 2186// m_log.DebugFormat(
2113 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2187// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2114 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2188// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2115 } 2189// }
2116 2190
2117 IncomingPacketsProcessed++; 2191 IncomingPacketsProcessed++;
2118 } 2192 }
@@ -2124,8 +2198,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2124 if (!client.IsLoggingOut) 2198 if (!client.IsLoggingOut)
2125 { 2199 {
2126 client.IsLoggingOut = true; 2200 client.IsLoggingOut = true;
2127 client.Close(); 2201 client.Close(false, false);
2128 } 2202 }
2129 } 2203 }
2130 } 2204 }
2131} \ No newline at end of file 2205}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index d0ed7e8..48c5b37 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,