aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1463
1 files changed, 899 insertions, 564 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 7ea538c..f8b9352 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -51,6 +51,7 @@ using RegionFlags = OpenMetaverse.RegionFlags;
51using Nini.Config; 51using Nini.Config;
52 52
53using System.IO; 53using System.IO;
54using PermissionMask = OpenSim.Framework.PermissionMask;
54 55
55namespace OpenSim.Region.ClientStack.LindenUDP 56namespace OpenSim.Region.ClientStack.LindenUDP
56{ 57{
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 public event AvatarPickerRequest OnAvatarPickerRequest; 100 public event AvatarPickerRequest OnAvatarPickerRequest;
100 public event StartAnim OnStartAnim; 101 public event StartAnim OnStartAnim;
101 public event StopAnim OnStopAnim; 102 public event StopAnim OnStopAnim;
103 public event ChangeAnim OnChangeAnim;
102 public event Action<IClientAPI> OnRequestAvatarsData; 104 public event Action<IClientAPI> OnRequestAvatarsData;
103 public event LinkObjects OnLinkObjects; 105 public event LinkObjects OnLinkObjects;
104 public event DelinkObjects OnDelinkObjects; 106 public event DelinkObjects OnDelinkObjects;
@@ -126,6 +128,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 128 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
127 public event UpdatePrimFlags OnUpdatePrimFlags; 129 public event UpdatePrimFlags OnUpdatePrimFlags;
128 public event UpdatePrimTexture OnUpdatePrimTexture; 130 public event UpdatePrimTexture OnUpdatePrimTexture;
131 public event ClientChangeObject onClientChangeObject;
129 public event UpdateVector OnUpdatePrimGroupPosition; 132 public event UpdateVector OnUpdatePrimGroupPosition;
130 public event UpdateVector OnUpdatePrimSinglePosition; 133 public event UpdateVector OnUpdatePrimSinglePosition;
131 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 134 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -159,6 +162,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 public event RequestTaskInventory OnRequestTaskInventory; 162 public event RequestTaskInventory OnRequestTaskInventory;
160 public event UpdateInventoryItem OnUpdateInventoryItem; 163 public event UpdateInventoryItem OnUpdateInventoryItem;
161 public event CopyInventoryItem OnCopyInventoryItem; 164 public event CopyInventoryItem OnCopyInventoryItem;
165 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
162 public event MoveInventoryItem OnMoveInventoryItem; 166 public event MoveInventoryItem OnMoveInventoryItem;
163 public event RemoveInventoryItem OnRemoveInventoryItem; 167 public event RemoveInventoryItem OnRemoveInventoryItem;
164 public event RemoveInventoryFolder OnRemoveInventoryFolder; 168 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -257,7 +261,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
257 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 261 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
258 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 262 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
259 public event ClassifiedDelete OnClassifiedDelete; 263 public event ClassifiedDelete OnClassifiedDelete;
260 public event ClassifiedDelete OnClassifiedGodDelete; 264 public event ClassifiedGodDelete OnClassifiedGodDelete;
261 public event EventNotificationAddRequest OnEventNotificationAddRequest; 265 public event EventNotificationAddRequest OnEventNotificationAddRequest;
262 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 266 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
263 public event EventGodDelete OnEventGodDelete; 267 public event EventGodDelete OnEventGodDelete;
@@ -288,10 +292,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
288 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 292 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
289 public event SimWideDeletesDelegate OnSimWideDeletes; 293 public event SimWideDeletesDelegate OnSimWideDeletes;
290 public event SendPostcard OnSendPostcard; 294 public event SendPostcard OnSendPostcard;
295 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
291 public event MuteListEntryUpdate OnUpdateMuteListEntry; 296 public event MuteListEntryUpdate OnUpdateMuteListEntry;
292 public event MuteListEntryRemove OnRemoveMuteListEntry; 297 public event MuteListEntryRemove OnRemoveMuteListEntry;
293 public event GodlikeMessage onGodlikeMessage; 298 public event GodlikeMessage onGodlikeMessage;
294 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 299 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
300 public event GenericCall2 OnUpdateThrottles;
295 301
296 #endregion Events 302 #endregion Events
297 303
@@ -326,6 +332,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
326 private Prioritizer m_prioritizer; 332 private Prioritizer m_prioritizer;
327 private bool m_disableFacelights = false; 333 private bool m_disableFacelights = false;
328 334
335 private bool m_VelocityInterpolate = false;
336 private const uint MaxTransferBytesPerPacket = 600;
337
338
329 /// <value> 339 /// <value>
330 /// List used in construction of data blocks for an object update packet. This is to stop us having to 340 /// List used in construction of data blocks for an object update packet. This is to stop us having to
331 /// continually recreate it. 341 /// continually recreate it.
@@ -337,14 +347,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 347 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 348 /// ownerless phantom.
339 /// 349 ///
340 /// All manipulation of this set has to occur under a lock 350 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 351 ///
342 /// </value> 352 /// </value>
343 protected HashSet<uint> m_killRecord; 353// protected HashSet<uint> m_killRecord;
344 354
345// protected HashSet<uint> m_attachmentsSent; 355// protected HashSet<uint> m_attachmentsSent;
346 356
347 private int m_moneyBalance; 357 private int m_moneyBalance;
358 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 359 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 360 private bool m_SendLogoutPacketWhenClosing = true;
350 361
@@ -391,6 +402,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 402 get { return m_startpos; }
392 set { m_startpos = value; } 403 set { m_startpos = value; }
393 } 404 }
405 public bool DeliverPackets
406 {
407 get { return m_deliverPackets; }
408 set {
409 m_deliverPackets = value;
410 m_udpClient.m_deliverPackets = value;
411 }
412 }
394 public UUID AgentId { get { return m_agentId; } } 413 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 414 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 415 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));
@@ -790,9 +822,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
790 handshake.RegionInfo3.ColoName = Utils.EmptyBytes; 822 handshake.RegionInfo3.ColoName = Utils.EmptyBytes;
791 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 823 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
792 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 824 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
825
793 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0]; 826 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0];
794 827// OutPacket(handshake, ThrottleOutPacketType.Task);
795 OutPacket(handshake, ThrottleOutPacketType.Task); 828 // use same as MoveAgentIntoRegion (both should be task )
829 OutPacket(handshake, ThrottleOutPacketType.Unknown);
796 } 830 }
797 831
798 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 832 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -832,7 +866,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
832 reply.ChatData.OwnerID = ownerID; 866 reply.ChatData.OwnerID = ownerID;
833 reply.ChatData.SourceID = fromAgentID; 867 reply.ChatData.SourceID = fromAgentID;
834 868
835 OutPacket(reply, ThrottleOutPacketType.Task); 869 OutPacket(reply, ThrottleOutPacketType.Unknown);
836 } 870 }
837 871
838 /// <summary> 872 /// <summary>
@@ -865,32 +899,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
865 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 899 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
866 msg.MessageBlock.BinaryBucket = im.binaryBucket; 900 msg.MessageBlock.BinaryBucket = im.binaryBucket;
867 901
868 if (im.message.StartsWith("[grouptest]")) 902 OutPacket(msg, ThrottleOutPacketType.Task);
869 { // this block is test code for implementing group IM - delete when group IM is finished
870 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
871 if (eq != null)
872 {
873 im.dialog = 17;
874
875 //eq.ChatterboxInvitation(
876 // new UUID("00000000-68f9-1111-024e-222222111123"),
877 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
878 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
879
880 eq.ChatterboxInvitation(
881 new UUID("00000000-68f9-1111-024e-222222111123"),
882 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
883 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
884
885 eq.ChatterBoxSessionAgentListUpdates(
886 new UUID("00000000-68f9-1111-024e-222222111123"),
887 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
888 }
889
890 Console.WriteLine("SendInstantMessage: " + msg);
891 }
892 else
893 OutPacket(msg, ThrottleOutPacketType.Task);
894 } 903 }
895 } 904 }
896 905
@@ -1118,6 +1127,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1118 public virtual void SendLayerData(float[] map) 1127 public virtual void SendLayerData(float[] map)
1119 { 1128 {
1120 Util.FireAndForget(DoSendLayerData, map); 1129 Util.FireAndForget(DoSendLayerData, map);
1130
1131 // Send it sync, and async. It's not that much data
1132 // and it improves user experience just so much!
1133 DoSendLayerData(map);
1121 } 1134 }
1122 1135
1123 /// <summary> 1136 /// <summary>
@@ -1130,16 +1143,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1130 1143
1131 try 1144 try
1132 { 1145 {
1133 //for (int y = 0; y < 16; y++) 1146 for (int y = 0; y < 16; y++)
1134 //{ 1147 {
1135 // for (int x = 0; x < 16; x++) 1148 for (int x = 0; x < 16; x+=4)
1136 // { 1149 {
1137 // SendLayerData(x, y, map); 1150 SendLayerPacket(x, y, map);
1138 // } 1151 }
1139 //} 1152 }
1140
1141 // Send LayerData in a spiral pattern. Fun!
1142 SendLayerTopRight(map, 0, 0, 15, 15);
1143 } 1153 }
1144 catch (Exception e) 1154 catch (Exception e)
1145 { 1155 {
@@ -1147,51 +1157,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1147 } 1157 }
1148 } 1158 }
1149 1159
1150 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1151 {
1152 // Row
1153 for (int i = x1; i <= x2; i++)
1154 SendLayerData(i, y1, map);
1155
1156 // Column
1157 for (int j = y1 + 1; j <= y2; j++)
1158 SendLayerData(x2, j, map);
1159
1160 if (x2 - x1 > 0)
1161 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1162 }
1163
1164 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1165 {
1166 // Row in reverse
1167 for (int i = x2; i >= x1; i--)
1168 SendLayerData(i, y2, map);
1169
1170 // Column in reverse
1171 for (int j = y2 - 1; j >= y1; j--)
1172 SendLayerData(x1, j, map);
1173
1174 if (x2 - x1 > 0)
1175 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1176 }
1177
1178 /// <summary> 1160 /// <summary>
1179 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1161 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1180 /// </summary> 1162 /// </summary>
1181 /// <param name="map">heightmap</param> 1163 /// <param name="map">heightmap</param>
1182 /// <param name="px">X coordinate for patches 0..12</param> 1164 /// <param name="px">X coordinate for patches 0..12</param>
1183 /// <param name="py">Y coordinate for patches 0..15</param> 1165 /// <param name="py">Y coordinate for patches 0..15</param>
1184 // private void SendLayerPacket(float[] map, int y, int x) 1166 private void SendLayerPacket(int x, int y, float[] map)
1185 // { 1167 {
1186 // int[] patches = new int[4]; 1168 int[] patches = new int[4];
1187 // patches[0] = x + 0 + y * 16; 1169 patches[0] = x + 0 + y * 16;
1188 // patches[1] = x + 1 + y * 16; 1170 patches[1] = x + 1 + y * 16;
1189 // patches[2] = x + 2 + y * 16; 1171 patches[2] = x + 2 + y * 16;
1190 // patches[3] = x + 3 + y * 16; 1172 patches[3] = x + 3 + y * 16;
1191 1173
1192 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1174 float[] heightmap = (map.Length == 65536) ?
1193 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1175 map :
1194 // } 1176 LLHeightFieldMoronize(map);
1177
1178 try
1179 {
1180 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1181 OutPacket(layerpack, ThrottleOutPacketType.Land);
1182 }
1183 catch
1184 {
1185 for (int px = x ; px < x + 4 ; px++)
1186 SendLayerData(px, y, map);
1187 }
1188 }
1195 1189
1196 /// <summary> 1190 /// <summary>
1197 /// Sends a specified patch to a client 1191 /// Sends a specified patch to a client
@@ -1211,7 +1205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1211 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1205 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1212 layerpack.Header.Reliable = true; 1206 layerpack.Header.Reliable = true;
1213 1207
1214 OutPacket(layerpack, ThrottleOutPacketType.Land); 1208 OutPacket(layerpack, ThrottleOutPacketType.Task);
1215 } 1209 }
1216 catch (Exception e) 1210 catch (Exception e)
1217 { 1211 {
@@ -1574,7 +1568,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1574 1568
1575 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1569 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1576 { 1570 {
1577// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1571// foreach (uint id in localIDs)
1572// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1578 1573
1579 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1574 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1580 // TODO: don't create new blocks if recycling an old packet 1575 // TODO: don't create new blocks if recycling an old packet
@@ -1596,17 +1591,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1596 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1591 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1597 // condition where a kill can be processed before an out-of-date update for the same object. 1592 // condition where a kill can be processed before an out-of-date update for the same object.
1598 // ProcessEntityUpdates() also takes the m_killRecord lock. 1593 // ProcessEntityUpdates() also takes the m_killRecord lock.
1599 lock (m_killRecord) 1594// lock (m_killRecord)
1600 { 1595// {
1601 foreach (uint localID in localIDs) 1596// foreach (uint localID in localIDs)
1602 m_killRecord.Add(localID); 1597// m_killRecord.Add(localID);
1603 1598
1604 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1599 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1605 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1600 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1606 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1601 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1607 // scene objects in a viewer until that viewer is relogged in. 1602 // scene objects in a viewer until that viewer is relogged in.
1608 OutPacket(kill, ThrottleOutPacketType.Task); 1603 OutPacket(kill, ThrottleOutPacketType.Task);
1609 } 1604// }
1610 } 1605 }
1611 } 1606 }
1612 1607
@@ -1808,7 +1803,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1808 1803
1809 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) 1804 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
1810 { 1805 {
1811 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 1806 // Fudge this value. It's only needed to make the CRC anyway
1807 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
1812 1808
1813 FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); 1809 FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply);
1814 // TODO: don't create new blocks if recycling an old packet 1810 // TODO: don't create new blocks if recycling an old packet
@@ -2013,7 +2009,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2013 2009
2014 protected void SendBulkUpdateInventoryItem(InventoryItemBase item) 2010 protected void SendBulkUpdateInventoryItem(InventoryItemBase item)
2015 { 2011 {
2016 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2012 const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff;
2017 2013
2018 BulkUpdateInventoryPacket bulkUpdate 2014 BulkUpdateInventoryPacket bulkUpdate
2019 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); 2015 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
@@ -2064,10 +2060,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2064 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2060 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2065 } 2061 }
2066 2062
2067 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2068 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2063 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2069 { 2064 {
2070 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2065 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2066 }
2067
2068 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2069 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2070 {
2071 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2071 2072
2072 UpdateCreateInventoryItemPacket InventoryReply 2073 UpdateCreateInventoryItemPacket InventoryReply
2073 = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket( 2074 = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket(
@@ -2076,6 +2077,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2076 // TODO: don't create new blocks if recycling an old packet 2077 // TODO: don't create new blocks if recycling an old packet
2077 InventoryReply.AgentData.AgentID = AgentId; 2078 InventoryReply.AgentData.AgentID = AgentId;
2078 InventoryReply.AgentData.SimApproved = true; 2079 InventoryReply.AgentData.SimApproved = true;
2080 InventoryReply.AgentData.TransactionID = transactionID;
2079 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2081 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2080 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2082 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2081 InventoryReply.InventoryData[0].ItemID = Item.ID; 2083 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2145,16 +2147,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2145 replytask.InventoryData.TaskID = taskID; 2147 replytask.InventoryData.TaskID = taskID;
2146 replytask.InventoryData.Serial = serial; 2148 replytask.InventoryData.Serial = serial;
2147 replytask.InventoryData.Filename = fileName; 2149 replytask.InventoryData.Filename = fileName;
2148 OutPacket(replytask, ThrottleOutPacketType.Asset); 2150 OutPacket(replytask, ThrottleOutPacketType.Task);
2149 } 2151 }
2150 2152
2151 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2153 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2152 { 2154 {
2155 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2156 if (isTaskInventory)
2157 type = ThrottleOutPacketType.Task;
2158
2153 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2159 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2154 sendXfer.XferID.ID = xferID; 2160 sendXfer.XferID.ID = xferID;
2155 sendXfer.XferID.Packet = packet; 2161 sendXfer.XferID.Packet = packet;
2156 sendXfer.DataPacket.Data = data; 2162 sendXfer.DataPacket.Data = data;
2157 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2163 OutPacket(sendXfer, type);
2158 } 2164 }
2159 2165
2160 public void SendAbortXferPacket(ulong xferID) 2166 public void SendAbortXferPacket(ulong xferID)
@@ -2336,6 +2342,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2336 OutPacket(sound, ThrottleOutPacketType.Task); 2342 OutPacket(sound, ThrottleOutPacketType.Task);
2337 } 2343 }
2338 2344
2345 public void SendTransferAbort(TransferRequestPacket transferRequest)
2346 {
2347 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2348 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2349 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2350 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2351 OutPacket(abort, ThrottleOutPacketType.Task);
2352 }
2353
2339 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2354 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2340 { 2355 {
2341 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2356 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2644,6 +2659,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2644 float friction = part.Friction; 2659 float friction = part.Friction;
2645 float bounce = part.Restitution; 2660 float bounce = part.Restitution;
2646 float gravmod = part.GravityModifier; 2661 float gravmod = part.GravityModifier;
2662
2647 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2663 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2648 } 2664 }
2649 } 2665 }
@@ -2714,8 +2730,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2714 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2730 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2715 return; 2731 return;
2716 } 2732 }
2733 int WearableOut = 0;
2734 bool isWearable = false;
2717 2735
2718 //m_log.Debug("sending asset " + req.RequestAssetID); 2736 if (req.AssetInf != null)
2737 isWearable =
2738 ((AssetType) req.AssetInf.Type ==
2739 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2740
2741
2742 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2743
2744
2745 //if (isWearable)
2746 // m_log.Debug((AssetType)req.AssetInf.Type);
2747
2719 TransferInfoPacket Transfer = new TransferInfoPacket(); 2748 TransferInfoPacket Transfer = new TransferInfoPacket();
2720 Transfer.TransferInfo.ChannelType = 2; 2749 Transfer.TransferInfo.ChannelType = 2;
2721 Transfer.TransferInfo.Status = 0; 2750 Transfer.TransferInfo.Status = 0;
@@ -2737,7 +2766,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2737 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2766 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2738 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2767 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2739 Transfer.Header.Zerocoded = true; 2768 Transfer.Header.Zerocoded = true;
2740 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2769 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2741 2770
2742 if (req.NumPackets == 1) 2771 if (req.NumPackets == 1)
2743 { 2772 {
@@ -2748,12 +2777,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2748 TransferPacket.TransferData.Data = req.AssetInf.Data; 2777 TransferPacket.TransferData.Data = req.AssetInf.Data;
2749 TransferPacket.TransferData.Status = 1; 2778 TransferPacket.TransferData.Status = 1;
2750 TransferPacket.Header.Zerocoded = true; 2779 TransferPacket.Header.Zerocoded = true;
2751 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2780 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2752 } 2781 }
2753 else 2782 else
2754 { 2783 {
2755 int processedLength = 0; 2784 int processedLength = 0;
2756 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2785// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2786
2787 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2757 int packetNumber = 0; 2788 int packetNumber = 0;
2758 2789
2759 while (processedLength < req.AssetInf.Data.Length) 2790 while (processedLength < req.AssetInf.Data.Length)
@@ -2779,7 +2810,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2779 TransferPacket.TransferData.Status = 1; 2810 TransferPacket.TransferData.Status = 1;
2780 } 2811 }
2781 TransferPacket.Header.Zerocoded = true; 2812 TransferPacket.Header.Zerocoded = true;
2782 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2813 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2783 2814
2784 processedLength += chunkSize; 2815 processedLength += chunkSize;
2785 packetNumber++; 2816 packetNumber++;
@@ -2824,7 +2855,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2824 reply.Data.ParcelID = parcelID; 2855 reply.Data.ParcelID = parcelID;
2825 reply.Data.OwnerID = land.OwnerID; 2856 reply.Data.OwnerID = land.OwnerID;
2826 reply.Data.Name = Utils.StringToBytes(land.Name); 2857 reply.Data.Name = Utils.StringToBytes(land.Name);
2827 reply.Data.Desc = Utils.StringToBytes(land.Description); 2858 if (land != null && land.Description != null && land.Description != String.Empty)
2859 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2860 else
2861 reply.Data.Desc = new Byte[0];
2828 reply.Data.ActualArea = land.Area; 2862 reply.Data.ActualArea = land.Area;
2829 reply.Data.BillableArea = land.Area; // TODO: what is this? 2863 reply.Data.BillableArea = land.Area; // TODO: what is this?
2830 2864
@@ -3531,24 +3565,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3531 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3565 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3532 AgentWearablesUpdatePacket.WearableDataBlock awb; 3566 AgentWearablesUpdatePacket.WearableDataBlock awb;
3533 int idx = 0; 3567 int idx = 0;
3534 for (int i = 0; i < wearables.Length; i++) 3568
3535 { 3569 for (int i = 0; i < wearables.Length; i++)
3536 for (int j = 0; j < wearables[i].Count; j++) 3570 {
3537 { 3571 for (int j = 0; j < wearables[i].Count; j++)
3538 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3572 {
3539 awb.WearableType = (byte)i; 3573 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3540 awb.AssetID = wearables[i][j].AssetID; 3574 awb.WearableType = (byte) i;
3541 awb.ItemID = wearables[i][j].ItemID; 3575 awb.AssetID = wearables[i][j].AssetID;
3542 aw.WearableData[idx] = awb; 3576 awb.ItemID = wearables[i][j].ItemID;
3543 idx++; 3577 aw.WearableData[idx] = awb;
3544 3578 idx++;
3545// m_log.DebugFormat( 3579
3546// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3580 // m_log.DebugFormat(
3547// awb.ItemID, awb.AssetID, i, Name); 3581 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3548 } 3582 // awb.ItemID, awb.AssetID, i, Name);
3549 } 3583 }
3584 }
3550 3585
3551 OutPacket(aw, ThrottleOutPacketType.Task); 3586 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3552 } 3587 }
3553 3588
3554 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3589 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3559,7 +3594,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3559 3594
3560 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3595 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3561 // TODO: don't create new blocks if recycling an old packet 3596 // TODO: don't create new blocks if recycling an old packet
3562 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3597 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3563 avp.ObjectData.TextureEntry = textureEntry; 3598 avp.ObjectData.TextureEntry = textureEntry;
3564 3599
3565 AvatarAppearancePacket.VisualParamBlock avblock = null; 3600 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3690,7 +3725,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3690 /// </summary> 3725 /// </summary>
3691 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3726 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3692 { 3727 {
3693 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3728 if (entity is SceneObjectPart)
3729 {
3730 SceneObjectPart e = (SceneObjectPart)entity;
3731 SceneObjectGroup g = e.ParentGroup;
3732 if (g.RootPart.Shape.State > 30) // HUD
3733 if (g.OwnerID != AgentId)
3734 return; // Don't send updates for other people's HUDs
3735 }
3736
3694 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3737 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3695 3738
3696 lock (m_entityUpdates.SyncRoot) 3739 lock (m_entityUpdates.SyncRoot)
@@ -3757,27 +3800,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3757 3800
3758 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3801 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3759 // condition where a kill can be processed before an out-of-date update for the same object. 3802 // condition where a kill can be processed before an out-of-date update for the same object.
3760 lock (m_killRecord) 3803 float avgTimeDilation = 1.0f;
3804 IEntityUpdate iupdate;
3805 Int32 timeinqueue; // this is just debugging code & can be dropped later
3806
3807 while (updatesThisCall < maxUpdates)
3761 { 3808 {
3762 float avgTimeDilation = 1.0f; 3809 lock (m_entityUpdates.SyncRoot)
3763 IEntityUpdate iupdate; 3810 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3764 Int32 timeinqueue; // this is just debugging code & can be dropped later 3811 break;
3812
3813 EntityUpdate update = (EntityUpdate)iupdate;
3814
3815 avgTimeDilation += update.TimeDilation;
3816 avgTimeDilation *= 0.5f;
3765 3817
3766 while (updatesThisCall < maxUpdates) 3818 if (update.Entity is SceneObjectPart)
3767 { 3819 {
3768 lock (m_entityUpdates.SyncRoot) 3820 SceneObjectPart part = (SceneObjectPart)update.Entity;
3769 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3770 break;
3771 3821
3772 EntityUpdate update = (EntityUpdate)iupdate; 3822 if (part.ParentGroup.IsDeleted)
3773 3823 continue;
3774 avgTimeDilation += update.TimeDilation;
3775 avgTimeDilation *= 0.5f;
3776 3824
3777 if (update.Entity is SceneObjectPart) 3825 if (part.ParentGroup.IsAttachment)
3826 { // Someone else's HUD, why are we getting these?
3827 if (part.ParentGroup.OwnerID != AgentId &&
3828 part.ParentGroup.RootPart.Shape.State > 30)
3829 continue;
3830 ScenePresence sp;
3831 // Owner is not in the sim, don't update it to
3832 // anyone
3833 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3834 continue;
3835
3836 List<SceneObjectGroup> atts = sp.GetAttachments();
3837 bool found = false;
3838 foreach (SceneObjectGroup att in atts)
3839 {
3840 if (att == part.ParentGroup)
3841 {
3842 found = true;
3843 break;
3844 }
3845 }
3846
3847 // It's an attachment of a valid avatar, but
3848 // doesn't seem to be attached, skip
3849 if (!found)
3850 continue;
3851
3852 // On vehicle crossing, the attachments are received
3853 // while the avatar is still a child. Don't send
3854 // updates here because the LocalId has not yet
3855 // been updated and the viewer will derender the
3856 // attachments until the avatar becomes root.
3857 if (sp.IsChildAgent)
3858 continue;
3859
3860 // If the object is an attachment we don't want it to be in the kill
3861 // record. Else attaching from inworld and subsequently dropping
3862 // it will no longer work.
3863// lock (m_killRecord)
3864// {
3865// m_killRecord.Remove(part.LocalId);
3866// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3867// }
3868 }
3869 else
3778 { 3870 {
3779 SceneObjectPart part = (SceneObjectPart)update.Entity;
3780
3781 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3871 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3782 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3872 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3783 // safety measure. 3873 // safety measure.
@@ -3788,21 +3878,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3788 // 3878 //
3789 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3879 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3790 // after the root prim has been deleted. 3880 // after the root prim has been deleted.
3791 if (m_killRecord.Contains(part.LocalId)) 3881 //
3792 { 3882 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3793 // m_log.WarnFormat( 3883// lock (m_killRecord)
3794 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3884// {
3795 // part.LocalId, Name); 3885// if (m_killRecord.Contains(part.LocalId))
3796 continue; 3886// continue;
3797 } 3887// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3798 3888// continue;
3799 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3889// }
3890 }
3891
3892 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3893 {
3894 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3895 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3800 { 3896 {
3801 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3897 part.Shape.LightEntry = false;
3802 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3803 {
3804 part.Shape.LightEntry = false;
3805 }
3806 } 3898 }
3807 3899
3808 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3900 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3813,224 +3905,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3813 part.Shape.ProfileHollow = 27500; 3905 part.Shape.ProfileHollow = 27500;
3814 } 3906 }
3815 } 3907 }
3816 3908
3817 #region UpdateFlags to packet type conversion 3909 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3818
3819 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3820
3821 bool canUseCompressed = true;
3822 bool canUseImproved = true;
3823
3824 // Compressed object updates only make sense for LL primitives
3825 if (!(update.Entity is SceneObjectPart))
3826 { 3910 {
3827 canUseCompressed = false; 3911 // Ensure that mesh has at least 8 valid faces
3912 part.Shape.ProfileBegin = 12500;
3913 part.Shape.ProfileEnd = 0;
3914 part.Shape.ProfileHollow = 27500;
3828 } 3915 }
3829 3916 }
3830 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3917
3918 ++updatesThisCall;
3919
3920 #region UpdateFlags to packet type conversion
3921
3922 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3923
3924 bool canUseCompressed = true;
3925 bool canUseImproved = true;
3926
3927 // Compressed object updates only make sense for LL primitives
3928 if (!(update.Entity is SceneObjectPart))
3929 {
3930 canUseCompressed = false;
3931 }
3932
3933 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3934 {
3935 canUseCompressed = false;
3936 canUseImproved = false;
3937 }
3938 else
3939 {
3940 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3941 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3942 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3943 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3831 { 3944 {
3832 canUseCompressed = false; 3945 canUseCompressed = false;
3833 canUseImproved = false;
3834 } 3946 }
3835 else 3947
3948 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3950 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3951 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3952 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3953 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3957 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3958 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3959 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3960 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3961 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3836 { 3962 {
3837 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3963 canUseImproved = false;
3838 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3839 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3840 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3841 {
3842 canUseCompressed = false;
3843 }
3844
3845 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3846 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3847 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3848 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3849 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3850 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3851 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3852 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3853 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3854 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3855 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3858 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3859 {
3860 canUseImproved = false;
3861 }
3862 } 3964 }
3965 }
3863 3966
3864 #endregion UpdateFlags to packet type conversion 3967 #endregion UpdateFlags to packet type conversion
3865
3866 #region Block Construction
3867
3868 // TODO: Remove this once we can build compressed updates
3869 canUseCompressed = false;
3870
3871 if (!canUseImproved && !canUseCompressed)
3872 {
3873 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3874 3968
3875 if (update.Entity is ScenePresence) 3969 #region Block Construction
3876 {
3877 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3878 }
3879 else
3880 {
3881 SceneObjectPart part = (SceneObjectPart)update.Entity;
3882 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3883
3884 // If the part has become a private hud since the update was scheduled then we do not
3885 // want to send it to other avatars.
3886 if (part.ParentGroup.IsAttachment
3887 && part.ParentGroup.HasPrivateAttachmentPoint
3888 && part.ParentGroup.AttachedAvatar != AgentId)
3889 continue;
3890
3891 // If the part has since been deleted, then drop the update. In the case of attachments,
3892 // this is to avoid spurious updates to other viewers since post-processing of attachments
3893 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3894 // of the test above).
3895 //
3896 // Actual deletions (kills) happen in another method.
3897 if (part.ParentGroup.IsDeleted)
3898 continue;
3899 }
3900 3970
3901 objectUpdateBlocks.Value.Add(updateBlock); 3971 // TODO: Remove this once we can build compressed updates
3902 objectUpdates.Value.Add(update); 3972 canUseCompressed = false;
3903 }
3904 else if (!canUseImproved)
3905 {
3906 SceneObjectPart part = (SceneObjectPart)update.Entity;
3907 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3908 = CreateCompressedUpdateBlock(part, updateFlags);
3909
3910 // If the part has since been deleted, then drop the update. In the case of attachments,
3911 // this is to avoid spurious updates to other viewers since post-processing of attachments
3912 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3913 // of the test above).
3914 //
3915 // Actual deletions (kills) happen in another method.
3916 if (part.ParentGroup.IsDeleted)
3917 continue;
3918 3973
3919 compressedUpdateBlocks.Value.Add(compressedBlock); 3974 if (!canUseImproved && !canUseCompressed)
3920 compressedUpdates.Value.Add(update); 3975 {
3976 if (update.Entity is ScenePresence)
3977 {
3978 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3921 } 3979 }
3922 else 3980 else
3923 { 3981 {
3924 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3982 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3925 {
3926 // Self updates go into a special list
3927 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3928 terseAgentUpdates.Value.Add(update);
3929 }
3930 else
3931 {
3932 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3933 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3934
3935 // Everything else goes here
3936 if (update.Entity is SceneObjectPart)
3937 {
3938 SceneObjectPart part = (SceneObjectPart)update.Entity;
3939
3940 // If the part has become a private hud since the update was scheduled then we do not
3941 // want to send it to other avatars.
3942 if (part.ParentGroup.IsAttachment
3943 && part.ParentGroup.HasPrivateAttachmentPoint
3944 && part.ParentGroup.AttachedAvatar != AgentId)
3945 continue;
3946
3947 // If the part has since been deleted, then drop the update. In the case of attachments,
3948 // this is to avoid spurious updates to other viewers since post-processing of attachments
3949 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3950 // of the test above).
3951 //
3952 // Actual deletions (kills) happen in another method.
3953 if (part.ParentGroup.IsDeleted)
3954 continue;
3955 }
3956
3957 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3958 terseUpdates.Value.Add(update);
3959 }
3960 } 3983 }
3961
3962 ++updatesThisCall;
3963
3964 #endregion Block Construction
3965 } 3984 }
3966 3985 else if (!canUseImproved)
3967 #region Packet Sending 3986 {
3968 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3987 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3969 3988 }
3970 if (terseAgentUpdateBlocks.IsValueCreated) 3989 else
3971 { 3990 {
3972 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3991 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3992 // Self updates go into a special list
3993 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3994 else
3995 // Everything else goes here
3996 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3997 }
3973 3998
3974 ImprovedTerseObjectUpdatePacket packet 3999 #endregion Block Construction
3975 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4000 }
3976 4001
3977 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4002 #region Packet Sending
3978 packet.RegionData.TimeDilation = timeDilation; 4003
3979 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4004 const float TIME_DILATION = 1.0f;
4005 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4006
4007 if (terseAgentUpdateBlocks.IsValueCreated)
4008 {
4009 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3980 4010
3981 for (int i = 0; i < blocks.Count; i++) 4011 ImprovedTerseObjectUpdatePacket packet
3982 packet.ObjectData[i] = blocks[i]; 4012 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3983 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4013 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3984 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4014 packet.RegionData.TimeDilation = timeDilation;
3985 } 4015 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3986 4016
3987 if (objectUpdateBlocks.IsValueCreated) 4017 for (int i = 0; i < blocks.Count; i++)
3988 { 4018 packet.ObjectData[i] = blocks[i];
3989 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3990
3991 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3992 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3993 packet.RegionData.TimeDilation = timeDilation;
3994 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3995
3996 for (int i = 0; i < blocks.Count; i++)
3997 packet.ObjectData[i] = blocks[i];
3998 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3999 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4000 }
4001
4002 if (compressedUpdateBlocks.IsValueCreated)
4003 {
4004 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4005
4006 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4007 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4008 packet.RegionData.TimeDilation = timeDilation;
4009 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4010
4011 for (int i = 0; i < blocks.Count; i++)
4012 packet.ObjectData[i] = blocks[i];
4013 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4014 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4015 }
4016 4019
4017 if (terseUpdateBlocks.IsValueCreated) 4020 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4018 { 4021 }
4019 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4020
4021 ImprovedTerseObjectUpdatePacket packet
4022 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4023 PacketType.ImprovedTerseObjectUpdate);
4024 4022
4025 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4023 if (objectUpdateBlocks.IsValueCreated)
4026 packet.RegionData.TimeDilation = timeDilation; 4024 {
4027 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4025 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4028 4026
4029 for (int i = 0; i < blocks.Count; i++) 4027 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4030 packet.ObjectData[i] = blocks[i]; 4028 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4031 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4029 packet.RegionData.TimeDilation = timeDilation;
4032 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4030 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4033 } 4031
4032 for (int i = 0; i < blocks.Count; i++)
4033 packet.ObjectData[i] = blocks[i];
4034
4035 OutPacket(packet, ThrottleOutPacketType.Task, true);
4036 }
4037
4038 if (compressedUpdateBlocks.IsValueCreated)
4039 {
4040 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4041
4042 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4043 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4044 packet.RegionData.TimeDilation = timeDilation;
4045 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4046
4047 for (int i = 0; i < blocks.Count; i++)
4048 packet.ObjectData[i] = blocks[i];
4049
4050 OutPacket(packet, ThrottleOutPacketType.Task, true);
4051 }
4052
4053 if (terseUpdateBlocks.IsValueCreated)
4054 {
4055 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4056
4057 ImprovedTerseObjectUpdatePacket packet
4058 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4059 PacketType.ImprovedTerseObjectUpdate);
4060 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4061 packet.RegionData.TimeDilation = timeDilation;
4062 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4063
4064 for (int i = 0; i < blocks.Count; i++)
4065 packet.ObjectData[i] = blocks[i];
4066
4067 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4034 } 4068 }
4035 4069
4036 #endregion Packet Sending 4070 #endregion Packet Sending
@@ -4323,11 +4357,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4323 4357
4324 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4358 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4325 // of the object rather than the properties when the packet was created 4359 // of the object rather than the properties when the packet was created
4326 OutPacket(packet, ThrottleOutPacketType.Task, true, 4360 // HACK : Remove intelligent resending until it's fixed in core
4327 delegate(OutgoingPacket oPacket) 4361 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4328 { 4362 // delegate(OutgoingPacket oPacket)
4329 ResendPropertyUpdates(updates, oPacket); 4363 // {
4330 }); 4364 // ResendPropertyUpdates(updates, oPacket);
4365 // });
4366 OutPacket(packet, ThrottleOutPacketType.Task, true);
4331 4367
4332 // pbcnt += blocks.Count; 4368 // pbcnt += blocks.Count;
4333 // ppcnt++; 4369 // ppcnt++;
@@ -4353,11 +4389,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4353 // of the object rather than the properties when the packet was created 4389 // of the object rather than the properties when the packet was created
4354 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4390 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4355 updates.Add(familyUpdates.Value[i]); 4391 updates.Add(familyUpdates.Value[i]);
4356 OutPacket(packet, ThrottleOutPacketType.Task, true, 4392 // HACK : Remove intelligent resending until it's fixed in core
4357 delegate(OutgoingPacket oPacket) 4393 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4358 { 4394 // delegate(OutgoingPacket oPacket)
4359 ResendPropertyUpdates(updates, oPacket); 4395 // {
4360 }); 4396 // ResendPropertyUpdates(updates, oPacket);
4397 // });
4398 OutPacket(packet, ThrottleOutPacketType.Task, true);
4361 4399
4362 // fpcnt++; 4400 // fpcnt++;
4363 // fbcnt++; 4401 // fbcnt++;
@@ -4729,7 +4767,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4729 4767
4730 if (landData.SimwideArea > 0) 4768 if (landData.SimwideArea > 0)
4731 { 4769 {
4732 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4770 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4771 // Never report more than sim total capacity
4772 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4773 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4733 updateMessage.SimWideMaxPrims = simulatorCapacity; 4774 updateMessage.SimWideMaxPrims = simulatorCapacity;
4734 } 4775 }
4735 else 4776 else
@@ -4858,14 +4899,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4858 4899
4859 if (notifyCount > 0) 4900 if (notifyCount > 0)
4860 { 4901 {
4861 if (notifyCount > 32) 4902// if (notifyCount > 32)
4862 { 4903// {
4863 m_log.InfoFormat( 4904// m_log.InfoFormat(
4864 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4905// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4865 + " - a developer might want to investigate whether this is a hard limit", 32); 4906// + " - a developer might want to investigate whether this is a hard limit", 32);
4866 4907//
4867 notifyCount = 32; 4908// notifyCount = 32;
4868 } 4909// }
4869 4910
4870 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4911 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4871 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4912 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4920,9 +4961,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4920 { 4961 {
4921 ScenePresence presence = (ScenePresence)entity; 4962 ScenePresence presence = (ScenePresence)entity;
4922 4963
4964 position = presence.OffsetPosition;
4965 rotation = presence.Rotation;
4966
4967 if (presence.ParentID != 0)
4968 {
4969 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4970 if (part != null && part != part.ParentGroup.RootPart)
4971 {
4972 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4973 rotation = part.RotationOffset * presence.Rotation;
4974 }
4975 angularVelocity = Vector3.Zero;
4976 }
4977 else
4978 {
4979 angularVelocity = presence.AngularVelocity;
4980 rotation = presence.Rotation;
4981 }
4982
4923 attachPoint = 0; 4983 attachPoint = 0;
4924 collisionPlane = presence.CollisionPlane; 4984 collisionPlane = presence.CollisionPlane;
4925 position = presence.OffsetPosition;
4926 velocity = presence.Velocity; 4985 velocity = presence.Velocity;
4927 acceleration = Vector3.Zero; 4986 acceleration = Vector3.Zero;
4928 4987
@@ -4931,9 +4990,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4931 // may improve movement smoothness. 4990 // may improve movement smoothness.
4932// acceleration = new Vector3(1, 0, 0); 4991// acceleration = new Vector3(1, 0, 0);
4933 4992
4934 angularVelocity = presence.AngularVelocity;
4935 rotation = presence.Rotation;
4936
4937 if (sendTexture) 4993 if (sendTexture)
4938 textureEntry = presence.Appearance.Texture.GetBytes(); 4994 textureEntry = presence.Appearance.Texture.GetBytes();
4939 else 4995 else
@@ -5039,13 +5095,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 5095
5040 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5096 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5041 { 5097 {
5098 Vector3 offsetPosition = data.OffsetPosition;
5099 Quaternion rotation = data.Rotation;
5100 uint parentID = data.ParentID;
5101
5102 if (parentID != 0)
5103 {
5104 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5105 if (part != null && part != part.ParentGroup.RootPart)
5106 {
5107 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5108 rotation = part.RotationOffset * data.Rotation;
5109 parentID = part.ParentGroup.RootPart.LocalId;
5110 }
5111 }
5112
5042 byte[] objectData = new byte[76]; 5113 byte[] objectData = new byte[76];
5043 5114
5044 data.CollisionPlane.ToBytes(objectData, 0); 5115 data.CollisionPlane.ToBytes(objectData, 0);
5045 data.OffsetPosition.ToBytes(objectData, 16); 5116 offsetPosition.ToBytes(objectData, 16);
5046// data.Velocity.ToBytes(objectData, 28); 5117// data.Velocity.ToBytes(objectData, 28);
5047// data.Acceleration.ToBytes(objectData, 40); 5118// data.Acceleration.ToBytes(objectData, 40);
5048 data.Rotation.ToBytes(objectData, 52); 5119 rotation.ToBytes(objectData, 52);
5049 //data.AngularVelocity.ToBytes(objectData, 64); 5120 //data.AngularVelocity.ToBytes(objectData, 64);
5050 5121
5051 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5122 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5059,14 +5130,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5059 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5130 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5060 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5131 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5061 update.ObjectData = objectData; 5132 update.ObjectData = objectData;
5062 update.ParentID = data.ParentID; 5133 update.ParentID = parentID;
5063 update.PathCurve = 16; 5134 update.PathCurve = 16;
5064 update.PathScaleX = 100; 5135 update.PathScaleX = 100;
5065 update.PathScaleY = 100; 5136 update.PathScaleY = 100;
5066 update.PCode = (byte)PCode.Avatar; 5137 update.PCode = (byte)PCode.Avatar;
5067 update.ProfileCurve = 1; 5138 update.ProfileCurve = 1;
5068 update.PSBlock = Utils.EmptyBytes; 5139 update.PSBlock = Utils.EmptyBytes;
5069 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5140 update.Scale = data.Appearance.AvatarSize;
5141// update.Scale.Z -= 0.2f;
5142
5070 update.Text = Utils.EmptyBytes; 5143 update.Text = Utils.EmptyBytes;
5071 update.TextColor = new byte[4]; 5144 update.TextColor = new byte[4];
5072 5145
@@ -5077,10 +5150,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5077 update.TextureEntry = Utils.EmptyBytes; 5150 update.TextureEntry = Utils.EmptyBytes;
5078// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5151// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5079 5152
5153/* 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)
5080 update.UpdateFlags = (uint)( 5154 update.UpdateFlags = (uint)(
5081 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5155 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5082 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5156 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5083 PrimFlags.ObjectOwnerModify); 5157 PrimFlags.ObjectOwnerModify);
5158*/
5159 update.UpdateFlags = 0;
5084 5160
5085 return update; 5161 return update;
5086 } 5162 }
@@ -5251,8 +5327,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5251 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5327 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5252 // for each AgentUpdate packet. 5328 // for each AgentUpdate packet.
5253 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5329 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5254 5330
5255 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5331 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5332 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5333 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5256 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5334 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5257 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5335 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5258 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5336 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5404,6 +5482,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5404 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5482 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5405 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5483 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5406 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5484 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5485 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5407 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5486 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5408 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5487 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5409 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5488 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5470,6 +5549,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5470 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5549 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5471 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5550 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5472 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5551 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5552 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5473 5553
5474 AddGenericPacketHandler("autopilot", HandleAutopilot); 5554 AddGenericPacketHandler("autopilot", HandleAutopilot);
5475 } 5555 }
@@ -5508,6 +5588,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5508 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5588 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5509 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5589 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5510 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5590 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5591 (x.ControlFlags != 0) ||
5511 (x.Far != m_lastAgentUpdateArgs.Far) || 5592 (x.Far != m_lastAgentUpdateArgs.Far) ||
5512 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5593 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5513 (x.State != m_lastAgentUpdateArgs.State) || 5594 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5767,6 +5848,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5767 return true; 5848 return true;
5768 } 5849 }
5769 5850
5851 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5852 {
5853 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5854 if (p.AgentData.SessionID != SessionId ||
5855 p.AgentData.AgentID != AgentId)
5856 return true;
5857
5858 m_VelocityInterpolate = false;
5859 return true;
5860 }
5861
5862 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5863 {
5864 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5865 if (p.AgentData.SessionID != SessionId ||
5866 p.AgentData.AgentID != AgentId)
5867 return true;
5868
5869 m_VelocityInterpolate = true;
5870 return true;
5871 }
5872
5873
5770 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5874 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5771 { 5875 {
5772 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5876 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6187,17 +6291,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6187 // Temporarily protect ourselves from the mantis #951 failure. 6291 // Temporarily protect ourselves from the mantis #951 failure.
6188 // However, we could do this for several other handlers where a failure isn't terminal 6292 // However, we could do this for several other handlers where a failure isn't terminal
6189 // for the client session anyway, in order to protect ourselves against bad code in plugins 6293 // for the client session anyway, in order to protect ourselves against bad code in plugins
6294 Vector3 avSize = appear.AgentData.Size;
6190 try 6295 try
6191 { 6296 {
6192 byte[] visualparams = new byte[appear.VisualParam.Length]; 6297 byte[] visualparams = new byte[appear.VisualParam.Length];
6193 for (int i = 0; i < appear.VisualParam.Length; i++) 6298 for (int i = 0; i < appear.VisualParam.Length; i++)
6194 visualparams[i] = appear.VisualParam[i].ParamValue; 6299 visualparams[i] = appear.VisualParam[i].ParamValue;
6195 6300 //var b = appear.WearableData[0];
6301
6196 Primitive.TextureEntry te = null; 6302 Primitive.TextureEntry te = null;
6197 if (appear.ObjectData.TextureEntry.Length > 1) 6303 if (appear.ObjectData.TextureEntry.Length > 1)
6198 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6304 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6305
6306 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6307 for (int i=0; i<appear.WearableData.Length;i++)
6308 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6199 6309
6200 handlerSetAppearance(sender, te, visualparams); 6310
6311
6312 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6201 } 6313 }
6202 catch (Exception e) 6314 catch (Exception e)
6203 { 6315 {
@@ -6406,6 +6518,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6406 { 6518 {
6407 handlerCompleteMovementToRegion(sender, true); 6519 handlerCompleteMovementToRegion(sender, true);
6408 } 6520 }
6521 else
6522 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6523
6409 handlerCompleteMovementToRegion = null; 6524 handlerCompleteMovementToRegion = null;
6410 6525
6411 return true; 6526 return true;
@@ -6423,7 +6538,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6423 return true; 6538 return true;
6424 } 6539 }
6425 #endregion 6540 #endregion
6426 6541/*
6427 StartAnim handlerStartAnim = null; 6542 StartAnim handlerStartAnim = null;
6428 StopAnim handlerStopAnim = null; 6543 StopAnim handlerStopAnim = null;
6429 6544
@@ -6447,6 +6562,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6447 } 6562 }
6448 } 6563 }
6449 return true; 6564 return true;
6565*/
6566 ChangeAnim handlerChangeAnim = null;
6567
6568 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6569 {
6570 handlerChangeAnim = OnChangeAnim;
6571 if (handlerChangeAnim != null)
6572 {
6573 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6574 }
6575 }
6576
6577 handlerChangeAnim = OnChangeAnim;
6578 if (handlerChangeAnim != null)
6579 {
6580 handlerChangeAnim(UUID.Zero, false, true);
6581 }
6582
6583 return true;
6450 } 6584 }
6451 6585
6452 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6586 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6672,6 +6806,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6672 #endregion 6806 #endregion
6673 6807
6674 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6808 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6809 GenericCall2 handler = OnUpdateThrottles;
6810 if (handler != null)
6811 {
6812 handler();
6813 }
6675 return true; 6814 return true;
6676 } 6815 }
6677 6816
@@ -7096,7 +7235,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7096 physdata.Bounce = phsblock.Restitution; 7235 physdata.Bounce = phsblock.Restitution;
7097 physdata.Density = phsblock.Density; 7236 physdata.Density = phsblock.Density;
7098 physdata.Friction = phsblock.Friction; 7237 physdata.Friction = phsblock.Friction;
7099 physdata.GravitationModifier = phsblock.GravityMultiplier; 7238 physdata.GravitationModifier = phsblock.GravityMultiplier;
7100 } 7239 }
7101 7240
7102 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7241 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7682,6 +7821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7682 // surrounding scene 7821 // surrounding scene
7683 if ((ImageType)block.Type == ImageType.Baked) 7822 if ((ImageType)block.Type == ImageType.Baked)
7684 args.Priority *= 2.0f; 7823 args.Priority *= 2.0f;
7824 int wearableout = 0;
7685 7825
7686 ImageManager.EnqueueReq(args); 7826 ImageManager.EnqueueReq(args);
7687 } 7827 }
@@ -8700,16 +8840,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8700 8840
8701 #region Parcel related packets 8841 #region Parcel related packets
8702 8842
8843 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8844 // to be done with minimal resources as possible
8845 // variables temporary here while in test
8846
8847 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8848 bool RegionHandleRequestsInService = false;
8849
8703 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8850 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8704 { 8851 {
8705 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8852 UUID currentUUID;
8706 8853
8707 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8854 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8708 if (handlerRegionHandleRequest != null) 8855
8856 if (handlerRegionHandleRequest == null)
8857 return true;
8858
8859 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8860
8861 lock (RegionHandleRequests)
8709 { 8862 {
8710 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8863 if (RegionHandleRequestsInService)
8864 {
8865 // we are already busy doing a previus request
8866 // so enqueue it
8867 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8868 return true;
8869 }
8870
8871 // else do it
8872 currentUUID = rhrPack.RequestBlock.RegionID;
8873 RegionHandleRequestsInService = true;
8711 } 8874 }
8712 return true; 8875
8876 while (true)
8877 {
8878 handlerRegionHandleRequest(this, currentUUID);
8879
8880 lock (RegionHandleRequests)
8881 {
8882 // exit condition, nothing to do or closed
8883 // current code seems to assume we may loose the handler at anytime,
8884 // so keep checking it
8885 handlerRegionHandleRequest = OnRegionHandleRequest;
8886
8887 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8888 {
8889 RegionHandleRequests.Clear();
8890 RegionHandleRequestsInService = false;
8891 return true;
8892 }
8893 currentUUID = RegionHandleRequests.Dequeue();
8894 }
8895 }
8896
8897 return true; // actually unreached
8713 } 8898 }
8714 8899
8715 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8900 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9965,7 +10150,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9965 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10150 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9966 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10151 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9967 UpdateMuteListEntry.MuteData.MuteType, 10152 UpdateMuteListEntry.MuteData.MuteType,
9968 UpdateMuteListEntry.AgentData.AgentID); 10153 UpdateMuteListEntry.MuteData.MuteFlags);
9969 return true; 10154 return true;
9970 } 10155 }
9971 return false; 10156 return false;
@@ -9980,8 +10165,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9980 { 10165 {
9981 handlerRemoveMuteListEntry(this, 10166 handlerRemoveMuteListEntry(this,
9982 RemoveMuteListEntry.MuteData.MuteID, 10167 RemoveMuteListEntry.MuteData.MuteID,
9983 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10168 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9984 RemoveMuteListEntry.AgentData.AgentID);
9985 return true; 10169 return true;
9986 } 10170 }
9987 return false; 10171 return false;
@@ -10025,10 +10209,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10025 return false; 10209 return false;
10026 } 10210 }
10027 10211
10212 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10213 {
10214 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10215 (ChangeInventoryItemFlagsPacket)packet;
10216 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10217 if (handlerChangeInventoryItemFlags != null)
10218 {
10219 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10220 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10221 return true;
10222 }
10223 return false;
10224 }
10225
10028 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10226 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10029 { 10227 {
10030 return true; 10228 return true;
10031 } 10229 }
10230
10231 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10232 {
10233 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10234
10235 #region Packet Session and User Check
10236 if (m_checkPackets)
10237 {
10238 if (packet.AgentData.SessionID != SessionId ||
10239 packet.AgentData.AgentID != AgentId)
10240 return true;
10241 }
10242 #endregion
10243 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10244 List<InventoryItemBase> items = new List<InventoryItemBase>();
10245 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10246 {
10247 InventoryItemBase b = new InventoryItemBase();
10248 b.ID = n.OldItemID;
10249 b.Folder = n.OldFolderID;
10250 items.Add(b);
10251 }
10252
10253 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10254 if (handlerMoveItemsAndLeaveCopy != null)
10255 {
10256 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10257 }
10258
10259 return true;
10260 }
10032 10261
10033 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10262 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10034 { 10263 {
@@ -10455,6 +10684,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10455 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10684 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10456 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10685 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10457 10686
10687 Scene scene = (Scene)m_scene;
10688 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10689 {
10690 ScenePresence p;
10691 if (scene.TryGetScenePresence(sender.AgentId, out p))
10692 {
10693 if (p.GodLevel >= 200)
10694 {
10695 groupProfileReply.GroupData.OpenEnrollment = true;
10696 groupProfileReply.GroupData.MembershipFee = 0;
10697 }
10698 }
10699 }
10700
10458 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10701 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10459 } 10702 }
10460 return true; 10703 return true;
@@ -11028,11 +11271,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11028 11271
11029 StartLure handlerStartLure = OnStartLure; 11272 StartLure handlerStartLure = OnStartLure;
11030 if (handlerStartLure != null) 11273 if (handlerStartLure != null)
11031 handlerStartLure(startLureRequest.Info.LureType, 11274 {
11032 Utils.BytesToString( 11275 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11033 startLureRequest.Info.Message), 11276 {
11034 startLureRequest.TargetData[0].TargetID, 11277 handlerStartLure(startLureRequest.Info.LureType,
11035 this); 11278 Utils.BytesToString(
11279 startLureRequest.Info.Message),
11280 startLureRequest.TargetData[i].TargetID,
11281 this);
11282 }
11283 }
11036 return true; 11284 return true;
11037 } 11285 }
11038 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11286 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11146,10 +11394,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11146 } 11394 }
11147 #endregion 11395 #endregion
11148 11396
11149 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11397 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11150 if (handlerClassifiedGodDelete != null) 11398 if (handlerClassifiedGodDelete != null)
11151 handlerClassifiedGodDelete( 11399 handlerClassifiedGodDelete(
11152 classifiedGodDelete.Data.ClassifiedID, 11400 classifiedGodDelete.Data.ClassifiedID,
11401 classifiedGodDelete.Data.QueryID,
11153 this); 11402 this);
11154 return true; 11403 return true;
11155 } 11404 }
@@ -11462,6 +11711,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11462 11711
11463 if (cachedtex.AgentData.SessionID != SessionId) 11712 if (cachedtex.AgentData.SessionID != SessionId)
11464 return false; 11713 return false;
11714
11465 11715
11466 // TODO: don't create new blocks if recycling an old packet 11716 // TODO: don't create new blocks if recycling an old packet
11467 cachedresp.AgentData.AgentID = AgentId; 11717 cachedresp.AgentData.AgentID = AgentId;
@@ -11471,14 +11721,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11471 cachedresp.WearableData = 11721 cachedresp.WearableData =
11472 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11722 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11473 11723
11474 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11724 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11725 // var item = fac.GetBakedTextureFaces(AgentId);
11726 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11727
11728 IAssetService cache = m_scene.AssetService;
11729 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11730 //bakedTextureModule = null;
11731 int maxWearablesLoop = cachedtex.WearableData.Length;
11732 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11733 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11734
11735 if (bakedTextureModule != null && cache != null)
11475 { 11736 {
11476 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11737 // 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
11477 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11738
11478 cachedresp.WearableData[i].TextureID = UUID.Zero; 11739 WearableCacheItem[] cacheItems = null;
11479 cachedresp.WearableData[i].HostName = new byte[0]; 11740 ScenePresence p = m_scene.GetScenePresence(AgentId);
11741 if (p.Appearance != null)
11742 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11743 {
11744 try
11745 {
11746 cacheItems = bakedTextureModule.Get(AgentId);
11747 p.Appearance.WearableCacheItems = cacheItems;
11748 p.Appearance.WearableCacheItemsDirty = false;
11749 }
11750
11751 /*
11752 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11753 *
11754 catch (System.Net.Sockets.SocketException)
11755 {
11756 cacheItems = null;
11757 }
11758 catch (WebException)
11759 {
11760 cacheItems = null;
11761 }
11762 catch (InvalidOperationException)
11763 {
11764 cacheItems = null;
11765 } */
11766 catch (Exception)
11767 {
11768 cacheItems = null;
11769 }
11770
11771 }
11772 else if (p.Appearance.WearableCacheItems != null)
11773 {
11774 cacheItems = p.Appearance.WearableCacheItems;
11775 }
11776
11777 if (cache != null && cacheItems != null)
11778 {
11779 foreach (WearableCacheItem item in cacheItems)
11780 {
11781
11782 if (cache.GetCached(item.TextureID.ToString()) == null)
11783 {
11784 item.TextureAsset.Temporary = true;
11785 cache.Store(item.TextureAsset);
11786 }
11787
11788
11789 }
11790 }
11791
11792 if (cacheItems != null)
11793 {
11794
11795 for (int i = 0; i < maxWearablesLoop; i++)
11796 {
11797 WearableCacheItem item =
11798 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11799
11800 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11801 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11802 cachedresp.WearableData[i].HostName = new byte[0];
11803 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11804 {
11805
11806 cachedresp.WearableData[i].TextureID = item.TextureID;
11807 }
11808 else
11809 {
11810 cachedresp.WearableData[i].TextureID = UUID.Zero;
11811 }
11812 }
11813 }
11814 else
11815 {
11816 for (int i = 0; i < maxWearablesLoop; i++)
11817 {
11818 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11819 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11820 cachedresp.WearableData[i].TextureID = UUID.Zero;
11821 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11822 cachedresp.WearableData[i].HostName = new byte[0];
11823 }
11824 }
11480 } 11825 }
11826 else
11827 {
11828 if (cache == null)
11829 {
11830 for (int i = 0; i < maxWearablesLoop; i++)
11831 {
11832 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11833 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11834 cachedresp.WearableData[i].TextureID = UUID.Zero;
11835 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11836 cachedresp.WearableData[i].HostName = new byte[0];
11837 }
11838 }
11839 else
11840 {
11841 for (int i = 0; i < maxWearablesLoop; i++)
11842 {
11843 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11844 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11481 11845
11846
11847
11848 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11849 cachedresp.WearableData[i].TextureID = UUID.Zero;
11850 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11851 else
11852 cachedresp.WearableData[i].TextureID = UUID.Zero;
11853 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11854 cachedresp.WearableData[i].HostName = new byte[0];
11855 }
11856 }
11857 }
11482 cachedresp.Header.Zerocoded = true; 11858 cachedresp.Header.Zerocoded = true;
11483 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11859 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11484 11860
@@ -11515,209 +11891,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11515 } 11891 }
11516 else 11892 else
11517 { 11893 {
11518// m_log.DebugFormat( 11894 ClientChangeObject updatehandler = onClientChangeObject;
11519// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11520// i, block.Type, part.Name, part.LocalId);
11521 11895
11522// // Do this once since fetch parts creates a new array. 11896 if (updatehandler != null)
11523// SceneObjectPart[] parts = part.ParentGroup.Parts; 11897 {
11524// for (int j = 0; j < parts.Length; j++) 11898 ObjectChangeData udata = new ObjectChangeData();
11525// {
11526// part.StoreUndoState();
11527// parts[j].IgnoreUndoUpdate = true;
11528// }
11529 11899
11530 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11900 /*ubit from ll JIRA:
11901 * 0x01 position
11902 * 0x02 rotation
11903 * 0x04 scale
11904
11905 * 0x08 LINK_SET
11906 * 0x10 UNIFORM for scale
11907 */
11531 11908
11532 switch (block.Type) 11909 // translate to internal changes
11533 { 11910 // not all cases .. just the ones older code did
11534 case 1:
11535 Vector3 pos1 = new Vector3(block.Data, 0);
11536 11911
11537 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11912 switch (block.Type)
11538 if (handlerUpdatePrimSinglePosition != null) 11913 {
11539 { 11914 case 1: //change position sp
11540 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11915 udata.position = new Vector3(block.Data, 0);
11541 handlerUpdatePrimSinglePosition(localId, pos1, this);
11542 }
11543 break;
11544 11916
11545 case 2: 11917 udata.change = ObjectChangeType.primP;
11546 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11918 updatehandler(localId, udata, this);
11919 break;
11547 11920
11548 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11921 case 2: // rotation sp
11549 if (handlerUpdatePrimSingleRotation != null) 11922 udata.rotation = new Quaternion(block.Data, 0, true);
11550 {
11551 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11552 handlerUpdatePrimSingleRotation(localId, rot1, this);
11553 }
11554 break;
11555 11923
11556 case 3: 11924 udata.change = ObjectChangeType.primR;
11557 Vector3 rotPos = new Vector3(block.Data, 0); 11925 updatehandler(localId, udata, this);
11558 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11926 break;
11559 11927
11560 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11928 case 3: // position plus rotation
11561 if (handlerUpdatePrimSingleRotationPosition != null) 11929 udata.position = new Vector3(block.Data, 0);
11562 { 11930 udata.rotation = new Quaternion(block.Data, 12, true);
11563 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11564 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11565 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11566 }
11567 break;
11568 11931
11569 case 4: 11932 udata.change = ObjectChangeType.primPR;
11570 case 20: 11933 updatehandler(localId, udata, this);
11571 Vector3 scale4 = new Vector3(block.Data, 0); 11934 break;
11572 11935
11573 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11936 case 4: // scale sp
11574 if (handlerUpdatePrimScale != null) 11937 udata.scale = new Vector3(block.Data, 0);
11575 { 11938 udata.change = ObjectChangeType.primS;
11576 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11577 handlerUpdatePrimScale(localId, scale4, this);
11578 }
11579 break;
11580 11939
11581 case 5: 11940 updatehandler(localId, udata, this);
11582 Vector3 scale1 = new Vector3(block.Data, 12); 11941 break;
11583 Vector3 pos11 = new Vector3(block.Data, 0);
11584 11942
11585 handlerUpdatePrimScale = OnUpdatePrimScale; 11943 case 0x14: // uniform scale sp
11586 if (handlerUpdatePrimScale != null) 11944 udata.scale = new Vector3(block.Data, 0);
11587 {
11588 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11589 handlerUpdatePrimScale(localId, scale1, this);
11590 11945
11591 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11946 udata.change = ObjectChangeType.primUS;
11592 if (handlerUpdatePrimSinglePosition != null) 11947 updatehandler(localId, udata, this);
11593 { 11948 break;
11594 handlerUpdatePrimSinglePosition(localId, pos11, this);
11595 }
11596 }
11597 break;
11598 11949
11599 case 9: 11950 case 5: // scale and position sp
11600 Vector3 pos2 = new Vector3(block.Data, 0); 11951 udata.position = new Vector3(block.Data, 0);
11952 udata.scale = new Vector3(block.Data, 12);
11601 11953
11602 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11954 udata.change = ObjectChangeType.primPS;
11955 updatehandler(localId, udata, this);
11956 break;
11603 11957
11604 if (handlerUpdateVector != null) 11958 case 0x15: //uniform scale and position
11605 { 11959 udata.position = new Vector3(block.Data, 0);
11606 handlerUpdateVector(localId, pos2, this); 11960 udata.scale = new Vector3(block.Data, 12);
11607 }
11608 break;
11609 11961
11610 case 10: 11962 udata.change = ObjectChangeType.primPUS;
11611 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11963 updatehandler(localId, udata, this);
11964 break;
11612 11965
11613 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11966 // now group related (bit 4)
11614 if (handlerUpdatePrimRotation != null) 11967 case 9: //( 8 + 1 )group position
11615 { 11968 udata.position = new Vector3(block.Data, 0);
11616 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11617 handlerUpdatePrimRotation(localId, rot3, this);
11618 }
11619 break;
11620 11969
11621 case 11: 11970 udata.change = ObjectChangeType.groupP;
11622 Vector3 pos3 = new Vector3(block.Data, 0); 11971 updatehandler(localId, udata, this);
11623 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11972 break;
11624 11973
11625 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11974 case 0x0A: // (8 + 2) group rotation
11626 if (handlerUpdatePrimGroupRotation != null) 11975 udata.rotation = new Quaternion(block.Data, 0, true);
11627 {
11628 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11629 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11630 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11631 }
11632 break;
11633 case 12:
11634 case 28:
11635 Vector3 scale7 = new Vector3(block.Data, 0);
11636 11976
11637 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11977 udata.change = ObjectChangeType.groupR;
11638 if (handlerUpdatePrimGroupScale != null) 11978 updatehandler(localId, udata, this);
11639 { 11979 break;
11640 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11641 handlerUpdatePrimGroupScale(localId, scale7, this);
11642 }
11643 break;
11644 11980
11645 case 13: 11981 case 0x0B: //( 8 + 2 + 1) group rotation and position
11646 Vector3 scale2 = new Vector3(block.Data, 12); 11982 udata.position = new Vector3(block.Data, 0);
11647 Vector3 pos4 = new Vector3(block.Data, 0); 11983 udata.rotation = new Quaternion(block.Data, 12, true);
11648 11984
11649 handlerUpdatePrimScale = OnUpdatePrimScale; 11985 udata.change = ObjectChangeType.groupPR;
11650 if (handlerUpdatePrimScale != null) 11986 updatehandler(localId, udata, this);
11651 { 11987 break;
11652 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11653 handlerUpdatePrimScale(localId, scale2, this);
11654 11988
11655 // Change the position based on scale (for bug number 246) 11989 case 0x0C: // (8 + 4) group scale
11656 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11990 // only afects root prim and only sent by viewer editor object tab scaling
11657 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11991 // mouse edition only allows uniform scaling
11658 if (handlerUpdatePrimSinglePosition != null) 11992 // SL MAY CHANGE THIS in viewers
11659 {
11660 handlerUpdatePrimSinglePosition(localId, pos4, this);
11661 }
11662 }
11663 break;
11664 11993
11665 case 29: 11994 udata.scale = new Vector3(block.Data, 0);
11666 Vector3 scale5 = new Vector3(block.Data, 12);
11667 Vector3 pos5 = new Vector3(block.Data, 0);
11668 11995
11669 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11996 udata.change = ObjectChangeType.groupS;
11670 if (handlerUpdatePrimGroupScale != null) 11997 updatehandler(localId, udata, this);
11671 {
11672 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11673 part.StoreUndoState(true);
11674 part.IgnoreUndoUpdate = true;
11675 handlerUpdatePrimGroupScale(localId, scale5, this);
11676 handlerUpdateVector = OnUpdatePrimGroupPosition;
11677 11998
11678 if (handlerUpdateVector != null) 11999 break;
11679 {
11680 handlerUpdateVector(localId, pos5, this);
11681 }
11682 12000
11683 part.IgnoreUndoUpdate = false; 12001 case 0x0D: //(8 + 4 + 1) group scale and position
11684 } 12002 // exception as above
11685 12003
11686 break; 12004 udata.position = new Vector3(block.Data, 0);
12005 udata.scale = new Vector3(block.Data, 12);
11687 12006
11688 case 21: 12007 udata.change = ObjectChangeType.groupPS;
11689 Vector3 scale6 = new Vector3(block.Data, 12); 12008 updatehandler(localId, udata, this);
11690 Vector3 pos6 = new Vector3(block.Data, 0); 12009 break;
11691 12010
11692 handlerUpdatePrimScale = OnUpdatePrimScale; 12011 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11693 if (handlerUpdatePrimScale != null) 12012 udata.scale = new Vector3(block.Data, 0);
11694 {
11695 part.StoreUndoState(false);
11696 part.IgnoreUndoUpdate = true;
11697 12013
11698 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12014 udata.change = ObjectChangeType.groupUS;
11699 handlerUpdatePrimScale(localId, scale6, this); 12015 updatehandler(localId, udata, this);
11700 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12016 break;
11701 if (handlerUpdatePrimSinglePosition != null)
11702 {
11703 handlerUpdatePrimSinglePosition(localId, pos6, this);
11704 }
11705 12017
11706 part.IgnoreUndoUpdate = false; 12018 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11707 } 12019 udata.position = new Vector3(block.Data, 0);
11708 break; 12020 udata.scale = new Vector3(block.Data, 12);
11709 12021
11710 default: 12022 udata.change = ObjectChangeType.groupPUS;
11711 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12023 updatehandler(localId, udata, this);
11712 break; 12024 break;
12025
12026 default:
12027 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12028 break;
12029 }
11713 } 12030 }
11714 12031
11715// for (int j = 0; j < parts.Length; j++)
11716// parts[j].IgnoreUndoUpdate = false;
11717 } 12032 }
11718 } 12033 }
11719 } 12034 }
11720
11721 return true; 12035 return true;
11722 } 12036 }
11723 12037
@@ -11778,9 +12092,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11778 public void SetChildAgentThrottle(byte[] throttles) 12092 public void SetChildAgentThrottle(byte[] throttles)
11779 { 12093 {
11780 m_udpClient.SetThrottles(throttles); 12094 m_udpClient.SetThrottles(throttles);
12095 GenericCall2 handler = OnUpdateThrottles;
12096 if (handler != null)
12097 {
12098 handler();
12099 }
11781 } 12100 }
11782 12101
11783 /// <summary> 12102 /// <summary>
12103 /// Sets the throttles from values supplied by the client
12104 /// </summary>
12105 /// <param name="throttles"></param>
12106 public void SetAgentThrottleSilent(int throttle, int setting)
12107 {
12108 m_udpClient.ForceThrottleSetting(throttle,setting);
12109 //m_udpClient.SetThrottles(throttles);
12110
12111 }
12112
12113
12114 /// <summary>
11784 /// Get the current throttles for this client as a packed byte array 12115 /// Get the current throttles for this client as a packed byte array
11785 /// </summary> 12116 /// </summary>
11786 /// <param name="multiplier">Unused</param> 12117 /// <param name="multiplier">Unused</param>
@@ -12172,7 +12503,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12172// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12503// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12173// requestID, taskID, (SourceType)sourceType, Name); 12504// requestID, taskID, (SourceType)sourceType, Name);
12174 12505
12506
12507 //Note, the bool returned from the below function is useless since it is always false.
12175 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12508 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12509
12176 } 12510 }
12177 12511
12178 /// <summary> 12512 /// <summary>
@@ -12238,7 +12572,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12238 /// <returns></returns> 12572 /// <returns></returns>
12239 private static int CalculateNumPackets(byte[] data) 12573 private static int CalculateNumPackets(byte[] data)
12240 { 12574 {
12241 const uint m_maxPacketSize = 600; 12575// const uint m_maxPacketSize = 600;
12576 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12242 int numPackets = 1; 12577 int numPackets = 1;
12243 12578
12244 if (data == null) 12579 if (data == null)