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