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.cs1475
1 files changed, 936 insertions, 539 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index a8517e6..ddbd677 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));
@@ -791,7 +822,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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;
793 824
794 OutPacket(handshake, ThrottleOutPacketType.Task); 825// OutPacket(handshake, ThrottleOutPacketType.Task);
826 // use same as MoveAgentIntoRegion (both should be task )
827 OutPacket(handshake, ThrottleOutPacketType.Unknown);
795 } 828 }
796 829
797 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 830 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -831,7 +864,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
831 reply.ChatData.OwnerID = ownerID; 864 reply.ChatData.OwnerID = ownerID;
832 reply.ChatData.SourceID = fromAgentID; 865 reply.ChatData.SourceID = fromAgentID;
833 866
834 OutPacket(reply, ThrottleOutPacketType.Task); 867 OutPacket(reply, ThrottleOutPacketType.Unknown);
835 } 868 }
836 869
837 /// <summary> 870 /// <summary>
@@ -1117,6 +1150,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 public virtual void SendLayerData(float[] map) 1150 public virtual void SendLayerData(float[] map)
1118 { 1151 {
1119 Util.FireAndForget(DoSendLayerData, map); 1152 Util.FireAndForget(DoSendLayerData, map);
1153
1154 // Send it sync, and async. It's not that much data
1155 // and it improves user experience just so much!
1156 DoSendLayerData(map);
1120 } 1157 }
1121 1158
1122 /// <summary> 1159 /// <summary>
@@ -1129,16 +1166,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1129 1166
1130 try 1167 try
1131 { 1168 {
1132 //for (int y = 0; y < 16; y++) 1169 for (int y = 0; y < 16; y++)
1133 //{ 1170 {
1134 // for (int x = 0; x < 16; x++) 1171 for (int x = 0; x < 16; x+=4)
1135 // { 1172 {
1136 // SendLayerData(x, y, map); 1173 SendLayerPacket(x, y, map);
1137 // } 1174 }
1138 //} 1175 }
1139
1140 // Send LayerData in a spiral pattern. Fun!
1141 SendLayerTopRight(map, 0, 0, 15, 15);
1142 } 1176 }
1143 catch (Exception e) 1177 catch (Exception e)
1144 { 1178 {
@@ -1146,51 +1180,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 } 1180 }
1147 } 1181 }
1148 1182
1149 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1150 {
1151 // Row
1152 for (int i = x1; i <= x2; i++)
1153 SendLayerData(i, y1, map);
1154
1155 // Column
1156 for (int j = y1 + 1; j <= y2; j++)
1157 SendLayerData(x2, j, map);
1158
1159 if (x2 - x1 > 0)
1160 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1161 }
1162
1163 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1164 {
1165 // Row in reverse
1166 for (int i = x2; i >= x1; i--)
1167 SendLayerData(i, y2, map);
1168
1169 // Column in reverse
1170 for (int j = y2 - 1; j >= y1; j--)
1171 SendLayerData(x1, j, map);
1172
1173 if (x2 - x1 > 0)
1174 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1175 }
1176
1177 /// <summary> 1183 /// <summary>
1178 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1184 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1179 /// </summary> 1185 /// </summary>
1180 /// <param name="map">heightmap</param> 1186 /// <param name="map">heightmap</param>
1181 /// <param name="px">X coordinate for patches 0..12</param> 1187 /// <param name="px">X coordinate for patches 0..12</param>
1182 /// <param name="py">Y coordinate for patches 0..15</param> 1188 /// <param name="py">Y coordinate for patches 0..15</param>
1183 // private void SendLayerPacket(float[] map, int y, int x) 1189 private void SendLayerPacket(int x, int y, float[] map)
1184 // { 1190 {
1185 // int[] patches = new int[4]; 1191 int[] patches = new int[4];
1186 // patches[0] = x + 0 + y * 16; 1192 patches[0] = x + 0 + y * 16;
1187 // patches[1] = x + 1 + y * 16; 1193 patches[1] = x + 1 + y * 16;
1188 // patches[2] = x + 2 + y * 16; 1194 patches[2] = x + 2 + y * 16;
1189 // patches[3] = x + 3 + y * 16; 1195 patches[3] = x + 3 + y * 16;
1190 1196
1191 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1197 float[] heightmap = (map.Length == 65536) ?
1192 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1198 map :
1193 // } 1199 LLHeightFieldMoronize(map);
1200
1201 try
1202 {
1203 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1204 OutPacket(layerpack, ThrottleOutPacketType.Land);
1205 }
1206 catch
1207 {
1208 for (int px = x ; px < x + 4 ; px++)
1209 SendLayerData(px, y, map);
1210 }
1211 }
1194 1212
1195 /// <summary> 1213 /// <summary>
1196 /// Sends a specified patch to a client 1214 /// Sends a specified patch to a client
@@ -1210,7 +1228,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1228 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1211 layerpack.Header.Reliable = true; 1229 layerpack.Header.Reliable = true;
1212 1230
1213 OutPacket(layerpack, ThrottleOutPacketType.Land); 1231 OutPacket(layerpack, ThrottleOutPacketType.Task);
1214 } 1232 }
1215 catch (Exception e) 1233 catch (Exception e)
1216 { 1234 {
@@ -1573,7 +1591,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1573 1591
1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1592 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1575 { 1593 {
1576// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1594// foreach (uint id in localIDs)
1595// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1577 1596
1578 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1597 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1579 // TODO: don't create new blocks if recycling an old packet 1598 // TODO: don't create new blocks if recycling an old packet
@@ -1595,17 +1614,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1595 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1614 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1596 // condition where a kill can be processed before an out-of-date update for the same object. 1615 // condition where a kill can be processed before an out-of-date update for the same object.
1597 // ProcessEntityUpdates() also takes the m_killRecord lock. 1616 // ProcessEntityUpdates() also takes the m_killRecord lock.
1598 lock (m_killRecord) 1617// lock (m_killRecord)
1599 { 1618// {
1600 foreach (uint localID in localIDs) 1619// foreach (uint localID in localIDs)
1601 m_killRecord.Add(localID); 1620// m_killRecord.Add(localID);
1602 1621
1603 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1622 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1604 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1623 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1605 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1624 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1606 // scene objects in a viewer until that viewer is relogged in. 1625 // scene objects in a viewer until that viewer is relogged in.
1607 OutPacket(kill, ThrottleOutPacketType.Task); 1626 OutPacket(kill, ThrottleOutPacketType.Task);
1608 } 1627// }
1609 } 1628 }
1610 } 1629 }
1611 1630
@@ -2063,9 +2082,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2082 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2064 } 2083 }
2065 2084
2066 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2067 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2085 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2068 { 2086 {
2087 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2088 }
2089
2090 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2091 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2092 {
2069 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2093 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2070 2094
2071 UpdateCreateInventoryItemPacket InventoryReply 2095 UpdateCreateInventoryItemPacket InventoryReply
@@ -2075,6 +2099,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2075 // TODO: don't create new blocks if recycling an old packet 2099 // TODO: don't create new blocks if recycling an old packet
2076 InventoryReply.AgentData.AgentID = AgentId; 2100 InventoryReply.AgentData.AgentID = AgentId;
2077 InventoryReply.AgentData.SimApproved = true; 2101 InventoryReply.AgentData.SimApproved = true;
2102 InventoryReply.AgentData.TransactionID = transactionID;
2078 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2103 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2079 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2104 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2080 InventoryReply.InventoryData[0].ItemID = Item.ID; 2105 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2144,16 +2169,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2144 replytask.InventoryData.TaskID = taskID; 2169 replytask.InventoryData.TaskID = taskID;
2145 replytask.InventoryData.Serial = serial; 2170 replytask.InventoryData.Serial = serial;
2146 replytask.InventoryData.Filename = fileName; 2171 replytask.InventoryData.Filename = fileName;
2147 OutPacket(replytask, ThrottleOutPacketType.Asset); 2172 OutPacket(replytask, ThrottleOutPacketType.Task);
2148 } 2173 }
2149 2174
2150 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2175 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2151 { 2176 {
2177 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2178 if (isTaskInventory)
2179 type = ThrottleOutPacketType.Task;
2180
2152 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2181 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2153 sendXfer.XferID.ID = xferID; 2182 sendXfer.XferID.ID = xferID;
2154 sendXfer.XferID.Packet = packet; 2183 sendXfer.XferID.Packet = packet;
2155 sendXfer.DataPacket.Data = data; 2184 sendXfer.DataPacket.Data = data;
2156 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2185 OutPacket(sendXfer, type);
2157 } 2186 }
2158 2187
2159 public void SendAbortXferPacket(ulong xferID) 2188 public void SendAbortXferPacket(ulong xferID)
@@ -2335,6 +2364,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2335 OutPacket(sound, ThrottleOutPacketType.Task); 2364 OutPacket(sound, ThrottleOutPacketType.Task);
2336 } 2365 }
2337 2366
2367 public void SendTransferAbort(TransferRequestPacket transferRequest)
2368 {
2369 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2370 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2371 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2372 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2373 OutPacket(abort, ThrottleOutPacketType.Task);
2374 }
2375
2338 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2376 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2339 { 2377 {
2340 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2378 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2627,6 +2665,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2627 } 2665 }
2628 } 2666 }
2629 2667
2668 public void SendPartPhysicsProprieties(ISceneEntity entity)
2669 {
2670 SceneObjectPart part = (SceneObjectPart)entity;
2671 if (part != null && AgentId != UUID.Zero)
2672 {
2673 try
2674 {
2675 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2676 if (eq != null)
2677 {
2678 uint localid = part.LocalId;
2679 byte physshapetype = part.PhysicsShapeType;
2680 float density = part.Density;
2681 float friction = part.Friction;
2682 float bounce = part.Bounciness;
2683 float gravmod = part.GravityModifier;
2684
2685 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2686 }
2687 }
2688 catch (Exception ex)
2689 {
2690 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2691 }
2692 part.UpdatePhysRequired = false;
2693 }
2694 }
2695
2696
2630 2697
2631 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2698 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2632 { 2699 {
@@ -2685,8 +2752,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2685 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2752 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2686 return; 2753 return;
2687 } 2754 }
2755 int WearableOut = 0;
2756 bool isWearable = false;
2757
2758 if (req.AssetInf != null)
2759 isWearable =
2760 ((AssetType) req.AssetInf.Type ==
2761 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2688 2762
2689 //m_log.Debug("sending asset " + req.RequestAssetID); 2763
2764 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2765
2766
2767 //if (isWearable)
2768 // m_log.Debug((AssetType)req.AssetInf.Type);
2769
2690 TransferInfoPacket Transfer = new TransferInfoPacket(); 2770 TransferInfoPacket Transfer = new TransferInfoPacket();
2691 Transfer.TransferInfo.ChannelType = 2; 2771 Transfer.TransferInfo.ChannelType = 2;
2692 Transfer.TransferInfo.Status = 0; 2772 Transfer.TransferInfo.Status = 0;
@@ -2708,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2708 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2788 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2709 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2789 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2710 Transfer.Header.Zerocoded = true; 2790 Transfer.Header.Zerocoded = true;
2711 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2791 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
2712 2792
2713 if (req.NumPackets == 1) 2793 if (req.NumPackets == 1)
2714 { 2794 {
@@ -2719,12 +2799,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2719 TransferPacket.TransferData.Data = req.AssetInf.Data; 2799 TransferPacket.TransferData.Data = req.AssetInf.Data;
2720 TransferPacket.TransferData.Status = 1; 2800 TransferPacket.TransferData.Status = 1;
2721 TransferPacket.Header.Zerocoded = true; 2801 TransferPacket.Header.Zerocoded = true;
2722 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2802 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
2723 } 2803 }
2724 else 2804 else
2725 { 2805 {
2726 int processedLength = 0; 2806 int processedLength = 0;
2727 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2807// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2808
2809 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2728 int packetNumber = 0; 2810 int packetNumber = 0;
2729 2811
2730 while (processedLength < req.AssetInf.Data.Length) 2812 while (processedLength < req.AssetInf.Data.Length)
@@ -2750,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2750 TransferPacket.TransferData.Status = 1; 2832 TransferPacket.TransferData.Status = 1;
2751 } 2833 }
2752 TransferPacket.Header.Zerocoded = true; 2834 TransferPacket.Header.Zerocoded = true;
2753 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2835 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
2754 2836
2755 processedLength += chunkSize; 2837 processedLength += chunkSize;
2756 packetNumber++; 2838 packetNumber++;
@@ -2795,7 +2877,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2795 reply.Data.ParcelID = parcelID; 2877 reply.Data.ParcelID = parcelID;
2796 reply.Data.OwnerID = land.OwnerID; 2878 reply.Data.OwnerID = land.OwnerID;
2797 reply.Data.Name = Utils.StringToBytes(land.Name); 2879 reply.Data.Name = Utils.StringToBytes(land.Name);
2798 reply.Data.Desc = Utils.StringToBytes(land.Description); 2880 if (land != null && land.Description != null && land.Description != String.Empty)
2881 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2882 else
2883 reply.Data.Desc = new Byte[0];
2799 reply.Data.ActualArea = land.Area; 2884 reply.Data.ActualArea = land.Area;
2800 reply.Data.BillableArea = land.Area; // TODO: what is this? 2885 reply.Data.BillableArea = land.Area; // TODO: what is this?
2801 2886
@@ -3502,24 +3587,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3502 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3587 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3503 AgentWearablesUpdatePacket.WearableDataBlock awb; 3588 AgentWearablesUpdatePacket.WearableDataBlock awb;
3504 int idx = 0; 3589 int idx = 0;
3505 for (int i = 0; i < wearables.Length; i++) 3590
3506 { 3591 for (int i = 0; i < wearables.Length; i++)
3507 for (int j = 0; j < wearables[i].Count; j++) 3592 {
3508 { 3593 for (int j = 0; j < wearables[i].Count; j++)
3509 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3594 {
3510 awb.WearableType = (byte)i; 3595 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3511 awb.AssetID = wearables[i][j].AssetID; 3596 awb.WearableType = (byte) i;
3512 awb.ItemID = wearables[i][j].ItemID; 3597 awb.AssetID = wearables[i][j].AssetID;
3513 aw.WearableData[idx] = awb; 3598 awb.ItemID = wearables[i][j].ItemID;
3514 idx++; 3599 aw.WearableData[idx] = awb;
3515 3600 idx++;
3516// m_log.DebugFormat( 3601
3517// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3602 // m_log.DebugFormat(
3518// awb.ItemID, awb.AssetID, i, Name); 3603 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3519 } 3604 // awb.ItemID, awb.AssetID, i, Name);
3520 } 3605 }
3606 }
3521 3607
3522 OutPacket(aw, ThrottleOutPacketType.Task); 3608 OutPacket(aw, ThrottleOutPacketType.State);
3523 } 3609 }
3524 3610
3525 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3611 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3530,7 +3616,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3530 3616
3531 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3617 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3532 // TODO: don't create new blocks if recycling an old packet 3618 // TODO: don't create new blocks if recycling an old packet
3533 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3619 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3534 avp.ObjectData.TextureEntry = textureEntry; 3620 avp.ObjectData.TextureEntry = textureEntry;
3535 3621
3536 AvatarAppearancePacket.VisualParamBlock avblock = null; 3622 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3543,8 +3629,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3543 3629
3544 avp.Sender.IsTrial = false; 3630 avp.Sender.IsTrial = false;
3545 avp.Sender.ID = agentID; 3631 avp.Sender.ID = agentID;
3546 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3632 m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3547 OutPacket(avp, ThrottleOutPacketType.Task); 3633 OutPacket(avp, ThrottleOutPacketType.State);
3548 } 3634 }
3549 3635
3550 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3636 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
@@ -3660,7 +3746,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3660 /// </summary> 3746 /// </summary>
3661 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3747 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3662 { 3748 {
3663 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3749 if (entity is SceneObjectPart)
3750 {
3751 SceneObjectPart e = (SceneObjectPart)entity;
3752 SceneObjectGroup g = e.ParentGroup;
3753 if (g.RootPart.Shape.State > 30) // HUD
3754 if (g.OwnerID != AgentId)
3755 return; // Don't send updates for other people's HUDs
3756 }
3757
3664 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3758 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3665 3759
3666 lock (m_entityUpdates.SyncRoot) 3760 lock (m_entityUpdates.SyncRoot)
@@ -3727,27 +3821,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3727 3821
3728 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3822 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3729 // condition where a kill can be processed before an out-of-date update for the same object. 3823 // condition where a kill can be processed before an out-of-date update for the same object.
3730 lock (m_killRecord) 3824 float avgTimeDilation = 1.0f;
3825 IEntityUpdate iupdate;
3826 Int32 timeinqueue; // this is just debugging code & can be dropped later
3827
3828 while (updatesThisCall < maxUpdates)
3731 { 3829 {
3732 float avgTimeDilation = 1.0f; 3830 lock (m_entityUpdates.SyncRoot)
3733 IEntityUpdate iupdate; 3831 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3734 Int32 timeinqueue; // this is just debugging code & can be dropped later 3832 break;
3833
3834 EntityUpdate update = (EntityUpdate)iupdate;
3835
3836 avgTimeDilation += update.TimeDilation;
3837 avgTimeDilation *= 0.5f;
3735 3838
3736 while (updatesThisCall < maxUpdates) 3839 if (update.Entity is SceneObjectPart)
3737 { 3840 {
3738 lock (m_entityUpdates.SyncRoot) 3841 SceneObjectPart part = (SceneObjectPart)update.Entity;
3739 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3740 break;
3741 3842
3742 EntityUpdate update = (EntityUpdate)iupdate; 3843 if (part.ParentGroup.IsDeleted)
3743 3844 continue;
3744 avgTimeDilation += update.TimeDilation;
3745 avgTimeDilation *= 0.5f;
3746 3845
3747 if (update.Entity is SceneObjectPart) 3846 if (part.ParentGroup.IsAttachment)
3847 { // Someone else's HUD, why are we getting these?
3848 if (part.ParentGroup.OwnerID != AgentId &&
3849 part.ParentGroup.RootPart.Shape.State > 30)
3850 continue;
3851 ScenePresence sp;
3852 // Owner is not in the sim, don't update it to
3853 // anyone
3854 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3855 continue;
3856
3857 List<SceneObjectGroup> atts = sp.GetAttachments();
3858 bool found = false;
3859 foreach (SceneObjectGroup att in atts)
3860 {
3861 if (att == part.ParentGroup)
3862 {
3863 found = true;
3864 break;
3865 }
3866 }
3867
3868 // It's an attachment of a valid avatar, but
3869 // doesn't seem to be attached, skip
3870 if (!found)
3871 continue;
3872
3873 // On vehicle crossing, the attachments are received
3874 // while the avatar is still a child. Don't send
3875 // updates here because the LocalId has not yet
3876 // been updated and the viewer will derender the
3877 // attachments until the avatar becomes root.
3878 if (sp.IsChildAgent)
3879 continue;
3880
3881 // If the object is an attachment we don't want it to be in the kill
3882 // record. Else attaching from inworld and subsequently dropping
3883 // it will no longer work.
3884// lock (m_killRecord)
3885// {
3886// m_killRecord.Remove(part.LocalId);
3887// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3888// }
3889 }
3890 else
3748 { 3891 {
3749 SceneObjectPart part = (SceneObjectPart)update.Entity;
3750
3751 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3892 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3752 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3893 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3753 // safety measure. 3894 // safety measure.
@@ -3758,241 +3899,177 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3758 // 3899 //
3759 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3900 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3760 // after the root prim has been deleted. 3901 // after the root prim has been deleted.
3761 if (m_killRecord.Contains(part.LocalId)) 3902 //
3762 { 3903 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3763 // m_log.WarnFormat( 3904// lock (m_killRecord)
3764 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3905// {
3765 // part.LocalId, Name); 3906// if (m_killRecord.Contains(part.LocalId))
3766 continue; 3907// continue;
3767 } 3908// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3768 3909// continue;
3769 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3910// }
3911 }
3912
3913 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3914 {
3915 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3916 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3770 { 3917 {
3771 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3918 part.Shape.LightEntry = false;
3772 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3773 {
3774 part.Shape.LightEntry = false;
3775 }
3776 } 3919 }
3777 } 3920 }
3778 3921 }
3779 #region UpdateFlags to packet type conversion 3922
3780 3923 ++updatesThisCall;
3781 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3924
3782 3925 #region UpdateFlags to packet type conversion
3783 bool canUseCompressed = true; 3926
3784 bool canUseImproved = true; 3927 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3785 3928
3786 // Compressed object updates only make sense for LL primitives 3929 bool canUseCompressed = true;
3787 if (!(update.Entity is SceneObjectPart)) 3930 bool canUseImproved = true;
3931
3932 // Compressed object updates only make sense for LL primitives
3933 if (!(update.Entity is SceneObjectPart))
3934 {
3935 canUseCompressed = false;
3936 }
3937
3938 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3939 {
3940 canUseCompressed = false;
3941 canUseImproved = false;
3942 }
3943 else
3944 {
3945 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3788 { 3949 {
3789 canUseCompressed = false; 3950 canUseCompressed = false;
3790 } 3951 }
3791 3952
3792 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3953 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3957 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3958 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3959 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3960 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3961 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3962 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3963 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3964 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3965 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3966 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3793 { 3967 {
3794 canUseCompressed = false;
3795 canUseImproved = false; 3968 canUseImproved = false;
3796 } 3969 }
3797 else 3970 }
3798 {
3799 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3803 {
3804 canUseCompressed = false;
3805 }
3806
3807 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3821 {
3822 canUseImproved = false;
3823 }
3824 }
3825
3826 #endregion UpdateFlags to packet type conversion
3827
3828 #region Block Construction
3829
3830 // TODO: Remove this once we can build compressed updates
3831 canUseCompressed = false;
3832 3971
3833 if (!canUseImproved && !canUseCompressed) 3972 #endregion UpdateFlags to packet type conversion
3834 {
3835 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3836 3973
3837 if (update.Entity is ScenePresence) 3974 #region Block Construction
3838 {
3839 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3840 }
3841 else
3842 {
3843 SceneObjectPart part = (SceneObjectPart)update.Entity;
3844 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3845
3846 // If the part has become a private hud since the update was scheduled then we do not
3847 // want to send it to other avatars.
3848 if (part.ParentGroup.IsAttachment
3849 && part.ParentGroup.HasPrivateAttachmentPoint
3850 && part.ParentGroup.AttachedAvatar != AgentId)
3851 continue;
3852
3853 // If the part has since been deleted, then drop the update. In the case of attachments,
3854 // this is to avoid spurious updates to other viewers since post-processing of attachments
3855 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3856 // of the test above).
3857 //
3858 // Actual deletions (kills) happen in another method.
3859 if (part.ParentGroup.IsDeleted)
3860 continue;
3861 }
3862 3975
3863 objectUpdateBlocks.Value.Add(updateBlock); 3976 // TODO: Remove this once we can build compressed updates
3864 objectUpdates.Value.Add(update); 3977 canUseCompressed = false;
3865 }
3866 else if (!canUseImproved)
3867 {
3868 SceneObjectPart part = (SceneObjectPart)update.Entity;
3869 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3870 = CreateCompressedUpdateBlock(part, updateFlags);
3871
3872 // If the part has since been deleted, then drop the update. In the case of attachments,
3873 // this is to avoid spurious updates to other viewers since post-processing of attachments
3874 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3875 // of the test above).
3876 //
3877 // Actual deletions (kills) happen in another method.
3878 if (part.ParentGroup.IsDeleted)
3879 continue;
3880 3978
3881 compressedUpdateBlocks.Value.Add(compressedBlock); 3979 if (!canUseImproved && !canUseCompressed)
3882 compressedUpdates.Value.Add(update); 3980 {
3981 if (update.Entity is ScenePresence)
3982 {
3983 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3883 } 3984 }
3884 else 3985 else
3885 { 3986 {
3886 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3987 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3887 {
3888 // Self updates go into a special list
3889 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3890 terseAgentUpdates.Value.Add(update);
3891 }
3892 else
3893 {
3894 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3895 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3896
3897 // Everything else goes here
3898 if (update.Entity is SceneObjectPart)
3899 {
3900 SceneObjectPart part = (SceneObjectPart)update.Entity;
3901
3902 // If the part has become a private hud since the update was scheduled then we do not
3903 // want to send it to other avatars.
3904 if (part.ParentGroup.IsAttachment
3905 && part.ParentGroup.HasPrivateAttachmentPoint
3906 && part.ParentGroup.AttachedAvatar != AgentId)
3907 continue;
3908
3909 // If the part has since been deleted, then drop the update. In the case of attachments,
3910 // this is to avoid spurious updates to other viewers since post-processing of attachments
3911 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3912 // of the test above).
3913 //
3914 // Actual deletions (kills) happen in another method.
3915 if (part.ParentGroup.IsDeleted)
3916 continue;
3917 }
3918
3919 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3920 terseUpdates.Value.Add(update);
3921 }
3922 } 3988 }
3923
3924 ++updatesThisCall;
3925
3926 #endregion Block Construction
3927 } 3989 }
3928 3990 else if (!canUseImproved)
3929 #region Packet Sending
3930 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3931
3932 if (terseAgentUpdateBlocks.IsValueCreated)
3933 { 3991 {
3934 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3992 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3993 }
3994 else
3995 {
3996 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3997 // Self updates go into a special list
3998 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3999 else
4000 // Everything else goes here
4001 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4002 }
3935 4003
3936 ImprovedTerseObjectUpdatePacket packet 4004 #endregion Block Construction
3937 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4005 }
3938 4006
3939 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4007 #region Packet Sending
3940 packet.RegionData.TimeDilation = timeDilation; 4008
3941 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4009 const float TIME_DILATION = 1.0f;
4010 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4011
4012 if (terseAgentUpdateBlocks.IsValueCreated)
4013 {
4014 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3942 4015
3943 for (int i = 0; i < blocks.Count; i++) 4016 ImprovedTerseObjectUpdatePacket packet
3944 packet.ObjectData[i] = blocks[i]; 4017 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3945 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4018 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3946 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4019 packet.RegionData.TimeDilation = timeDilation;
3947 } 4020 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3948 4021
3949 if (objectUpdateBlocks.IsValueCreated) 4022 for (int i = 0; i < blocks.Count; i++)
3950 { 4023 packet.ObjectData[i] = blocks[i];
3951 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3952
3953 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3954 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3955 packet.RegionData.TimeDilation = timeDilation;
3956 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3957
3958 for (int i = 0; i < blocks.Count; i++)
3959 packet.ObjectData[i] = blocks[i];
3960 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3961 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3962 }
3963
3964 if (compressedUpdateBlocks.IsValueCreated)
3965 {
3966 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3967
3968 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3969 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3970 packet.RegionData.TimeDilation = timeDilation;
3971 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3972
3973 for (int i = 0; i < blocks.Count; i++)
3974 packet.ObjectData[i] = blocks[i];
3975 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3976 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3977 }
3978 4024
3979 if (terseUpdateBlocks.IsValueCreated) 4025 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3980 { 4026 }
3981 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3982
3983 ImprovedTerseObjectUpdatePacket packet
3984 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
3985 PacketType.ImprovedTerseObjectUpdate);
3986 4027
3987 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4028 if (objectUpdateBlocks.IsValueCreated)
3988 packet.RegionData.TimeDilation = timeDilation; 4029 {
3989 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4030 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3990 4031
3991 for (int i = 0; i < blocks.Count; i++) 4032 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3992 packet.ObjectData[i] = blocks[i]; 4033 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3993 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4034 packet.RegionData.TimeDilation = timeDilation;
3994 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4035 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3995 } 4036
4037 for (int i = 0; i < blocks.Count; i++)
4038 packet.ObjectData[i] = blocks[i];
4039
4040 OutPacket(packet, ThrottleOutPacketType.Task, true);
4041 }
4042
4043 if (compressedUpdateBlocks.IsValueCreated)
4044 {
4045 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4046
4047 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4048 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4049 packet.RegionData.TimeDilation = timeDilation;
4050 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4051
4052 for (int i = 0; i < blocks.Count; i++)
4053 packet.ObjectData[i] = blocks[i];
4054
4055 OutPacket(packet, ThrottleOutPacketType.Task, true);
4056 }
4057
4058 if (terseUpdateBlocks.IsValueCreated)
4059 {
4060 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4061
4062 ImprovedTerseObjectUpdatePacket packet
4063 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4064 PacketType.ImprovedTerseObjectUpdate);
4065 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4066 packet.RegionData.TimeDilation = timeDilation;
4067 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4068
4069 for (int i = 0; i < blocks.Count; i++)
4070 packet.ObjectData[i] = blocks[i];
4071
4072 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3996 } 4073 }
3997 4074
3998 #endregion Packet Sending 4075 #endregion Packet Sending
@@ -4285,11 +4362,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4285 4362
4286 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4363 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4287 // of the object rather than the properties when the packet was created 4364 // of the object rather than the properties when the packet was created
4288 OutPacket(packet, ThrottleOutPacketType.Task, true, 4365 // HACK : Remove intelligent resending until it's fixed in core
4289 delegate(OutgoingPacket oPacket) 4366 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4290 { 4367 // delegate(OutgoingPacket oPacket)
4291 ResendPropertyUpdates(updates, oPacket); 4368 // {
4292 }); 4369 // ResendPropertyUpdates(updates, oPacket);
4370 // });
4371 OutPacket(packet, ThrottleOutPacketType.Task, true);
4293 4372
4294 // pbcnt += blocks.Count; 4373 // pbcnt += blocks.Count;
4295 // ppcnt++; 4374 // ppcnt++;
@@ -4315,11 +4394,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4315 // of the object rather than the properties when the packet was created 4394 // of the object rather than the properties when the packet was created
4316 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4395 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4317 updates.Add(familyUpdates.Value[i]); 4396 updates.Add(familyUpdates.Value[i]);
4318 OutPacket(packet, ThrottleOutPacketType.Task, true, 4397 // HACK : Remove intelligent resending until it's fixed in core
4319 delegate(OutgoingPacket oPacket) 4398 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4320 { 4399 // delegate(OutgoingPacket oPacket)
4321 ResendPropertyUpdates(updates, oPacket); 4400 // {
4322 }); 4401 // ResendPropertyUpdates(updates, oPacket);
4402 // });
4403 OutPacket(packet, ThrottleOutPacketType.Task, true);
4323 4404
4324 // fpcnt++; 4405 // fpcnt++;
4325 // fbcnt++; 4406 // fbcnt++;
@@ -4691,7 +4772,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4691 4772
4692 if (landData.SimwideArea > 0) 4773 if (landData.SimwideArea > 0)
4693 { 4774 {
4694 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4775 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4776 // Never report more than sim total capacity
4777 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4778 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4695 updateMessage.SimWideMaxPrims = simulatorCapacity; 4779 updateMessage.SimWideMaxPrims = simulatorCapacity;
4696 } 4780 }
4697 else 4781 else
@@ -4820,14 +4904,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4820 4904
4821 if (notifyCount > 0) 4905 if (notifyCount > 0)
4822 { 4906 {
4823 if (notifyCount > 32) 4907// if (notifyCount > 32)
4824 { 4908// {
4825 m_log.InfoFormat( 4909// m_log.InfoFormat(
4826 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4910// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4827 + " - a developer might want to investigate whether this is a hard limit", 32); 4911// + " - a developer might want to investigate whether this is a hard limit", 32);
4828 4912//
4829 notifyCount = 32; 4913// notifyCount = 32;
4830 } 4914// }
4831 4915
4832 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4916 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4833 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4917 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4882,9 +4966,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4882 { 4966 {
4883 ScenePresence presence = (ScenePresence)entity; 4967 ScenePresence presence = (ScenePresence)entity;
4884 4968
4969 position = presence.OffsetPosition;
4970 rotation = presence.Rotation;
4971
4972 if (presence.ParentID != 0)
4973 {
4974 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4975 if (part != null && part != part.ParentGroup.RootPart)
4976 {
4977 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4978 rotation = part.RotationOffset * presence.Rotation;
4979 }
4980 }
4981
4885 attachPoint = 0; 4982 attachPoint = 0;
4886 collisionPlane = presence.CollisionPlane; 4983 collisionPlane = presence.CollisionPlane;
4887 position = presence.OffsetPosition;
4888 velocity = presence.Velocity; 4984 velocity = presence.Velocity;
4889 acceleration = Vector3.Zero; 4985 acceleration = Vector3.Zero;
4890 4986
@@ -4892,9 +4988,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4892 // in that direction, even though we don't model this on the server. Implementing this in the future 4988 // in that direction, even though we don't model this on the server. Implementing this in the future
4893 // may improve movement smoothness. 4989 // may improve movement smoothness.
4894// acceleration = new Vector3(1, 0, 0); 4990// acceleration = new Vector3(1, 0, 0);
4895 4991
4896 angularVelocity = Vector3.Zero; 4992 angularVelocity = Vector3.Zero;
4897 rotation = presence.Rotation;
4898 4993
4899 if (sendTexture) 4994 if (sendTexture)
4900 textureEntry = presence.Appearance.Texture.GetBytes(); 4995 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -5001,13 +5096,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5001 5096
5002 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5097 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5003 { 5098 {
5099 Vector3 offsetPosition = data.OffsetPosition;
5100 Quaternion rotation = data.Rotation;
5101 uint parentID = data.ParentID;
5102
5103 if (parentID != 0)
5104 {
5105 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5106 if (part != null && part != part.ParentGroup.RootPart)
5107 {
5108 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5109 rotation = part.RotationOffset * data.Rotation;
5110 parentID = part.ParentGroup.RootPart.LocalId;
5111 }
5112 }
5113
5004 byte[] objectData = new byte[76]; 5114 byte[] objectData = new byte[76];
5005 5115
5006 data.CollisionPlane.ToBytes(objectData, 0); 5116 data.CollisionPlane.ToBytes(objectData, 0);
5007 data.OffsetPosition.ToBytes(objectData, 16); 5117 offsetPosition.ToBytes(objectData, 16);
5008// data.Velocity.ToBytes(objectData, 28); 5118// data.Velocity.ToBytes(objectData, 28);
5009// data.Acceleration.ToBytes(objectData, 40); 5119// data.Acceleration.ToBytes(objectData, 40);
5010 data.Rotation.ToBytes(objectData, 52); 5120 rotation.ToBytes(objectData, 52);
5011 //data.AngularVelocity.ToBytes(objectData, 64); 5121 //data.AngularVelocity.ToBytes(objectData, 64);
5012 5122
5013 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5123 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5021,14 +5131,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5021 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5131 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5022 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5132 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5023 update.ObjectData = objectData; 5133 update.ObjectData = objectData;
5024 update.ParentID = data.ParentID; 5134 update.ParentID = parentID;
5025 update.PathCurve = 16; 5135 update.PathCurve = 16;
5026 update.PathScaleX = 100; 5136 update.PathScaleX = 100;
5027 update.PathScaleY = 100; 5137 update.PathScaleY = 100;
5028 update.PCode = (byte)PCode.Avatar; 5138 update.PCode = (byte)PCode.Avatar;
5029 update.ProfileCurve = 1; 5139 update.ProfileCurve = 1;
5030 update.PSBlock = Utils.EmptyBytes; 5140 update.PSBlock = Utils.EmptyBytes;
5031 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5141 update.Scale = data.Appearance.AvatarSize;
5142// update.Scale.Z -= 0.2f;
5143
5032 update.Text = Utils.EmptyBytes; 5144 update.Text = Utils.EmptyBytes;
5033 update.TextColor = new byte[4]; 5145 update.TextColor = new byte[4];
5034 5146
@@ -5039,10 +5151,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 update.TextureEntry = Utils.EmptyBytes; 5151 update.TextureEntry = Utils.EmptyBytes;
5040// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5152// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5041 5153
5154/* 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)
5042 update.UpdateFlags = (uint)( 5155 update.UpdateFlags = (uint)(
5043 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5156 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5044 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5157 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5045 PrimFlags.ObjectOwnerModify); 5158 PrimFlags.ObjectOwnerModify);
5159*/
5160 update.UpdateFlags = 0;
5046 5161
5047 return update; 5162 return update;
5048 } 5163 }
@@ -5213,8 +5328,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5213 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5328 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5214 // for each AgentUpdate packet. 5329 // for each AgentUpdate packet.
5215 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5330 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5216 5331
5217 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5332 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5333 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5334 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5218 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5335 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5219 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5336 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5220 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5337 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5366,6 +5483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5366 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5483 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5367 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5484 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5368 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5485 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5486 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5369 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5487 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5370 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5488 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5371 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5489 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5432,6 +5550,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5432 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5550 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5433 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5551 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5434 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5552 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5553 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5435 5554
5436 AddGenericPacketHandler("autopilot", HandleAutopilot); 5555 AddGenericPacketHandler("autopilot", HandleAutopilot);
5437 } 5556 }
@@ -5470,6 +5589,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5470 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5589 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5471 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5590 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5472 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5591 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5592 (x.ControlFlags != 0) ||
5473 (x.Far != m_lastAgentUpdateArgs.Far) || 5593 (x.Far != m_lastAgentUpdateArgs.Far) ||
5474 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5594 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5475 (x.State != m_lastAgentUpdateArgs.State) || 5595 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5729,6 +5849,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5729 return true; 5849 return true;
5730 } 5850 }
5731 5851
5852 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5853 {
5854 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5855 if (p.AgentData.SessionID != SessionId ||
5856 p.AgentData.AgentID != AgentId)
5857 return true;
5858
5859 m_VelocityInterpolate = false;
5860 return true;
5861 }
5862
5863 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5864 {
5865 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5866 if (p.AgentData.SessionID != SessionId ||
5867 p.AgentData.AgentID != AgentId)
5868 return true;
5869
5870 m_VelocityInterpolate = true;
5871 return true;
5872 }
5873
5874
5732 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5875 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5733 { 5876 {
5734 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5877 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6149,17 +6292,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6149 // Temporarily protect ourselves from the mantis #951 failure. 6292 // Temporarily protect ourselves from the mantis #951 failure.
6150 // However, we could do this for several other handlers where a failure isn't terminal 6293 // However, we could do this for several other handlers where a failure isn't terminal
6151 // for the client session anyway, in order to protect ourselves against bad code in plugins 6294 // for the client session anyway, in order to protect ourselves against bad code in plugins
6295 Vector3 avSize = appear.AgentData.Size;
6152 try 6296 try
6153 { 6297 {
6154 byte[] visualparams = new byte[appear.VisualParam.Length]; 6298 byte[] visualparams = new byte[appear.VisualParam.Length];
6155 for (int i = 0; i < appear.VisualParam.Length; i++) 6299 for (int i = 0; i < appear.VisualParam.Length; i++)
6156 visualparams[i] = appear.VisualParam[i].ParamValue; 6300 visualparams[i] = appear.VisualParam[i].ParamValue;
6157 6301 //var b = appear.WearableData[0];
6302
6158 Primitive.TextureEntry te = null; 6303 Primitive.TextureEntry te = null;
6159 if (appear.ObjectData.TextureEntry.Length > 1) 6304 if (appear.ObjectData.TextureEntry.Length > 1)
6160 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6305 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6306
6307 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6308 for (int i=0; i<appear.WearableData.Length;i++)
6309 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6161 6310
6162 handlerSetAppearance(sender, te, visualparams); 6311
6312
6313 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6163 } 6314 }
6164 catch (Exception e) 6315 catch (Exception e)
6165 { 6316 {
@@ -6368,6 +6519,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6368 { 6519 {
6369 handlerCompleteMovementToRegion(sender, true); 6520 handlerCompleteMovementToRegion(sender, true);
6370 } 6521 }
6522 else
6523 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6524
6371 handlerCompleteMovementToRegion = null; 6525 handlerCompleteMovementToRegion = null;
6372 6526
6373 return true; 6527 return true;
@@ -6385,7 +6539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6385 return true; 6539 return true;
6386 } 6540 }
6387 #endregion 6541 #endregion
6388 6542/*
6389 StartAnim handlerStartAnim = null; 6543 StartAnim handlerStartAnim = null;
6390 StopAnim handlerStopAnim = null; 6544 StopAnim handlerStopAnim = null;
6391 6545
@@ -6409,6 +6563,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6409 } 6563 }
6410 } 6564 }
6411 return true; 6565 return true;
6566*/
6567 ChangeAnim handlerChangeAnim = null;
6568
6569 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6570 {
6571 handlerChangeAnim = OnChangeAnim;
6572 if (handlerChangeAnim != null)
6573 {
6574 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6575 }
6576 }
6577
6578 handlerChangeAnim = OnChangeAnim;
6579 if (handlerChangeAnim != null)
6580 {
6581 handlerChangeAnim(UUID.Zero, false, true);
6582 }
6583
6584 return true;
6412 } 6585 }
6413 6586
6414 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6587 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6643,6 +6816,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6643 #endregion 6816 #endregion
6644 6817
6645 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6818 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6819 GenericCall2 handler = OnUpdateThrottles;
6820 if (handler != null)
6821 {
6822 handler();
6823 }
6646 return true; 6824 return true;
6647 } 6825 }
6648 6826
@@ -7044,10 +7222,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7044 // 46,47,48 are special positions within the packet 7222 // 46,47,48 are special positions within the packet
7045 // This may change so perhaps we need a better way 7223 // This may change so perhaps we need a better way
7046 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7224 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7047 bool UsePhysics = (data[46] != 0) ? true : false; 7225 /*
7048 bool IsTemporary = (data[47] != 0) ? true : false; 7226 bool UsePhysics = (data[46] != 0) ? true : false;
7049 bool IsPhantom = (data[48] != 0) ? true : false; 7227 bool IsTemporary = (data[47] != 0) ? true : false;
7050 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7228 bool IsPhantom = (data[48] != 0) ? true : false;
7229 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7230 */
7231 bool UsePhysics = flags.AgentData.UsePhysics;
7232 bool IsPhantom = flags.AgentData.IsPhantom;
7233 bool IsTemporary = flags.AgentData.IsTemporary;
7234 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7235 ExtraPhysicsData physdata = new ExtraPhysicsData();
7236
7237 if (blocks == null || blocks.Length == 0)
7238 {
7239 physdata.PhysShapeType = PhysShapeType.invalid;
7240 }
7241 else
7242 {
7243 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7244 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7245 physdata.Bounce = phsblock.Restitution;
7246 physdata.Density = phsblock.Density;
7247 physdata.Friction = phsblock.Friction;
7248 physdata.GravitationModifier = phsblock.GravityMultiplier;
7249 }
7250
7251 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7051 } 7252 }
7052 return true; 7253 return true;
7053 } 7254 }
@@ -7630,6 +7831,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7630 // surrounding scene 7831 // surrounding scene
7631 if ((ImageType)block.Type == ImageType.Baked) 7832 if ((ImageType)block.Type == ImageType.Baked)
7632 args.Priority *= 2.0f; 7833 args.Priority *= 2.0f;
7834 int wearableout = 0;
7633 7835
7634 ImageManager.EnqueueReq(args); 7836 ImageManager.EnqueueReq(args);
7635 } 7837 }
@@ -8648,16 +8850,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8648 8850
8649 #region Parcel related packets 8851 #region Parcel related packets
8650 8852
8853 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8854 // to be done with minimal resources as possible
8855 // variables temporary here while in test
8856
8857 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8858 bool RegionHandleRequestsInService = false;
8859
8651 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8860 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8652 { 8861 {
8653 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8862 UUID currentUUID;
8654 8863
8655 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8864 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8656 if (handlerRegionHandleRequest != null) 8865
8866 if (handlerRegionHandleRequest == null)
8867 return true;
8868
8869 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8870
8871 lock (RegionHandleRequests)
8657 { 8872 {
8658 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8873 if (RegionHandleRequestsInService)
8874 {
8875 // we are already busy doing a previus request
8876 // so enqueue it
8877 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8878 return true;
8879 }
8880
8881 // else do it
8882 currentUUID = rhrPack.RequestBlock.RegionID;
8883 RegionHandleRequestsInService = true;
8659 } 8884 }
8660 return true; 8885
8886 while (true)
8887 {
8888 handlerRegionHandleRequest(this, currentUUID);
8889
8890 lock (RegionHandleRequests)
8891 {
8892 // exit condition, nothing to do or closed
8893 // current code seems to assume we may loose the handler at anytime,
8894 // so keep checking it
8895 handlerRegionHandleRequest = OnRegionHandleRequest;
8896
8897 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8898 {
8899 RegionHandleRequests.Clear();
8900 RegionHandleRequestsInService = false;
8901 return true;
8902 }
8903 currentUUID = RegionHandleRequests.Dequeue();
8904 }
8905 }
8906
8907 return true; // actually unreached
8661 } 8908 }
8662 8909
8663 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8910 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9913,7 +10160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9913 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10160 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9914 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10161 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9915 UpdateMuteListEntry.MuteData.MuteType, 10162 UpdateMuteListEntry.MuteData.MuteType,
9916 UpdateMuteListEntry.AgentData.AgentID); 10163 UpdateMuteListEntry.MuteData.MuteFlags);
9917 return true; 10164 return true;
9918 } 10165 }
9919 return false; 10166 return false;
@@ -9928,8 +10175,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9928 { 10175 {
9929 handlerRemoveMuteListEntry(this, 10176 handlerRemoveMuteListEntry(this,
9930 RemoveMuteListEntry.MuteData.MuteID, 10177 RemoveMuteListEntry.MuteData.MuteID,
9931 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10178 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9932 RemoveMuteListEntry.AgentData.AgentID);
9933 return true; 10179 return true;
9934 } 10180 }
9935 return false; 10181 return false;
@@ -9973,10 +10219,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9973 return false; 10219 return false;
9974 } 10220 }
9975 10221
10222 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10223 {
10224 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10225 (ChangeInventoryItemFlagsPacket)packet;
10226 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10227 if (handlerChangeInventoryItemFlags != null)
10228 {
10229 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10230 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10231 return true;
10232 }
10233 return false;
10234 }
10235
9976 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10236 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9977 { 10237 {
9978 return true; 10238 return true;
9979 } 10239 }
10240
10241 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10242 {
10243 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10244
10245 #region Packet Session and User Check
10246 if (m_checkPackets)
10247 {
10248 if (packet.AgentData.SessionID != SessionId ||
10249 packet.AgentData.AgentID != AgentId)
10250 return true;
10251 }
10252 #endregion
10253 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10254 List<InventoryItemBase> items = new List<InventoryItemBase>();
10255 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10256 {
10257 InventoryItemBase b = new InventoryItemBase();
10258 b.ID = n.OldItemID;
10259 b.Folder = n.OldFolderID;
10260 items.Add(b);
10261 }
10262
10263 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10264 if (handlerMoveItemsAndLeaveCopy != null)
10265 {
10266 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10267 }
10268
10269 return true;
10270 }
9980 10271
9981 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10272 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9982 { 10273 {
@@ -10403,6 +10694,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10403 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10694 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10404 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10695 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10405 10696
10697 Scene scene = (Scene)m_scene;
10698 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10699 {
10700 ScenePresence p;
10701 if (scene.TryGetScenePresence(sender.AgentId, out p))
10702 {
10703 if (p.GodLevel >= 200)
10704 {
10705 groupProfileReply.GroupData.OpenEnrollment = true;
10706 groupProfileReply.GroupData.MembershipFee = 0;
10707 }
10708 }
10709 }
10710
10406 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10711 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10407 } 10712 }
10408 return true; 10713 return true;
@@ -10976,11 +11281,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10976 11281
10977 StartLure handlerStartLure = OnStartLure; 11282 StartLure handlerStartLure = OnStartLure;
10978 if (handlerStartLure != null) 11283 if (handlerStartLure != null)
10979 handlerStartLure(startLureRequest.Info.LureType, 11284 {
10980 Utils.BytesToString( 11285 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10981 startLureRequest.Info.Message), 11286 {
10982 startLureRequest.TargetData[0].TargetID, 11287 handlerStartLure(startLureRequest.Info.LureType,
10983 this); 11288 Utils.BytesToString(
11289 startLureRequest.Info.Message),
11290 startLureRequest.TargetData[i].TargetID,
11291 this);
11292 }
11293 }
10984 return true; 11294 return true;
10985 } 11295 }
10986 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11296 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11094,10 +11404,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11094 } 11404 }
11095 #endregion 11405 #endregion
11096 11406
11097 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11407 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11098 if (handlerClassifiedGodDelete != null) 11408 if (handlerClassifiedGodDelete != null)
11099 handlerClassifiedGodDelete( 11409 handlerClassifiedGodDelete(
11100 classifiedGodDelete.Data.ClassifiedID, 11410 classifiedGodDelete.Data.ClassifiedID,
11411 classifiedGodDelete.Data.QueryID,
11101 this); 11412 this);
11102 return true; 11413 return true;
11103 } 11414 }
@@ -11410,6 +11721,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11410 11721
11411 if (cachedtex.AgentData.SessionID != SessionId) 11722 if (cachedtex.AgentData.SessionID != SessionId)
11412 return false; 11723 return false;
11724
11413 11725
11414 // TODO: don't create new blocks if recycling an old packet 11726 // TODO: don't create new blocks if recycling an old packet
11415 cachedresp.AgentData.AgentID = AgentId; 11727 cachedresp.AgentData.AgentID = AgentId;
@@ -11419,14 +11731,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11419 cachedresp.WearableData = 11731 cachedresp.WearableData =
11420 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11732 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11421 11733
11422 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11734 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11735 // var item = fac.GetBakedTextureFaces(AgentId);
11736 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11737
11738 IAssetService cache = m_scene.AssetService;
11739 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11740 //bakedTextureModule = null;
11741 int maxWearablesLoop = cachedtex.WearableData.Length;
11742 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11743 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11744
11745 if (bakedTextureModule != null && cache != null)
11423 { 11746 {
11424 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11747 // 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
11425 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11748
11426 cachedresp.WearableData[i].TextureID = UUID.Zero; 11749 WearableCacheItem[] cacheItems = null;
11427 cachedresp.WearableData[i].HostName = new byte[0]; 11750 ScenePresence p = m_scene.GetScenePresence(AgentId);
11751 if (p.Appearance != null)
11752 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11753 {
11754 try
11755 {
11756 cacheItems = bakedTextureModule.Get(AgentId);
11757 p.Appearance.WearableCacheItems = cacheItems;
11758 p.Appearance.WearableCacheItemsDirty = false;
11759 }
11760
11761 /*
11762 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11763 *
11764 catch (System.Net.Sockets.SocketException)
11765 {
11766 cacheItems = null;
11767 }
11768 catch (WebException)
11769 {
11770 cacheItems = null;
11771 }
11772 catch (InvalidOperationException)
11773 {
11774 cacheItems = null;
11775 } */
11776 catch (Exception)
11777 {
11778 cacheItems = null;
11779 }
11780
11781 }
11782 else if (p.Appearance.WearableCacheItems != null)
11783 {
11784 cacheItems = p.Appearance.WearableCacheItems;
11785 }
11786
11787 if (cache != null && cacheItems != null)
11788 {
11789 foreach (WearableCacheItem item in cacheItems)
11790 {
11791
11792 if (cache.GetCached(item.TextureID.ToString()) == null)
11793 {
11794 item.TextureAsset.Temporary = true;
11795 cache.Store(item.TextureAsset);
11796 }
11797
11798
11799 }
11800 }
11801
11802 if (cacheItems != null)
11803 {
11804
11805 for (int i = 0; i < maxWearablesLoop; i++)
11806 {
11807 WearableCacheItem item =
11808 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11809
11810 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11811 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11812 cachedresp.WearableData[i].HostName = new byte[0];
11813 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11814 {
11815
11816 cachedresp.WearableData[i].TextureID = item.TextureID;
11817 }
11818 else
11819 {
11820 cachedresp.WearableData[i].TextureID = UUID.Zero;
11821 }
11822 }
11823 }
11824 else
11825 {
11826 for (int i = 0; i < maxWearablesLoop; i++)
11827 {
11828 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11829 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11830 cachedresp.WearableData[i].TextureID = UUID.Zero;
11831 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11832 cachedresp.WearableData[i].HostName = new byte[0];
11833 }
11834 }
11428 } 11835 }
11836 else
11837 {
11838 if (cache == null)
11839 {
11840 for (int i = 0; i < maxWearablesLoop; i++)
11841 {
11842 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11843 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11844 cachedresp.WearableData[i].TextureID = UUID.Zero;
11845 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11846 cachedresp.WearableData[i].HostName = new byte[0];
11847 }
11848 }
11849 else
11850 {
11851 for (int i = 0; i < maxWearablesLoop; i++)
11852 {
11853 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11854 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11429 11855
11856
11857
11858 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11859 cachedresp.WearableData[i].TextureID = UUID.Zero;
11860 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11861 else
11862 cachedresp.WearableData[i].TextureID = UUID.Zero;
11863 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11864 cachedresp.WearableData[i].HostName = new byte[0];
11865 }
11866 }
11867 }
11430 cachedresp.Header.Zerocoded = true; 11868 cachedresp.Header.Zerocoded = true;
11431 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11869 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11432 11870
@@ -11463,209 +11901,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11463 } 11901 }
11464 else 11902 else
11465 { 11903 {
11466// m_log.DebugFormat( 11904 ClientChangeObject updatehandler = onClientChangeObject;
11467// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11468// i, block.Type, part.Name, part.LocalId);
11469 11905
11470// // Do this once since fetch parts creates a new array. 11906 if (updatehandler != null)
11471// SceneObjectPart[] parts = part.ParentGroup.Parts; 11907 {
11472// for (int j = 0; j < parts.Length; j++) 11908 ObjectChangeData udata = new ObjectChangeData();
11473// {
11474// part.StoreUndoState();
11475// parts[j].IgnoreUndoUpdate = true;
11476// }
11477 11909
11478 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11910 /*ubit from ll JIRA:
11911 * 0x01 position
11912 * 0x02 rotation
11913 * 0x04 scale
11914
11915 * 0x08 LINK_SET
11916 * 0x10 UNIFORM for scale
11917 */
11479 11918
11480 switch (block.Type) 11919 // translate to internal changes
11481 { 11920 // not all cases .. just the ones older code did
11482 case 1:
11483 Vector3 pos1 = new Vector3(block.Data, 0);
11484 11921
11485 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11922 switch (block.Type)
11486 if (handlerUpdatePrimSinglePosition != null) 11923 {
11487 { 11924 case 1: //change position sp
11488 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11925 udata.position = new Vector3(block.Data, 0);
11489 handlerUpdatePrimSinglePosition(localId, pos1, this);
11490 }
11491 break;
11492 11926
11493 case 2: 11927 udata.change = ObjectChangeType.primP;
11494 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11928 updatehandler(localId, udata, this);
11929 break;
11495 11930
11496 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11931 case 2: // rotation sp
11497 if (handlerUpdatePrimSingleRotation != null) 11932 udata.rotation = new Quaternion(block.Data, 0, true);
11498 {
11499 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11500 handlerUpdatePrimSingleRotation(localId, rot1, this);
11501 }
11502 break;
11503 11933
11504 case 3: 11934 udata.change = ObjectChangeType.primR;
11505 Vector3 rotPos = new Vector3(block.Data, 0); 11935 updatehandler(localId, udata, this);
11506 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11936 break;
11507 11937
11508 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11938 case 3: // position plus rotation
11509 if (handlerUpdatePrimSingleRotationPosition != null) 11939 udata.position = new Vector3(block.Data, 0);
11510 { 11940 udata.rotation = new Quaternion(block.Data, 12, true);
11511 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11512 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11513 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11514 }
11515 break;
11516 11941
11517 case 4: 11942 udata.change = ObjectChangeType.primPR;
11518 case 20: 11943 updatehandler(localId, udata, this);
11519 Vector3 scale4 = new Vector3(block.Data, 0); 11944 break;
11520 11945
11521 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11946 case 4: // scale sp
11522 if (handlerUpdatePrimScale != null) 11947 udata.scale = new Vector3(block.Data, 0);
11523 { 11948 udata.change = ObjectChangeType.primS;
11524 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11525 handlerUpdatePrimScale(localId, scale4, this);
11526 }
11527 break;
11528 11949
11529 case 5: 11950 updatehandler(localId, udata, this);
11530 Vector3 scale1 = new Vector3(block.Data, 12); 11951 break;
11531 Vector3 pos11 = new Vector3(block.Data, 0);
11532 11952
11533 handlerUpdatePrimScale = OnUpdatePrimScale; 11953 case 0x14: // uniform scale sp
11534 if (handlerUpdatePrimScale != null) 11954 udata.scale = new Vector3(block.Data, 0);
11535 {
11536 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11537 handlerUpdatePrimScale(localId, scale1, this);
11538 11955
11539 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11956 udata.change = ObjectChangeType.primUS;
11540 if (handlerUpdatePrimSinglePosition != null) 11957 updatehandler(localId, udata, this);
11541 { 11958 break;
11542 handlerUpdatePrimSinglePosition(localId, pos11, this);
11543 }
11544 }
11545 break;
11546 11959
11547 case 9: 11960 case 5: // scale and position sp
11548 Vector3 pos2 = new Vector3(block.Data, 0); 11961 udata.position = new Vector3(block.Data, 0);
11962 udata.scale = new Vector3(block.Data, 12);
11549 11963
11550 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11964 udata.change = ObjectChangeType.primPS;
11965 updatehandler(localId, udata, this);
11966 break;
11551 11967
11552 if (handlerUpdateVector != null) 11968 case 0x15: //uniform scale and position
11553 { 11969 udata.position = new Vector3(block.Data, 0);
11554 handlerUpdateVector(localId, pos2, this); 11970 udata.scale = new Vector3(block.Data, 12);
11555 }
11556 break;
11557 11971
11558 case 10: 11972 udata.change = ObjectChangeType.primPUS;
11559 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11973 updatehandler(localId, udata, this);
11974 break;
11560 11975
11561 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11976 // now group related (bit 4)
11562 if (handlerUpdatePrimRotation != null) 11977 case 9: //( 8 + 1 )group position
11563 { 11978 udata.position = new Vector3(block.Data, 0);
11564 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11565 handlerUpdatePrimRotation(localId, rot3, this);
11566 }
11567 break;
11568 11979
11569 case 11: 11980 udata.change = ObjectChangeType.groupP;
11570 Vector3 pos3 = new Vector3(block.Data, 0); 11981 updatehandler(localId, udata, this);
11571 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11982 break;
11572 11983
11573 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11984 case 0x0A: // (8 + 2) group rotation
11574 if (handlerUpdatePrimGroupRotation != null) 11985 udata.rotation = new Quaternion(block.Data, 0, true);
11575 {
11576 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11577 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11578 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11579 }
11580 break;
11581 case 12:
11582 case 28:
11583 Vector3 scale7 = new Vector3(block.Data, 0);
11584 11986
11585 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11987 udata.change = ObjectChangeType.groupR;
11586 if (handlerUpdatePrimGroupScale != null) 11988 updatehandler(localId, udata, this);
11587 { 11989 break;
11588 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11589 handlerUpdatePrimGroupScale(localId, scale7, this);
11590 }
11591 break;
11592 11990
11593 case 13: 11991 case 0x0B: //( 8 + 2 + 1) group rotation and position
11594 Vector3 scale2 = new Vector3(block.Data, 12); 11992 udata.position = new Vector3(block.Data, 0);
11595 Vector3 pos4 = new Vector3(block.Data, 0); 11993 udata.rotation = new Quaternion(block.Data, 12, true);
11596 11994
11597 handlerUpdatePrimScale = OnUpdatePrimScale; 11995 udata.change = ObjectChangeType.groupPR;
11598 if (handlerUpdatePrimScale != null) 11996 updatehandler(localId, udata, this);
11599 { 11997 break;
11600 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11601 handlerUpdatePrimScale(localId, scale2, this);
11602 11998
11603 // Change the position based on scale (for bug number 246) 11999 case 0x0C: // (8 + 4) group scale
11604 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12000 // only afects root prim and only sent by viewer editor object tab scaling
11605 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12001 // mouse edition only allows uniform scaling
11606 if (handlerUpdatePrimSinglePosition != null) 12002 // SL MAY CHANGE THIS in viewers
11607 {
11608 handlerUpdatePrimSinglePosition(localId, pos4, this);
11609 }
11610 }
11611 break;
11612 12003
11613 case 29: 12004 udata.scale = new Vector3(block.Data, 0);
11614 Vector3 scale5 = new Vector3(block.Data, 12);
11615 Vector3 pos5 = new Vector3(block.Data, 0);
11616 12005
11617 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12006 udata.change = ObjectChangeType.groupS;
11618 if (handlerUpdatePrimGroupScale != null) 12007 updatehandler(localId, udata, this);
11619 {
11620 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11621 part.StoreUndoState(true);
11622 part.IgnoreUndoUpdate = true;
11623 handlerUpdatePrimGroupScale(localId, scale5, this);
11624 handlerUpdateVector = OnUpdatePrimGroupPosition;
11625 12008
11626 if (handlerUpdateVector != null) 12009 break;
11627 {
11628 handlerUpdateVector(localId, pos5, this);
11629 }
11630 12010
11631 part.IgnoreUndoUpdate = false; 12011 case 0x0D: //(8 + 4 + 1) group scale and position
11632 } 12012 // exception as above
11633 12013
11634 break; 12014 udata.position = new Vector3(block.Data, 0);
12015 udata.scale = new Vector3(block.Data, 12);
11635 12016
11636 case 21: 12017 udata.change = ObjectChangeType.groupPS;
11637 Vector3 scale6 = new Vector3(block.Data, 12); 12018 updatehandler(localId, udata, this);
11638 Vector3 pos6 = new Vector3(block.Data, 0); 12019 break;
11639 12020
11640 handlerUpdatePrimScale = OnUpdatePrimScale; 12021 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11641 if (handlerUpdatePrimScale != null) 12022 udata.scale = new Vector3(block.Data, 0);
11642 {
11643 part.StoreUndoState(false);
11644 part.IgnoreUndoUpdate = true;
11645 12023
11646 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12024 udata.change = ObjectChangeType.groupUS;
11647 handlerUpdatePrimScale(localId, scale6, this); 12025 updatehandler(localId, udata, this);
11648 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12026 break;
11649 if (handlerUpdatePrimSinglePosition != null)
11650 {
11651 handlerUpdatePrimSinglePosition(localId, pos6, this);
11652 }
11653 12027
11654 part.IgnoreUndoUpdate = false; 12028 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11655 } 12029 udata.position = new Vector3(block.Data, 0);
11656 break; 12030 udata.scale = new Vector3(block.Data, 12);
11657 12031
11658 default: 12032 udata.change = ObjectChangeType.groupPUS;
11659 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12033 updatehandler(localId, udata, this);
11660 break; 12034 break;
12035
12036 default:
12037 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12038 break;
12039 }
11661 } 12040 }
11662 12041
11663// for (int j = 0; j < parts.Length; j++)
11664// parts[j].IgnoreUndoUpdate = false;
11665 } 12042 }
11666 } 12043 }
11667 } 12044 }
11668
11669 return true; 12045 return true;
11670 } 12046 }
11671 12047
@@ -11726,9 +12102,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11726 public void SetChildAgentThrottle(byte[] throttles) 12102 public void SetChildAgentThrottle(byte[] throttles)
11727 { 12103 {
11728 m_udpClient.SetThrottles(throttles); 12104 m_udpClient.SetThrottles(throttles);
12105 GenericCall2 handler = OnUpdateThrottles;
12106 if (handler != null)
12107 {
12108 handler();
12109 }
11729 } 12110 }
11730 12111
11731 /// <summary> 12112 /// <summary>
12113 /// Sets the throttles from values supplied by the client
12114 /// </summary>
12115 /// <param name="throttles"></param>
12116 public void SetAgentThrottleSilent(int throttle, int setting)
12117 {
12118 m_udpClient.ForceThrottleSetting(throttle,setting);
12119 //m_udpClient.SetThrottles(throttles);
12120
12121 }
12122
12123
12124 /// <summary>
11732 /// Get the current throttles for this client as a packed byte array 12125 /// Get the current throttles for this client as a packed byte array
11733 /// </summary> 12126 /// </summary>
11734 /// <param name="multiplier">Unused</param> 12127 /// <param name="multiplier">Unused</param>
@@ -12115,7 +12508,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12115// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12508// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12116// requestID, taskID, (SourceType)sourceType, Name); 12509// requestID, taskID, (SourceType)sourceType, Name);
12117 12510
12511
12512 //Note, the bool returned from the below function is useless since it is always false.
12118 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12513 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12514
12119 } 12515 }
12120 12516
12121 /// <summary> 12517 /// <summary>
@@ -12181,7 +12577,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12181 /// <returns></returns> 12577 /// <returns></returns>
12182 private static int CalculateNumPackets(byte[] data) 12578 private static int CalculateNumPackets(byte[] data)
12183 { 12579 {
12184 const uint m_maxPacketSize = 600; 12580// const uint m_maxPacketSize = 600;
12581 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12185 int numPackets = 1; 12582 int numPackets = 1;
12186 12583
12187 if (data == null) 12584 if (data == null)