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.cs1538
1 files changed, 933 insertions, 605 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 3a0ddae..f8e2a60 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);
@@ -2719,6 +2732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2719 float friction = part.Friction; 2732 float friction = part.Friction;
2720 float bounce = part.Restitution; 2733 float bounce = part.Restitution;
2721 float gravmod = part.GravityModifier; 2734 float gravmod = part.GravityModifier;
2735
2722 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2736 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2723 } 2737 }
2724 } 2738 }
@@ -2789,8 +2803,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2789 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2803 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2790 return; 2804 return;
2791 } 2805 }
2806 int WearableOut = 0;
2807 bool isWearable = false;
2792 2808
2793 //m_log.Debug("sending asset " + req.RequestAssetID); 2809 if (req.AssetInf != null)
2810 isWearable =
2811 ((AssetType) req.AssetInf.Type ==
2812 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2813
2814
2815 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2816
2817
2818 //if (isWearable)
2819 // m_log.Debug((AssetType)req.AssetInf.Type);
2820
2794 TransferInfoPacket Transfer = new TransferInfoPacket(); 2821 TransferInfoPacket Transfer = new TransferInfoPacket();
2795 Transfer.TransferInfo.ChannelType = 2; 2822 Transfer.TransferInfo.ChannelType = 2;
2796 Transfer.TransferInfo.Status = 0; 2823 Transfer.TransferInfo.Status = 0;
@@ -2812,7 +2839,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2812 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2839 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2813 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2840 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2814 Transfer.Header.Zerocoded = true; 2841 Transfer.Header.Zerocoded = true;
2815 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2842 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2816 2843
2817 if (req.NumPackets == 1) 2844 if (req.NumPackets == 1)
2818 { 2845 {
@@ -2823,12 +2850,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2823 TransferPacket.TransferData.Data = req.AssetInf.Data; 2850 TransferPacket.TransferData.Data = req.AssetInf.Data;
2824 TransferPacket.TransferData.Status = 1; 2851 TransferPacket.TransferData.Status = 1;
2825 TransferPacket.Header.Zerocoded = true; 2852 TransferPacket.Header.Zerocoded = true;
2826 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2853 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2827 } 2854 }
2828 else 2855 else
2829 { 2856 {
2830 int processedLength = 0; 2857 int processedLength = 0;
2831 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2858// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2859
2860 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2832 int packetNumber = 0; 2861 int packetNumber = 0;
2833 2862
2834 while (processedLength < req.AssetInf.Data.Length) 2863 while (processedLength < req.AssetInf.Data.Length)
@@ -2854,7 +2883,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2854 TransferPacket.TransferData.Status = 1; 2883 TransferPacket.TransferData.Status = 1;
2855 } 2884 }
2856 TransferPacket.Header.Zerocoded = true; 2885 TransferPacket.Header.Zerocoded = true;
2857 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2886 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2858 2887
2859 processedLength += chunkSize; 2888 processedLength += chunkSize;
2860 packetNumber++; 2889 packetNumber++;
@@ -2899,7 +2928,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2899 reply.Data.ParcelID = parcelID; 2928 reply.Data.ParcelID = parcelID;
2900 reply.Data.OwnerID = land.OwnerID; 2929 reply.Data.OwnerID = land.OwnerID;
2901 reply.Data.Name = Utils.StringToBytes(land.Name); 2930 reply.Data.Name = Utils.StringToBytes(land.Name);
2902 reply.Data.Desc = Utils.StringToBytes(land.Description); 2931 if (land != null && land.Description != null && land.Description != String.Empty)
2932 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2933 else
2934 reply.Data.Desc = new Byte[0];
2903 reply.Data.ActualArea = land.Area; 2935 reply.Data.ActualArea = land.Area;
2904 reply.Data.BillableArea = land.Area; // TODO: what is this? 2936 reply.Data.BillableArea = land.Area; // TODO: what is this?
2905 2937
@@ -3606,24 +3638,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3606 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3638 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3607 AgentWearablesUpdatePacket.WearableDataBlock awb; 3639 AgentWearablesUpdatePacket.WearableDataBlock awb;
3608 int idx = 0; 3640 int idx = 0;
3609 for (int i = 0; i < wearables.Length; i++) 3641
3610 { 3642 for (int i = 0; i < wearables.Length; i++)
3611 for (int j = 0; j < wearables[i].Count; j++) 3643 {
3612 { 3644 for (int j = 0; j < wearables[i].Count; j++)
3613 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3645 {
3614 awb.WearableType = (byte)i; 3646 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3615 awb.AssetID = wearables[i][j].AssetID; 3647 awb.WearableType = (byte) i;
3616 awb.ItemID = wearables[i][j].ItemID; 3648 awb.AssetID = wearables[i][j].AssetID;
3617 aw.WearableData[idx] = awb; 3649 awb.ItemID = wearables[i][j].ItemID;
3618 idx++; 3650 aw.WearableData[idx] = awb;
3619 3651 idx++;
3620// m_log.DebugFormat( 3652
3621// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3653 // m_log.DebugFormat(
3622// awb.ItemID, awb.AssetID, i, Name); 3654 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3623 } 3655 // awb.ItemID, awb.AssetID, i, Name);
3624 } 3656 }
3657 }
3625 3658
3626 OutPacket(aw, ThrottleOutPacketType.Task); 3659 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3627 } 3660 }
3628 3661
3629 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3662 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3765,7 +3798,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3765 /// </summary> 3798 /// </summary>
3766 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3799 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3767 { 3800 {
3768 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3801 if (entity is SceneObjectPart)
3802 {
3803 SceneObjectPart e = (SceneObjectPart)entity;
3804 SceneObjectGroup g = e.ParentGroup;
3805 if (g.RootPart.Shape.State > 30) // HUD
3806 if (g.OwnerID != AgentId)
3807 return; // Don't send updates for other people's HUDs
3808 }
3809
3769 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3810 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3770 3811
3771 lock (m_entityUpdates.SyncRoot) 3812 lock (m_entityUpdates.SyncRoot)
@@ -3856,27 +3897,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3856 3897
3857 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3898 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3858 // condition where a kill can be processed before an out-of-date update for the same object. 3899 // condition where a kill can be processed before an out-of-date update for the same object.
3859 lock (m_killRecord) 3900 float avgTimeDilation = 1.0f;
3901 IEntityUpdate iupdate;
3902 Int32 timeinqueue; // this is just debugging code & can be dropped later
3903
3904 while (updatesThisCall < maxUpdates)
3860 { 3905 {
3861 float avgTimeDilation = 1.0f; 3906 lock (m_entityUpdates.SyncRoot)
3862 IEntityUpdate iupdate; 3907 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3863 Int32 timeinqueue; // this is just debugging code & can be dropped later 3908 break;
3864 3909
3865 while (updatesThisCall < maxUpdates) 3910 EntityUpdate update = (EntityUpdate)iupdate;
3911
3912 avgTimeDilation += update.TimeDilation;
3913 avgTimeDilation *= 0.5f;
3914
3915 if (update.Entity is SceneObjectPart)
3866 { 3916 {
3867 lock (m_entityUpdates.SyncRoot) 3917 SceneObjectPart part = (SceneObjectPart)update.Entity;
3868 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3869 break;
3870 3918
3871 EntityUpdate update = (EntityUpdate)iupdate; 3919 if (part.ParentGroup.IsDeleted)
3872 3920 continue;
3873 avgTimeDilation += update.TimeDilation;
3874 avgTimeDilation *= 0.5f;
3875 3921
3876 if (update.Entity is SceneObjectPart) 3922 if (part.ParentGroup.IsAttachment)
3923 { // Someone else's HUD, why are we getting these?
3924 if (part.ParentGroup.OwnerID != AgentId &&
3925 part.ParentGroup.RootPart.Shape.State > 30)
3926 continue;
3927 ScenePresence sp;
3928 // Owner is not in the sim, don't update it to
3929 // anyone
3930 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3931 continue;
3932
3933 List<SceneObjectGroup> atts = sp.GetAttachments();
3934 bool found = false;
3935 foreach (SceneObjectGroup att in atts)
3936 {
3937 if (att == part.ParentGroup)
3938 {
3939 found = true;
3940 break;
3941 }
3942 }
3943
3944 // It's an attachment of a valid avatar, but
3945 // doesn't seem to be attached, skip
3946 if (!found)
3947 continue;
3948
3949 // On vehicle crossing, the attachments are received
3950 // while the avatar is still a child. Don't send
3951 // updates here because the LocalId has not yet
3952 // been updated and the viewer will derender the
3953 // attachments until the avatar becomes root.
3954 if (sp.IsChildAgent)
3955 continue;
3956
3957 // If the object is an attachment we don't want it to be in the kill
3958 // record. Else attaching from inworld and subsequently dropping
3959 // it will no longer work.
3960// lock (m_killRecord)
3961// {
3962// m_killRecord.Remove(part.LocalId);
3963// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3964// }
3965 }
3966 else
3877 { 3967 {
3878 SceneObjectPart part = (SceneObjectPart)update.Entity;
3879
3880 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3968 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3881 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3969 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3882 // safety measure. 3970 // safety measure.
@@ -3887,21 +3975,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3887 // 3975 //
3888 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3976 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3889 // after the root prim has been deleted. 3977 // after the root prim has been deleted.
3890 if (m_killRecord.Contains(part.LocalId)) 3978 //
3891 { 3979 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3892 // m_log.WarnFormat( 3980// lock (m_killRecord)
3893 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3981// {
3894 // part.LocalId, Name); 3982// if (m_killRecord.Contains(part.LocalId))
3895 continue; 3983// continue;
3896 } 3984// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3897 3985// continue;
3898 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3986// }
3987 }
3988
3989 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3990 {
3991 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3992 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3899 { 3993 {
3900 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3994 part.Shape.LightEntry = false;
3901 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3902 {
3903 part.Shape.LightEntry = false;
3904 }
3905 } 3995 }
3906 3996
3907 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3997 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3912,224 +4002,178 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3912 part.Shape.ProfileHollow = 27500; 4002 part.Shape.ProfileHollow = 27500;
3913 } 4003 }
3914 } 4004 }
3915 4005
3916 #region UpdateFlags to packet type conversion 4006 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3917
3918 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3919
3920 bool canUseCompressed = true;
3921 bool canUseImproved = true;
3922
3923 // Compressed object updates only make sense for LL primitives
3924 if (!(update.Entity is SceneObjectPart))
3925 { 4007 {
3926 canUseCompressed = false; 4008 // Ensure that mesh has at least 8 valid faces
4009 part.Shape.ProfileBegin = 12500;
4010 part.Shape.ProfileEnd = 0;
4011 part.Shape.ProfileHollow = 27500;
3927 } 4012 }
3928 4013 }
3929 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 4014 else if (update.Entity is ScenePresence)
4015 {
4016 ScenePresence presence = (ScenePresence)update.Entity;
4017
4018 // If ParentUUID is not UUID.Zero and ParentID is 0, this
4019 // avatar is in the process of crossing regions while
4020 // sat on an object. In this state, we don't want any
4021 // updates because they will visually orbit the avatar.
4022 // Update will be forced once crossing is completed anyway.
4023 if (presence.ParentUUID != UUID.Zero && presence.ParentID == 0)
4024 continue;
4025 }
4026
4027 ++updatesThisCall;
4028
4029 #region UpdateFlags to packet type conversion
4030
4031 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
4032
4033 bool canUseCompressed = true;
4034 bool canUseImproved = true;
4035
4036 // Compressed object updates only make sense for LL primitives
4037 if (!(update.Entity is SceneObjectPart))
4038 {
4039 canUseCompressed = false;
4040 }
4041
4042 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
4043 {
4044 canUseCompressed = false;
4045 canUseImproved = false;
4046 }
4047 else
4048 {
4049 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
4050 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
4051 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
4052 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3930 { 4053 {
3931 canUseCompressed = false; 4054 canUseCompressed = false;
3932 canUseImproved = false;
3933 } 4055 }
3934 else 4056
4057 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
4058 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
4059 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
4060 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
4061 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
4062 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
4063 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
4064 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
4065 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
4066 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
4067 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
4068 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
4069 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
4070 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3935 { 4071 {
3936 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 4072 canUseImproved = false;
3937 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3938 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3939 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3940 {
3941 canUseCompressed = false;
3942 }
3943
3944 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3945 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3950 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3951 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3952 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3953 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3957 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3958 {
3959 canUseImproved = false;
3960 }
3961 } 4073 }
4074 }
3962 4075
3963 #endregion UpdateFlags to packet type conversion 4076 #endregion UpdateFlags to packet type conversion
3964
3965 #region Block Construction
3966
3967 // TODO: Remove this once we can build compressed updates
3968 canUseCompressed = false;
3969
3970 if (!canUseImproved && !canUseCompressed)
3971 {
3972 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3973 4077
3974 if (update.Entity is ScenePresence) 4078 #region Block Construction
3975 {
3976 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3977 }
3978 else
3979 {
3980 SceneObjectPart part = (SceneObjectPart)update.Entity;
3981 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3982
3983 // If the part has become a private hud since the update was scheduled then we do not
3984 // want to send it to other avatars.
3985 if (part.ParentGroup.IsAttachment
3986 && part.ParentGroup.HasPrivateAttachmentPoint
3987 && part.ParentGroup.AttachedAvatar != AgentId)
3988 continue;
3989
3990 // If the part has since been deleted, then drop the update. In the case of attachments,
3991 // this is to avoid spurious updates to other viewers since post-processing of attachments
3992 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3993 // of the test above).
3994 //
3995 // Actual deletions (kills) happen in another method.
3996 if (part.ParentGroup.IsDeleted)
3997 continue;
3998 }
3999 4079
4000 objectUpdateBlocks.Value.Add(updateBlock); 4080 // TODO: Remove this once we can build compressed updates
4001 objectUpdates.Value.Add(update); 4081 canUseCompressed = false;
4002 }
4003 else if (!canUseImproved)
4004 {
4005 SceneObjectPart part = (SceneObjectPart)update.Entity;
4006 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
4007 = CreateCompressedUpdateBlock(part, updateFlags);
4008
4009 // If the part has since been deleted, then drop the update. In the case of attachments,
4010 // this is to avoid spurious updates to other viewers since post-processing of attachments
4011 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4012 // of the test above).
4013 //
4014 // Actual deletions (kills) happen in another method.
4015 if (part.ParentGroup.IsDeleted)
4016 continue;
4017 4082
4018 compressedUpdateBlocks.Value.Add(compressedBlock); 4083 if (!canUseImproved && !canUseCompressed)
4019 compressedUpdates.Value.Add(update); 4084 {
4085 if (update.Entity is ScenePresence)
4086 {
4087 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
4020 } 4088 }
4021 else 4089 else
4022 { 4090 {
4023 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 4091 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
4024 {
4025 // Self updates go into a special list
4026 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4027 terseAgentUpdates.Value.Add(update);
4028 }
4029 else
4030 {
4031 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
4032 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4033
4034 // Everything else goes here
4035 if (update.Entity is SceneObjectPart)
4036 {
4037 SceneObjectPart part = (SceneObjectPart)update.Entity;
4038
4039 // If the part has become a private hud since the update was scheduled then we do not
4040 // want to send it to other avatars.
4041 if (part.ParentGroup.IsAttachment
4042 && part.ParentGroup.HasPrivateAttachmentPoint
4043 && part.ParentGroup.AttachedAvatar != AgentId)
4044 continue;
4045
4046 // If the part has since been deleted, then drop the update. In the case of attachments,
4047 // this is to avoid spurious updates to other viewers since post-processing of attachments
4048 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4049 // of the test above).
4050 //
4051 // Actual deletions (kills) happen in another method.
4052 if (part.ParentGroup.IsDeleted)
4053 continue;
4054 }
4055
4056 terseUpdateBlocks.Value.Add(terseUpdateBlock);
4057 terseUpdates.Value.Add(update);
4058 }
4059 } 4092 }
4060
4061 ++updatesThisCall;
4062
4063 #endregion Block Construction
4064 } 4093 }
4065 4094 else if (!canUseImproved)
4066 #region Packet Sending
4067 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4068
4069 if (terseAgentUpdateBlocks.IsValueCreated)
4070 { 4095 {
4071 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4096 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
4097 }
4098 else
4099 {
4100 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4101 // Self updates go into a special list
4102 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4103 else
4104 // Everything else goes here
4105 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4106 }
4072 4107
4073 ImprovedTerseObjectUpdatePacket packet 4108 #endregion Block Construction
4074 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4109 }
4075 4110
4076 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4111 #region Packet Sending
4077 packet.RegionData.TimeDilation = timeDilation; 4112
4078 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4113 const float TIME_DILATION = 1.0f;
4114 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4115
4116 if (terseAgentUpdateBlocks.IsValueCreated)
4117 {
4118 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4079 4119
4080 for (int i = 0; i < blocks.Count; i++) 4120 ImprovedTerseObjectUpdatePacket packet
4081 packet.ObjectData[i] = blocks[i]; 4121 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4082 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4122 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4083 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4123 packet.RegionData.TimeDilation = timeDilation;
4084 } 4124 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4085 4125
4086 if (objectUpdateBlocks.IsValueCreated) 4126 for (int i = 0; i < blocks.Count; i++)
4087 { 4127 packet.ObjectData[i] = blocks[i];
4088 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4089
4090 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4091 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4092 packet.RegionData.TimeDilation = timeDilation;
4093 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4094
4095 for (int i = 0; i < blocks.Count; i++)
4096 packet.ObjectData[i] = blocks[i];
4097 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4098 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4099 }
4100
4101 if (compressedUpdateBlocks.IsValueCreated)
4102 {
4103 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4104
4105 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4106 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4107 packet.RegionData.TimeDilation = timeDilation;
4108 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4109
4110 for (int i = 0; i < blocks.Count; i++)
4111 packet.ObjectData[i] = blocks[i];
4112 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4113 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4114 }
4115 4128
4116 if (terseUpdateBlocks.IsValueCreated) 4129 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4117 { 4130 }
4118 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4119
4120 ImprovedTerseObjectUpdatePacket packet
4121 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4122 PacketType.ImprovedTerseObjectUpdate);
4123 4131
4124 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4132 if (objectUpdateBlocks.IsValueCreated)
4125 packet.RegionData.TimeDilation = timeDilation; 4133 {
4126 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4134 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4127 4135
4128 for (int i = 0; i < blocks.Count; i++) 4136 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4129 packet.ObjectData[i] = blocks[i]; 4137 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4130 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4138 packet.RegionData.TimeDilation = timeDilation;
4131 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4139 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4132 } 4140
4141 for (int i = 0; i < blocks.Count; i++)
4142 packet.ObjectData[i] = blocks[i];
4143
4144 OutPacket(packet, ThrottleOutPacketType.Task, true);
4145 }
4146
4147 if (compressedUpdateBlocks.IsValueCreated)
4148 {
4149 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4150
4151 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4152 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4153 packet.RegionData.TimeDilation = timeDilation;
4154 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4155
4156 for (int i = 0; i < blocks.Count; i++)
4157 packet.ObjectData[i] = blocks[i];
4158
4159 OutPacket(packet, ThrottleOutPacketType.Task, true);
4160 }
4161
4162 if (terseUpdateBlocks.IsValueCreated)
4163 {
4164 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4165
4166 ImprovedTerseObjectUpdatePacket packet
4167 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4168 PacketType.ImprovedTerseObjectUpdate);
4169 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4170 packet.RegionData.TimeDilation = timeDilation;
4171 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4172
4173 for (int i = 0; i < blocks.Count; i++)
4174 packet.ObjectData[i] = blocks[i];
4175
4176 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4133 } 4177 }
4134 4178
4135 #endregion Packet Sending 4179 #endregion Packet Sending
@@ -4453,11 +4497,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4453 4497
4454 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4498 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4455 // of the object rather than the properties when the packet was created 4499 // of the object rather than the properties when the packet was created
4456 OutPacket(packet, ThrottleOutPacketType.Task, true, 4500 // HACK : Remove intelligent resending until it's fixed in core
4457 delegate(OutgoingPacket oPacket) 4501 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4458 { 4502 // delegate(OutgoingPacket oPacket)
4459 ResendPropertyUpdates(updates, oPacket); 4503 // {
4460 }); 4504 // ResendPropertyUpdates(updates, oPacket);
4505 // });
4506 OutPacket(packet, ThrottleOutPacketType.Task, true);
4461 4507
4462 // pbcnt += blocks.Count; 4508 // pbcnt += blocks.Count;
4463 // ppcnt++; 4509 // ppcnt++;
@@ -4483,11 +4529,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4483 // of the object rather than the properties when the packet was created 4529 // of the object rather than the properties when the packet was created
4484 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4530 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4485 updates.Add(familyUpdates.Value[i]); 4531 updates.Add(familyUpdates.Value[i]);
4486 OutPacket(packet, ThrottleOutPacketType.Task, true, 4532 // HACK : Remove intelligent resending until it's fixed in core
4487 delegate(OutgoingPacket oPacket) 4533 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4488 { 4534 // delegate(OutgoingPacket oPacket)
4489 ResendPropertyUpdates(updates, oPacket); 4535 // {
4490 }); 4536 // ResendPropertyUpdates(updates, oPacket);
4537 // });
4538 OutPacket(packet, ThrottleOutPacketType.Task, true);
4491 4539
4492 // fpcnt++; 4540 // fpcnt++;
4493 // fbcnt++; 4541 // fbcnt++;
@@ -4885,7 +4933,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4885 4933
4886 if (landData.SimwideArea > 0) 4934 if (landData.SimwideArea > 0)
4887 { 4935 {
4888 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4936 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4937 // Never report more than sim total capacity
4938 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4939 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4889 updateMessage.SimWideMaxPrims = simulatorCapacity; 4940 updateMessage.SimWideMaxPrims = simulatorCapacity;
4890 } 4941 }
4891 else 4942 else
@@ -5014,14 +5065,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5014 5065
5015 if (notifyCount > 0) 5066 if (notifyCount > 0)
5016 { 5067 {
5017 if (notifyCount > 32) 5068// if (notifyCount > 32)
5018 { 5069// {
5019 m_log.InfoFormat( 5070// m_log.InfoFormat(
5020 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 5071// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
5021 + " - a developer might want to investigate whether this is a hard limit", 32); 5072// + " - a developer might want to investigate whether this is a hard limit", 32);
5022 5073//
5023 notifyCount = 32; 5074// notifyCount = 32;
5024 } 5075// }
5025 5076
5026 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 5077 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
5027 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 5078 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -5076,38 +5127,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5076 { 5127 {
5077 ScenePresence presence = (ScenePresence)entity; 5128 ScenePresence presence = (ScenePresence)entity;
5078 5129
5130 position = presence.OffsetPosition;
5131 rotation = presence.Rotation;
5132
5133 if (presence.ParentID != 0)
5134 {
5135 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
5136 if (part != null && part != part.ParentGroup.RootPart)
5137 {
5138 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
5139 rotation = part.RotationOffset * presence.Rotation;
5140 }
5141 angularVelocity = Vector3.Zero;
5142 }
5143 else
5144 {
5145 angularVelocity = presence.AngularVelocity;
5146 rotation = presence.Rotation;
5147 }
5148
5149 attachPoint = 0;
5079// m_log.DebugFormat( 5150// m_log.DebugFormat(
5080// "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name); 5151// "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name);
5081 5152
5082 attachPoint = presence.State; 5153 // attachPoint = presence.State; // Core: commented
5083 collisionPlane = presence.CollisionPlane; 5154 collisionPlane = presence.CollisionPlane;
5084 position = presence.OffsetPosition;
5085 velocity = presence.Velocity; 5155 velocity = presence.Velocity;
5086 acceleration = Vector3.Zero; 5156 acceleration = Vector3.Zero;
5087 5157
5088 // Interestingly, sending this to non-zero will cause the client's avatar to start moving & accelerating
5089 // in that direction, even though we don't model this on the server. Implementing this in the future
5090 // may improve movement smoothness.
5091// acceleration = new Vector3(1, 0, 0);
5092
5093 angularVelocity = presence.AngularVelocity;
5094
5095 // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis
5096 // it rotates around.
5097 // In mouselook, X and Y co-ordinate will also be sent but when used in Rotation, these cause unwanted
5098 // excessive up and down movements of the camera when looking up and down.
5099 // See http://opensimulator.org/mantis/view.php?id=3274
5100 // This does not affect head movement, since this is controlled entirely by camera movement rather than
5101 // body rotation. We still need to transmit X and Y for sitting avatars but mouselook does not change
5102 // the rotation in this case.
5103 rotation = presence.Rotation;
5104
5105 if (!presence.IsSatOnObject)
5106 {
5107 rotation.X = 0;
5108 rotation.Y = 0;
5109 }
5110
5111 if (sendTexture) 5158 if (sendTexture)
5112 textureEntry = presence.Appearance.Texture.GetBytes(); 5159 textureEntry = presence.Appearance.Texture.GetBytes();
5113 else 5160 else
@@ -5213,33 +5260,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5213 5260
5214 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5261 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5215 { 5262 {
5263 Vector3 offsetPosition = data.OffsetPosition;
5264 Quaternion rotation = data.Rotation;
5265 uint parentID = data.ParentID;
5266
5267 if (parentID != 0)
5268 {
5269 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5270 if (part != null && part != part.ParentGroup.RootPart)
5271 {
5272 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5273 rotation = part.RotationOffset * data.Rotation;
5274 parentID = part.ParentGroup.RootPart.LocalId;
5275 }
5276 }
5216// m_log.DebugFormat( 5277// m_log.DebugFormat(
5217// "[LLCLIENTVIEW]: Sending full update to {0} with position {1} in {2}", Name, data.OffsetPosition, m_scene.Name); 5278// "[LLCLIENTVIEW]: Sending full update to {0} with position {1} in {2}", Name, data.OffsetPosition, m_scene.Name);
5218 5279
5219 byte[] objectData = new byte[76]; 5280 byte[] objectData = new byte[76];
5220 5281
5221 data.CollisionPlane.ToBytes(objectData, 0); 5282 data.CollisionPlane.ToBytes(objectData, 0);
5222 data.OffsetPosition.ToBytes(objectData, 16); 5283 offsetPosition.ToBytes(objectData, 16);
5284 Vector3 velocity = new Vector3(0, 0, 0);
5285 Vector3 acceleration = new Vector3(0, 0, 0);
5286 velocity.ToBytes(objectData, 28);
5287 acceleration.ToBytes(objectData, 40);
5223// data.Velocity.ToBytes(objectData, 28); 5288// data.Velocity.ToBytes(objectData, 28);
5224// data.Acceleration.ToBytes(objectData, 40); 5289// data.Acceleration.ToBytes(objectData, 40);
5225 5290 rotation.ToBytes(objectData, 52);
5226 // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis
5227 // it rotates around.
5228 // In mouselook, X and Y co-ordinate will also be sent but when used in Rotation, these cause unwanted
5229 // excessive up and down movements of the camera when looking up and down.
5230 // See http://opensimulator.org/mantis/view.php?id=3274
5231 // This does not affect head movement, since this is controlled entirely by camera movement rather than
5232 // body rotation. We still need to transmit X and Y for sitting avatars but mouselook does not change
5233 // the rotation in this case.
5234 Quaternion rot = data.Rotation;
5235
5236 if (!data.IsSatOnObject)
5237 {
5238 rot.X = 0;
5239 rot.Y = 0;
5240 }
5241
5242 rot.ToBytes(objectData, 52);
5243 //data.AngularVelocity.ToBytes(objectData, 64); 5291 //data.AngularVelocity.ToBytes(objectData, 64);
5244 5292
5245 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5293 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5266,7 +5314,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5266 update.PCode = (byte)PCode.Avatar; 5314 update.PCode = (byte)PCode.Avatar;
5267 update.ProfileCurve = 1; 5315 update.ProfileCurve = 1;
5268 update.PSBlock = Utils.EmptyBytes; 5316 update.PSBlock = Utils.EmptyBytes;
5269 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5317 update.Scale = data.Appearance.AvatarSize;
5318// update.Scale.Z -= 0.2f;
5319
5270 update.Text = Utils.EmptyBytes; 5320 update.Text = Utils.EmptyBytes;
5271 update.TextColor = new byte[4]; 5321 update.TextColor = new byte[4];
5272 5322
@@ -5277,10 +5327,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5277 update.TextureEntry = Utils.EmptyBytes; 5327 update.TextureEntry = Utils.EmptyBytes;
5278// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5328// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5279 5329
5330/* 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)
5280 update.UpdateFlags = (uint)( 5331 update.UpdateFlags = (uint)(
5281 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5332 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5282 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5333 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5283 PrimFlags.ObjectOwnerModify); 5334 PrimFlags.ObjectOwnerModify);
5335*/
5336 update.UpdateFlags = 0;
5284 5337
5285 return update; 5338 return update;
5286 } 5339 }
@@ -5451,8 +5504,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5451 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5504 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5452 // for each AgentUpdate packet. 5505 // for each AgentUpdate packet.
5453 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5506 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5454 5507
5455 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5508 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5509 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5510 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5456 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5511 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5457 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5512 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5458 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5513 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5604,6 +5659,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5604 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5659 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5605 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5660 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5606 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5661 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5662 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5607 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5663 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5608 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5664 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5609 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5665 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5670,6 +5726,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5670 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5726 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5671 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5727 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5672 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5728 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5729 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5673 5730
5674 AddGenericPacketHandler("autopilot", HandleAutopilot); 5731 AddGenericPacketHandler("autopilot", HandleAutopilot);
5675 } 5732 }
@@ -6022,6 +6079,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6022 return true; 6079 return true;
6023 } 6080 }
6024 6081
6082 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
6083 {
6084 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
6085 if (p.AgentData.SessionID != SessionId ||
6086 p.AgentData.AgentID != AgentId)
6087 return true;
6088
6089 m_VelocityInterpolate = false;
6090 return true;
6091 }
6092
6093 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
6094 {
6095 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
6096 if (p.AgentData.SessionID != SessionId ||
6097 p.AgentData.AgentID != AgentId)
6098 return true;
6099
6100 m_VelocityInterpolate = true;
6101 return true;
6102 }
6103
6104
6025 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 6105 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
6026 { 6106 {
6027 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 6107 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6453,16 +6533,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6453 for (int i = 0; i < appear.VisualParam.Length; i++) 6533 for (int i = 0; i < appear.VisualParam.Length; i++)
6454 visualparams[i] = appear.VisualParam[i].ParamValue; 6534 visualparams[i] = appear.VisualParam[i].ParamValue;
6455 //var b = appear.WearableData[0]; 6535 //var b = appear.WearableData[0];
6456 6536
6457 Primitive.TextureEntry te = null; 6537 Primitive.TextureEntry te = null;
6458 if (appear.ObjectData.TextureEntry.Length > 1) 6538 if (appear.ObjectData.TextureEntry.Length > 1)
6459 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6539 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6460 6540
6461 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length]; 6541 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6462 for (int i=0; i<appear.WearableData.Length;i++) 6542 for (int i=0; i<appear.WearableData.Length;i++)
6463 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)}; 6543 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6464 6544
6465 6545
6466 6546
6467 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems); 6547 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6468 } 6548 }
@@ -6673,6 +6753,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6673 { 6753 {
6674 handlerCompleteMovementToRegion(sender, true); 6754 handlerCompleteMovementToRegion(sender, true);
6675 } 6755 }
6756 else
6757 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6758
6676 handlerCompleteMovementToRegion = null; 6759 handlerCompleteMovementToRegion = null;
6677 6760
6678 return true; 6761 return true;
@@ -6690,7 +6773,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6690 return true; 6773 return true;
6691 } 6774 }
6692 #endregion 6775 #endregion
6693 6776/*
6694 StartAnim handlerStartAnim = null; 6777 StartAnim handlerStartAnim = null;
6695 StopAnim handlerStopAnim = null; 6778 StopAnim handlerStopAnim = null;
6696 6779
@@ -6714,6 +6797,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6714 } 6797 }
6715 } 6798 }
6716 return true; 6799 return true;
6800*/
6801 ChangeAnim handlerChangeAnim = null;
6802
6803 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6804 {
6805 handlerChangeAnim = OnChangeAnim;
6806 if (handlerChangeAnim != null)
6807 {
6808 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6809 }
6810 }
6811
6812 handlerChangeAnim = OnChangeAnim;
6813 if (handlerChangeAnim != null)
6814 {
6815 handlerChangeAnim(UUID.Zero, false, true);
6816 }
6817
6818 return true;
6717 } 6819 }
6718 6820
6719 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6821 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6959,6 +7061,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6959 #endregion 7061 #endregion
6960 7062
6961 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 7063 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
7064 GenericCall2 handler = OnUpdateThrottles;
7065 if (handler != null)
7066 {
7067 handler();
7068 }
6962 return true; 7069 return true;
6963 } 7070 }
6964 7071
@@ -7383,7 +7490,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7383 physdata.Bounce = phsblock.Restitution; 7490 physdata.Bounce = phsblock.Restitution;
7384 physdata.Density = phsblock.Density; 7491 physdata.Density = phsblock.Density;
7385 physdata.Friction = phsblock.Friction; 7492 physdata.Friction = phsblock.Friction;
7386 physdata.GravitationModifier = phsblock.GravityMultiplier; 7493 physdata.GravitationModifier = phsblock.GravityMultiplier;
7387 } 7494 }
7388 7495
7389 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7496 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7969,6 +8076,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7969 // surrounding scene 8076 // surrounding scene
7970 if ((ImageType)block.Type == ImageType.Baked) 8077 if ((ImageType)block.Type == ImageType.Baked)
7971 args.Priority *= 2.0f; 8078 args.Priority *= 2.0f;
8079 int wearableout = 0;
7972 8080
7973 ImageManager.EnqueueReq(args); 8081 ImageManager.EnqueueReq(args);
7974 } 8082 }
@@ -9003,16 +9111,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9003 9111
9004 #region Parcel related packets 9112 #region Parcel related packets
9005 9113
9114 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
9115 // to be done with minimal resources as possible
9116 // variables temporary here while in test
9117
9118 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
9119 bool RegionHandleRequestsInService = false;
9120
9006 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 9121 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
9007 { 9122 {
9008 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 9123 UUID currentUUID;
9009 9124
9010 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 9125 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
9011 if (handlerRegionHandleRequest != null) 9126
9127 if (handlerRegionHandleRequest == null)
9128 return true;
9129
9130 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
9131
9132 lock (RegionHandleRequests)
9012 { 9133 {
9013 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 9134 if (RegionHandleRequestsInService)
9135 {
9136 // we are already busy doing a previus request
9137 // so enqueue it
9138 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
9139 return true;
9140 }
9141
9142 // else do it
9143 currentUUID = rhrPack.RequestBlock.RegionID;
9144 RegionHandleRequestsInService = true;
9014 } 9145 }
9015 return true; 9146
9147 while (true)
9148 {
9149 handlerRegionHandleRequest(this, currentUUID);
9150
9151 lock (RegionHandleRequests)
9152 {
9153 // exit condition, nothing to do or closed
9154 // current code seems to assume we may loose the handler at anytime,
9155 // so keep checking it
9156 handlerRegionHandleRequest = OnRegionHandleRequest;
9157
9158 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
9159 {
9160 RegionHandleRequests.Clear();
9161 RegionHandleRequestsInService = false;
9162 return true;
9163 }
9164 currentUUID = RegionHandleRequests.Dequeue();
9165 }
9166 }
9167
9168 return true; // actually unreached
9016 } 9169 }
9017 9170
9018 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 9171 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -10268,7 +10421,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10268 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10421 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10269 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10422 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10270 UpdateMuteListEntry.MuteData.MuteType, 10423 UpdateMuteListEntry.MuteData.MuteType,
10271 UpdateMuteListEntry.AgentData.AgentID); 10424 UpdateMuteListEntry.MuteData.MuteFlags);
10272 return true; 10425 return true;
10273 } 10426 }
10274 return false; 10427 return false;
@@ -10283,8 +10436,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10283 { 10436 {
10284 handlerRemoveMuteListEntry(this, 10437 handlerRemoveMuteListEntry(this,
10285 RemoveMuteListEntry.MuteData.MuteID, 10438 RemoveMuteListEntry.MuteData.MuteID,
10286 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10439 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10287 RemoveMuteListEntry.AgentData.AgentID);
10288 return true; 10440 return true;
10289 } 10441 }
10290 return false; 10442 return false;
@@ -10328,10 +10480,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10328 return false; 10480 return false;
10329 } 10481 }
10330 10482
10483 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10484 {
10485 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10486 (ChangeInventoryItemFlagsPacket)packet;
10487 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10488 if (handlerChangeInventoryItemFlags != null)
10489 {
10490 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10491 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10492 return true;
10493 }
10494 return false;
10495 }
10496
10331 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10497 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10332 { 10498 {
10333 return true; 10499 return true;
10334 } 10500 }
10501
10502 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10503 {
10504 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10505
10506 #region Packet Session and User Check
10507 if (m_checkPackets)
10508 {
10509 if (packet.AgentData.SessionID != SessionId ||
10510 packet.AgentData.AgentID != AgentId)
10511 return true;
10512 }
10513 #endregion
10514 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10515 List<InventoryItemBase> items = new List<InventoryItemBase>();
10516 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10517 {
10518 InventoryItemBase b = new InventoryItemBase();
10519 b.ID = n.OldItemID;
10520 b.Folder = n.OldFolderID;
10521 items.Add(b);
10522 }
10523
10524 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10525 if (handlerMoveItemsAndLeaveCopy != null)
10526 {
10527 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10528 }
10529
10530 return true;
10531 }
10335 10532
10336 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10533 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10337 { 10534 {
@@ -10758,6 +10955,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10758 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10955 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10759 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10956 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10760 10957
10958 Scene scene = (Scene)m_scene;
10959 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10960 {
10961 ScenePresence p;
10962 if (scene.TryGetScenePresence(sender.AgentId, out p))
10963 {
10964 if (p.GodLevel >= 200)
10965 {
10966 groupProfileReply.GroupData.OpenEnrollment = true;
10967 groupProfileReply.GroupData.MembershipFee = 0;
10968 }
10969 }
10970 }
10971
10761 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10972 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10762 } 10973 }
10763 return true; 10974 return true;
@@ -11331,11 +11542,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11331 11542
11332 StartLure handlerStartLure = OnStartLure; 11543 StartLure handlerStartLure = OnStartLure;
11333 if (handlerStartLure != null) 11544 if (handlerStartLure != null)
11334 handlerStartLure(startLureRequest.Info.LureType, 11545 {
11335 Utils.BytesToString( 11546 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11336 startLureRequest.Info.Message), 11547 {
11337 startLureRequest.TargetData[0].TargetID, 11548 handlerStartLure(startLureRequest.Info.LureType,
11338 this); 11549 Utils.BytesToString(
11550 startLureRequest.Info.Message),
11551 startLureRequest.TargetData[i].TargetID,
11552 this);
11553 }
11554 }
11339 return true; 11555 return true;
11340 } 11556 }
11341 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11557 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11449,10 +11665,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11449 } 11665 }
11450 #endregion 11666 #endregion
11451 11667
11452 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11668 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11453 if (handlerClassifiedGodDelete != null) 11669 if (handlerClassifiedGodDelete != null)
11454 handlerClassifiedGodDelete( 11670 handlerClassifiedGodDelete(
11455 classifiedGodDelete.Data.ClassifiedID, 11671 classifiedGodDelete.Data.ClassifiedID,
11672 classifiedGodDelete.Data.QueryID,
11456 this); 11673 this);
11457 return true; 11674 return true;
11458 } 11675 }
@@ -11755,12 +11972,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11755 /// <param name="simclient"></param> 11972 /// <param name="simclient"></param>
11756 /// <param name="packet"></param> 11973 /// <param name="packet"></param>
11757 /// <returns></returns> 11974 /// <returns></returns>
11758 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11975 // TODO: Convert old handler to use new method
11976 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11759 { 11977 {
11760 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11978 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11761 11979
11762 if (cachedtex.AgentData.SessionID != SessionId) 11980 if (cachedtex.AgentData.SessionID != SessionId)
11763 return false; 11981 return false;
11982
11764 11983
11765 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); 11984 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11766 11985
@@ -11773,23 +11992,173 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11773 requestArgs.Add(arg); 11992 requestArgs.Add(arg);
11774 } 11993 }
11775 11994
11776 try 11995 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11996 if (handlerCachedTextureRequest != null)
11777 { 11997 {
11778 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11998 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11779 if (handlerCachedTextureRequest != null) 11999 }
12000
12001 return true;
12002 }*/
12003
12004 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
12005 {
12006 //m_log.Debug("texture cached: " + packet.ToString());
12007 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
12008 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
12009
12010 if (cachedtex.AgentData.SessionID != SessionId)
12011 return false;
12012
12013
12014 // TODO: don't create new blocks if recycling an old packet
12015 cachedresp.AgentData.AgentID = AgentId;
12016 cachedresp.AgentData.SessionID = m_sessionId;
12017 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
12018 m_cachedTextureSerial++;
12019 cachedresp.WearableData =
12020 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
12021
12022 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
12023 // var item = fac.GetBakedTextureFaces(AgentId);
12024 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
12025
12026 IAssetService cache = m_scene.AssetService;
12027 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
12028 //bakedTextureModule = null;
12029 int maxWearablesLoop = cachedtex.WearableData.Length;
12030 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
12031 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
12032
12033 if (bakedTextureModule != null && cache != null)
12034 {
12035 // 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
12036
12037 WearableCacheItem[] cacheItems = null;
12038 ScenePresence p = m_scene.GetScenePresence(AgentId);
12039 if (p.Appearance != null)
12040 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
12041 {
12042 try
12043 {
12044 cacheItems = bakedTextureModule.Get(AgentId);
12045 p.Appearance.WearableCacheItems = cacheItems;
12046 p.Appearance.WearableCacheItemsDirty = false;
12047 }
12048
12049 /*
12050 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
12051 *
12052 catch (System.Net.Sockets.SocketException)
12053 {
12054 cacheItems = null;
12055 }
12056 catch (WebException)
12057 {
12058 cacheItems = null;
12059 }
12060 catch (InvalidOperationException)
12061 {
12062 cacheItems = null;
12063 } */
12064 catch (Exception)
12065 {
12066 cacheItems = null;
12067 }
12068
12069 }
12070 else if (p.Appearance.WearableCacheItems != null)
12071 {
12072 cacheItems = p.Appearance.WearableCacheItems;
12073 }
12074
12075 if (cache != null && cacheItems != null)
11780 { 12076 {
11781 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 12077 foreach (WearableCacheItem item in cacheItems)
12078 {
12079
12080 if (cache.GetCached(item.TextureID.ToString()) == null)
12081 {
12082 item.TextureAsset.Temporary = true;
12083 cache.Store(item.TextureAsset);
12084 }
12085
12086
12087 }
12088 }
12089
12090 if (cacheItems != null)
12091 {
12092
12093 for (int i = 0; i < maxWearablesLoop; i++)
12094 {
12095 WearableCacheItem item =
12096 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
12097
12098 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12099 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
12100 cachedresp.WearableData[i].HostName = new byte[0];
12101 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
12102 {
12103
12104 cachedresp.WearableData[i].TextureID = item.TextureID;
12105 }
12106 else
12107 {
12108 cachedresp.WearableData[i].TextureID = UUID.Zero;
12109 }
12110 }
12111 }
12112 else
12113 {
12114 for (int i = 0; i < maxWearablesLoop; i++)
12115 {
12116 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12117 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12118 cachedresp.WearableData[i].TextureID = UUID.Zero;
12119 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12120 cachedresp.WearableData[i].HostName = new byte[0];
12121 }
11782 } 12122 }
11783 } 12123 }
11784 catch (Exception e) 12124 else
11785 { 12125 {
11786 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); 12126 if (cache == null)
11787 return false; 12127 {
12128 for (int i = 0; i < maxWearablesLoop; i++)
12129 {
12130 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12131 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12132 cachedresp.WearableData[i].TextureID = UUID.Zero;
12133 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12134 cachedresp.WearableData[i].HostName = new byte[0];
12135 }
12136 }
12137 else
12138 {
12139 for (int i = 0; i < maxWearablesLoop; i++)
12140 {
12141 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12142 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12143
12144
12145
12146 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
12147 cachedresp.WearableData[i].TextureID = UUID.Zero;
12148 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12149 else
12150 cachedresp.WearableData[i].TextureID = UUID.Zero;
12151 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12152 cachedresp.WearableData[i].HostName = new byte[0];
12153 }
12154 }
11788 } 12155 }
11789 12156 cachedresp.Header.Zerocoded = true;
12157 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12158
11790 return true; 12159 return true;
11791 } 12160 }
11792 12161
11793 /// <summary> 12162 /// <summary>
11794 /// Send a response back to a client when it asks the asset server (via the region server) if it has 12163 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11795 /// its appearance texture cached. 12164 /// its appearance texture cached.
@@ -11853,209 +12222,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11853 } 12222 }
11854 else 12223 else
11855 { 12224 {
11856// m_log.DebugFormat( 12225 ClientChangeObject updatehandler = onClientChangeObject;
11857// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11858// i, block.Type, part.Name, part.LocalId);
11859 12226
11860// // Do this once since fetch parts creates a new array. 12227 if (updatehandler != null)
11861// SceneObjectPart[] parts = part.ParentGroup.Parts; 12228 {
11862// for (int j = 0; j < parts.Length; j++) 12229 ObjectChangeData udata = new ObjectChangeData();
11863// {
11864// part.StoreUndoState();
11865// parts[j].IgnoreUndoUpdate = true;
11866// }
11867 12230
11868 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 12231 /*ubit from ll JIRA:
12232 * 0x01 position
12233 * 0x02 rotation
12234 * 0x04 scale
12235
12236 * 0x08 LINK_SET
12237 * 0x10 UNIFORM for scale
12238 */
11869 12239
11870 switch (block.Type) 12240 // translate to internal changes
11871 { 12241 // not all cases .. just the ones older code did
11872 case 1:
11873 Vector3 pos1 = new Vector3(block.Data, 0);
11874 12242
11875 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12243 switch (block.Type)
11876 if (handlerUpdatePrimSinglePosition != null) 12244 {
11877 { 12245 case 1: //change position sp
11878 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12246 udata.position = new Vector3(block.Data, 0);
11879 handlerUpdatePrimSinglePosition(localId, pos1, this);
11880 }
11881 break;
11882 12247
11883 case 2: 12248 udata.change = ObjectChangeType.primP;
11884 Quaternion rot1 = new Quaternion(block.Data, 0, true); 12249 updatehandler(localId, udata, this);
12250 break;
11885 12251
11886 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 12252 case 2: // rotation sp
11887 if (handlerUpdatePrimSingleRotation != null) 12253 udata.rotation = new Quaternion(block.Data, 0, true);
11888 {
11889 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11890 handlerUpdatePrimSingleRotation(localId, rot1, this);
11891 }
11892 break;
11893 12254
11894 case 3: 12255 udata.change = ObjectChangeType.primR;
11895 Vector3 rotPos = new Vector3(block.Data, 0); 12256 updatehandler(localId, udata, this);
11896 Quaternion rot2 = new Quaternion(block.Data, 12, true); 12257 break;
11897 12258
11898 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 12259 case 3: // position plus rotation
11899 if (handlerUpdatePrimSingleRotationPosition != null) 12260 udata.position = new Vector3(block.Data, 0);
11900 { 12261 udata.rotation = new Quaternion(block.Data, 12, true);
11901 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11902 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11903 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11904 }
11905 break;
11906 12262
11907 case 4: 12263 udata.change = ObjectChangeType.primPR;
11908 case 20: 12264 updatehandler(localId, udata, this);
11909 Vector3 scale4 = new Vector3(block.Data, 0); 12265 break;
11910 12266
11911 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 12267 case 4: // scale sp
11912 if (handlerUpdatePrimScale != null) 12268 udata.scale = new Vector3(block.Data, 0);
11913 { 12269 udata.change = ObjectChangeType.primS;
11914 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11915 handlerUpdatePrimScale(localId, scale4, this);
11916 }
11917 break;
11918 12270
11919 case 5: 12271 updatehandler(localId, udata, this);
11920 Vector3 scale1 = new Vector3(block.Data, 12); 12272 break;
11921 Vector3 pos11 = new Vector3(block.Data, 0);
11922 12273
11923 handlerUpdatePrimScale = OnUpdatePrimScale; 12274 case 0x14: // uniform scale sp
11924 if (handlerUpdatePrimScale != null) 12275 udata.scale = new Vector3(block.Data, 0);
11925 {
11926 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11927 handlerUpdatePrimScale(localId, scale1, this);
11928 12276
11929 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12277 udata.change = ObjectChangeType.primUS;
11930 if (handlerUpdatePrimSinglePosition != null) 12278 updatehandler(localId, udata, this);
11931 { 12279 break;
11932 handlerUpdatePrimSinglePosition(localId, pos11, this);
11933 }
11934 }
11935 break;
11936 12280
11937 case 9: 12281 case 5: // scale and position sp
11938 Vector3 pos2 = new Vector3(block.Data, 0); 12282 udata.position = new Vector3(block.Data, 0);
12283 udata.scale = new Vector3(block.Data, 12);
11939 12284
11940 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 12285 udata.change = ObjectChangeType.primPS;
12286 updatehandler(localId, udata, this);
12287 break;
11941 12288
11942 if (handlerUpdateVector != null) 12289 case 0x15: //uniform scale and position
11943 { 12290 udata.position = new Vector3(block.Data, 0);
11944 handlerUpdateVector(localId, pos2, this); 12291 udata.scale = new Vector3(block.Data, 12);
11945 }
11946 break;
11947 12292
11948 case 10: 12293 udata.change = ObjectChangeType.primPUS;
11949 Quaternion rot3 = new Quaternion(block.Data, 0, true); 12294 updatehandler(localId, udata, this);
12295 break;
11950 12296
11951 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 12297 // now group related (bit 4)
11952 if (handlerUpdatePrimRotation != null) 12298 case 9: //( 8 + 1 )group position
11953 { 12299 udata.position = new Vector3(block.Data, 0);
11954 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11955 handlerUpdatePrimRotation(localId, rot3, this);
11956 }
11957 break;
11958 12300
11959 case 11: 12301 udata.change = ObjectChangeType.groupP;
11960 Vector3 pos3 = new Vector3(block.Data, 0); 12302 updatehandler(localId, udata, this);
11961 Quaternion rot4 = new Quaternion(block.Data, 12, true); 12303 break;
11962 12304
11963 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 12305 case 0x0A: // (8 + 2) group rotation
11964 if (handlerUpdatePrimGroupRotation != null) 12306 udata.rotation = new Quaternion(block.Data, 0, true);
11965 {
11966 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11967 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11968 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11969 }
11970 break;
11971 case 12:
11972 case 28:
11973 Vector3 scale7 = new Vector3(block.Data, 0);
11974 12307
11975 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12308 udata.change = ObjectChangeType.groupR;
11976 if (handlerUpdatePrimGroupScale != null) 12309 updatehandler(localId, udata, this);
11977 { 12310 break;
11978 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11979 handlerUpdatePrimGroupScale(localId, scale7, this);
11980 }
11981 break;
11982 12311
11983 case 13: 12312 case 0x0B: //( 8 + 2 + 1) group rotation and position
11984 Vector3 scale2 = new Vector3(block.Data, 12); 12313 udata.position = new Vector3(block.Data, 0);
11985 Vector3 pos4 = new Vector3(block.Data, 0); 12314 udata.rotation = new Quaternion(block.Data, 12, true);
11986 12315
11987 handlerUpdatePrimScale = OnUpdatePrimScale; 12316 udata.change = ObjectChangeType.groupPR;
11988 if (handlerUpdatePrimScale != null) 12317 updatehandler(localId, udata, this);
11989 { 12318 break;
11990 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11991 handlerUpdatePrimScale(localId, scale2, this);
11992 12319
11993 // Change the position based on scale (for bug number 246) 12320 case 0x0C: // (8 + 4) group scale
11994 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12321 // only afects root prim and only sent by viewer editor object tab scaling
11995 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12322 // mouse edition only allows uniform scaling
11996 if (handlerUpdatePrimSinglePosition != null) 12323 // SL MAY CHANGE THIS in viewers
11997 {
11998 handlerUpdatePrimSinglePosition(localId, pos4, this);
11999 }
12000 }
12001 break;
12002 12324
12003 case 29: 12325 udata.scale = new Vector3(block.Data, 0);
12004 Vector3 scale5 = new Vector3(block.Data, 12);
12005 Vector3 pos5 = new Vector3(block.Data, 0);
12006 12326
12007 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12327 udata.change = ObjectChangeType.groupS;
12008 if (handlerUpdatePrimGroupScale != null) 12328 updatehandler(localId, udata, this);
12009 {
12010 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
12011 part.StoreUndoState(true);
12012 part.IgnoreUndoUpdate = true;
12013 handlerUpdatePrimGroupScale(localId, scale5, this);
12014 handlerUpdateVector = OnUpdatePrimGroupPosition;
12015 12329
12016 if (handlerUpdateVector != null) 12330 break;
12017 {
12018 handlerUpdateVector(localId, pos5, this);
12019 }
12020 12331
12021 part.IgnoreUndoUpdate = false; 12332 case 0x0D: //(8 + 4 + 1) group scale and position
12022 } 12333 // exception as above
12023 12334
12024 break; 12335 udata.position = new Vector3(block.Data, 0);
12336 udata.scale = new Vector3(block.Data, 12);
12025 12337
12026 case 21: 12338 udata.change = ObjectChangeType.groupPS;
12027 Vector3 scale6 = new Vector3(block.Data, 12); 12339 updatehandler(localId, udata, this);
12028 Vector3 pos6 = new Vector3(block.Data, 0); 12340 break;
12029 12341
12030 handlerUpdatePrimScale = OnUpdatePrimScale; 12342 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
12031 if (handlerUpdatePrimScale != null) 12343 udata.scale = new Vector3(block.Data, 0);
12032 {
12033 part.StoreUndoState(false);
12034 part.IgnoreUndoUpdate = true;
12035 12344
12036 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12345 udata.change = ObjectChangeType.groupUS;
12037 handlerUpdatePrimScale(localId, scale6, this); 12346 updatehandler(localId, udata, this);
12038 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12347 break;
12039 if (handlerUpdatePrimSinglePosition != null)
12040 {
12041 handlerUpdatePrimSinglePosition(localId, pos6, this);
12042 }
12043 12348
12044 part.IgnoreUndoUpdate = false; 12349 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
12045 } 12350 udata.position = new Vector3(block.Data, 0);
12046 break; 12351 udata.scale = new Vector3(block.Data, 12);
12047 12352
12048 default: 12353 udata.change = ObjectChangeType.groupPUS;
12049 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12354 updatehandler(localId, udata, this);
12050 break; 12355 break;
12356
12357 default:
12358 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12359 break;
12360 }
12051 } 12361 }
12052 12362
12053// for (int j = 0; j < parts.Length; j++)
12054// parts[j].IgnoreUndoUpdate = false;
12055 } 12363 }
12056 } 12364 }
12057 } 12365 }
12058
12059 return true; 12366 return true;
12060 } 12367 }
12061 12368
@@ -12116,8 +12423,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12116 public void SetChildAgentThrottle(byte[] throttles) 12423 public void SetChildAgentThrottle(byte[] throttles)
12117 { 12424 {
12118 m_udpClient.SetThrottles(throttles); 12425 m_udpClient.SetThrottles(throttles);
12426 GenericCall2 handler = OnUpdateThrottles;
12427 if (handler != null)
12428 {
12429 handler();
12430 }
12431 }
12432
12433 /// <summary>
12434 /// Sets the throttles from values supplied by the client
12435 /// </summary>
12436 /// <param name="throttles"></param>
12437 public void SetAgentThrottleSilent(int throttle, int setting)
12438 {
12439 m_udpClient.ForceThrottleSetting(throttle,setting);
12440 //m_udpClient.SetThrottles(throttles);
12441
12119 } 12442 }
12120 12443
12444
12121 /// <summary> 12445 /// <summary>
12122 /// Get the current throttles for this client as a packed byte array 12446 /// Get the current throttles for this client as a packed byte array
12123 /// </summary> 12447 /// </summary>
@@ -12501,7 +12825,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12501// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12825// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12502// requestID, taskID, (SourceType)sourceType, Name); 12826// requestID, taskID, (SourceType)sourceType, Name);
12503 12827
12828
12829 //Note, the bool returned from the below function is useless since it is always false.
12504 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12830 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12831
12505 } 12832 }
12506 12833
12507 /// <summary> 12834 /// <summary>
@@ -12567,7 +12894,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12567 /// <returns></returns> 12894 /// <returns></returns>
12568 private static int CalculateNumPackets(byte[] data) 12895 private static int CalculateNumPackets(byte[] data)
12569 { 12896 {
12570 const uint m_maxPacketSize = 600; 12897// const uint m_maxPacketSize = 600;
12898 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12571 int numPackets = 1; 12899 int numPackets = 1;
12572 12900
12573 if (data == null) 12901 if (data == null)