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.cs1198
1 files changed, 697 insertions, 501 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index d05ffea..6f00957 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -98,6 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 public event AvatarPickerRequest OnAvatarPickerRequest; 98 public event AvatarPickerRequest OnAvatarPickerRequest;
99 public event StartAnim OnStartAnim; 99 public event StartAnim OnStartAnim;
100 public event StopAnim OnStopAnim; 100 public event StopAnim OnStopAnim;
101 public event ChangeAnim OnChangeAnim;
101 public event Action<IClientAPI> OnRequestAvatarsData; 102 public event Action<IClientAPI> OnRequestAvatarsData;
102 public event LinkObjects OnLinkObjects; 103 public event LinkObjects OnLinkObjects;
103 public event DelinkObjects OnDelinkObjects; 104 public event DelinkObjects OnDelinkObjects;
@@ -125,6 +126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 127 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 128 public event UpdatePrimTexture OnUpdatePrimTexture;
129 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 130 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 131 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 160 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 161 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 162 public event CopyInventoryItem OnCopyInventoryItem;
163 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 164 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 165 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 166 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +259,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 259 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 261 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 262 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 263 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 265 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 291 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 292 public event SendPostcard OnSendPostcard;
293 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 294 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 295 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 296 public event GodlikeMessage onGodlikeMessage;
@@ -325,6 +329,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 private Prioritizer m_prioritizer; 329 private Prioritizer m_prioritizer;
326 private bool m_disableFacelights = false; 330 private bool m_disableFacelights = false;
327 331
332 private const uint MaxTransferBytesPerPacket = 600;
333
334
328 /// <value> 335 /// <value>
329 /// List used in construction of data blocks for an object update packet. This is to stop us having to 336 /// List used in construction of data blocks for an object update packet. This is to stop us having to
330 /// continually recreate it. 337 /// continually recreate it.
@@ -336,14 +343,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 343 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 344 /// ownerless phantom.
338 /// 345 ///
339 /// All manipulation of this set has to occur under a lock 346 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 347 ///
341 /// </value> 348 /// </value>
342 protected HashSet<uint> m_killRecord; 349// protected HashSet<uint> m_killRecord;
343 350
344// protected HashSet<uint> m_attachmentsSent; 351// protected HashSet<uint> m_attachmentsSent;
345 352
346 private int m_moneyBalance; 353 private int m_moneyBalance;
354 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 355 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 356 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 357 private AgentUpdateArgs lastarg;
@@ -380,6 +388,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
380 get { return m_startpos; } 388 get { return m_startpos; }
381 set { m_startpos = value; } 389 set { m_startpos = value; }
382 } 390 }
391 public bool DeliverPackets
392 {
393 get { return m_deliverPackets; }
394 set {
395 m_deliverPackets = value;
396 m_udpClient.m_deliverPackets = value;
397 }
398 }
383 public UUID AgentId { get { return m_agentId; } } 399 public UUID AgentId { get { return m_agentId; } }
384 public ISceneAgent SceneAgent { get; set; } 400 public ISceneAgent SceneAgent { get; set; }
385 public UUID ActiveGroupId { get { return m_activeGroupID; } } 401 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -457,7 +473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
457 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 473 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
458 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 474 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
459 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 475 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
460 m_killRecord = new HashSet<uint>(); 476// m_killRecord = new HashSet<uint>();
461// m_attachmentsSent = new HashSet<uint>(); 477// m_attachmentsSent = new HashSet<uint>();
462 478
463 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 479 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -487,12 +503,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
487 503
488 #region Client Methods 504 #region Client Methods
489 505
506
507 /// <summary>
508 /// Close down the client view
509 /// </summary>
490 public void Close() 510 public void Close()
491 { 511 {
492 Close(false); 512 Close(true, false);
493 } 513 }
494 514
495 public void Close(bool force) 515 public void Close(bool sendStop, bool force)
496 { 516 {
497 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 517 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
498 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 518 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -504,7 +524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 return; 524 return;
505 525
506 IsActive = false; 526 IsActive = false;
507 CloseWithoutChecks(); 527 CloseWithoutChecks(sendStop);
508 } 528 }
509 } 529 }
510 530
@@ -517,12 +537,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
517 /// 537 ///
518 /// Callers must lock ClosingSyncLock before calling. 538 /// Callers must lock ClosingSyncLock before calling.
519 /// </remarks> 539 /// </remarks>
520 public void CloseWithoutChecks() 540 public void CloseWithoutChecks(bool sendStop)
521 { 541 {
522 m_log.DebugFormat( 542 m_log.DebugFormat(
523 "[CLIENT]: Close has been called for {0} attached to scene {1}", 543 "[CLIENT]: Close has been called for {0} attached to scene {1}",
524 Name, m_scene.RegionInfo.RegionName); 544 Name, m_scene.RegionInfo.RegionName);
525 545
546 if (sendStop)
547 {
548 // Send the STOP packet
549 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
550 OutPacket(disable, ThrottleOutPacketType.Unknown);
551 }
552
526 // Shutdown the image manager 553 // Shutdown the image manager
527 ImageManager.Close(); 554 ImageManager.Close();
528 555
@@ -780,7 +807,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
780 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 807 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
781 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 808 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
782 809
783 OutPacket(handshake, ThrottleOutPacketType.Task); 810// OutPacket(handshake, ThrottleOutPacketType.Task);
811 // use same as MoveAgentIntoRegion (both should be task )
812 OutPacket(handshake, ThrottleOutPacketType.Unknown);
784 } 813 }
785 814
786 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 815 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -819,7 +848,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
819 reply.ChatData.OwnerID = fromAgentID; 848 reply.ChatData.OwnerID = fromAgentID;
820 reply.ChatData.SourceID = fromAgentID; 849 reply.ChatData.SourceID = fromAgentID;
821 850
822 OutPacket(reply, ThrottleOutPacketType.Task); 851 OutPacket(reply, ThrottleOutPacketType.Unknown);
823 } 852 }
824 853
825 /// <summary> 854 /// <summary>
@@ -1105,6 +1134,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1105 public virtual void SendLayerData(float[] map) 1134 public virtual void SendLayerData(float[] map)
1106 { 1135 {
1107 Util.FireAndForget(DoSendLayerData, map); 1136 Util.FireAndForget(DoSendLayerData, map);
1137
1138 // Send it sync, and async. It's not that much data
1139 // and it improves user experience just so much!
1140 DoSendLayerData(map);
1108 } 1141 }
1109 1142
1110 /// <summary> 1143 /// <summary>
@@ -1117,16 +1150,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 1150
1118 try 1151 try
1119 { 1152 {
1120 //for (int y = 0; y < 16; y++) 1153 for (int y = 0; y < 16; y++)
1121 //{ 1154 {
1122 // for (int x = 0; x < 16; x++) 1155 for (int x = 0; x < 16; x+=4)
1123 // { 1156 {
1124 // SendLayerData(x, y, map); 1157 SendLayerPacket(x, y, map);
1125 // } 1158 }
1126 //} 1159 }
1127
1128 // Send LayerData in a spiral pattern. Fun!
1129 SendLayerTopRight(map, 0, 0, 15, 15);
1130 } 1160 }
1131 catch (Exception e) 1161 catch (Exception e)
1132 { 1162 {
@@ -1134,51 +1164,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1134 } 1164 }
1135 } 1165 }
1136 1166
1137 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1138 {
1139 // Row
1140 for (int i = x1; i <= x2; i++)
1141 SendLayerData(i, y1, map);
1142
1143 // Column
1144 for (int j = y1 + 1; j <= y2; j++)
1145 SendLayerData(x2, j, map);
1146
1147 if (x2 - x1 > 0)
1148 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1149 }
1150
1151 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1152 {
1153 // Row in reverse
1154 for (int i = x2; i >= x1; i--)
1155 SendLayerData(i, y2, map);
1156
1157 // Column in reverse
1158 for (int j = y2 - 1; j >= y1; j--)
1159 SendLayerData(x1, j, map);
1160
1161 if (x2 - x1 > 0)
1162 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1163 }
1164
1165 /// <summary> 1167 /// <summary>
1166 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1168 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1167 /// </summary> 1169 /// </summary>
1168 /// <param name="map">heightmap</param> 1170 /// <param name="map">heightmap</param>
1169 /// <param name="px">X coordinate for patches 0..12</param> 1171 /// <param name="px">X coordinate for patches 0..12</param>
1170 /// <param name="py">Y coordinate for patches 0..15</param> 1172 /// <param name="py">Y coordinate for patches 0..15</param>
1171 // private void SendLayerPacket(float[] map, int y, int x) 1173 private void SendLayerPacket(int x, int y, float[] map)
1172 // { 1174 {
1173 // int[] patches = new int[4]; 1175 int[] patches = new int[4];
1174 // patches[0] = x + 0 + y * 16; 1176 patches[0] = x + 0 + y * 16;
1175 // patches[1] = x + 1 + y * 16; 1177 patches[1] = x + 1 + y * 16;
1176 // patches[2] = x + 2 + y * 16; 1178 patches[2] = x + 2 + y * 16;
1177 // patches[3] = x + 3 + y * 16; 1179 patches[3] = x + 3 + y * 16;
1178 1180
1179 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1181 float[] heightmap = (map.Length == 65536) ?
1180 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1182 map :
1181 // } 1183 LLHeightFieldMoronize(map);
1184
1185 try
1186 {
1187 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1188 OutPacket(layerpack, ThrottleOutPacketType.Land);
1189 }
1190 catch
1191 {
1192 for (int px = x ; px < x + 4 ; px++)
1193 SendLayerData(px, y, map);
1194 }
1195 }
1182 1196
1183 /// <summary> 1197 /// <summary>
1184 /// Sends a specified patch to a client 1198 /// Sends a specified patch to a client
@@ -1198,7 +1212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1198 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1212 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1199 layerpack.Header.Reliable = true; 1213 layerpack.Header.Reliable = true;
1200 1214
1201 OutPacket(layerpack, ThrottleOutPacketType.Land); 1215 OutPacket(layerpack, ThrottleOutPacketType.Task);
1202 } 1216 }
1203 catch (Exception e) 1217 catch (Exception e)
1204 { 1218 {
@@ -1561,7 +1575,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1561 1575
1562 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1576 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1563 { 1577 {
1564// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1578// foreach (uint id in localIDs)
1579// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1565 1580
1566 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1581 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1567 // TODO: don't create new blocks if recycling an old packet 1582 // TODO: don't create new blocks if recycling an old packet
@@ -1583,17 +1598,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1583 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1598 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1584 // condition where a kill can be processed before an out-of-date update for the same object. 1599 // condition where a kill can be processed before an out-of-date update for the same object.
1585 // ProcessEntityUpdates() also takes the m_killRecord lock. 1600 // ProcessEntityUpdates() also takes the m_killRecord lock.
1586 lock (m_killRecord) 1601// lock (m_killRecord)
1587 { 1602// {
1588 foreach (uint localID in localIDs) 1603// foreach (uint localID in localIDs)
1589 m_killRecord.Add(localID); 1604// m_killRecord.Add(localID);
1590 1605
1591 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1606 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1592 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1607 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1593 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1608 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1594 // scene objects in a viewer until that viewer is relogged in. 1609 // scene objects in a viewer until that viewer is relogged in.
1595 OutPacket(kill, ThrottleOutPacketType.Task); 1610 OutPacket(kill, ThrottleOutPacketType.Task);
1596 } 1611// }
1597 } 1612 }
1598 } 1613 }
1599 1614
@@ -2051,9 +2066,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2051 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2066 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2052 } 2067 }
2053 2068
2054 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2055 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2069 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2056 { 2070 {
2071 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2072 }
2073
2074 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2075 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2076 {
2057 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2077 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2058 2078
2059 UpdateCreateInventoryItemPacket InventoryReply 2079 UpdateCreateInventoryItemPacket InventoryReply
@@ -2063,6 +2083,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 // TODO: don't create new blocks if recycling an old packet 2083 // TODO: don't create new blocks if recycling an old packet
2064 InventoryReply.AgentData.AgentID = AgentId; 2084 InventoryReply.AgentData.AgentID = AgentId;
2065 InventoryReply.AgentData.SimApproved = true; 2085 InventoryReply.AgentData.SimApproved = true;
2086 InventoryReply.AgentData.TransactionID = transactionID;
2066 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2087 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2067 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2088 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2068 InventoryReply.InventoryData[0].ItemID = Item.ID; 2089 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2132,16 +2153,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2132 replytask.InventoryData.TaskID = taskID; 2153 replytask.InventoryData.TaskID = taskID;
2133 replytask.InventoryData.Serial = serial; 2154 replytask.InventoryData.Serial = serial;
2134 replytask.InventoryData.Filename = fileName; 2155 replytask.InventoryData.Filename = fileName;
2135 OutPacket(replytask, ThrottleOutPacketType.Asset); 2156 OutPacket(replytask, ThrottleOutPacketType.Task);
2136 } 2157 }
2137 2158
2138 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2159 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2139 { 2160 {
2161 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2162 if (isTaskInventory)
2163 type = ThrottleOutPacketType.Task;
2164
2140 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2165 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2141 sendXfer.XferID.ID = xferID; 2166 sendXfer.XferID.ID = xferID;
2142 sendXfer.XferID.Packet = packet; 2167 sendXfer.XferID.Packet = packet;
2143 sendXfer.DataPacket.Data = data; 2168 sendXfer.DataPacket.Data = data;
2144 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2169 OutPacket(sendXfer, type);
2145 } 2170 }
2146 2171
2147 public void SendAbortXferPacket(ulong xferID) 2172 public void SendAbortXferPacket(ulong xferID)
@@ -2323,6 +2348,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2323 OutPacket(sound, ThrottleOutPacketType.Task); 2348 OutPacket(sound, ThrottleOutPacketType.Task);
2324 } 2349 }
2325 2350
2351 public void SendTransferAbort(TransferRequestPacket transferRequest)
2352 {
2353 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2354 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2355 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2356 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2357 OutPacket(abort, ThrottleOutPacketType.Task);
2358 }
2359
2326 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2360 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2327 { 2361 {
2328 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2362 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2615,6 +2649,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2615 } 2649 }
2616 } 2650 }
2617 2651
2652 public void SendPartPhysicsProprieties(ISceneEntity entity)
2653 {
2654 SceneObjectPart part = (SceneObjectPart)entity;
2655 if (part != null && AgentId != UUID.Zero)
2656 {
2657 try
2658 {
2659 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2660 if (eq != null)
2661 {
2662 uint localid = part.LocalId;
2663 byte physshapetype = part.PhysicsShapeType;
2664 float density = part.Density;
2665 float friction = part.Friction;
2666 float bounce = part.Bounciness;
2667 float gravmod = part.GravityModifier;
2668
2669 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2670 }
2671 }
2672 catch (Exception ex)
2673 {
2674 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2675 }
2676 part.UpdatePhysRequired = false;
2677 }
2678 }
2679
2680
2618 2681
2619 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2682 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2620 { 2683 {
@@ -2712,7 +2775,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2712 else 2775 else
2713 { 2776 {
2714 int processedLength = 0; 2777 int processedLength = 0;
2715 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2778// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2779
2780 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2716 int packetNumber = 0; 2781 int packetNumber = 0;
2717 2782
2718 while (processedLength < req.AssetInf.Data.Length) 2783 while (processedLength < req.AssetInf.Data.Length)
@@ -2783,7 +2848,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2783 reply.Data.ParcelID = parcelID; 2848 reply.Data.ParcelID = parcelID;
2784 reply.Data.OwnerID = land.OwnerID; 2849 reply.Data.OwnerID = land.OwnerID;
2785 reply.Data.Name = Utils.StringToBytes(land.Name); 2850 reply.Data.Name = Utils.StringToBytes(land.Name);
2786 reply.Data.Desc = Utils.StringToBytes(land.Description); 2851 if (land != null && land.Description != null && land.Description != String.Empty)
2852 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2853 else
2854 reply.Data.Desc = new Byte[0];
2787 reply.Data.ActualArea = land.Area; 2855 reply.Data.ActualArea = land.Area;
2788 reply.Data.BillableArea = land.Area; // TODO: what is this? 2856 reply.Data.BillableArea = land.Area; // TODO: what is this?
2789 2857
@@ -3518,7 +3586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3518 3586
3519 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3587 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3520 // TODO: don't create new blocks if recycling an old packet 3588 // TODO: don't create new blocks if recycling an old packet
3521 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3589 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3522 avp.ObjectData.TextureEntry = textureEntry; 3590 avp.ObjectData.TextureEntry = textureEntry;
3523 3591
3524 AvatarAppearancePacket.VisualParamBlock avblock = null; 3592 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3648,7 +3716,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3648 /// </summary> 3716 /// </summary>
3649 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3717 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3650 { 3718 {
3651 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3719 if (entity is SceneObjectPart)
3720 {
3721 SceneObjectPart e = (SceneObjectPart)entity;
3722 SceneObjectGroup g = e.ParentGroup;
3723 if (g.RootPart.Shape.State > 30) // HUD
3724 if (g.OwnerID != AgentId)
3725 return; // Don't send updates for other people's HUDs
3726 }
3727
3652 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3728 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3653 3729
3654 lock (m_entityUpdates.SyncRoot) 3730 lock (m_entityUpdates.SyncRoot)
@@ -3715,27 +3791,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3715 3791
3716 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3792 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3717 // condition where a kill can be processed before an out-of-date update for the same object. 3793 // condition where a kill can be processed before an out-of-date update for the same object.
3718 lock (m_killRecord) 3794 float avgTimeDilation = 1.0f;
3795 IEntityUpdate iupdate;
3796 Int32 timeinqueue; // this is just debugging code & can be dropped later
3797
3798 while (updatesThisCall < maxUpdates)
3719 { 3799 {
3720 float avgTimeDilation = 1.0f; 3800 lock (m_entityUpdates.SyncRoot)
3721 IEntityUpdate iupdate; 3801 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3722 Int32 timeinqueue; // this is just debugging code & can be dropped later 3802 break;
3803
3804 EntityUpdate update = (EntityUpdate)iupdate;
3805
3806 avgTimeDilation += update.TimeDilation;
3807 avgTimeDilation *= 0.5f;
3723 3808
3724 while (updatesThisCall < maxUpdates) 3809 if (update.Entity is SceneObjectPart)
3725 { 3810 {
3726 lock (m_entityUpdates.SyncRoot) 3811 SceneObjectPart part = (SceneObjectPart)update.Entity;
3727 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3728 break;
3729 3812
3730 EntityUpdate update = (EntityUpdate)iupdate; 3813 if (part.ParentGroup.IsDeleted)
3731 3814 continue;
3732 avgTimeDilation += update.TimeDilation;
3733 avgTimeDilation *= 0.5f;
3734 3815
3735 if (update.Entity is SceneObjectPart) 3816 if (part.ParentGroup.IsAttachment)
3817 { // Someone else's HUD, why are we getting these?
3818 if (part.ParentGroup.OwnerID != AgentId &&
3819 part.ParentGroup.RootPart.Shape.State > 30)
3820 continue;
3821 ScenePresence sp;
3822 // Owner is not in the sim, don't update it to
3823 // anyone
3824 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3825 continue;
3826
3827 List<SceneObjectGroup> atts = sp.GetAttachments();
3828 bool found = false;
3829 foreach (SceneObjectGroup att in atts)
3830 {
3831 if (att == part.ParentGroup)
3832 {
3833 found = true;
3834 break;
3835 }
3836 }
3837
3838 // It's an attachment of a valid avatar, but
3839 // doesn't seem to be attached, skip
3840 if (!found)
3841 continue;
3842
3843 // On vehicle crossing, the attachments are received
3844 // while the avatar is still a child. Don't send
3845 // updates here because the LocalId has not yet
3846 // been updated and the viewer will derender the
3847 // attachments until the avatar becomes root.
3848 if (sp.IsChildAgent)
3849 continue;
3850
3851 // If the object is an attachment we don't want it to be in the kill
3852 // record. Else attaching from inworld and subsequently dropping
3853 // it will no longer work.
3854// lock (m_killRecord)
3855// {
3856// m_killRecord.Remove(part.LocalId);
3857// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3858// }
3859 }
3860 else
3736 { 3861 {
3737 SceneObjectPart part = (SceneObjectPart)update.Entity;
3738
3739 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3862 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3740 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3863 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3741 // safety measure. 3864 // safety measure.
@@ -3746,236 +3869,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3746 // 3869 //
3747 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3870 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3748 // after the root prim has been deleted. 3871 // after the root prim has been deleted.
3749 if (m_killRecord.Contains(part.LocalId)) 3872 //
3750 { 3873 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3751 // m_log.WarnFormat( 3874// lock (m_killRecord)
3752 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3875// {
3753 // part.LocalId, Name); 3876// if (m_killRecord.Contains(part.LocalId))
3754 continue; 3877// continue;
3755 } 3878// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3756 3879// continue;
3757 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3880// }
3881 }
3882
3883 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3884 {
3885 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3886 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3758 { 3887 {
3759 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3888 part.Shape.LightEntry = false;
3760 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3761 {
3762 part.Shape.LightEntry = false;
3763 }
3764 } 3889 }
3765 } 3890 }
3766 3891 }
3767 #region UpdateFlags to packet type conversion 3892
3768 3893 ++updatesThisCall;
3769 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3894
3770 3895 #region UpdateFlags to packet type conversion
3771 bool canUseCompressed = true; 3896
3772 bool canUseImproved = true; 3897 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3773 3898
3774 // Compressed object updates only make sense for LL primitives 3899 bool canUseCompressed = true;
3775 if (!(update.Entity is SceneObjectPart)) 3900 bool canUseImproved = true;
3901
3902 // Compressed object updates only make sense for LL primitives
3903 if (!(update.Entity is SceneObjectPart))
3904 {
3905 canUseCompressed = false;
3906 }
3907
3908 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3909 {
3910 canUseCompressed = false;
3911 canUseImproved = false;
3912 }
3913 else
3914 {
3915 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3916 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3917 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3918 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3776 { 3919 {
3777 canUseCompressed = false; 3920 canUseCompressed = false;
3778 } 3921 }
3779 3922
3780 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3923 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3924 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3925 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3926 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3927 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3928 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3929 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3930 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3932 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3933 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3934 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3935 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3936 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3781 { 3937 {
3782 canUseCompressed = false;
3783 canUseImproved = false; 3938 canUseImproved = false;
3784 } 3939 }
3785 else 3940 }
3786 {
3787 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3788 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3789 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3790 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3791 {
3792 canUseCompressed = false;
3793 }
3794
3795 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3796 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3797 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3798 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3809 {
3810 canUseImproved = false;
3811 }
3812 }
3813
3814 #endregion UpdateFlags to packet type conversion
3815
3816 #region Block Construction
3817
3818 // TODO: Remove this once we can build compressed updates
3819 canUseCompressed = false;
3820 3941
3821 if (!canUseImproved && !canUseCompressed) 3942 #endregion UpdateFlags to packet type conversion
3822 {
3823 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3824 3943
3825 if (update.Entity is ScenePresence) 3944 #region Block Construction
3826 {
3827 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3828 }
3829 else
3830 {
3831 SceneObjectPart part = (SceneObjectPart)update.Entity;
3832 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3833
3834 // If the part has become a private hud since the update was scheduled then we do not
3835 // want to send it to other avatars.
3836 if (part.ParentGroup.IsAttachment
3837 && part.ParentGroup.HasPrivateAttachmentPoint
3838 && part.ParentGroup.AttachedAvatar != AgentId)
3839 continue;
3840
3841 // If the part has since been deleted, then drop the update. In the case of attachments,
3842 // this is to avoid spurious updates to other viewers since post-processing of attachments
3843 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3844 // of the test above).
3845 //
3846 // Actual deletions (kills) happen in another method.
3847 if (part.ParentGroup.IsDeleted)
3848 continue;
3849 }
3850 3945
3851 objectUpdateBlocks.Value.Add(updateBlock); 3946 // TODO: Remove this once we can build compressed updates
3852 objectUpdates.Value.Add(update); 3947 canUseCompressed = false;
3853 }
3854 else if (!canUseImproved)
3855 {
3856 SceneObjectPart part = (SceneObjectPart)update.Entity;
3857 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3858 = CreateCompressedUpdateBlock(part, updateFlags);
3859
3860 // If the part has since been deleted, then drop the update. In the case of attachments,
3861 // this is to avoid spurious updates to other viewers since post-processing of attachments
3862 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3863 // of the test above).
3864 //
3865 // Actual deletions (kills) happen in another method.
3866 if (part.ParentGroup.IsDeleted)
3867 continue;
3868 3948
3869 compressedUpdateBlocks.Value.Add(compressedBlock); 3949 if (!canUseImproved && !canUseCompressed)
3870 compressedUpdates.Value.Add(update); 3950 {
3951 if (update.Entity is ScenePresence)
3952 {
3953 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3871 } 3954 }
3872 else 3955 else
3873 { 3956 {
3874 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3957 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3875 {
3876 // Self updates go into a special list
3877 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 terseAgentUpdates.Value.Add(update);
3879 }
3880 else
3881 {
3882 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3883 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3884
3885 // Everything else goes here
3886 if (update.Entity is SceneObjectPart)
3887 {
3888 SceneObjectPart part = (SceneObjectPart)update.Entity;
3889
3890 // If the part has become a private hud since the update was scheduled then we do not
3891 // want to send it to other avatars.
3892 if (part.ParentGroup.IsAttachment
3893 && part.ParentGroup.HasPrivateAttachmentPoint
3894 && part.ParentGroup.AttachedAvatar != AgentId)
3895 continue;
3896
3897 // If the part has since been deleted, then drop the update. In the case of attachments,
3898 // this is to avoid spurious updates to other viewers since post-processing of attachments
3899 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3900 // of the test above).
3901 //
3902 // Actual deletions (kills) happen in another method.
3903 if (part.ParentGroup.IsDeleted)
3904 continue;
3905 }
3906
3907 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3908 terseUpdates.Value.Add(update);
3909 }
3910 } 3958 }
3959 }
3960 else if (!canUseImproved)
3961 {
3962 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3963 }
3964 else
3965 {
3966 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3967 // Self updates go into a special list
3968 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3969 else
3970 // Everything else goes here
3971 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3972 }
3973
3974 #endregion Block Construction
3975 }
3911 3976
3912 ++updatesThisCall; 3977 #region Packet Sending
3913 3978
3914 #endregion Block Construction 3979 const float TIME_DILATION = 1.0f;
3915 } 3980 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3916 3981
3917 #region Packet Sending 3982 if (terseAgentUpdateBlocks.IsValueCreated)
3918 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3983 {
3984 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3919 3985
3920 if (terseAgentUpdateBlocks.IsValueCreated) 3986 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3921 { 3987 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3922 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3988 packet.RegionData.TimeDilation = timeDilation;
3989 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3923 3990
3924 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3991 for (int i = 0; i < blocks.Count; i++)
3925 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3992 packet.ObjectData[i] = blocks[i];
3926 packet.RegionData.TimeDilation = timeDilation;
3927 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3928 3993
3929 for (int i = 0; i < blocks.Count; i++) 3994 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3930 packet.ObjectData[i] = blocks[i]; 3995 }
3931 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3932 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3933 }
3934 3996
3935 if (objectUpdateBlocks.IsValueCreated) 3997 if (objectUpdateBlocks.IsValueCreated)
3936 { 3998 {
3937 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3999 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3938 4000
3939 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 4001 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3940 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4002 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3941 packet.RegionData.TimeDilation = timeDilation; 4003 packet.RegionData.TimeDilation = timeDilation;
3942 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4004 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3943 4005
3944 for (int i = 0; i < blocks.Count; i++) 4006 for (int i = 0; i < blocks.Count; i++)
3945 packet.ObjectData[i] = blocks[i]; 4007 packet.ObjectData[i] = blocks[i];
3946 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4008
3947 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 4009 OutPacket(packet, ThrottleOutPacketType.Task, true);
3948 } 4010 }
3949 4011
3950 if (compressedUpdateBlocks.IsValueCreated) 4012 if (compressedUpdateBlocks.IsValueCreated)
3951 { 4013 {
3952 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 4014 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3953 4015
3954 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 4016 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3955 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4017 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3956 packet.RegionData.TimeDilation = timeDilation; 4018 packet.RegionData.TimeDilation = timeDilation;
3957 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 4019 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3958
3959 for (int i = 0; i < blocks.Count; i++)
3960 packet.ObjectData[i] = blocks[i];
3961 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3962 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3963 }
3964 4020
3965 if (terseUpdateBlocks.IsValueCreated) 4021 for (int i = 0; i < blocks.Count; i++)
3966 { 4022 packet.ObjectData[i] = blocks[i];
3967 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 4023
3968 4024 OutPacket(packet, ThrottleOutPacketType.Task, true);
3969 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 4025 }
3970 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4026
3971 packet.RegionData.TimeDilation = timeDilation; 4027 if (terseUpdateBlocks.IsValueCreated)
3972 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4028 {
3973 4029 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3974 for (int i = 0; i < blocks.Count; i++) 4030
3975 packet.ObjectData[i] = blocks[i]; 4031 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3976 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4032 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3977 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4033 packet.RegionData.TimeDilation = timeDilation;
3978 } 4034 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4035
4036 for (int i = 0; i < blocks.Count; i++)
4037 packet.ObjectData[i] = blocks[i];
4038
4039 OutPacket(packet, ThrottleOutPacketType.Task, true);
3979 } 4040 }
3980 4041
3981 #endregion Packet Sending 4042 #endregion Packet Sending
@@ -4268,11 +4329,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4268 4329
4269 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4330 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4270 // of the object rather than the properties when the packet was created 4331 // of the object rather than the properties when the packet was created
4271 OutPacket(packet, ThrottleOutPacketType.Task, true, 4332 // HACK : Remove intelligent resending until it's fixed in core
4272 delegate(OutgoingPacket oPacket) 4333 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4273 { 4334 // delegate(OutgoingPacket oPacket)
4274 ResendPropertyUpdates(updates, oPacket); 4335 // {
4275 }); 4336 // ResendPropertyUpdates(updates, oPacket);
4337 // });
4338 OutPacket(packet, ThrottleOutPacketType.Task, true);
4276 4339
4277 // pbcnt += blocks.Count; 4340 // pbcnt += blocks.Count;
4278 // ppcnt++; 4341 // ppcnt++;
@@ -4298,11 +4361,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4298 // of the object rather than the properties when the packet was created 4361 // of the object rather than the properties when the packet was created
4299 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4362 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4300 updates.Add(familyUpdates.Value[i]); 4363 updates.Add(familyUpdates.Value[i]);
4301 OutPacket(packet, ThrottleOutPacketType.Task, true, 4364 // HACK : Remove intelligent resending until it's fixed in core
4302 delegate(OutgoingPacket oPacket) 4365 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4303 { 4366 // delegate(OutgoingPacket oPacket)
4304 ResendPropertyUpdates(updates, oPacket); 4367 // {
4305 }); 4368 // ResendPropertyUpdates(updates, oPacket);
4369 // });
4370 OutPacket(packet, ThrottleOutPacketType.Task, true);
4306 4371
4307 // fpcnt++; 4372 // fpcnt++;
4308 // fbcnt++; 4373 // fbcnt++;
@@ -4674,7 +4739,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4674 4739
4675 if (landData.SimwideArea > 0) 4740 if (landData.SimwideArea > 0)
4676 { 4741 {
4677 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4742 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4743 // Never report more than sim total capacity
4744 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4745 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4678 updateMessage.SimWideMaxPrims = simulatorCapacity; 4746 updateMessage.SimWideMaxPrims = simulatorCapacity;
4679 } 4747 }
4680 else 4748 else
@@ -4803,14 +4871,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4803 4871
4804 if (notifyCount > 0) 4872 if (notifyCount > 0)
4805 { 4873 {
4806 if (notifyCount > 32) 4874// if (notifyCount > 32)
4807 { 4875// {
4808 m_log.InfoFormat( 4876// m_log.InfoFormat(
4809 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4877// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4810 + " - a developer might want to investigate whether this is a hard limit", 32); 4878// + " - a developer might want to investigate whether this is a hard limit", 32);
4811 4879//
4812 notifyCount = 32; 4880// notifyCount = 32;
4813 } 4881// }
4814 4882
4815 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4883 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4816 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4884 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4865,9 +4933,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4865 { 4933 {
4866 ScenePresence presence = (ScenePresence)entity; 4934 ScenePresence presence = (ScenePresence)entity;
4867 4935
4936 position = presence.OffsetPosition;
4937 rotation = presence.Rotation;
4938
4939 if (presence.ParentID != 0)
4940 {
4941 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4942 if (part != null && part != part.ParentGroup.RootPart)
4943 {
4944 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4945 rotation = part.RotationOffset * presence.Rotation;
4946 }
4947 }
4948
4868 attachPoint = 0; 4949 attachPoint = 0;
4869 collisionPlane = presence.CollisionPlane; 4950 collisionPlane = presence.CollisionPlane;
4870 position = presence.OffsetPosition;
4871 velocity = presence.Velocity; 4951 velocity = presence.Velocity;
4872 acceleration = Vector3.Zero; 4952 acceleration = Vector3.Zero;
4873 4953
@@ -4877,7 +4957,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4877// acceleration = new Vector3(1, 0, 0); 4957// acceleration = new Vector3(1, 0, 0);
4878 4958
4879 angularVelocity = Vector3.Zero; 4959 angularVelocity = Vector3.Zero;
4880 rotation = presence.Rotation;
4881 4960
4882 if (sendTexture) 4961 if (sendTexture)
4883 textureEntry = presence.Appearance.Texture.GetBytes(); 4962 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4982,13 +5061,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4982 5061
4983 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5062 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4984 { 5063 {
5064 Vector3 offsetPosition = data.OffsetPosition;
5065 Quaternion rotation = data.Rotation;
5066 uint parentID = data.ParentID;
5067
5068 if (parentID != 0)
5069 {
5070 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5071 if (part != null && part != part.ParentGroup.RootPart)
5072 {
5073 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5074 rotation = part.RotationOffset * data.Rotation;
5075 parentID = part.ParentGroup.RootPart.LocalId;
5076 }
5077 }
5078
4985 byte[] objectData = new byte[76]; 5079 byte[] objectData = new byte[76];
4986 5080
4987 data.CollisionPlane.ToBytes(objectData, 0); 5081 data.CollisionPlane.ToBytes(objectData, 0);
4988 data.OffsetPosition.ToBytes(objectData, 16); 5082 offsetPosition.ToBytes(objectData, 16);
4989// data.Velocity.ToBytes(objectData, 28); 5083// data.Velocity.ToBytes(objectData, 28);
4990// data.Acceleration.ToBytes(objectData, 40); 5084// data.Acceleration.ToBytes(objectData, 40);
4991 data.Rotation.ToBytes(objectData, 52); 5085 rotation.ToBytes(objectData, 52);
4992 //data.AngularVelocity.ToBytes(objectData, 64); 5086 //data.AngularVelocity.ToBytes(objectData, 64);
4993 5087
4994 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5088 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5002,7 +5096,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5002 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5096 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5003 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5097 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5004 update.ObjectData = objectData; 5098 update.ObjectData = objectData;
5005 update.ParentID = data.ParentID; 5099 update.ParentID = parentID;
5006 update.PathCurve = 16; 5100 update.PathCurve = 16;
5007 update.PathScaleX = 100; 5101 update.PathScaleX = 100;
5008 update.PathScaleY = 100; 5102 update.PathScaleY = 100;
@@ -5020,10 +5114,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5020 update.TextureEntry = Utils.EmptyBytes; 5114 update.TextureEntry = Utils.EmptyBytes;
5021// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5115// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5022 5116
5117/* 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)
5023 update.UpdateFlags = (uint)( 5118 update.UpdateFlags = (uint)(
5024 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5119 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5025 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5120 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5026 PrimFlags.ObjectOwnerModify); 5121 PrimFlags.ObjectOwnerModify);
5122*/
5123 update.UpdateFlags = 0;
5027 5124
5028 return update; 5125 return update;
5029 } 5126 }
@@ -5343,6 +5440,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5343 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5440 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5344 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5441 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5345 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5442 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5443 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5346 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5444 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5347 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5445 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5348 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5446 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5409,6 +5507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5409 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5507 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5410 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5508 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5411 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5509 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5510 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5412 5511
5413 AddGenericPacketHandler("autopilot", HandleAutopilot); 5512 AddGenericPacketHandler("autopilot", HandleAutopilot);
5414 } 5513 }
@@ -5444,6 +5543,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5444 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5543 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5445 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5544 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5446 (x.ControlFlags != lastarg.ControlFlags) || 5545 (x.ControlFlags != lastarg.ControlFlags) ||
5546 (x.ControlFlags != 0) ||
5447 (x.Far != lastarg.Far) || 5547 (x.Far != lastarg.Far) ||
5448 (x.Flags != lastarg.Flags) || 5548 (x.Flags != lastarg.Flags) ||
5449 (x.State != lastarg.State) || 5549 (x.State != lastarg.State) ||
@@ -6341,6 +6441,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6341 { 6441 {
6342 handlerCompleteMovementToRegion(sender, true); 6442 handlerCompleteMovementToRegion(sender, true);
6343 } 6443 }
6444 else
6445 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6446
6344 handlerCompleteMovementToRegion = null; 6447 handlerCompleteMovementToRegion = null;
6345 6448
6346 return true; 6449 return true;
@@ -6358,7 +6461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6358 return true; 6461 return true;
6359 } 6462 }
6360 #endregion 6463 #endregion
6361 6464/*
6362 StartAnim handlerStartAnim = null; 6465 StartAnim handlerStartAnim = null;
6363 StopAnim handlerStopAnim = null; 6466 StopAnim handlerStopAnim = null;
6364 6467
@@ -6382,6 +6485,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6382 } 6485 }
6383 } 6486 }
6384 return true; 6487 return true;
6488*/
6489 ChangeAnim handlerChangeAnim = null;
6490
6491 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6492 {
6493 handlerChangeAnim = OnChangeAnim;
6494 if (handlerChangeAnim != null)
6495 {
6496 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6497 }
6498 }
6499
6500 handlerChangeAnim = OnChangeAnim;
6501 if (handlerChangeAnim != null)
6502 {
6503 handlerChangeAnim(UUID.Zero, false, true);
6504 }
6505
6506 return true;
6385 } 6507 }
6386 6508
6387 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6509 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -7007,10 +7129,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7007 // 46,47,48 are special positions within the packet 7129 // 46,47,48 are special positions within the packet
7008 // This may change so perhaps we need a better way 7130 // This may change so perhaps we need a better way
7009 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7131 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7010 bool UsePhysics = (data[46] != 0) ? true : false; 7132 /*
7011 bool IsTemporary = (data[47] != 0) ? true : false; 7133 bool UsePhysics = (data[46] != 0) ? true : false;
7012 bool IsPhantom = (data[48] != 0) ? true : false; 7134 bool IsTemporary = (data[47] != 0) ? true : false;
7013 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7135 bool IsPhantom = (data[48] != 0) ? true : false;
7136 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7137 */
7138 bool UsePhysics = flags.AgentData.UsePhysics;
7139 bool IsPhantom = flags.AgentData.IsPhantom;
7140 bool IsTemporary = flags.AgentData.IsTemporary;
7141 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7142 ExtraPhysicsData physdata = new ExtraPhysicsData();
7143
7144 if (blocks == null || blocks.Length == 0)
7145 {
7146 physdata.PhysShapeType = PhysShapeType.invalid;
7147 }
7148 else
7149 {
7150 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7151 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7152 physdata.Bounce = phsblock.Restitution;
7153 physdata.Density = phsblock.Density;
7154 physdata.Friction = phsblock.Friction;
7155 physdata.GravitationModifier = phsblock.GravityMultiplier;
7156 }
7157
7158 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7014 } 7159 }
7015 return true; 7160 return true;
7016 } 7161 }
@@ -8611,16 +8756,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8611 8756
8612 #region Parcel related packets 8757 #region Parcel related packets
8613 8758
8759 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8760 // to be done with minimal resources as possible
8761 // variables temporary here while in test
8762
8763 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8764 bool RegionHandleRequestsInService = false;
8765
8614 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8766 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8615 { 8767 {
8616 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8768 UUID currentUUID;
8617 8769
8618 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8770 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8619 if (handlerRegionHandleRequest != null) 8771
8772 if (handlerRegionHandleRequest == null)
8773 return true;
8774
8775 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8776
8777 lock (RegionHandleRequests)
8620 { 8778 {
8621 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8779 if (RegionHandleRequestsInService)
8780 {
8781 // we are already busy doing a previus request
8782 // so enqueue it
8783 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8784 return true;
8785 }
8786
8787 // else do it
8788 currentUUID = rhrPack.RequestBlock.RegionID;
8789 RegionHandleRequestsInService = true;
8622 } 8790 }
8623 return true; 8791
8792 while (true)
8793 {
8794 handlerRegionHandleRequest(this, currentUUID);
8795
8796 lock (RegionHandleRequests)
8797 {
8798 // exit condition, nothing to do or closed
8799 // current code seems to assume we may loose the handler at anytime,
8800 // so keep checking it
8801 handlerRegionHandleRequest = OnRegionHandleRequest;
8802
8803 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8804 {
8805 RegionHandleRequests.Clear();
8806 RegionHandleRequestsInService = false;
8807 return true;
8808 }
8809 currentUUID = RegionHandleRequests.Dequeue();
8810 }
8811 }
8812
8813 return true; // actually unreached
8624 } 8814 }
8625 8815
8626 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8816 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9864,7 +10054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9864 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10054 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9865 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10055 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9866 UpdateMuteListEntry.MuteData.MuteType, 10056 UpdateMuteListEntry.MuteData.MuteType,
9867 UpdateMuteListEntry.AgentData.AgentID); 10057 UpdateMuteListEntry.MuteData.MuteFlags);
9868 return true; 10058 return true;
9869 } 10059 }
9870 return false; 10060 return false;
@@ -9879,8 +10069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9879 { 10069 {
9880 handlerRemoveMuteListEntry(this, 10070 handlerRemoveMuteListEntry(this,
9881 RemoveMuteListEntry.MuteData.MuteID, 10071 RemoveMuteListEntry.MuteData.MuteID,
9882 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10072 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9883 RemoveMuteListEntry.AgentData.AgentID);
9884 return true; 10073 return true;
9885 } 10074 }
9886 return false; 10075 return false;
@@ -9924,10 +10113,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9924 return false; 10113 return false;
9925 } 10114 }
9926 10115
10116 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10117 {
10118 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10119 (ChangeInventoryItemFlagsPacket)packet;
10120 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10121 if (handlerChangeInventoryItemFlags != null)
10122 {
10123 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10124 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10125 return true;
10126 }
10127 return false;
10128 }
10129
9927 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10130 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9928 { 10131 {
9929 return true; 10132 return true;
9930 } 10133 }
10134
10135 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10136 {
10137 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10138
10139 #region Packet Session and User Check
10140 if (m_checkPackets)
10141 {
10142 if (packet.AgentData.SessionID != SessionId ||
10143 packet.AgentData.AgentID != AgentId)
10144 return true;
10145 }
10146 #endregion
10147 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10148 List<InventoryItemBase> items = new List<InventoryItemBase>();
10149 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10150 {
10151 InventoryItemBase b = new InventoryItemBase();
10152 b.ID = n.OldItemID;
10153 b.Folder = n.OldFolderID;
10154 items.Add(b);
10155 }
10156
10157 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10158 if (handlerMoveItemsAndLeaveCopy != null)
10159 {
10160 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10161 }
10162
10163 return true;
10164 }
9931 10165
9932 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10166 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9933 { 10167 {
@@ -10354,6 +10588,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10354 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10588 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10355 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10589 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10356 10590
10591 Scene scene = (Scene)m_scene;
10592 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10593 {
10594 ScenePresence p;
10595 if (scene.TryGetScenePresence(sender.AgentId, out p))
10596 {
10597 if (p.GodLevel >= 200)
10598 {
10599 groupProfileReply.GroupData.OpenEnrollment = true;
10600 groupProfileReply.GroupData.MembershipFee = 0;
10601 }
10602 }
10603 }
10604
10357 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10605 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10358 } 10606 }
10359 return true; 10607 return true;
@@ -10927,11 +11175,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10927 11175
10928 StartLure handlerStartLure = OnStartLure; 11176 StartLure handlerStartLure = OnStartLure;
10929 if (handlerStartLure != null) 11177 if (handlerStartLure != null)
10930 handlerStartLure(startLureRequest.Info.LureType, 11178 {
10931 Utils.BytesToString( 11179 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10932 startLureRequest.Info.Message), 11180 {
10933 startLureRequest.TargetData[0].TargetID, 11181 handlerStartLure(startLureRequest.Info.LureType,
10934 this); 11182 Utils.BytesToString(
11183 startLureRequest.Info.Message),
11184 startLureRequest.TargetData[i].TargetID,
11185 this);
11186 }
11187 }
10935 return true; 11188 return true;
10936 } 11189 }
10937 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11190 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11045,10 +11298,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11045 } 11298 }
11046 #endregion 11299 #endregion
11047 11300
11048 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11301 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11049 if (handlerClassifiedGodDelete != null) 11302 if (handlerClassifiedGodDelete != null)
11050 handlerClassifiedGodDelete( 11303 handlerClassifiedGodDelete(
11051 classifiedGodDelete.Data.ClassifiedID, 11304 classifiedGodDelete.Data.ClassifiedID,
11305 classifiedGodDelete.Data.QueryID,
11052 this); 11306 this);
11053 return true; 11307 return true;
11054 } 11308 }
@@ -11414,209 +11668,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11414 } 11668 }
11415 else 11669 else
11416 { 11670 {
11417// m_log.DebugFormat( 11671 ClientChangeObject updatehandler = onClientChangeObject;
11418// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11419// i, block.Type, part.Name, part.LocalId);
11420 11672
11421// // Do this once since fetch parts creates a new array. 11673 if (updatehandler != null)
11422// SceneObjectPart[] parts = part.ParentGroup.Parts; 11674 {
11423// for (int j = 0; j < parts.Length; j++) 11675 ObjectChangeData udata = new ObjectChangeData();
11424// {
11425// part.StoreUndoState();
11426// parts[j].IgnoreUndoUpdate = true;
11427// }
11428 11676
11429 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11677 /*ubit from ll JIRA:
11678 * 0x01 position
11679 * 0x02 rotation
11680 * 0x04 scale
11681
11682 * 0x08 LINK_SET
11683 * 0x10 UNIFORM for scale
11684 */
11430 11685
11431 switch (block.Type) 11686 // translate to internal changes
11432 { 11687 // not all cases .. just the ones older code did
11433 case 1:
11434 Vector3 pos1 = new Vector3(block.Data, 0);
11435 11688
11436 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11689 switch (block.Type)
11437 if (handlerUpdatePrimSinglePosition != null) 11690 {
11438 { 11691 case 1: //change position sp
11439 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11692 udata.position = new Vector3(block.Data, 0);
11440 handlerUpdatePrimSinglePosition(localId, pos1, this);
11441 }
11442 break;
11443 11693
11444 case 2: 11694 udata.change = ObjectChangeType.primP;
11445 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11695 updatehandler(localId, udata, this);
11696 break;
11446 11697
11447 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11698 case 2: // rotation sp
11448 if (handlerUpdatePrimSingleRotation != null) 11699 udata.rotation = new Quaternion(block.Data, 0, true);
11449 {
11450 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11451 handlerUpdatePrimSingleRotation(localId, rot1, this);
11452 }
11453 break;
11454 11700
11455 case 3: 11701 udata.change = ObjectChangeType.primR;
11456 Vector3 rotPos = new Vector3(block.Data, 0); 11702 updatehandler(localId, udata, this);
11457 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11703 break;
11458 11704
11459 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11705 case 3: // position plus rotation
11460 if (handlerUpdatePrimSingleRotationPosition != null) 11706 udata.position = new Vector3(block.Data, 0);
11461 { 11707 udata.rotation = new Quaternion(block.Data, 12, true);
11462 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11463 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11464 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11465 }
11466 break;
11467 11708
11468 case 4: 11709 udata.change = ObjectChangeType.primPR;
11469 case 20: 11710 updatehandler(localId, udata, this);
11470 Vector3 scale4 = new Vector3(block.Data, 0); 11711 break;
11471 11712
11472 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11713 case 4: // scale sp
11473 if (handlerUpdatePrimScale != null) 11714 udata.scale = new Vector3(block.Data, 0);
11474 { 11715 udata.change = ObjectChangeType.primS;
11475 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11476 handlerUpdatePrimScale(localId, scale4, this);
11477 }
11478 break;
11479 11716
11480 case 5: 11717 updatehandler(localId, udata, this);
11481 Vector3 scale1 = new Vector3(block.Data, 12); 11718 break;
11482 Vector3 pos11 = new Vector3(block.Data, 0);
11483 11719
11484 handlerUpdatePrimScale = OnUpdatePrimScale; 11720 case 0x14: // uniform scale sp
11485 if (handlerUpdatePrimScale != null) 11721 udata.scale = new Vector3(block.Data, 0);
11486 {
11487 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11488 handlerUpdatePrimScale(localId, scale1, this);
11489 11722
11490 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11723 udata.change = ObjectChangeType.primUS;
11491 if (handlerUpdatePrimSinglePosition != null) 11724 updatehandler(localId, udata, this);
11492 { 11725 break;
11493 handlerUpdatePrimSinglePosition(localId, pos11, this);
11494 }
11495 }
11496 break;
11497 11726
11498 case 9: 11727 case 5: // scale and position sp
11499 Vector3 pos2 = new Vector3(block.Data, 0); 11728 udata.position = new Vector3(block.Data, 0);
11729 udata.scale = new Vector3(block.Data, 12);
11500 11730
11501 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11731 udata.change = ObjectChangeType.primPS;
11732 updatehandler(localId, udata, this);
11733 break;
11502 11734
11503 if (handlerUpdateVector != null) 11735 case 0x15: //uniform scale and position
11504 { 11736 udata.position = new Vector3(block.Data, 0);
11505 handlerUpdateVector(localId, pos2, this); 11737 udata.scale = new Vector3(block.Data, 12);
11506 }
11507 break;
11508 11738
11509 case 10: 11739 udata.change = ObjectChangeType.primPUS;
11510 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11740 updatehandler(localId, udata, this);
11741 break;
11511 11742
11512 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11743 // now group related (bit 4)
11513 if (handlerUpdatePrimRotation != null) 11744 case 9: //( 8 + 1 )group position
11514 { 11745 udata.position = new Vector3(block.Data, 0);
11515 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11516 handlerUpdatePrimRotation(localId, rot3, this);
11517 }
11518 break;
11519 11746
11520 case 11: 11747 udata.change = ObjectChangeType.groupP;
11521 Vector3 pos3 = new Vector3(block.Data, 0); 11748 updatehandler(localId, udata, this);
11522 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11749 break;
11523 11750
11524 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11751 case 0x0A: // (8 + 2) group rotation
11525 if (handlerUpdatePrimGroupRotation != null) 11752 udata.rotation = new Quaternion(block.Data, 0, true);
11526 {
11527 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11528 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11529 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11530 }
11531 break;
11532 case 12:
11533 case 28:
11534 Vector3 scale7 = new Vector3(block.Data, 0);
11535 11753
11536 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11754 udata.change = ObjectChangeType.groupR;
11537 if (handlerUpdatePrimGroupScale != null) 11755 updatehandler(localId, udata, this);
11538 { 11756 break;
11539 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11540 handlerUpdatePrimGroupScale(localId, scale7, this);
11541 }
11542 break;
11543 11757
11544 case 13: 11758 case 0x0B: //( 8 + 2 + 1) group rotation and position
11545 Vector3 scale2 = new Vector3(block.Data, 12); 11759 udata.position = new Vector3(block.Data, 0);
11546 Vector3 pos4 = new Vector3(block.Data, 0); 11760 udata.rotation = new Quaternion(block.Data, 12, true);
11547 11761
11548 handlerUpdatePrimScale = OnUpdatePrimScale; 11762 udata.change = ObjectChangeType.groupPR;
11549 if (handlerUpdatePrimScale != null) 11763 updatehandler(localId, udata, this);
11550 { 11764 break;
11551 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11552 handlerUpdatePrimScale(localId, scale2, this);
11553 11765
11554 // Change the position based on scale (for bug number 246) 11766 case 0x0C: // (8 + 4) group scale
11555 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11767 // only afects root prim and only sent by viewer editor object tab scaling
11556 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11768 // mouse edition only allows uniform scaling
11557 if (handlerUpdatePrimSinglePosition != null) 11769 // SL MAY CHANGE THIS in viewers
11558 {
11559 handlerUpdatePrimSinglePosition(localId, pos4, this);
11560 }
11561 }
11562 break;
11563 11770
11564 case 29: 11771 udata.scale = new Vector3(block.Data, 0);
11565 Vector3 scale5 = new Vector3(block.Data, 12);
11566 Vector3 pos5 = new Vector3(block.Data, 0);
11567 11772
11568 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11773 udata.change = ObjectChangeType.groupS;
11569 if (handlerUpdatePrimGroupScale != null) 11774 updatehandler(localId, udata, this);
11570 {
11571 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11572 part.StoreUndoState(true);
11573 part.IgnoreUndoUpdate = true;
11574 handlerUpdatePrimGroupScale(localId, scale5, this);
11575 handlerUpdateVector = OnUpdatePrimGroupPosition;
11576 11775
11577 if (handlerUpdateVector != null) 11776 break;
11578 {
11579 handlerUpdateVector(localId, pos5, this);
11580 }
11581 11777
11582 part.IgnoreUndoUpdate = false; 11778 case 0x0D: //(8 + 4 + 1) group scale and position
11583 } 11779 // exception as above
11584 11780
11585 break; 11781 udata.position = new Vector3(block.Data, 0);
11782 udata.scale = new Vector3(block.Data, 12);
11586 11783
11587 case 21: 11784 udata.change = ObjectChangeType.groupPS;
11588 Vector3 scale6 = new Vector3(block.Data, 12); 11785 updatehandler(localId, udata, this);
11589 Vector3 pos6 = new Vector3(block.Data, 0); 11786 break;
11590 11787
11591 handlerUpdatePrimScale = OnUpdatePrimScale; 11788 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11592 if (handlerUpdatePrimScale != null) 11789 udata.scale = new Vector3(block.Data, 0);
11593 {
11594 part.StoreUndoState(false);
11595 part.IgnoreUndoUpdate = true;
11596 11790
11597 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11791 udata.change = ObjectChangeType.groupUS;
11598 handlerUpdatePrimScale(localId, scale6, this); 11792 updatehandler(localId, udata, this);
11599 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11793 break;
11600 if (handlerUpdatePrimSinglePosition != null)
11601 {
11602 handlerUpdatePrimSinglePosition(localId, pos6, this);
11603 }
11604 11794
11605 part.IgnoreUndoUpdate = false; 11795 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11606 } 11796 udata.position = new Vector3(block.Data, 0);
11607 break; 11797 udata.scale = new Vector3(block.Data, 12);
11608 11798
11609 default: 11799 udata.change = ObjectChangeType.groupPUS;
11610 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11800 updatehandler(localId, udata, this);
11611 break; 11801 break;
11802
11803 default:
11804 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11805 break;
11806 }
11612 } 11807 }
11613 11808
11614// for (int j = 0; j < parts.Length; j++)
11615// parts[j].IgnoreUndoUpdate = false;
11616 } 11809 }
11617 } 11810 }
11618 } 11811 }
11619
11620 return true; 11812 return true;
11621 } 11813 }
11622 11814
@@ -12066,7 +12258,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12066// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12258// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12067// requestID, taskID, (SourceType)sourceType, Name); 12259// requestID, taskID, (SourceType)sourceType, Name);
12068 12260
12261
12262 //Note, the bool returned from the below function is useless since it is always false.
12069 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12263 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12264
12070 } 12265 }
12071 12266
12072 /// <summary> 12267 /// <summary>
@@ -12132,7 +12327,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12132 /// <returns></returns> 12327 /// <returns></returns>
12133 private static int CalculateNumPackets(byte[] data) 12328 private static int CalculateNumPackets(byte[] data)
12134 { 12329 {
12135 const uint m_maxPacketSize = 600; 12330// const uint m_maxPacketSize = 600;
12331 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12136 int numPackets = 1; 12332 int numPackets = 1;
12137 12333
12138 if (data == null) 12334 if (data == null)