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.cs1518
1 files changed, 941 insertions, 577 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 20bc59c..21a173d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -102,6 +102,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
102 public event AvatarPickerRequest OnAvatarPickerRequest; 102 public event AvatarPickerRequest OnAvatarPickerRequest;
103 public event StartAnim OnStartAnim; 103 public event StartAnim OnStartAnim;
104 public event StopAnim OnStopAnim; 104 public event StopAnim OnStopAnim;
105 public event ChangeAnim OnChangeAnim;
105 public event Action<IClientAPI> OnRequestAvatarsData; 106 public event Action<IClientAPI> OnRequestAvatarsData;
106 public event LinkObjects OnLinkObjects; 107 public event LinkObjects OnLinkObjects;
107 public event DelinkObjects OnDelinkObjects; 108 public event DelinkObjects OnDelinkObjects;
@@ -129,6 +130,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
129 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 130 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
130 public event UpdatePrimFlags OnUpdatePrimFlags; 131 public event UpdatePrimFlags OnUpdatePrimFlags;
131 public event UpdatePrimTexture OnUpdatePrimTexture; 132 public event UpdatePrimTexture OnUpdatePrimTexture;
133 public event ClientChangeObject onClientChangeObject;
132 public event UpdateVector OnUpdatePrimGroupPosition; 134 public event UpdateVector OnUpdatePrimGroupPosition;
133 public event UpdateVector OnUpdatePrimSinglePosition; 135 public event UpdateVector OnUpdatePrimSinglePosition;
134 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 136 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -162,6 +164,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
162 public event RequestTaskInventory OnRequestTaskInventory; 164 public event RequestTaskInventory OnRequestTaskInventory;
163 public event UpdateInventoryItem OnUpdateInventoryItem; 165 public event UpdateInventoryItem OnUpdateInventoryItem;
164 public event CopyInventoryItem OnCopyInventoryItem; 166 public event CopyInventoryItem OnCopyInventoryItem;
167 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
165 public event MoveInventoryItem OnMoveInventoryItem; 168 public event MoveInventoryItem OnMoveInventoryItem;
166 public event RemoveInventoryItem OnRemoveInventoryItem; 169 public event RemoveInventoryItem OnRemoveInventoryItem;
167 public event RemoveInventoryFolder OnRemoveInventoryFolder; 170 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -260,7 +263,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
260 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 263 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
261 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 264 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
262 public event ClassifiedDelete OnClassifiedDelete; 265 public event ClassifiedDelete OnClassifiedDelete;
263 public event ClassifiedDelete OnClassifiedGodDelete; 266 public event ClassifiedGodDelete OnClassifiedGodDelete;
264 public event EventNotificationAddRequest OnEventNotificationAddRequest; 267 public event EventNotificationAddRequest OnEventNotificationAddRequest;
265 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 268 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
266 public event EventGodDelete OnEventGodDelete; 269 public event EventGodDelete OnEventGodDelete;
@@ -291,10 +294,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
291 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 294 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
292 public event SimWideDeletesDelegate OnSimWideDeletes; 295 public event SimWideDeletesDelegate OnSimWideDeletes;
293 public event SendPostcard OnSendPostcard; 296 public event SendPostcard OnSendPostcard;
297 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
294 public event MuteListEntryUpdate OnUpdateMuteListEntry; 298 public event MuteListEntryUpdate OnUpdateMuteListEntry;
295 public event MuteListEntryRemove OnRemoveMuteListEntry; 299 public event MuteListEntryRemove OnRemoveMuteListEntry;
296 public event GodlikeMessage onGodlikeMessage; 300 public event GodlikeMessage onGodlikeMessage;
297 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 301 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
302 public event GenericCall2 OnUpdateThrottles;
298 303
299 #endregion Events 304 #endregion Events
300 305
@@ -323,11 +328,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
323 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 328 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
324 private readonly IGroupsModule m_GroupsModule; 329 private readonly IGroupsModule m_GroupsModule;
325 330
331 private int m_cachedTextureSerial;
326 private PriorityQueue m_entityUpdates; 332 private PriorityQueue m_entityUpdates;
327 private PriorityQueue m_entityProps; 333 private PriorityQueue m_entityProps;
328 private Prioritizer m_prioritizer; 334 private Prioritizer m_prioritizer;
329 private bool m_disableFacelights = false; 335 private bool m_disableFacelights = false;
336
337 private bool m_VelocityInterpolate = false;
338 private const uint MaxTransferBytesPerPacket = 600;
339
330 private volatile bool m_justEditedTerrain = false; 340 private volatile bool m_justEditedTerrain = false;
341
331 /// <value> 342 /// <value>
332 /// List used in construction of data blocks for an object update packet. This is to stop us having to 343 /// List used in construction of data blocks for an object update packet. This is to stop us having to
333 /// continually recreate it. 344 /// continually recreate it.
@@ -339,13 +350,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 350 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
340 /// ownerless phantom. 351 /// ownerless phantom.
341 /// 352 ///
342 /// All manipulation of this set has to occur under a lock 353 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
343 /// 354 ///
344 /// </value> 355 /// </value>
345 protected HashSet<uint> m_killRecord; 356// protected HashSet<uint> m_killRecord;
346 357
347// protected HashSet<uint> m_attachmentsSent; 358// protected HashSet<uint> m_attachmentsSent;
348 359
360 private bool m_deliverPackets = true;
349 private int m_animationSequenceNumber = 1; 361 private int m_animationSequenceNumber = 1;
350 private bool m_SendLogoutPacketWhenClosing = true; 362 private bool m_SendLogoutPacketWhenClosing = true;
351 363
@@ -392,6 +404,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
392 get { return m_startpos; } 404 get { return m_startpos; }
393 set { m_startpos = value; } 405 set { m_startpos = value; }
394 } 406 }
407 public bool DeliverPackets
408 {
409 get { return m_deliverPackets; }
410 set {
411 m_deliverPackets = value;
412 m_udpClient.m_deliverPackets = value;
413 }
414 }
395 public UUID AgentId { get { return m_agentId; } } 415 public UUID AgentId { get { return m_agentId; } }
396 public ISceneAgent SceneAgent { get; set; } 416 public ISceneAgent SceneAgent { get; set; }
397 public UUID ActiveGroupId { get { return m_activeGroupID; } } 417 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -442,6 +462,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
442 } 462 }
443 463
444 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 464 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
465
445 466
446 #endregion Properties 467 #endregion Properties
447 468
@@ -468,7 +489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 489 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 490 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 491 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 492// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 493// m_attachmentsSent = new HashSet<uint>();
473 494
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 495 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +519,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 519
499 #region Client Methods 520 #region Client Methods
500 521
522
523 /// <summary>
524 /// Close down the client view
525 /// </summary>
501 public void Close() 526 public void Close()
502 { 527 {
503 Close(false); 528 Close(true, false);
504 } 529 }
505 530
506 public void Close(bool force) 531 public void Close(bool sendStop, bool force)
507 { 532 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 533 // 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. 534 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -521,7 +546,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 } 546 }
522 547
523 IsActive = false; 548 IsActive = false;
524 CloseWithoutChecks(); 549 CloseWithoutChecks(sendStop);
525 } 550 }
526 } 551 }
527 552
@@ -534,12 +559,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
534 /// 559 ///
535 /// Callers must lock ClosingSyncLock before calling. 560 /// Callers must lock ClosingSyncLock before calling.
536 /// </remarks> 561 /// </remarks>
537 public void CloseWithoutChecks() 562 public void CloseWithoutChecks(bool sendStop)
538 { 563 {
539 m_log.DebugFormat( 564 m_log.DebugFormat(
540 "[CLIENT]: Close has been called for {0} attached to scene {1}", 565 "[CLIENT]: Close has been called for {0} attached to scene {1}",
541 Name, m_scene.RegionInfo.RegionName); 566 Name, m_scene.RegionInfo.RegionName);
542 567
568 if (sendStop)
569 {
570 // Send the STOP packet
571 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
572 OutPacket(disable, ThrottleOutPacketType.Unknown);
573 }
574
543 // Shutdown the image manager 575 // Shutdown the image manager
544 ImageManager.Close(); 576 ImageManager.Close();
545 577
@@ -562,6 +594,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
562 // Disable UDP handling for this client 594 // Disable UDP handling for this client
563 m_udpClient.Shutdown(); 595 m_udpClient.Shutdown();
564 596
597
565 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 598 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
566 //GC.Collect(); 599 //GC.Collect();
567 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 600 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -858,7 +891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
858 reply.ChatData.OwnerID = ownerID; 891 reply.ChatData.OwnerID = ownerID;
859 reply.ChatData.SourceID = fromAgentID; 892 reply.ChatData.SourceID = fromAgentID;
860 893
861 OutPacket(reply, ThrottleOutPacketType.Task); 894 OutPacket(reply, ThrottleOutPacketType.Unknown);
862 } 895 }
863 896
864 /// <summary> 897 /// <summary>
@@ -891,32 +924,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
891 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 924 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
892 msg.MessageBlock.BinaryBucket = im.binaryBucket; 925 msg.MessageBlock.BinaryBucket = im.binaryBucket;
893 926
894 if (im.message.StartsWith("[grouptest]")) 927 OutPacket(msg, ThrottleOutPacketType.Task);
895 { // this block is test code for implementing group IM - delete when group IM is finished
896 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
897 if (eq != null)
898 {
899 im.dialog = 17;
900
901 //eq.ChatterboxInvitation(
902 // new UUID("00000000-68f9-1111-024e-222222111123"),
903 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
904 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
905
906 eq.ChatterboxInvitation(
907 new UUID("00000000-68f9-1111-024e-222222111123"),
908 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
909 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
910
911 eq.ChatterBoxSessionAgentListUpdates(
912 new UUID("00000000-68f9-1111-024e-222222111123"),
913 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
914 }
915
916 Console.WriteLine("SendInstantMessage: " + msg);
917 }
918 else
919 OutPacket(msg, ThrottleOutPacketType.Task);
920 } 928 }
921 } 929 }
922 930
@@ -1154,6 +1162,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1154 public virtual void SendLayerData(float[] map) 1162 public virtual void SendLayerData(float[] map)
1155 { 1163 {
1156 Util.FireAndForget(DoSendLayerData, map); 1164 Util.FireAndForget(DoSendLayerData, map);
1165
1166 // Send it sync, and async. It's not that much data
1167 // and it improves user experience just so much!
1168 DoSendLayerData(map);
1157 } 1169 }
1158 1170
1159 /// <summary> 1171 /// <summary>
@@ -1166,16 +1178,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1166 1178
1167 try 1179 try
1168 { 1180 {
1169 //for (int y = 0; y < 16; y++) 1181 for (int y = 0; y < 16; y++)
1170 //{ 1182 {
1171 // for (int x = 0; x < 16; x++) 1183 for (int x = 0; x < 16; x+=4)
1172 // { 1184 {
1173 // SendLayerData(x, y, map); 1185 SendLayerPacket(x, y, map);
1174 // } 1186 }
1175 //} 1187 }
1176
1177 // Send LayerData in a spiral pattern. Fun!
1178 SendLayerTopRight(map, 0, 0, 15, 15);
1179 } 1188 }
1180 catch (Exception e) 1189 catch (Exception e)
1181 { 1190 {
@@ -1183,51 +1192,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1183 } 1192 }
1184 } 1193 }
1185 1194
1186 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1187 {
1188 // Row
1189 for (int i = x1; i <= x2; i++)
1190 SendLayerData(i, y1, map);
1191
1192 // Column
1193 for (int j = y1 + 1; j <= y2; j++)
1194 SendLayerData(x2, j, map);
1195
1196 if (x2 - x1 > 0)
1197 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1198 }
1199
1200 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1201 {
1202 // Row in reverse
1203 for (int i = x2; i >= x1; i--)
1204 SendLayerData(i, y2, map);
1205
1206 // Column in reverse
1207 for (int j = y2 - 1; j >= y1; j--)
1208 SendLayerData(x1, j, map);
1209
1210 if (x2 - x1 > 0)
1211 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1212 }
1213
1214 /// <summary> 1195 /// <summary>
1215 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1196 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1216 /// </summary> 1197 /// </summary>
1217 /// <param name="map">heightmap</param> 1198 /// <param name="map">heightmap</param>
1218 /// <param name="px">X coordinate for patches 0..12</param> 1199 /// <param name="px">X coordinate for patches 0..12</param>
1219 /// <param name="py">Y coordinate for patches 0..15</param> 1200 /// <param name="py">Y coordinate for patches 0..15</param>
1220 // private void SendLayerPacket(float[] map, int y, int x) 1201 private void SendLayerPacket(int x, int y, float[] map)
1221 // { 1202 {
1222 // int[] patches = new int[4]; 1203 int[] patches = new int[4];
1223 // patches[0] = x + 0 + y * 16; 1204 patches[0] = x + 0 + y * 16;
1224 // patches[1] = x + 1 + y * 16; 1205 patches[1] = x + 1 + y * 16;
1225 // patches[2] = x + 2 + y * 16; 1206 patches[2] = x + 2 + y * 16;
1226 // patches[3] = x + 3 + y * 16; 1207 patches[3] = x + 3 + y * 16;
1227 1208
1228 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1209 float[] heightmap = (map.Length == 65536) ?
1229 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1210 map :
1230 // } 1211 LLHeightFieldMoronize(map);
1212
1213 try
1214 {
1215 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1216 OutPacket(layerpack, ThrottleOutPacketType.Land);
1217 }
1218 catch
1219 {
1220 for (int px = x ; px < x + 4 ; px++)
1221 SendLayerData(px, y, map);
1222 }
1223 }
1231 1224
1232 /// <summary> 1225 /// <summary>
1233 /// Sends a specified patch to a client 1226 /// Sends a specified patch to a client
@@ -1269,7 +1262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1269 { 1262 {
1270 layerpack.Header.Reliable = true; 1263 layerpack.Header.Reliable = true;
1271 OutPacket(layerpack, 1264 OutPacket(layerpack,
1272 ThrottleOutPacketType.Land); 1265 ThrottleOutPacketType.Task);
1273 } 1266 }
1274 } 1267 }
1275 catch (Exception e) 1268 catch (Exception e)
@@ -1646,7 +1639,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1646 1639
1647 public void SendKillObject(List<uint> localIDs) 1640 public void SendKillObject(List<uint> localIDs)
1648 { 1641 {
1649// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1642// foreach (uint id in localIDs)
1643// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1650 1644
1651 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1645 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1652 // TODO: don't create new blocks if recycling an old packet 1646 // TODO: don't create new blocks if recycling an old packet
@@ -1668,17 +1662,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1668 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1662 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1669 // condition where a kill can be processed before an out-of-date update for the same object. 1663 // condition where a kill can be processed before an out-of-date update for the same object.
1670 // ProcessEntityUpdates() also takes the m_killRecord lock. 1664 // ProcessEntityUpdates() also takes the m_killRecord lock.
1671 lock (m_killRecord) 1665// lock (m_killRecord)
1672 { 1666// {
1673 foreach (uint localID in localIDs) 1667// foreach (uint localID in localIDs)
1674 m_killRecord.Add(localID); 1668// m_killRecord.Add(localID);
1675 1669
1676 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1670 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1677 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1671 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1678 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1672 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1679 // scene objects in a viewer until that viewer is relogged in. 1673 // scene objects in a viewer until that viewer is relogged in.
1680 OutPacket(kill, ThrottleOutPacketType.Task); 1674 OutPacket(kill, ThrottleOutPacketType.Task);
1681 } 1675// }
1682 } 1676 }
1683 } 1677 }
1684 1678
@@ -1800,7 +1794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1800 newBlock.CreationDate = item.CreationDate; 1794 newBlock.CreationDate = item.CreationDate;
1801 newBlock.SalePrice = item.SalePrice; 1795 newBlock.SalePrice = item.SalePrice;
1802 newBlock.SaleType = item.SaleType; 1796 newBlock.SaleType = item.SaleType;
1803 newBlock.Flags = item.Flags; 1797 newBlock.Flags = item.Flags & 0xff;
1804 1798
1805 newBlock.CRC = 1799 newBlock.CRC =
1806 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, 1800 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
@@ -2054,7 +2048,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2054 itemBlock.GroupID = item.GroupID; 2048 itemBlock.GroupID = item.GroupID;
2055 itemBlock.GroupOwned = item.GroupOwned; 2049 itemBlock.GroupOwned = item.GroupOwned;
2056 itemBlock.GroupMask = item.GroupPermissions; 2050 itemBlock.GroupMask = item.GroupPermissions;
2057 itemBlock.Flags = item.Flags; 2051 itemBlock.Flags = item.Flags & 0xff;
2058 itemBlock.SalePrice = item.SalePrice; 2052 itemBlock.SalePrice = item.SalePrice;
2059 itemBlock.SaleType = item.SaleType; 2053 itemBlock.SaleType = item.SaleType;
2060 itemBlock.CreationDate = item.CreationDate; 2054 itemBlock.CreationDate = item.CreationDate;
@@ -2121,7 +2115,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2121 bulkUpdate.ItemData[0].GroupID = item.GroupID; 2115 bulkUpdate.ItemData[0].GroupID = item.GroupID;
2122 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned; 2116 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned;
2123 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions; 2117 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions;
2124 bulkUpdate.ItemData[0].Flags = item.Flags; 2118 bulkUpdate.ItemData[0].Flags = item.Flags & 0xff;
2125 bulkUpdate.ItemData[0].SalePrice = item.SalePrice; 2119 bulkUpdate.ItemData[0].SalePrice = item.SalePrice;
2126 bulkUpdate.ItemData[0].SaleType = item.SaleType; 2120 bulkUpdate.ItemData[0].SaleType = item.SaleType;
2127 2121
@@ -2137,9 +2131,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2137 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2131 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2138 } 2132 }
2139 2133
2140 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2141 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2134 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2142 { 2135 {
2136 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2137 }
2138
2139 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2140 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2141 {
2143 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2142 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2144 2143
2145 UpdateCreateInventoryItemPacket InventoryReply 2144 UpdateCreateInventoryItemPacket InventoryReply
@@ -2149,6 +2148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2149 // TODO: don't create new blocks if recycling an old packet 2148 // TODO: don't create new blocks if recycling an old packet
2150 InventoryReply.AgentData.AgentID = AgentId; 2149 InventoryReply.AgentData.AgentID = AgentId;
2151 InventoryReply.AgentData.SimApproved = true; 2150 InventoryReply.AgentData.SimApproved = true;
2151 InventoryReply.AgentData.TransactionID = transactionID;
2152 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2152 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2153 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2153 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2154 InventoryReply.InventoryData[0].ItemID = Item.ID; 2154 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2169,7 +2169,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2169 InventoryReply.InventoryData[0].GroupID = Item.GroupID; 2169 InventoryReply.InventoryData[0].GroupID = Item.GroupID;
2170 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned; 2170 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned;
2171 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions; 2171 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions;
2172 InventoryReply.InventoryData[0].Flags = Item.Flags; 2172 InventoryReply.InventoryData[0].Flags = Item.Flags & 0xff;
2173 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice; 2173 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice;
2174 InventoryReply.InventoryData[0].SaleType = Item.SaleType; 2174 InventoryReply.InventoryData[0].SaleType = Item.SaleType;
2175 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate; 2175 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate;
@@ -2218,16 +2218,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2218 replytask.InventoryData.TaskID = taskID; 2218 replytask.InventoryData.TaskID = taskID;
2219 replytask.InventoryData.Serial = serial; 2219 replytask.InventoryData.Serial = serial;
2220 replytask.InventoryData.Filename = fileName; 2220 replytask.InventoryData.Filename = fileName;
2221 OutPacket(replytask, ThrottleOutPacketType.Asset); 2221 OutPacket(replytask, ThrottleOutPacketType.Task);
2222 } 2222 }
2223 2223
2224 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2224 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2225 { 2225 {
2226 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2227 if (isTaskInventory)
2228 type = ThrottleOutPacketType.Task;
2229
2226 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2230 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2227 sendXfer.XferID.ID = xferID; 2231 sendXfer.XferID.ID = xferID;
2228 sendXfer.XferID.Packet = packet; 2232 sendXfer.XferID.Packet = packet;
2229 sendXfer.DataPacket.Data = data; 2233 sendXfer.DataPacket.Data = data;
2230 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2234 OutPacket(sendXfer, type);
2231 } 2235 }
2232 2236
2233 public void SendAbortXferPacket(ulong xferID) 2237 public void SendAbortXferPacket(ulong xferID)
@@ -2414,6 +2418,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2414 OutPacket(sound, ThrottleOutPacketType.Task); 2418 OutPacket(sound, ThrottleOutPacketType.Task);
2415 } 2419 }
2416 2420
2421 public void SendTransferAbort(TransferRequestPacket transferRequest)
2422 {
2423 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2424 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2425 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2426 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2427 OutPacket(abort, ThrottleOutPacketType.Task);
2428 }
2429
2417 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2430 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2418 { 2431 {
2419 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2432 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2722,6 +2735,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2722 float friction = part.Friction; 2735 float friction = part.Friction;
2723 float bounce = part.Restitution; 2736 float bounce = part.Restitution;
2724 float gravmod = part.GravityModifier; 2737 float gravmod = part.GravityModifier;
2738
2725 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2739 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2726 } 2740 }
2727 } 2741 }
@@ -2792,8 +2806,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2792 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2806 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2793 return; 2807 return;
2794 } 2808 }
2809 int WearableOut = 0;
2810 bool isWearable = false;
2811
2812 if (req.AssetInf != null)
2813 isWearable =
2814 ((AssetType) req.AssetInf.Type ==
2815 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2795 2816
2796 //m_log.Debug("sending asset " + req.RequestAssetID); 2817
2818 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2819
2820
2821 //if (isWearable)
2822 // m_log.Debug((AssetType)req.AssetInf.Type);
2823
2797 TransferInfoPacket Transfer = new TransferInfoPacket(); 2824 TransferInfoPacket Transfer = new TransferInfoPacket();
2798 Transfer.TransferInfo.ChannelType = 2; 2825 Transfer.TransferInfo.ChannelType = 2;
2799 Transfer.TransferInfo.Status = 0; 2826 Transfer.TransferInfo.Status = 0;
@@ -2815,7 +2842,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2815 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2842 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2816 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2843 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2817 Transfer.Header.Zerocoded = true; 2844 Transfer.Header.Zerocoded = true;
2818 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2845 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2819 2846
2820 if (req.NumPackets == 1) 2847 if (req.NumPackets == 1)
2821 { 2848 {
@@ -2826,12 +2853,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2826 TransferPacket.TransferData.Data = req.AssetInf.Data; 2853 TransferPacket.TransferData.Data = req.AssetInf.Data;
2827 TransferPacket.TransferData.Status = 1; 2854 TransferPacket.TransferData.Status = 1;
2828 TransferPacket.Header.Zerocoded = true; 2855 TransferPacket.Header.Zerocoded = true;
2829 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2856 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2830 } 2857 }
2831 else 2858 else
2832 { 2859 {
2833 int processedLength = 0; 2860 int processedLength = 0;
2834 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2861// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2862
2863 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2835 int packetNumber = 0; 2864 int packetNumber = 0;
2836 2865
2837 while (processedLength < req.AssetInf.Data.Length) 2866 while (processedLength < req.AssetInf.Data.Length)
@@ -2857,7 +2886,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2857 TransferPacket.TransferData.Status = 1; 2886 TransferPacket.TransferData.Status = 1;
2858 } 2887 }
2859 TransferPacket.Header.Zerocoded = true; 2888 TransferPacket.Header.Zerocoded = true;
2860 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2889 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2861 2890
2862 processedLength += chunkSize; 2891 processedLength += chunkSize;
2863 packetNumber++; 2892 packetNumber++;
@@ -2902,7 +2931,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2902 reply.Data.ParcelID = parcelID; 2931 reply.Data.ParcelID = parcelID;
2903 reply.Data.OwnerID = land.OwnerID; 2932 reply.Data.OwnerID = land.OwnerID;
2904 reply.Data.Name = Utils.StringToBytes(land.Name); 2933 reply.Data.Name = Utils.StringToBytes(land.Name);
2905 reply.Data.Desc = Utils.StringToBytes(land.Description); 2934 if (land != null && land.Description != null && land.Description != String.Empty)
2935 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2936 else
2937 reply.Data.Desc = new Byte[0];
2906 reply.Data.ActualArea = land.Area; 2938 reply.Data.ActualArea = land.Area;
2907 reply.Data.BillableArea = land.Area; // TODO: what is this? 2939 reply.Data.BillableArea = land.Area; // TODO: what is this?
2908 2940
@@ -3609,24 +3641,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3609 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3641 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3610 AgentWearablesUpdatePacket.WearableDataBlock awb; 3642 AgentWearablesUpdatePacket.WearableDataBlock awb;
3611 int idx = 0; 3643 int idx = 0;
3612 for (int i = 0; i < wearables.Length; i++) 3644
3613 { 3645 for (int i = 0; i < wearables.Length; i++)
3614 for (int j = 0; j < wearables[i].Count; j++) 3646 {
3615 { 3647 for (int j = 0; j < wearables[i].Count; j++)
3616 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3648 {
3617 awb.WearableType = (byte)i; 3649 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3618 awb.AssetID = wearables[i][j].AssetID; 3650 awb.WearableType = (byte) i;
3619 awb.ItemID = wearables[i][j].ItemID; 3651 awb.AssetID = wearables[i][j].AssetID;
3620 aw.WearableData[idx] = awb; 3652 awb.ItemID = wearables[i][j].ItemID;
3621 idx++; 3653 aw.WearableData[idx] = awb;
3622 3654 idx++;
3623// m_log.DebugFormat( 3655
3624// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3656 // m_log.DebugFormat(
3625// awb.ItemID, awb.AssetID, i, Name); 3657 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3626 } 3658 // awb.ItemID, awb.AssetID, i, Name);
3627 } 3659 }
3660 }
3628 3661
3629 OutPacket(aw, ThrottleOutPacketType.Task); 3662 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3630 } 3663 }
3631 3664
3632 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3665 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3637,7 +3670,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3637 3670
3638 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3671 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3639 // TODO: don't create new blocks if recycling an old packet 3672 // TODO: don't create new blocks if recycling an old packet
3640 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3673 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3641 avp.ObjectData.TextureEntry = textureEntry; 3674 avp.ObjectData.TextureEntry = textureEntry;
3642 3675
3643 AvatarAppearancePacket.VisualParamBlock avblock = null; 3676 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3768,7 +3801,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3768 /// </summary> 3801 /// </summary>
3769 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3802 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3770 { 3803 {
3771 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3804 if (entity is SceneObjectPart)
3805 {
3806 SceneObjectPart e = (SceneObjectPart)entity;
3807 SceneObjectGroup g = e.ParentGroup;
3808 if (g.RootPart.Shape.State > 30) // HUD
3809 if (g.OwnerID != AgentId)
3810 return; // Don't send updates for other people's HUDs
3811 }
3812
3772 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3813 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3773 3814
3774 lock (m_entityUpdates.SyncRoot) 3815 lock (m_entityUpdates.SyncRoot)
@@ -3859,27 +3900,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3859 3900
3860 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3901 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3861 // condition where a kill can be processed before an out-of-date update for the same object. 3902 // condition where a kill can be processed before an out-of-date update for the same object.
3862 lock (m_killRecord) 3903 float avgTimeDilation = 1.0f;
3904 IEntityUpdate iupdate;
3905 Int32 timeinqueue; // this is just debugging code & can be dropped later
3906
3907 while (updatesThisCall < maxUpdates)
3863 { 3908 {
3864 float avgTimeDilation = 1.0f; 3909 lock (m_entityUpdates.SyncRoot)
3865 IEntityUpdate iupdate; 3910 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3866 Int32 timeinqueue; // this is just debugging code & can be dropped later 3911 break;
3912
3913 EntityUpdate update = (EntityUpdate)iupdate;
3914
3915 avgTimeDilation += update.TimeDilation;
3916 avgTimeDilation *= 0.5f;
3867 3917
3868 while (updatesThisCall < maxUpdates) 3918 if (update.Entity is SceneObjectPart)
3869 { 3919 {
3870 lock (m_entityUpdates.SyncRoot) 3920 SceneObjectPart part = (SceneObjectPart)update.Entity;
3871 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3872 break;
3873 3921
3874 EntityUpdate update = (EntityUpdate)iupdate; 3922 if (part.ParentGroup.IsDeleted)
3875 3923 continue;
3876 avgTimeDilation += update.TimeDilation;
3877 avgTimeDilation *= 0.5f;
3878 3924
3879 if (update.Entity is SceneObjectPart) 3925 if (part.ParentGroup.IsAttachment)
3926 { // Someone else's HUD, why are we getting these?
3927 if (part.ParentGroup.OwnerID != AgentId &&
3928 part.ParentGroup.RootPart.Shape.State > 30)
3929 continue;
3930 ScenePresence sp;
3931 // Owner is not in the sim, don't update it to
3932 // anyone
3933 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3934 continue;
3935
3936 List<SceneObjectGroup> atts = sp.GetAttachments();
3937 bool found = false;
3938 foreach (SceneObjectGroup att in atts)
3939 {
3940 if (att == part.ParentGroup)
3941 {
3942 found = true;
3943 break;
3944 }
3945 }
3946
3947 // It's an attachment of a valid avatar, but
3948 // doesn't seem to be attached, skip
3949 if (!found)
3950 continue;
3951
3952 // On vehicle crossing, the attachments are received
3953 // while the avatar is still a child. Don't send
3954 // updates here because the LocalId has not yet
3955 // been updated and the viewer will derender the
3956 // attachments until the avatar becomes root.
3957 if (sp.IsChildAgent)
3958 continue;
3959
3960 // If the object is an attachment we don't want it to be in the kill
3961 // record. Else attaching from inworld and subsequently dropping
3962 // it will no longer work.
3963// lock (m_killRecord)
3964// {
3965// m_killRecord.Remove(part.LocalId);
3966// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3967// }
3968 }
3969 else
3880 { 3970 {
3881 SceneObjectPart part = (SceneObjectPart)update.Entity;
3882
3883 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3971 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3884 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3972 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3885 // safety measure. 3973 // safety measure.
@@ -3890,21 +3978,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3890 // 3978 //
3891 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3979 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3892 // after the root prim has been deleted. 3980 // after the root prim has been deleted.
3893 if (m_killRecord.Contains(part.LocalId)) 3981 //
3894 { 3982 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3895 // m_log.WarnFormat( 3983// lock (m_killRecord)
3896 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3984// {
3897 // part.LocalId, Name); 3985// if (m_killRecord.Contains(part.LocalId))
3898 continue; 3986// continue;
3899 } 3987// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3900 3988// continue;
3901 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3989// }
3990 }
3991
3992 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3993 {
3994 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3995 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3902 { 3996 {
3903 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3997 part.Shape.LightEntry = false;
3904 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3905 {
3906 part.Shape.LightEntry = false;
3907 }
3908 } 3998 }
3909 3999
3910 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 4000 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3915,224 +4005,178 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3915 part.Shape.ProfileHollow = 27500; 4005 part.Shape.ProfileHollow = 27500;
3916 } 4006 }
3917 } 4007 }
3918 4008
3919 #region UpdateFlags to packet type conversion 4009 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3920
3921 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3922
3923 bool canUseCompressed = true;
3924 bool canUseImproved = true;
3925
3926 // Compressed object updates only make sense for LL primitives
3927 if (!(update.Entity is SceneObjectPart))
3928 { 4010 {
3929 canUseCompressed = false; 4011 // Ensure that mesh has at least 8 valid faces
4012 part.Shape.ProfileBegin = 12500;
4013 part.Shape.ProfileEnd = 0;
4014 part.Shape.ProfileHollow = 27500;
3930 } 4015 }
3931 4016 }
3932 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 4017 else if (update.Entity is ScenePresence)
4018 {
4019 ScenePresence presence = (ScenePresence)update.Entity;
4020
4021 // If ParentUUID is not UUID.Zero and ParentID is 0, this
4022 // avatar is in the process of crossing regions while
4023 // sat on an object. In this state, we don't want any
4024 // updates because they will visually orbit the avatar.
4025 // Update will be forced once crossing is completed anyway.
4026 if (presence.ParentUUID != UUID.Zero && presence.ParentID == 0)
4027 continue;
4028 }
4029
4030 ++updatesThisCall;
4031
4032 #region UpdateFlags to packet type conversion
4033
4034 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
4035
4036 bool canUseCompressed = true;
4037 bool canUseImproved = true;
4038
4039 // Compressed object updates only make sense for LL primitives
4040 if (!(update.Entity is SceneObjectPart))
4041 {
4042 canUseCompressed = false;
4043 }
4044
4045 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
4046 {
4047 canUseCompressed = false;
4048 canUseImproved = false;
4049 }
4050 else
4051 {
4052 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
4053 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
4054 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
4055 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3933 { 4056 {
3934 canUseCompressed = false; 4057 canUseCompressed = false;
3935 canUseImproved = false;
3936 } 4058 }
3937 else 4059
4060 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
4061 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
4062 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
4063 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
4064 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
4065 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
4066 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
4067 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
4068 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
4069 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
4070 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
4071 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
4072 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
4073 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3938 { 4074 {
3939 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 4075 canUseImproved = false;
3940 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3941 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3942 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3943 {
3944 canUseCompressed = false;
3945 }
3946
3947 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3950 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3951 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3952 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3953 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3957 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3958 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3959 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3960 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3961 {
3962 canUseImproved = false;
3963 }
3964 } 4076 }
4077 }
3965 4078
3966 #endregion UpdateFlags to packet type conversion 4079 #endregion UpdateFlags to packet type conversion
3967
3968 #region Block Construction
3969
3970 // TODO: Remove this once we can build compressed updates
3971 canUseCompressed = false;
3972
3973 if (!canUseImproved && !canUseCompressed)
3974 {
3975 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3976 4080
3977 if (update.Entity is ScenePresence) 4081 #region Block Construction
3978 {
3979 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3980 }
3981 else
3982 {
3983 SceneObjectPart part = (SceneObjectPart)update.Entity;
3984 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3985
3986 // If the part has become a private hud since the update was scheduled then we do not
3987 // want to send it to other avatars.
3988 if (part.ParentGroup.IsAttachment
3989 && part.ParentGroup.HasPrivateAttachmentPoint
3990 && part.ParentGroup.AttachedAvatar != AgentId)
3991 continue;
3992
3993 // If the part has since been deleted, then drop the update. In the case of attachments,
3994 // this is to avoid spurious updates to other viewers since post-processing of attachments
3995 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3996 // of the test above).
3997 //
3998 // Actual deletions (kills) happen in another method.
3999 if (part.ParentGroup.IsDeleted)
4000 continue;
4001 }
4002 4082
4003 objectUpdateBlocks.Value.Add(updateBlock); 4083 // TODO: Remove this once we can build compressed updates
4004 objectUpdates.Value.Add(update); 4084 canUseCompressed = false;
4005 }
4006 else if (!canUseImproved)
4007 {
4008 SceneObjectPart part = (SceneObjectPart)update.Entity;
4009 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
4010 = CreateCompressedUpdateBlock(part, updateFlags);
4011
4012 // If the part has since been deleted, then drop the update. In the case of attachments,
4013 // this is to avoid spurious updates to other viewers since post-processing of attachments
4014 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4015 // of the test above).
4016 //
4017 // Actual deletions (kills) happen in another method.
4018 if (part.ParentGroup.IsDeleted)
4019 continue;
4020 4085
4021 compressedUpdateBlocks.Value.Add(compressedBlock); 4086 if (!canUseImproved && !canUseCompressed)
4022 compressedUpdates.Value.Add(update); 4087 {
4088 if (update.Entity is ScenePresence)
4089 {
4090 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
4023 } 4091 }
4024 else 4092 else
4025 { 4093 {
4026 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 4094 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
4027 {
4028 // Self updates go into a special list
4029 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4030 terseAgentUpdates.Value.Add(update);
4031 }
4032 else
4033 {
4034 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
4035 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4036
4037 // Everything else goes here
4038 if (update.Entity is SceneObjectPart)
4039 {
4040 SceneObjectPart part = (SceneObjectPart)update.Entity;
4041
4042 // If the part has become a private hud since the update was scheduled then we do not
4043 // want to send it to other avatars.
4044 if (part.ParentGroup.IsAttachment
4045 && part.ParentGroup.HasPrivateAttachmentPoint
4046 && part.ParentGroup.AttachedAvatar != AgentId)
4047 continue;
4048
4049 // If the part has since been deleted, then drop the update. In the case of attachments,
4050 // this is to avoid spurious updates to other viewers since post-processing of attachments
4051 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4052 // of the test above).
4053 //
4054 // Actual deletions (kills) happen in another method.
4055 if (part.ParentGroup.IsDeleted)
4056 continue;
4057 }
4058
4059 terseUpdateBlocks.Value.Add(terseUpdateBlock);
4060 terseUpdates.Value.Add(update);
4061 }
4062 } 4095 }
4063
4064 ++updatesThisCall;
4065
4066 #endregion Block Construction
4067 } 4096 }
4068 4097 else if (!canUseImproved)
4069 #region Packet Sending 4098 {
4070 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 4099 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
4071 4100 }
4072 if (terseAgentUpdateBlocks.IsValueCreated) 4101 else
4073 { 4102 {
4074 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4103 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4104 // Self updates go into a special list
4105 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4106 else
4107 // Everything else goes here
4108 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4109 }
4075 4110
4076 ImprovedTerseObjectUpdatePacket packet 4111 #endregion Block Construction
4077 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4112 }
4078 4113
4079 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4114 #region Packet Sending
4080 packet.RegionData.TimeDilation = timeDilation; 4115
4081 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4116 const float TIME_DILATION = 1.0f;
4117 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4118
4119 if (terseAgentUpdateBlocks.IsValueCreated)
4120 {
4121 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4082 4122
4083 for (int i = 0; i < blocks.Count; i++) 4123 ImprovedTerseObjectUpdatePacket packet
4084 packet.ObjectData[i] = blocks[i]; 4124 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4085 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4125 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4086 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4126 packet.RegionData.TimeDilation = timeDilation;
4087 } 4127 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4088 4128
4089 if (objectUpdateBlocks.IsValueCreated) 4129 for (int i = 0; i < blocks.Count; i++)
4090 { 4130 packet.ObjectData[i] = blocks[i];
4091 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4092
4093 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4094 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4095 packet.RegionData.TimeDilation = timeDilation;
4096 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4097
4098 for (int i = 0; i < blocks.Count; i++)
4099 packet.ObjectData[i] = blocks[i];
4100 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4101 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4102 }
4103
4104 if (compressedUpdateBlocks.IsValueCreated)
4105 {
4106 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4107
4108 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4109 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4110 packet.RegionData.TimeDilation = timeDilation;
4111 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4112
4113 for (int i = 0; i < blocks.Count; i++)
4114 packet.ObjectData[i] = blocks[i];
4115 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4116 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4117 }
4118 4131
4119 if (terseUpdateBlocks.IsValueCreated) 4132 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4120 { 4133 }
4121 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4122
4123 ImprovedTerseObjectUpdatePacket packet
4124 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4125 PacketType.ImprovedTerseObjectUpdate);
4126 4134
4127 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4135 if (objectUpdateBlocks.IsValueCreated)
4128 packet.RegionData.TimeDilation = timeDilation; 4136 {
4129 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4137 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4130 4138
4131 for (int i = 0; i < blocks.Count; i++) 4139 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4132 packet.ObjectData[i] = blocks[i]; 4140 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4133 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4141 packet.RegionData.TimeDilation = timeDilation;
4134 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4142 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4135 } 4143
4144 for (int i = 0; i < blocks.Count; i++)
4145 packet.ObjectData[i] = blocks[i];
4146
4147 OutPacket(packet, ThrottleOutPacketType.Task, true);
4148 }
4149
4150 if (compressedUpdateBlocks.IsValueCreated)
4151 {
4152 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4153
4154 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4155 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4156 packet.RegionData.TimeDilation = timeDilation;
4157 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4158
4159 for (int i = 0; i < blocks.Count; i++)
4160 packet.ObjectData[i] = blocks[i];
4161
4162 OutPacket(packet, ThrottleOutPacketType.Task, true);
4163 }
4164
4165 if (terseUpdateBlocks.IsValueCreated)
4166 {
4167 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4168
4169 ImprovedTerseObjectUpdatePacket packet
4170 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4171 PacketType.ImprovedTerseObjectUpdate);
4172 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4173 packet.RegionData.TimeDilation = timeDilation;
4174 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4175
4176 for (int i = 0; i < blocks.Count; i++)
4177 packet.ObjectData[i] = blocks[i];
4178
4179 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4136 } 4180 }
4137 4181
4138 #endregion Packet Sending 4182 #endregion Packet Sending
@@ -4456,11 +4500,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4456 4500
4457 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4501 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4458 // of the object rather than the properties when the packet was created 4502 // of the object rather than the properties when the packet was created
4459 OutPacket(packet, ThrottleOutPacketType.Task, true, 4503 // HACK : Remove intelligent resending until it's fixed in core
4460 delegate(OutgoingPacket oPacket) 4504 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4461 { 4505 // delegate(OutgoingPacket oPacket)
4462 ResendPropertyUpdates(updates, oPacket); 4506 // {
4463 }); 4507 // ResendPropertyUpdates(updates, oPacket);
4508 // });
4509 OutPacket(packet, ThrottleOutPacketType.Task, true);
4464 4510
4465 // pbcnt += blocks.Count; 4511 // pbcnt += blocks.Count;
4466 // ppcnt++; 4512 // ppcnt++;
@@ -4486,11 +4532,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4486 // of the object rather than the properties when the packet was created 4532 // of the object rather than the properties when the packet was created
4487 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4533 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4488 updates.Add(familyUpdates.Value[i]); 4534 updates.Add(familyUpdates.Value[i]);
4489 OutPacket(packet, ThrottleOutPacketType.Task, true, 4535 // HACK : Remove intelligent resending until it's fixed in core
4490 delegate(OutgoingPacket oPacket) 4536 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4491 { 4537 // delegate(OutgoingPacket oPacket)
4492 ResendPropertyUpdates(updates, oPacket); 4538 // {
4493 }); 4539 // ResendPropertyUpdates(updates, oPacket);
4540 // });
4541 OutPacket(packet, ThrottleOutPacketType.Task, true);
4494 4542
4495 // fpcnt++; 4543 // fpcnt++;
4496 // fbcnt++; 4544 // fbcnt++;
@@ -4888,7 +4936,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4888 4936
4889 if (landData.SimwideArea > 0) 4937 if (landData.SimwideArea > 0)
4890 { 4938 {
4891 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4939 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4940 // Never report more than sim total capacity
4941 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4942 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4892 updateMessage.SimWideMaxPrims = simulatorCapacity; 4943 updateMessage.SimWideMaxPrims = simulatorCapacity;
4893 } 4944 }
4894 else 4945 else
@@ -5017,14 +5068,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5017 5068
5018 if (notifyCount > 0) 5069 if (notifyCount > 0)
5019 { 5070 {
5020 if (notifyCount > 32) 5071// if (notifyCount > 32)
5021 { 5072// {
5022 m_log.InfoFormat( 5073// m_log.InfoFormat(
5023 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 5074// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
5024 + " - a developer might want to investigate whether this is a hard limit", 32); 5075// + " - a developer might want to investigate whether this is a hard limit", 32);
5025 5076//
5026 notifyCount = 32; 5077// notifyCount = 32;
5027 } 5078// }
5028 5079
5029 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 5080 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
5030 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 5081 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5079,9 +5130,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5079 { 5130 {
5080 ScenePresence presence = (ScenePresence)entity; 5131 ScenePresence presence = (ScenePresence)entity;
5081 5132
5082 attachPoint = presence.State;
5083 collisionPlane = presence.CollisionPlane;
5084 position = presence.OffsetPosition; 5133 position = presence.OffsetPosition;
5134 rotation = presence.Rotation;
5135
5136 if (presence.ParentID != 0)
5137 {
5138 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
5139 if (part != null && part != part.ParentGroup.RootPart)
5140 {
5141 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
5142 rotation = part.RotationOffset * presence.Rotation;
5143 }
5144 angularVelocity = Vector3.Zero;
5145 }
5146 else
5147 {
5148 angularVelocity = presence.AngularVelocity;
5149 rotation = presence.Rotation;
5150 }
5151
5152 attachPoint = 0;
5153 collisionPlane = presence.CollisionPlane;
5085 velocity = presence.Velocity; 5154 velocity = presence.Velocity;
5086 acceleration = Vector3.Zero; 5155 acceleration = Vector3.Zero;
5087 5156
@@ -5090,9 +5159,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5090 // may improve movement smoothness. 5159 // may improve movement smoothness.
5091// acceleration = new Vector3(1, 0, 0); 5160// acceleration = new Vector3(1, 0, 0);
5092 5161
5093 angularVelocity = presence.AngularVelocity;
5094 rotation = presence.Rotation;
5095
5096 if (sendTexture) 5162 if (sendTexture)
5097 textureEntry = presence.Appearance.Texture.GetBytes(); 5163 textureEntry = presence.Appearance.Texture.GetBytes();
5098 else 5164 else
@@ -5198,13 +5264,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5198 5264
5199 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5265 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5200 { 5266 {
5267 Vector3 offsetPosition = data.OffsetPosition;
5268 Quaternion rotation = data.Rotation;
5269 uint parentID = data.ParentID;
5270
5271 if (parentID != 0)
5272 {
5273 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5274 if (part != null && part != part.ParentGroup.RootPart)
5275 {
5276 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5277 rotation = part.RotationOffset * data.Rotation;
5278 parentID = part.ParentGroup.RootPart.LocalId;
5279 }
5280 }
5281
5201 byte[] objectData = new byte[76]; 5282 byte[] objectData = new byte[76];
5202 5283
5203 data.CollisionPlane.ToBytes(objectData, 0); 5284 data.CollisionPlane.ToBytes(objectData, 0);
5204 data.OffsetPosition.ToBytes(objectData, 16); 5285 offsetPosition.ToBytes(objectData, 16);
5286 Vector3 velocity = new Vector3(0, 0, 0);
5287 Vector3 acceleration = new Vector3(0, 0, 0);
5288 velocity.ToBytes(objectData, 28);
5289 acceleration.ToBytes(objectData, 40);
5205// data.Velocity.ToBytes(objectData, 28); 5290// data.Velocity.ToBytes(objectData, 28);
5206// data.Acceleration.ToBytes(objectData, 40); 5291// data.Acceleration.ToBytes(objectData, 40);
5207 data.Rotation.ToBytes(objectData, 52); 5292 rotation.ToBytes(objectData, 52);
5208 //data.AngularVelocity.ToBytes(objectData, 64); 5293 //data.AngularVelocity.ToBytes(objectData, 64);
5209 5294
5210 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5295 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5218,14 +5303,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5218 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5303 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5219 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5304 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5220 update.ObjectData = objectData; 5305 update.ObjectData = objectData;
5221 update.ParentID = data.ParentID; 5306 update.ParentID = parentID;
5222 update.PathCurve = 16; 5307 update.PathCurve = 16;
5223 update.PathScaleX = 100; 5308 update.PathScaleX = 100;
5224 update.PathScaleY = 100; 5309 update.PathScaleY = 100;
5225 update.PCode = (byte)PCode.Avatar; 5310 update.PCode = (byte)PCode.Avatar;
5226 update.ProfileCurve = 1; 5311 update.ProfileCurve = 1;
5227 update.PSBlock = Utils.EmptyBytes; 5312 update.PSBlock = Utils.EmptyBytes;
5228 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5313 update.Scale = data.Appearance.AvatarSize;
5314// update.Scale.Z -= 0.2f;
5315
5229 update.Text = Utils.EmptyBytes; 5316 update.Text = Utils.EmptyBytes;
5230 update.TextColor = new byte[4]; 5317 update.TextColor = new byte[4];
5231 5318
@@ -5236,10 +5323,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5236 update.TextureEntry = Utils.EmptyBytes; 5323 update.TextureEntry = Utils.EmptyBytes;
5237// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5324// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5238 5325
5326/* 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)
5239 update.UpdateFlags = (uint)( 5327 update.UpdateFlags = (uint)(
5240 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5328 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5241 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5329 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5242 PrimFlags.ObjectOwnerModify); 5330 PrimFlags.ObjectOwnerModify);
5331*/
5332 update.UpdateFlags = 0;
5243 5333
5244 return update; 5334 return update;
5245 } 5335 }
@@ -5410,8 +5500,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5410 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5500 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5411 // for each AgentUpdate packet. 5501 // for each AgentUpdate packet.
5412 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5502 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5413 5503
5414 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5504 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5505 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5506 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5415 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5507 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5416 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5508 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5417 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5509 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5563,6 +5655,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5563 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5655 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5564 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5656 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5565 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5657 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5658 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5566 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5659 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5567 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5660 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5568 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5661 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5629,6 +5722,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5629 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5722 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5630 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5723 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5631 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5724 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5725 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5632 5726
5633 AddGenericPacketHandler("autopilot", HandleAutopilot); 5727 AddGenericPacketHandler("autopilot", HandleAutopilot);
5634 } 5728 }
@@ -5981,6 +6075,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5981 return true; 6075 return true;
5982 } 6076 }
5983 6077
6078 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
6079 {
6080 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
6081 if (p.AgentData.SessionID != SessionId ||
6082 p.AgentData.AgentID != AgentId)
6083 return true;
6084
6085 m_VelocityInterpolate = false;
6086 return true;
6087 }
6088
6089 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
6090 {
6091 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
6092 if (p.AgentData.SessionID != SessionId ||
6093 p.AgentData.AgentID != AgentId)
6094 return true;
6095
6096 m_VelocityInterpolate = true;
6097 return true;
6098 }
6099
6100
5984 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 6101 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5985 { 6102 {
5986 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 6103 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6405,26 +6522,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6405 // Temporarily protect ourselves from the mantis #951 failure. 6522 // Temporarily protect ourselves from the mantis #951 failure.
6406 // However, we could do this for several other handlers where a failure isn't terminal 6523 // However, we could do this for several other handlers where a failure isn't terminal
6407 // for the client session anyway, in order to protect ourselves against bad code in plugins 6524 // for the client session anyway, in order to protect ourselves against bad code in plugins
6525 Vector3 avSize = appear.AgentData.Size;
6408 try 6526 try
6409 { 6527 {
6410 byte[] visualparams = new byte[appear.VisualParam.Length]; 6528 byte[] visualparams = new byte[appear.VisualParam.Length];
6411 for (int i = 0; i < appear.VisualParam.Length; i++) 6529 for (int i = 0; i < appear.VisualParam.Length; i++)
6412 visualparams[i] = appear.VisualParam[i].ParamValue; 6530 visualparams[i] = appear.VisualParam[i].ParamValue;
6413 6531 //var b = appear.WearableData[0];
6532
6414 Primitive.TextureEntry te = null; 6533 Primitive.TextureEntry te = null;
6415 if (appear.ObjectData.TextureEntry.Length > 1) 6534 if (appear.ObjectData.TextureEntry.Length > 1)
6416 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6535 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6536
6537 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6538 for (int i=0; i<appear.WearableData.Length;i++)
6539 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6417 6540
6418 List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); 6541
6419 for (int i = 0; i < appear.WearableData.Length; i++)
6420 {
6421 CachedTextureRequestArg arg = new CachedTextureRequestArg();
6422 arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
6423 arg.WearableHashID = appear.WearableData[i].CacheID;
6424 hashes.Add(arg);
6425 }
6426 6542
6427 handlerSetAppearance(sender, te, visualparams, hashes); 6543 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6428 } 6544 }
6429 catch (Exception e) 6545 catch (Exception e)
6430 { 6546 {
@@ -6633,6 +6749,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6633 { 6749 {
6634 handlerCompleteMovementToRegion(sender, true); 6750 handlerCompleteMovementToRegion(sender, true);
6635 } 6751 }
6752 else
6753 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6754
6636 handlerCompleteMovementToRegion = null; 6755 handlerCompleteMovementToRegion = null;
6637 6756
6638 return true; 6757 return true;
@@ -6650,7 +6769,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6650 return true; 6769 return true;
6651 } 6770 }
6652 #endregion 6771 #endregion
6653 6772/*
6654 StartAnim handlerStartAnim = null; 6773 StartAnim handlerStartAnim = null;
6655 StopAnim handlerStopAnim = null; 6774 StopAnim handlerStopAnim = null;
6656 6775
@@ -6674,6 +6793,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6674 } 6793 }
6675 } 6794 }
6676 return true; 6795 return true;
6796*/
6797 ChangeAnim handlerChangeAnim = null;
6798
6799 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6800 {
6801 handlerChangeAnim = OnChangeAnim;
6802 if (handlerChangeAnim != null)
6803 {
6804 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6805 }
6806 }
6807
6808 handlerChangeAnim = OnChangeAnim;
6809 if (handlerChangeAnim != null)
6810 {
6811 handlerChangeAnim(UUID.Zero, false, true);
6812 }
6813
6814 return true;
6677 } 6815 }
6678 6816
6679 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6817 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6919,6 +7057,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6919 #endregion 7057 #endregion
6920 7058
6921 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 7059 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
7060 GenericCall2 handler = OnUpdateThrottles;
7061 if (handler != null)
7062 {
7063 handler();
7064 }
6922 return true; 7065 return true;
6923 } 7066 }
6924 7067
@@ -7343,7 +7486,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7343 physdata.Bounce = phsblock.Restitution; 7486 physdata.Bounce = phsblock.Restitution;
7344 physdata.Density = phsblock.Density; 7487 physdata.Density = phsblock.Density;
7345 physdata.Friction = phsblock.Friction; 7488 physdata.Friction = phsblock.Friction;
7346 physdata.GravitationModifier = phsblock.GravityMultiplier; 7489 physdata.GravitationModifier = phsblock.GravityMultiplier;
7347 } 7490 }
7348 7491
7349 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7492 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7929,6 +8072,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7929 // surrounding scene 8072 // surrounding scene
7930 if ((ImageType)block.Type == ImageType.Baked) 8073 if ((ImageType)block.Type == ImageType.Baked)
7931 args.Priority *= 2.0f; 8074 args.Priority *= 2.0f;
8075 int wearableout = 0;
7932 8076
7933 ImageManager.EnqueueReq(args); 8077 ImageManager.EnqueueReq(args);
7934 } 8078 }
@@ -8963,16 +9107,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8963 9107
8964 #region Parcel related packets 9108 #region Parcel related packets
8965 9109
9110 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
9111 // to be done with minimal resources as possible
9112 // variables temporary here while in test
9113
9114 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
9115 bool RegionHandleRequestsInService = false;
9116
8966 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 9117 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8967 { 9118 {
8968 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 9119 UUID currentUUID;
8969 9120
8970 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 9121 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8971 if (handlerRegionHandleRequest != null) 9122
9123 if (handlerRegionHandleRequest == null)
9124 return true;
9125
9126 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
9127
9128 lock (RegionHandleRequests)
8972 { 9129 {
8973 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 9130 if (RegionHandleRequestsInService)
9131 {
9132 // we are already busy doing a previus request
9133 // so enqueue it
9134 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
9135 return true;
9136 }
9137
9138 // else do it
9139 currentUUID = rhrPack.RequestBlock.RegionID;
9140 RegionHandleRequestsInService = true;
8974 } 9141 }
8975 return true; 9142
9143 while (true)
9144 {
9145 handlerRegionHandleRequest(this, currentUUID);
9146
9147 lock (RegionHandleRequests)
9148 {
9149 // exit condition, nothing to do or closed
9150 // current code seems to assume we may loose the handler at anytime,
9151 // so keep checking it
9152 handlerRegionHandleRequest = OnRegionHandleRequest;
9153
9154 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
9155 {
9156 RegionHandleRequests.Clear();
9157 RegionHandleRequestsInService = false;
9158 return true;
9159 }
9160 currentUUID = RegionHandleRequests.Dequeue();
9161 }
9162 }
9163
9164 return true; // actually unreached
8976 } 9165 }
8977 9166
8978 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 9167 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -10228,7 +10417,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10228 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10417 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10229 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10418 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10230 UpdateMuteListEntry.MuteData.MuteType, 10419 UpdateMuteListEntry.MuteData.MuteType,
10231 UpdateMuteListEntry.AgentData.AgentID); 10420 UpdateMuteListEntry.MuteData.MuteFlags);
10232 return true; 10421 return true;
10233 } 10422 }
10234 return false; 10423 return false;
@@ -10243,8 +10432,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10243 { 10432 {
10244 handlerRemoveMuteListEntry(this, 10433 handlerRemoveMuteListEntry(this,
10245 RemoveMuteListEntry.MuteData.MuteID, 10434 RemoveMuteListEntry.MuteData.MuteID,
10246 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10435 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10247 RemoveMuteListEntry.AgentData.AgentID);
10248 return true; 10436 return true;
10249 } 10437 }
10250 return false; 10438 return false;
@@ -10288,10 +10476,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10288 return false; 10476 return false;
10289 } 10477 }
10290 10478
10479 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10480 {
10481 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10482 (ChangeInventoryItemFlagsPacket)packet;
10483 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10484 if (handlerChangeInventoryItemFlags != null)
10485 {
10486 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10487 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10488 return true;
10489 }
10490 return false;
10491 }
10492
10291 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10493 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10292 { 10494 {
10293 return true; 10495 return true;
10294 } 10496 }
10497
10498 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10499 {
10500 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10501
10502 #region Packet Session and User Check
10503 if (m_checkPackets)
10504 {
10505 if (packet.AgentData.SessionID != SessionId ||
10506 packet.AgentData.AgentID != AgentId)
10507 return true;
10508 }
10509 #endregion
10510 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10511 List<InventoryItemBase> items = new List<InventoryItemBase>();
10512 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10513 {
10514 InventoryItemBase b = new InventoryItemBase();
10515 b.ID = n.OldItemID;
10516 b.Folder = n.OldFolderID;
10517 items.Add(b);
10518 }
10519
10520 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10521 if (handlerMoveItemsAndLeaveCopy != null)
10522 {
10523 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10524 }
10525
10526 return true;
10527 }
10295 10528
10296 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10529 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10297 { 10530 {
@@ -10718,6 +10951,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10718 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10951 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10719 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10952 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10720 10953
10954 Scene scene = (Scene)m_scene;
10955 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10956 {
10957 ScenePresence p;
10958 if (scene.TryGetScenePresence(sender.AgentId, out p))
10959 {
10960 if (p.GodLevel >= 200)
10961 {
10962 groupProfileReply.GroupData.OpenEnrollment = true;
10963 groupProfileReply.GroupData.MembershipFee = 0;
10964 }
10965 }
10966 }
10967
10721 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10968 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10722 } 10969 }
10723 return true; 10970 return true;
@@ -11291,11 +11538,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11291 11538
11292 StartLure handlerStartLure = OnStartLure; 11539 StartLure handlerStartLure = OnStartLure;
11293 if (handlerStartLure != null) 11540 if (handlerStartLure != null)
11294 handlerStartLure(startLureRequest.Info.LureType, 11541 {
11295 Utils.BytesToString( 11542 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11296 startLureRequest.Info.Message), 11543 {
11297 startLureRequest.TargetData[0].TargetID, 11544 handlerStartLure(startLureRequest.Info.LureType,
11298 this); 11545 Utils.BytesToString(
11546 startLureRequest.Info.Message),
11547 startLureRequest.TargetData[i].TargetID,
11548 this);
11549 }
11550 }
11299 return true; 11551 return true;
11300 } 11552 }
11301 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11553 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11409,10 +11661,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11409 } 11661 }
11410 #endregion 11662 #endregion
11411 11663
11412 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11664 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11413 if (handlerClassifiedGodDelete != null) 11665 if (handlerClassifiedGodDelete != null)
11414 handlerClassifiedGodDelete( 11666 handlerClassifiedGodDelete(
11415 classifiedGodDelete.Data.ClassifiedID, 11667 classifiedGodDelete.Data.ClassifiedID,
11668 classifiedGodDelete.Data.QueryID,
11416 this); 11669 this);
11417 return true; 11670 return true;
11418 } 11671 }
@@ -11715,12 +11968,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11715 /// <param name="simclient"></param> 11968 /// <param name="simclient"></param>
11716 /// <param name="packet"></param> 11969 /// <param name="packet"></param>
11717 /// <returns></returns> 11970 /// <returns></returns>
11718 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11971 // TODO: Convert old handler to use new method
11972 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11719 { 11973 {
11720 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11974 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11721 11975
11722 if (cachedtex.AgentData.SessionID != SessionId) 11976 if (cachedtex.AgentData.SessionID != SessionId)
11723 return false; 11977 return false;
11978
11724 11979
11725 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); 11980 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11726 11981
@@ -11733,23 +11988,173 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11733 requestArgs.Add(arg); 11988 requestArgs.Add(arg);
11734 } 11989 }
11735 11990
11736 try 11991 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11992 if (handlerCachedTextureRequest != null)
11737 { 11993 {
11738 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11994 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11739 if (handlerCachedTextureRequest != null) 11995 }
11996
11997 return true;
11998 }*/
11999
12000 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
12001 {
12002 //m_log.Debug("texture cached: " + packet.ToString());
12003 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
12004 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
12005
12006 if (cachedtex.AgentData.SessionID != SessionId)
12007 return false;
12008
12009
12010 // TODO: don't create new blocks if recycling an old packet
12011 cachedresp.AgentData.AgentID = AgentId;
12012 cachedresp.AgentData.SessionID = m_sessionId;
12013 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
12014 m_cachedTextureSerial++;
12015 cachedresp.WearableData =
12016 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
12017
12018 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
12019 // var item = fac.GetBakedTextureFaces(AgentId);
12020 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
12021
12022 IAssetService cache = m_scene.AssetService;
12023 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
12024 //bakedTextureModule = null;
12025 int maxWearablesLoop = cachedtex.WearableData.Length;
12026 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
12027 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
12028
12029 if (bakedTextureModule != null && cache != null)
12030 {
12031 // 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
12032
12033 WearableCacheItem[] cacheItems = null;
12034 ScenePresence p = m_scene.GetScenePresence(AgentId);
12035 if (p.Appearance != null)
12036 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
12037 {
12038 try
12039 {
12040 cacheItems = bakedTextureModule.Get(AgentId);
12041 p.Appearance.WearableCacheItems = cacheItems;
12042 p.Appearance.WearableCacheItemsDirty = false;
12043 }
12044
12045 /*
12046 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
12047 *
12048 catch (System.Net.Sockets.SocketException)
12049 {
12050 cacheItems = null;
12051 }
12052 catch (WebException)
12053 {
12054 cacheItems = null;
12055 }
12056 catch (InvalidOperationException)
12057 {
12058 cacheItems = null;
12059 } */
12060 catch (Exception)
12061 {
12062 cacheItems = null;
12063 }
12064
12065 }
12066 else if (p.Appearance.WearableCacheItems != null)
12067 {
12068 cacheItems = p.Appearance.WearableCacheItems;
12069 }
12070
12071 if (cache != null && cacheItems != null)
12072 {
12073 foreach (WearableCacheItem item in cacheItems)
12074 {
12075
12076 if (cache.GetCached(item.TextureID.ToString()) == null)
12077 {
12078 item.TextureAsset.Temporary = true;
12079 cache.Store(item.TextureAsset);
12080 }
12081
12082
12083 }
12084 }
12085
12086 if (cacheItems != null)
12087 {
12088
12089 for (int i = 0; i < maxWearablesLoop; i++)
12090 {
12091 WearableCacheItem item =
12092 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
12093
12094 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12095 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
12096 cachedresp.WearableData[i].HostName = new byte[0];
12097 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
12098 {
12099
12100 cachedresp.WearableData[i].TextureID = item.TextureID;
12101 }
12102 else
12103 {
12104 cachedresp.WearableData[i].TextureID = UUID.Zero;
12105 }
12106 }
12107 }
12108 else
11740 { 12109 {
11741 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 12110 for (int i = 0; i < maxWearablesLoop; i++)
12111 {
12112 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12113 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12114 cachedresp.WearableData[i].TextureID = UUID.Zero;
12115 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12116 cachedresp.WearableData[i].HostName = new byte[0];
12117 }
11742 } 12118 }
11743 } 12119 }
11744 catch (Exception e) 12120 else
11745 { 12121 {
11746 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); 12122 if (cache == null)
11747 return false; 12123 {
12124 for (int i = 0; i < maxWearablesLoop; i++)
12125 {
12126 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12127 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12128 cachedresp.WearableData[i].TextureID = UUID.Zero;
12129 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12130 cachedresp.WearableData[i].HostName = new byte[0];
12131 }
12132 }
12133 else
12134 {
12135 for (int i = 0; i < maxWearablesLoop; i++)
12136 {
12137 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12138 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12139
12140
12141
12142 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
12143 cachedresp.WearableData[i].TextureID = UUID.Zero;
12144 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12145 else
12146 cachedresp.WearableData[i].TextureID = UUID.Zero;
12147 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12148 cachedresp.WearableData[i].HostName = new byte[0];
12149 }
12150 }
11748 } 12151 }
11749 12152 cachedresp.Header.Zerocoded = true;
12153 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12154
11750 return true; 12155 return true;
11751 } 12156 }
11752 12157
11753 /// <summary> 12158 /// <summary>
11754 /// Send a response back to a client when it asks the asset server (via the region server) if it has 12159 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11755 /// its appearance texture cached. 12160 /// its appearance texture cached.
@@ -11813,209 +12218,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11813 } 12218 }
11814 else 12219 else
11815 { 12220 {
11816// m_log.DebugFormat( 12221 ClientChangeObject updatehandler = onClientChangeObject;
11817// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11818// i, block.Type, part.Name, part.LocalId);
11819 12222
11820// // Do this once since fetch parts creates a new array. 12223 if (updatehandler != null)
11821// SceneObjectPart[] parts = part.ParentGroup.Parts; 12224 {
11822// for (int j = 0; j < parts.Length; j++) 12225 ObjectChangeData udata = new ObjectChangeData();
11823// {
11824// part.StoreUndoState();
11825// parts[j].IgnoreUndoUpdate = true;
11826// }
11827 12226
11828 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 12227 /*ubit from ll JIRA:
12228 * 0x01 position
12229 * 0x02 rotation
12230 * 0x04 scale
12231
12232 * 0x08 LINK_SET
12233 * 0x10 UNIFORM for scale
12234 */
11829 12235
11830 switch (block.Type) 12236 // translate to internal changes
11831 { 12237 // not all cases .. just the ones older code did
11832 case 1:
11833 Vector3 pos1 = new Vector3(block.Data, 0);
11834 12238
11835 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12239 switch (block.Type)
11836 if (handlerUpdatePrimSinglePosition != null) 12240 {
11837 { 12241 case 1: //change position sp
11838 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12242 udata.position = new Vector3(block.Data, 0);
11839 handlerUpdatePrimSinglePosition(localId, pos1, this);
11840 }
11841 break;
11842 12243
11843 case 2: 12244 udata.change = ObjectChangeType.primP;
11844 Quaternion rot1 = new Quaternion(block.Data, 0, true); 12245 updatehandler(localId, udata, this);
12246 break;
11845 12247
11846 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 12248 case 2: // rotation sp
11847 if (handlerUpdatePrimSingleRotation != null) 12249 udata.rotation = new Quaternion(block.Data, 0, true);
11848 {
11849 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11850 handlerUpdatePrimSingleRotation(localId, rot1, this);
11851 }
11852 break;
11853 12250
11854 case 3: 12251 udata.change = ObjectChangeType.primR;
11855 Vector3 rotPos = new Vector3(block.Data, 0); 12252 updatehandler(localId, udata, this);
11856 Quaternion rot2 = new Quaternion(block.Data, 12, true); 12253 break;
11857 12254
11858 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 12255 case 3: // position plus rotation
11859 if (handlerUpdatePrimSingleRotationPosition != null) 12256 udata.position = new Vector3(block.Data, 0);
11860 { 12257 udata.rotation = new Quaternion(block.Data, 12, true);
11861 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11862 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11863 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11864 }
11865 break;
11866 12258
11867 case 4: 12259 udata.change = ObjectChangeType.primPR;
11868 case 20: 12260 updatehandler(localId, udata, this);
11869 Vector3 scale4 = new Vector3(block.Data, 0); 12261 break;
11870 12262
11871 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 12263 case 4: // scale sp
11872 if (handlerUpdatePrimScale != null) 12264 udata.scale = new Vector3(block.Data, 0);
11873 { 12265 udata.change = ObjectChangeType.primS;
11874 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11875 handlerUpdatePrimScale(localId, scale4, this);
11876 }
11877 break;
11878 12266
11879 case 5: 12267 updatehandler(localId, udata, this);
11880 Vector3 scale1 = new Vector3(block.Data, 12); 12268 break;
11881 Vector3 pos11 = new Vector3(block.Data, 0);
11882 12269
11883 handlerUpdatePrimScale = OnUpdatePrimScale; 12270 case 0x14: // uniform scale sp
11884 if (handlerUpdatePrimScale != null) 12271 udata.scale = new Vector3(block.Data, 0);
11885 {
11886 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11887 handlerUpdatePrimScale(localId, scale1, this);
11888 12272
11889 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12273 udata.change = ObjectChangeType.primUS;
11890 if (handlerUpdatePrimSinglePosition != null) 12274 updatehandler(localId, udata, this);
11891 { 12275 break;
11892 handlerUpdatePrimSinglePosition(localId, pos11, this);
11893 }
11894 }
11895 break;
11896 12276
11897 case 9: 12277 case 5: // scale and position sp
11898 Vector3 pos2 = new Vector3(block.Data, 0); 12278 udata.position = new Vector3(block.Data, 0);
12279 udata.scale = new Vector3(block.Data, 12);
11899 12280
11900 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 12281 udata.change = ObjectChangeType.primPS;
12282 updatehandler(localId, udata, this);
12283 break;
11901 12284
11902 if (handlerUpdateVector != null) 12285 case 0x15: //uniform scale and position
11903 { 12286 udata.position = new Vector3(block.Data, 0);
11904 handlerUpdateVector(localId, pos2, this); 12287 udata.scale = new Vector3(block.Data, 12);
11905 }
11906 break;
11907 12288
11908 case 10: 12289 udata.change = ObjectChangeType.primPUS;
11909 Quaternion rot3 = new Quaternion(block.Data, 0, true); 12290 updatehandler(localId, udata, this);
12291 break;
11910 12292
11911 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 12293 // now group related (bit 4)
11912 if (handlerUpdatePrimRotation != null) 12294 case 9: //( 8 + 1 )group position
11913 { 12295 udata.position = new Vector3(block.Data, 0);
11914 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11915 handlerUpdatePrimRotation(localId, rot3, this);
11916 }
11917 break;
11918 12296
11919 case 11: 12297 udata.change = ObjectChangeType.groupP;
11920 Vector3 pos3 = new Vector3(block.Data, 0); 12298 updatehandler(localId, udata, this);
11921 Quaternion rot4 = new Quaternion(block.Data, 12, true); 12299 break;
11922 12300
11923 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 12301 case 0x0A: // (8 + 2) group rotation
11924 if (handlerUpdatePrimGroupRotation != null) 12302 udata.rotation = new Quaternion(block.Data, 0, true);
11925 {
11926 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11927 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11928 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11929 }
11930 break;
11931 case 12:
11932 case 28:
11933 Vector3 scale7 = new Vector3(block.Data, 0);
11934 12303
11935 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12304 udata.change = ObjectChangeType.groupR;
11936 if (handlerUpdatePrimGroupScale != null) 12305 updatehandler(localId, udata, this);
11937 { 12306 break;
11938 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11939 handlerUpdatePrimGroupScale(localId, scale7, this);
11940 }
11941 break;
11942 12307
11943 case 13: 12308 case 0x0B: //( 8 + 2 + 1) group rotation and position
11944 Vector3 scale2 = new Vector3(block.Data, 12); 12309 udata.position = new Vector3(block.Data, 0);
11945 Vector3 pos4 = new Vector3(block.Data, 0); 12310 udata.rotation = new Quaternion(block.Data, 12, true);
11946 12311
11947 handlerUpdatePrimScale = OnUpdatePrimScale; 12312 udata.change = ObjectChangeType.groupPR;
11948 if (handlerUpdatePrimScale != null) 12313 updatehandler(localId, udata, this);
11949 { 12314 break;
11950 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11951 handlerUpdatePrimScale(localId, scale2, this);
11952 12315
11953 // Change the position based on scale (for bug number 246) 12316 case 0x0C: // (8 + 4) group scale
11954 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12317 // only afects root prim and only sent by viewer editor object tab scaling
11955 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12318 // mouse edition only allows uniform scaling
11956 if (handlerUpdatePrimSinglePosition != null) 12319 // SL MAY CHANGE THIS in viewers
11957 {
11958 handlerUpdatePrimSinglePosition(localId, pos4, this);
11959 }
11960 }
11961 break;
11962 12320
11963 case 29: 12321 udata.scale = new Vector3(block.Data, 0);
11964 Vector3 scale5 = new Vector3(block.Data, 12);
11965 Vector3 pos5 = new Vector3(block.Data, 0);
11966 12322
11967 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12323 udata.change = ObjectChangeType.groupS;
11968 if (handlerUpdatePrimGroupScale != null) 12324 updatehandler(localId, udata, this);
11969 {
11970 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11971 part.StoreUndoState(true);
11972 part.IgnoreUndoUpdate = true;
11973 handlerUpdatePrimGroupScale(localId, scale5, this);
11974 handlerUpdateVector = OnUpdatePrimGroupPosition;
11975 12325
11976 if (handlerUpdateVector != null) 12326 break;
11977 {
11978 handlerUpdateVector(localId, pos5, this);
11979 }
11980 12327
11981 part.IgnoreUndoUpdate = false; 12328 case 0x0D: //(8 + 4 + 1) group scale and position
11982 } 12329 // exception as above
11983 12330
11984 break; 12331 udata.position = new Vector3(block.Data, 0);
12332 udata.scale = new Vector3(block.Data, 12);
11985 12333
11986 case 21: 12334 udata.change = ObjectChangeType.groupPS;
11987 Vector3 scale6 = new Vector3(block.Data, 12); 12335 updatehandler(localId, udata, this);
11988 Vector3 pos6 = new Vector3(block.Data, 0); 12336 break;
11989 12337
11990 handlerUpdatePrimScale = OnUpdatePrimScale; 12338 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11991 if (handlerUpdatePrimScale != null) 12339 udata.scale = new Vector3(block.Data, 0);
11992 {
11993 part.StoreUndoState(false);
11994 part.IgnoreUndoUpdate = true;
11995 12340
11996 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12341 udata.change = ObjectChangeType.groupUS;
11997 handlerUpdatePrimScale(localId, scale6, this); 12342 updatehandler(localId, udata, this);
11998 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12343 break;
11999 if (handlerUpdatePrimSinglePosition != null)
12000 {
12001 handlerUpdatePrimSinglePosition(localId, pos6, this);
12002 }
12003 12344
12004 part.IgnoreUndoUpdate = false; 12345 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
12005 } 12346 udata.position = new Vector3(block.Data, 0);
12006 break; 12347 udata.scale = new Vector3(block.Data, 12);
12007 12348
12008 default: 12349 udata.change = ObjectChangeType.groupPUS;
12009 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12350 updatehandler(localId, udata, this);
12010 break; 12351 break;
12352
12353 default:
12354 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12355 break;
12356 }
12011 } 12357 }
12012 12358
12013// for (int j = 0; j < parts.Length; j++)
12014// parts[j].IgnoreUndoUpdate = false;
12015 } 12359 }
12016 } 12360 }
12017 } 12361 }
12018
12019 return true; 12362 return true;
12020 } 12363 }
12021 12364
@@ -12076,8 +12419,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12076 public void SetChildAgentThrottle(byte[] throttles) 12419 public void SetChildAgentThrottle(byte[] throttles)
12077 { 12420 {
12078 m_udpClient.SetThrottles(throttles); 12421 m_udpClient.SetThrottles(throttles);
12422 GenericCall2 handler = OnUpdateThrottles;
12423 if (handler != null)
12424 {
12425 handler();
12426 }
12427 }
12428
12429 /// <summary>
12430 /// Sets the throttles from values supplied by the client
12431 /// </summary>
12432 /// <param name="throttles"></param>
12433 public void SetAgentThrottleSilent(int throttle, int setting)
12434 {
12435 m_udpClient.ForceThrottleSetting(throttle,setting);
12436 //m_udpClient.SetThrottles(throttles);
12437
12079 } 12438 }
12080 12439
12440
12081 /// <summary> 12441 /// <summary>
12082 /// Get the current throttles for this client as a packed byte array 12442 /// Get the current throttles for this client as a packed byte array
12083 /// </summary> 12443 /// </summary>
@@ -12461,7 +12821,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12461// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12821// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12462// requestID, taskID, (SourceType)sourceType, Name); 12822// requestID, taskID, (SourceType)sourceType, Name);
12463 12823
12824
12825 //Note, the bool returned from the below function is useless since it is always false.
12464 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12826 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12827
12465 } 12828 }
12466 12829
12467 /// <summary> 12830 /// <summary>
@@ -12527,7 +12890,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12527 /// <returns></returns> 12890 /// <returns></returns>
12528 private static int CalculateNumPackets(byte[] data) 12891 private static int CalculateNumPackets(byte[] data)
12529 { 12892 {
12530 const uint m_maxPacketSize = 600; 12893// const uint m_maxPacketSize = 600;
12894 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12531 int numPackets = 1; 12895 int numPackets = 1;
12532 12896
12533 if (data == null) 12897 if (data == null)