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.cs1440
1 files changed, 881 insertions, 559 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 5675870..cc4d014 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -99,6 +99,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 public event AvatarPickerRequest OnAvatarPickerRequest; 99 public event AvatarPickerRequest OnAvatarPickerRequest;
100 public event StartAnim OnStartAnim; 100 public event StartAnim OnStartAnim;
101 public event StopAnim OnStopAnim; 101 public event StopAnim OnStopAnim;
102 public event ChangeAnim OnChangeAnim;
102 public event Action<IClientAPI> OnRequestAvatarsData; 103 public event Action<IClientAPI> OnRequestAvatarsData;
103 public event LinkObjects OnLinkObjects; 104 public event LinkObjects OnLinkObjects;
104 public event DelinkObjects OnDelinkObjects; 105 public event DelinkObjects OnDelinkObjects;
@@ -126,6 +127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 127 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
127 public event UpdatePrimFlags OnUpdatePrimFlags; 128 public event UpdatePrimFlags OnUpdatePrimFlags;
128 public event UpdatePrimTexture OnUpdatePrimTexture; 129 public event UpdatePrimTexture OnUpdatePrimTexture;
130 public event ClientChangeObject onClientChangeObject;
129 public event UpdateVector OnUpdatePrimGroupPosition; 131 public event UpdateVector OnUpdatePrimGroupPosition;
130 public event UpdateVector OnUpdatePrimSinglePosition; 132 public event UpdateVector OnUpdatePrimSinglePosition;
131 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 133 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -159,6 +161,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 public event RequestTaskInventory OnRequestTaskInventory; 161 public event RequestTaskInventory OnRequestTaskInventory;
160 public event UpdateInventoryItem OnUpdateInventoryItem; 162 public event UpdateInventoryItem OnUpdateInventoryItem;
161 public event CopyInventoryItem OnCopyInventoryItem; 163 public event CopyInventoryItem OnCopyInventoryItem;
164 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
162 public event MoveInventoryItem OnMoveInventoryItem; 165 public event MoveInventoryItem OnMoveInventoryItem;
163 public event RemoveInventoryItem OnRemoveInventoryItem; 166 public event RemoveInventoryItem OnRemoveInventoryItem;
164 public event RemoveInventoryFolder OnRemoveInventoryFolder; 167 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -257,7 +260,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
257 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 260 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
258 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 261 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
259 public event ClassifiedDelete OnClassifiedDelete; 262 public event ClassifiedDelete OnClassifiedDelete;
260 public event ClassifiedDelete OnClassifiedGodDelete; 263 public event ClassifiedGodDelete OnClassifiedGodDelete;
261 public event EventNotificationAddRequest OnEventNotificationAddRequest; 264 public event EventNotificationAddRequest OnEventNotificationAddRequest;
262 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 265 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
263 public event EventGodDelete OnEventGodDelete; 266 public event EventGodDelete OnEventGodDelete;
@@ -288,10 +291,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
288 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 291 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
289 public event SimWideDeletesDelegate OnSimWideDeletes; 292 public event SimWideDeletesDelegate OnSimWideDeletes;
290 public event SendPostcard OnSendPostcard; 293 public event SendPostcard OnSendPostcard;
294 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
291 public event MuteListEntryUpdate OnUpdateMuteListEntry; 295 public event MuteListEntryUpdate OnUpdateMuteListEntry;
292 public event MuteListEntryRemove OnRemoveMuteListEntry; 296 public event MuteListEntryRemove OnRemoveMuteListEntry;
293 public event GodlikeMessage onGodlikeMessage; 297 public event GodlikeMessage onGodlikeMessage;
294 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 298 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
299 public event GenericCall2 OnUpdateThrottles;
295 300
296 #endregion Events 301 #endregion Events
297 302
@@ -326,6 +331,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
326 private Prioritizer m_prioritizer; 331 private Prioritizer m_prioritizer;
327 private bool m_disableFacelights = false; 332 private bool m_disableFacelights = false;
328 333
334 private bool m_VelocityInterpolate = false;
335 private const uint MaxTransferBytesPerPacket = 600;
336
337
329 /// <value> 338 /// <value>
330 /// List used in construction of data blocks for an object update packet. This is to stop us having to 339 /// List used in construction of data blocks for an object update packet. This is to stop us having to
331 /// continually recreate it. 340 /// continually recreate it.
@@ -337,14 +346,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 346 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 347 /// ownerless phantom.
339 /// 348 ///
340 /// All manipulation of this set has to occur under a lock 349 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 350 ///
342 /// </value> 351 /// </value>
343 protected HashSet<uint> m_killRecord; 352// protected HashSet<uint> m_killRecord;
344 353
345// protected HashSet<uint> m_attachmentsSent; 354// protected HashSet<uint> m_attachmentsSent;
346 355
347 private int m_moneyBalance; 356 private int m_moneyBalance;
357 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 358 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 359 private bool m_SendLogoutPacketWhenClosing = true;
350 360
@@ -391,6 +401,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 401 get { return m_startpos; }
392 set { m_startpos = value; } 402 set { m_startpos = value; }
393 } 403 }
404 public bool DeliverPackets
405 {
406 get { return m_deliverPackets; }
407 set {
408 m_deliverPackets = value;
409 m_udpClient.m_deliverPackets = value;
410 }
411 }
394 public UUID AgentId { get { return m_agentId; } } 412 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 413 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 414 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -442,6 +460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
442 } 460 }
443 461
444 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 462 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
463
445 464
446 #endregion Properties 465 #endregion Properties
447 466
@@ -468,7 +487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 487 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 488 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 489 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 490// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 491// m_attachmentsSent = new HashSet<uint>();
473 492
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 493 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +517,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 517
499 #region Client Methods 518 #region Client Methods
500 519
520
521 /// <summary>
522 /// Close down the client view
523 /// </summary>
501 public void Close() 524 public void Close()
502 { 525 {
503 Close(false); 526 Close(true, false);
504 } 527 }
505 528
506 public void Close(bool force) 529 public void Close(bool sendStop, bool force)
507 { 530 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 531 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
509 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 532 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -515,7 +538,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return; 538 return;
516 539
517 IsActive = false; 540 IsActive = false;
518 CloseWithoutChecks(); 541 CloseWithoutChecks(sendStop);
519 } 542 }
520 } 543 }
521 544
@@ -528,12 +551,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
528 /// 551 ///
529 /// Callers must lock ClosingSyncLock before calling. 552 /// Callers must lock ClosingSyncLock before calling.
530 /// </remarks> 553 /// </remarks>
531 public void CloseWithoutChecks() 554 public void CloseWithoutChecks(bool sendStop)
532 { 555 {
533 m_log.DebugFormat( 556 m_log.DebugFormat(
534 "[CLIENT]: Close has been called for {0} attached to scene {1}", 557 "[CLIENT]: Close has been called for {0} attached to scene {1}",
535 Name, m_scene.RegionInfo.RegionName); 558 Name, m_scene.RegionInfo.RegionName);
536 559
560 if (sendStop)
561 {
562 // Send the STOP packet
563 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
564 OutPacket(disable, ThrottleOutPacketType.Unknown);
565 }
566
537 // Shutdown the image manager 567 // Shutdown the image manager
538 ImageManager.Close(); 568 ImageManager.Close();
539 569
@@ -556,6 +586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
556 // Disable UDP handling for this client 586 // Disable UDP handling for this client
557 m_udpClient.Shutdown(); 587 m_udpClient.Shutdown();
558 588
589
559 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 590 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
560 //GC.Collect(); 591 //GC.Collect();
561 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 592 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -791,7 +822,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 822 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
792 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 823 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
793 824
794 OutPacket(handshake, ThrottleOutPacketType.Task); 825// OutPacket(handshake, ThrottleOutPacketType.Task);
826 // use same as MoveAgentIntoRegion (both should be task )
827 OutPacket(handshake, ThrottleOutPacketType.Unknown);
795 } 828 }
796 829
797 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 830 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -831,7 +864,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
831 reply.ChatData.OwnerID = ownerID; 864 reply.ChatData.OwnerID = ownerID;
832 reply.ChatData.SourceID = fromAgentID; 865 reply.ChatData.SourceID = fromAgentID;
833 866
834 OutPacket(reply, ThrottleOutPacketType.Task); 867 OutPacket(reply, ThrottleOutPacketType.Unknown);
835 } 868 }
836 869
837 /// <summary> 870 /// <summary>
@@ -864,32 +897,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
864 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 897 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
865 msg.MessageBlock.BinaryBucket = im.binaryBucket; 898 msg.MessageBlock.BinaryBucket = im.binaryBucket;
866 899
867 if (im.message.StartsWith("[grouptest]")) 900 OutPacket(msg, ThrottleOutPacketType.Task);
868 { // this block is test code for implementing group IM - delete when group IM is finished
869 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
870 if (eq != null)
871 {
872 im.dialog = 17;
873
874 //eq.ChatterboxInvitation(
875 // new UUID("00000000-68f9-1111-024e-222222111123"),
876 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
877 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
878
879 eq.ChatterboxInvitation(
880 new UUID("00000000-68f9-1111-024e-222222111123"),
881 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
882 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
883
884 eq.ChatterBoxSessionAgentListUpdates(
885 new UUID("00000000-68f9-1111-024e-222222111123"),
886 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
887 }
888
889 Console.WriteLine("SendInstantMessage: " + msg);
890 }
891 else
892 OutPacket(msg, ThrottleOutPacketType.Task);
893 } 901 }
894 } 902 }
895 903
@@ -1117,6 +1125,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 public virtual void SendLayerData(float[] map) 1125 public virtual void SendLayerData(float[] map)
1118 { 1126 {
1119 Util.FireAndForget(DoSendLayerData, map); 1127 Util.FireAndForget(DoSendLayerData, map);
1128
1129 // Send it sync, and async. It's not that much data
1130 // and it improves user experience just so much!
1131 DoSendLayerData(map);
1120 } 1132 }
1121 1133
1122 /// <summary> 1134 /// <summary>
@@ -1129,16 +1141,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1129 1141
1130 try 1142 try
1131 { 1143 {
1132 //for (int y = 0; y < 16; y++) 1144 for (int y = 0; y < 16; y++)
1133 //{ 1145 {
1134 // for (int x = 0; x < 16; x++) 1146 for (int x = 0; x < 16; x+=4)
1135 // { 1147 {
1136 // SendLayerData(x, y, map); 1148 SendLayerPacket(x, y, map);
1137 // } 1149 }
1138 //} 1150 }
1139
1140 // Send LayerData in a spiral pattern. Fun!
1141 SendLayerTopRight(map, 0, 0, 15, 15);
1142 } 1151 }
1143 catch (Exception e) 1152 catch (Exception e)
1144 { 1153 {
@@ -1146,51 +1155,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 } 1155 }
1147 } 1156 }
1148 1157
1149 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1150 {
1151 // Row
1152 for (int i = x1; i <= x2; i++)
1153 SendLayerData(i, y1, map);
1154
1155 // Column
1156 for (int j = y1 + 1; j <= y2; j++)
1157 SendLayerData(x2, j, map);
1158
1159 if (x2 - x1 > 0)
1160 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1161 }
1162
1163 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1164 {
1165 // Row in reverse
1166 for (int i = x2; i >= x1; i--)
1167 SendLayerData(i, y2, map);
1168
1169 // Column in reverse
1170 for (int j = y2 - 1; j >= y1; j--)
1171 SendLayerData(x1, j, map);
1172
1173 if (x2 - x1 > 0)
1174 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1175 }
1176
1177 /// <summary> 1158 /// <summary>
1178 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1159 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1179 /// </summary> 1160 /// </summary>
1180 /// <param name="map">heightmap</param> 1161 /// <param name="map">heightmap</param>
1181 /// <param name="px">X coordinate for patches 0..12</param> 1162 /// <param name="px">X coordinate for patches 0..12</param>
1182 /// <param name="py">Y coordinate for patches 0..15</param> 1163 /// <param name="py">Y coordinate for patches 0..15</param>
1183 // private void SendLayerPacket(float[] map, int y, int x) 1164 private void SendLayerPacket(int x, int y, float[] map)
1184 // { 1165 {
1185 // int[] patches = new int[4]; 1166 int[] patches = new int[4];
1186 // patches[0] = x + 0 + y * 16; 1167 patches[0] = x + 0 + y * 16;
1187 // patches[1] = x + 1 + y * 16; 1168 patches[1] = x + 1 + y * 16;
1188 // patches[2] = x + 2 + y * 16; 1169 patches[2] = x + 2 + y * 16;
1189 // patches[3] = x + 3 + y * 16; 1170 patches[3] = x + 3 + y * 16;
1190 1171
1191 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1172 float[] heightmap = (map.Length == 65536) ?
1192 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1173 map :
1193 // } 1174 LLHeightFieldMoronize(map);
1175
1176 try
1177 {
1178 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1179 OutPacket(layerpack, ThrottleOutPacketType.Land);
1180 }
1181 catch
1182 {
1183 for (int px = x ; px < x + 4 ; px++)
1184 SendLayerData(px, y, map);
1185 }
1186 }
1194 1187
1195 /// <summary> 1188 /// <summary>
1196 /// Sends a specified patch to a client 1189 /// Sends a specified patch to a client
@@ -1210,7 +1203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1203 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1211 layerpack.Header.Reliable = true; 1204 layerpack.Header.Reliable = true;
1212 1205
1213 OutPacket(layerpack, ThrottleOutPacketType.Land); 1206 OutPacket(layerpack, ThrottleOutPacketType.Task);
1214 } 1207 }
1215 catch (Exception e) 1208 catch (Exception e)
1216 { 1209 {
@@ -1573,7 +1566,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1573 1566
1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1567 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1575 { 1568 {
1576// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1569// foreach (uint id in localIDs)
1570// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1577 1571
1578 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1572 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1579 // TODO: don't create new blocks if recycling an old packet 1573 // TODO: don't create new blocks if recycling an old packet
@@ -1595,17 +1589,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1595 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1589 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1596 // condition where a kill can be processed before an out-of-date update for the same object. 1590 // condition where a kill can be processed before an out-of-date update for the same object.
1597 // ProcessEntityUpdates() also takes the m_killRecord lock. 1591 // ProcessEntityUpdates() also takes the m_killRecord lock.
1598 lock (m_killRecord) 1592// lock (m_killRecord)
1599 { 1593// {
1600 foreach (uint localID in localIDs) 1594// foreach (uint localID in localIDs)
1601 m_killRecord.Add(localID); 1595// m_killRecord.Add(localID);
1602 1596
1603 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1597 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1604 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1598 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1605 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1599 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1606 // scene objects in a viewer until that viewer is relogged in. 1600 // scene objects in a viewer until that viewer is relogged in.
1607 OutPacket(kill, ThrottleOutPacketType.Task); 1601 OutPacket(kill, ThrottleOutPacketType.Task);
1608 } 1602// }
1609 } 1603 }
1610 } 1604 }
1611 1605
@@ -2063,9 +2057,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2057 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2064 } 2058 }
2065 2059
2066 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2067 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2060 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2068 { 2061 {
2062 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2063 }
2064
2065 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2066 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2067 {
2069 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2068 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2070 2069
2071 UpdateCreateInventoryItemPacket InventoryReply 2070 UpdateCreateInventoryItemPacket InventoryReply
@@ -2075,6 +2074,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2075 // TODO: don't create new blocks if recycling an old packet 2074 // TODO: don't create new blocks if recycling an old packet
2076 InventoryReply.AgentData.AgentID = AgentId; 2075 InventoryReply.AgentData.AgentID = AgentId;
2077 InventoryReply.AgentData.SimApproved = true; 2076 InventoryReply.AgentData.SimApproved = true;
2077 InventoryReply.AgentData.TransactionID = transactionID;
2078 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2078 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2079 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2079 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2080 InventoryReply.InventoryData[0].ItemID = Item.ID; 2080 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2144,16 +2144,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2144 replytask.InventoryData.TaskID = taskID; 2144 replytask.InventoryData.TaskID = taskID;
2145 replytask.InventoryData.Serial = serial; 2145 replytask.InventoryData.Serial = serial;
2146 replytask.InventoryData.Filename = fileName; 2146 replytask.InventoryData.Filename = fileName;
2147 OutPacket(replytask, ThrottleOutPacketType.Asset); 2147 OutPacket(replytask, ThrottleOutPacketType.Task);
2148 } 2148 }
2149 2149
2150 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2150 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2151 { 2151 {
2152 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2153 if (isTaskInventory)
2154 type = ThrottleOutPacketType.Task;
2155
2152 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2156 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2153 sendXfer.XferID.ID = xferID; 2157 sendXfer.XferID.ID = xferID;
2154 sendXfer.XferID.Packet = packet; 2158 sendXfer.XferID.Packet = packet;
2155 sendXfer.DataPacket.Data = data; 2159 sendXfer.DataPacket.Data = data;
2156 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2160 OutPacket(sendXfer, type);
2157 } 2161 }
2158 2162
2159 public void SendAbortXferPacket(ulong xferID) 2163 public void SendAbortXferPacket(ulong xferID)
@@ -2335,6 +2339,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2335 OutPacket(sound, ThrottleOutPacketType.Task); 2339 OutPacket(sound, ThrottleOutPacketType.Task);
2336 } 2340 }
2337 2341
2342 public void SendTransferAbort(TransferRequestPacket transferRequest)
2343 {
2344 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2345 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2346 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2347 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2348 OutPacket(abort, ThrottleOutPacketType.Task);
2349 }
2350
2338 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2351 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2339 { 2352 {
2340 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2353 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2643,6 +2656,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2643 float friction = part.Friction; 2656 float friction = part.Friction;
2644 float bounce = part.Restitution; 2657 float bounce = part.Restitution;
2645 float gravmod = part.GravityModifier; 2658 float gravmod = part.GravityModifier;
2659
2646 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2660 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2647 } 2661 }
2648 } 2662 }
@@ -2713,8 +2727,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2713 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2727 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2714 return; 2728 return;
2715 } 2729 }
2730 int WearableOut = 0;
2731 bool isWearable = false;
2732
2733 if (req.AssetInf != null)
2734 isWearable =
2735 ((AssetType) req.AssetInf.Type ==
2736 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2716 2737
2717 //m_log.Debug("sending asset " + req.RequestAssetID); 2738
2739 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2740
2741
2742 //if (isWearable)
2743 // m_log.Debug((AssetType)req.AssetInf.Type);
2744
2718 TransferInfoPacket Transfer = new TransferInfoPacket(); 2745 TransferInfoPacket Transfer = new TransferInfoPacket();
2719 Transfer.TransferInfo.ChannelType = 2; 2746 Transfer.TransferInfo.ChannelType = 2;
2720 Transfer.TransferInfo.Status = 0; 2747 Transfer.TransferInfo.Status = 0;
@@ -2736,7 +2763,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2736 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2763 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2737 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2764 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2738 Transfer.Header.Zerocoded = true; 2765 Transfer.Header.Zerocoded = true;
2739 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2766 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2740 2767
2741 if (req.NumPackets == 1) 2768 if (req.NumPackets == 1)
2742 { 2769 {
@@ -2747,12 +2774,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2747 TransferPacket.TransferData.Data = req.AssetInf.Data; 2774 TransferPacket.TransferData.Data = req.AssetInf.Data;
2748 TransferPacket.TransferData.Status = 1; 2775 TransferPacket.TransferData.Status = 1;
2749 TransferPacket.Header.Zerocoded = true; 2776 TransferPacket.Header.Zerocoded = true;
2750 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2777 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2751 } 2778 }
2752 else 2779 else
2753 { 2780 {
2754 int processedLength = 0; 2781 int processedLength = 0;
2755 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2782// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2783
2784 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2756 int packetNumber = 0; 2785 int packetNumber = 0;
2757 2786
2758 while (processedLength < req.AssetInf.Data.Length) 2787 while (processedLength < req.AssetInf.Data.Length)
@@ -2778,7 +2807,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2778 TransferPacket.TransferData.Status = 1; 2807 TransferPacket.TransferData.Status = 1;
2779 } 2808 }
2780 TransferPacket.Header.Zerocoded = true; 2809 TransferPacket.Header.Zerocoded = true;
2781 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2810 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2782 2811
2783 processedLength += chunkSize; 2812 processedLength += chunkSize;
2784 packetNumber++; 2813 packetNumber++;
@@ -2823,7 +2852,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2823 reply.Data.ParcelID = parcelID; 2852 reply.Data.ParcelID = parcelID;
2824 reply.Data.OwnerID = land.OwnerID; 2853 reply.Data.OwnerID = land.OwnerID;
2825 reply.Data.Name = Utils.StringToBytes(land.Name); 2854 reply.Data.Name = Utils.StringToBytes(land.Name);
2826 reply.Data.Desc = Utils.StringToBytes(land.Description); 2855 if (land != null && land.Description != null && land.Description != String.Empty)
2856 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2857 else
2858 reply.Data.Desc = new Byte[0];
2827 reply.Data.ActualArea = land.Area; 2859 reply.Data.ActualArea = land.Area;
2828 reply.Data.BillableArea = land.Area; // TODO: what is this? 2860 reply.Data.BillableArea = land.Area; // TODO: what is this?
2829 2861
@@ -3530,24 +3562,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3530 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3562 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3531 AgentWearablesUpdatePacket.WearableDataBlock awb; 3563 AgentWearablesUpdatePacket.WearableDataBlock awb;
3532 int idx = 0; 3564 int idx = 0;
3533 for (int i = 0; i < wearables.Length; i++) 3565
3534 { 3566 for (int i = 0; i < wearables.Length; i++)
3535 for (int j = 0; j < wearables[i].Count; j++) 3567 {
3536 { 3568 for (int j = 0; j < wearables[i].Count; j++)
3537 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3569 {
3538 awb.WearableType = (byte)i; 3570 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3539 awb.AssetID = wearables[i][j].AssetID; 3571 awb.WearableType = (byte) i;
3540 awb.ItemID = wearables[i][j].ItemID; 3572 awb.AssetID = wearables[i][j].AssetID;
3541 aw.WearableData[idx] = awb; 3573 awb.ItemID = wearables[i][j].ItemID;
3542 idx++; 3574 aw.WearableData[idx] = awb;
3543 3575 idx++;
3544// m_log.DebugFormat( 3576
3545// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3577 // m_log.DebugFormat(
3546// awb.ItemID, awb.AssetID, i, Name); 3578 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3547 } 3579 // awb.ItemID, awb.AssetID, i, Name);
3548 } 3580 }
3581 }
3549 3582
3550 OutPacket(aw, ThrottleOutPacketType.Task); 3583 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3551 } 3584 }
3552 3585
3553 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3586 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3558,7 +3591,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3558 3591
3559 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3592 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3560 // TODO: don't create new blocks if recycling an old packet 3593 // TODO: don't create new blocks if recycling an old packet
3561 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3594 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3562 avp.ObjectData.TextureEntry = textureEntry; 3595 avp.ObjectData.TextureEntry = textureEntry;
3563 3596
3564 AvatarAppearancePacket.VisualParamBlock avblock = null; 3597 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3571,7 +3604,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3571 3604
3572 avp.Sender.IsTrial = false; 3605 avp.Sender.IsTrial = false;
3573 avp.Sender.ID = agentID; 3606 avp.Sender.ID = agentID;
3574 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3607 m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3575 OutPacket(avp, ThrottleOutPacketType.Task); 3608 OutPacket(avp, ThrottleOutPacketType.Task);
3576 } 3609 }
3577 3610
@@ -3688,7 +3721,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3688 /// </summary> 3721 /// </summary>
3689 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3722 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3690 { 3723 {
3691 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3724 if (entity is SceneObjectPart)
3725 {
3726 SceneObjectPart e = (SceneObjectPart)entity;
3727 SceneObjectGroup g = e.ParentGroup;
3728 if (g.RootPart.Shape.State > 30) // HUD
3729 if (g.OwnerID != AgentId)
3730 return; // Don't send updates for other people's HUDs
3731 }
3732
3692 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3733 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3693 3734
3694 lock (m_entityUpdates.SyncRoot) 3735 lock (m_entityUpdates.SyncRoot)
@@ -3755,27 +3796,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3755 3796
3756 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3797 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3757 // condition where a kill can be processed before an out-of-date update for the same object. 3798 // condition where a kill can be processed before an out-of-date update for the same object.
3758 lock (m_killRecord) 3799 float avgTimeDilation = 1.0f;
3800 IEntityUpdate iupdate;
3801 Int32 timeinqueue; // this is just debugging code & can be dropped later
3802
3803 while (updatesThisCall < maxUpdates)
3759 { 3804 {
3760 float avgTimeDilation = 1.0f; 3805 lock (m_entityUpdates.SyncRoot)
3761 IEntityUpdate iupdate; 3806 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3762 Int32 timeinqueue; // this is just debugging code & can be dropped later 3807 break;
3808
3809 EntityUpdate update = (EntityUpdate)iupdate;
3810
3811 avgTimeDilation += update.TimeDilation;
3812 avgTimeDilation *= 0.5f;
3763 3813
3764 while (updatesThisCall < maxUpdates) 3814 if (update.Entity is SceneObjectPart)
3765 { 3815 {
3766 lock (m_entityUpdates.SyncRoot) 3816 SceneObjectPart part = (SceneObjectPart)update.Entity;
3767 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3768 break;
3769 3817
3770 EntityUpdate update = (EntityUpdate)iupdate; 3818 if (part.ParentGroup.IsDeleted)
3771 3819 continue;
3772 avgTimeDilation += update.TimeDilation;
3773 avgTimeDilation *= 0.5f;
3774 3820
3775 if (update.Entity is SceneObjectPart) 3821 if (part.ParentGroup.IsAttachment)
3822 { // Someone else's HUD, why are we getting these?
3823 if (part.ParentGroup.OwnerID != AgentId &&
3824 part.ParentGroup.RootPart.Shape.State > 30)
3825 continue;
3826 ScenePresence sp;
3827 // Owner is not in the sim, don't update it to
3828 // anyone
3829 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3830 continue;
3831
3832 List<SceneObjectGroup> atts = sp.GetAttachments();
3833 bool found = false;
3834 foreach (SceneObjectGroup att in atts)
3835 {
3836 if (att == part.ParentGroup)
3837 {
3838 found = true;
3839 break;
3840 }
3841 }
3842
3843 // It's an attachment of a valid avatar, but
3844 // doesn't seem to be attached, skip
3845 if (!found)
3846 continue;
3847
3848 // On vehicle crossing, the attachments are received
3849 // while the avatar is still a child. Don't send
3850 // updates here because the LocalId has not yet
3851 // been updated and the viewer will derender the
3852 // attachments until the avatar becomes root.
3853 if (sp.IsChildAgent)
3854 continue;
3855
3856 // If the object is an attachment we don't want it to be in the kill
3857 // record. Else attaching from inworld and subsequently dropping
3858 // it will no longer work.
3859// lock (m_killRecord)
3860// {
3861// m_killRecord.Remove(part.LocalId);
3862// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3863// }
3864 }
3865 else
3776 { 3866 {
3777 SceneObjectPart part = (SceneObjectPart)update.Entity;
3778
3779 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3867 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3780 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3868 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3781 // safety measure. 3869 // safety measure.
@@ -3786,21 +3874,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3786 // 3874 //
3787 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3875 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3788 // after the root prim has been deleted. 3876 // after the root prim has been deleted.
3789 if (m_killRecord.Contains(part.LocalId)) 3877 //
3790 { 3878 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3791 // m_log.WarnFormat( 3879// lock (m_killRecord)
3792 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3880// {
3793 // part.LocalId, Name); 3881// if (m_killRecord.Contains(part.LocalId))
3794 continue; 3882// continue;
3795 } 3883// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3796 3884// continue;
3797 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3885// }
3886 }
3887
3888 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3889 {
3890 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3891 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3798 { 3892 {
3799 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3893 part.Shape.LightEntry = false;
3800 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3801 {
3802 part.Shape.LightEntry = false;
3803 }
3804 } 3894 }
3805 3895
3806 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3896 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3811,224 +3901,158 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3811 part.Shape.ProfileHollow = 27500; 3901 part.Shape.ProfileHollow = 27500;
3812 } 3902 }
3813 } 3903 }
3814 3904 }
3815 #region UpdateFlags to packet type conversion 3905
3816 3906 ++updatesThisCall;
3817 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3907
3818 3908 #region UpdateFlags to packet type conversion
3819 bool canUseCompressed = true; 3909
3820 bool canUseImproved = true; 3910 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3821 3911
3822 // Compressed object updates only make sense for LL primitives 3912 bool canUseCompressed = true;
3823 if (!(update.Entity is SceneObjectPart)) 3913 bool canUseImproved = true;
3914
3915 // Compressed object updates only make sense for LL primitives
3916 if (!(update.Entity is SceneObjectPart))
3917 {
3918 canUseCompressed = false;
3919 }
3920
3921 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3922 {
3923 canUseCompressed = false;
3924 canUseImproved = false;
3925 }
3926 else
3927 {
3928 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3929 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3930 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3824 { 3932 {
3825 canUseCompressed = false; 3933 canUseCompressed = false;
3826 } 3934 }
3827 3935
3828 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3936 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3937 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3938 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3939 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3940 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3941 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3942 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3943 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3944 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3945 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3829 { 3950 {
3830 canUseCompressed = false;
3831 canUseImproved = false; 3951 canUseImproved = false;
3832 } 3952 }
3833 else 3953 }
3834 {
3835 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3836 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3837 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3838 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3839 {
3840 canUseCompressed = false;
3841 }
3842
3843 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3844 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3845 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3846 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3847 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3848 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3849 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3850 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3851 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3852 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3853 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3854 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3855 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3857 {
3858 canUseImproved = false;
3859 }
3860 }
3861
3862 #endregion UpdateFlags to packet type conversion
3863
3864 #region Block Construction
3865
3866 // TODO: Remove this once we can build compressed updates
3867 canUseCompressed = false;
3868 3954
3869 if (!canUseImproved && !canUseCompressed) 3955 #endregion UpdateFlags to packet type conversion
3870 {
3871 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3872 3956
3873 if (update.Entity is ScenePresence) 3957 #region Block Construction
3874 {
3875 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3876 }
3877 else
3878 {
3879 SceneObjectPart part = (SceneObjectPart)update.Entity;
3880 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3881
3882 // If the part has become a private hud since the update was scheduled then we do not
3883 // want to send it to other avatars.
3884 if (part.ParentGroup.IsAttachment
3885 && part.ParentGroup.HasPrivateAttachmentPoint
3886 && part.ParentGroup.AttachedAvatar != AgentId)
3887 continue;
3888
3889 // If the part has since been deleted, then drop the update. In the case of attachments,
3890 // this is to avoid spurious updates to other viewers since post-processing of attachments
3891 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3892 // of the test above).
3893 //
3894 // Actual deletions (kills) happen in another method.
3895 if (part.ParentGroup.IsDeleted)
3896 continue;
3897 }
3898 3958
3899 objectUpdateBlocks.Value.Add(updateBlock); 3959 // TODO: Remove this once we can build compressed updates
3900 objectUpdates.Value.Add(update); 3960 canUseCompressed = false;
3901 }
3902 else if (!canUseImproved)
3903 {
3904 SceneObjectPart part = (SceneObjectPart)update.Entity;
3905 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3906 = CreateCompressedUpdateBlock(part, updateFlags);
3907
3908 // If the part has since been deleted, then drop the update. In the case of attachments,
3909 // this is to avoid spurious updates to other viewers since post-processing of attachments
3910 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3911 // of the test above).
3912 //
3913 // Actual deletions (kills) happen in another method.
3914 if (part.ParentGroup.IsDeleted)
3915 continue;
3916 3961
3917 compressedUpdateBlocks.Value.Add(compressedBlock); 3962 if (!canUseImproved && !canUseCompressed)
3918 compressedUpdates.Value.Add(update); 3963 {
3964 if (update.Entity is ScenePresence)
3965 {
3966 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3919 } 3967 }
3920 else 3968 else
3921 { 3969 {
3922 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3970 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3923 {
3924 // Self updates go into a special list
3925 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3926 terseAgentUpdates.Value.Add(update);
3927 }
3928 else
3929 {
3930 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3931 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3932
3933 // Everything else goes here
3934 if (update.Entity is SceneObjectPart)
3935 {
3936 SceneObjectPart part = (SceneObjectPart)update.Entity;
3937
3938 // If the part has become a private hud since the update was scheduled then we do not
3939 // want to send it to other avatars.
3940 if (part.ParentGroup.IsAttachment
3941 && part.ParentGroup.HasPrivateAttachmentPoint
3942 && part.ParentGroup.AttachedAvatar != AgentId)
3943 continue;
3944
3945 // If the part has since been deleted, then drop the update. In the case of attachments,
3946 // this is to avoid spurious updates to other viewers since post-processing of attachments
3947 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3948 // of the test above).
3949 //
3950 // Actual deletions (kills) happen in another method.
3951 if (part.ParentGroup.IsDeleted)
3952 continue;
3953 }
3954
3955 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3956 terseUpdates.Value.Add(update);
3957 }
3958 } 3971 }
3959
3960 ++updatesThisCall;
3961
3962 #endregion Block Construction
3963 } 3972 }
3964 3973 else if (!canUseImproved)
3965 #region Packet Sending 3974 {
3966 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3975 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3967 3976 }
3968 if (terseAgentUpdateBlocks.IsValueCreated) 3977 else
3969 { 3978 {
3970 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3979 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3980 // Self updates go into a special list
3981 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3982 else
3983 // Everything else goes here
3984 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3985 }
3971 3986
3972 ImprovedTerseObjectUpdatePacket packet 3987 #endregion Block Construction
3973 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3988 }
3974 3989
3975 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3990 #region Packet Sending
3976 packet.RegionData.TimeDilation = timeDilation; 3991
3977 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3992 const float TIME_DILATION = 1.0f;
3993 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3994
3995 if (terseAgentUpdateBlocks.IsValueCreated)
3996 {
3997 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3978 3998
3979 for (int i = 0; i < blocks.Count; i++) 3999 ImprovedTerseObjectUpdatePacket packet
3980 packet.ObjectData[i] = blocks[i]; 4000 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3981 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4001 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3982 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4002 packet.RegionData.TimeDilation = timeDilation;
3983 } 4003 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3984 4004
3985 if (objectUpdateBlocks.IsValueCreated) 4005 for (int i = 0; i < blocks.Count; i++)
3986 { 4006 packet.ObjectData[i] = blocks[i];
3987 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3988
3989 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3990 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3991 packet.RegionData.TimeDilation = timeDilation;
3992 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3993
3994 for (int i = 0; i < blocks.Count; i++)
3995 packet.ObjectData[i] = blocks[i];
3996 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3997 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3998 }
3999
4000 if (compressedUpdateBlocks.IsValueCreated)
4001 {
4002 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4003
4004 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4005 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4006 packet.RegionData.TimeDilation = timeDilation;
4007 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4008
4009 for (int i = 0; i < blocks.Count; i++)
4010 packet.ObjectData[i] = blocks[i];
4011 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4012 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4013 }
4014 4007
4015 if (terseUpdateBlocks.IsValueCreated) 4008 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4016 { 4009 }
4017 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4018
4019 ImprovedTerseObjectUpdatePacket packet
4020 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4021 PacketType.ImprovedTerseObjectUpdate);
4022 4010
4023 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4011 if (objectUpdateBlocks.IsValueCreated)
4024 packet.RegionData.TimeDilation = timeDilation; 4012 {
4025 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4013 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4026 4014
4027 for (int i = 0; i < blocks.Count; i++) 4015 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4028 packet.ObjectData[i] = blocks[i]; 4016 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4029 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4017 packet.RegionData.TimeDilation = timeDilation;
4030 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4018 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4031 } 4019
4020 for (int i = 0; i < blocks.Count; i++)
4021 packet.ObjectData[i] = blocks[i];
4022
4023 OutPacket(packet, ThrottleOutPacketType.Task, true);
4024 }
4025
4026 if (compressedUpdateBlocks.IsValueCreated)
4027 {
4028 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4029
4030 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4031 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4032 packet.RegionData.TimeDilation = timeDilation;
4033 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4034
4035 for (int i = 0; i < blocks.Count; i++)
4036 packet.ObjectData[i] = blocks[i];
4037
4038 OutPacket(packet, ThrottleOutPacketType.Task, true);
4039 }
4040
4041 if (terseUpdateBlocks.IsValueCreated)
4042 {
4043 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4044
4045 ImprovedTerseObjectUpdatePacket packet
4046 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4047 PacketType.ImprovedTerseObjectUpdate);
4048 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4049 packet.RegionData.TimeDilation = timeDilation;
4050 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4051
4052 for (int i = 0; i < blocks.Count; i++)
4053 packet.ObjectData[i] = blocks[i];
4054
4055 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4032 } 4056 }
4033 4057
4034 #endregion Packet Sending 4058 #endregion Packet Sending
@@ -4321,11 +4345,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4321 4345
4322 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4346 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4323 // of the object rather than the properties when the packet was created 4347 // of the object rather than the properties when the packet was created
4324 OutPacket(packet, ThrottleOutPacketType.Task, true, 4348 // HACK : Remove intelligent resending until it's fixed in core
4325 delegate(OutgoingPacket oPacket) 4349 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4326 { 4350 // delegate(OutgoingPacket oPacket)
4327 ResendPropertyUpdates(updates, oPacket); 4351 // {
4328 }); 4352 // ResendPropertyUpdates(updates, oPacket);
4353 // });
4354 OutPacket(packet, ThrottleOutPacketType.Task, true);
4329 4355
4330 // pbcnt += blocks.Count; 4356 // pbcnt += blocks.Count;
4331 // ppcnt++; 4357 // ppcnt++;
@@ -4351,11 +4377,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4351 // of the object rather than the properties when the packet was created 4377 // of the object rather than the properties when the packet was created
4352 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4378 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4353 updates.Add(familyUpdates.Value[i]); 4379 updates.Add(familyUpdates.Value[i]);
4354 OutPacket(packet, ThrottleOutPacketType.Task, true, 4380 // HACK : Remove intelligent resending until it's fixed in core
4355 delegate(OutgoingPacket oPacket) 4381 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4356 { 4382 // delegate(OutgoingPacket oPacket)
4357 ResendPropertyUpdates(updates, oPacket); 4383 // {
4358 }); 4384 // ResendPropertyUpdates(updates, oPacket);
4385 // });
4386 OutPacket(packet, ThrottleOutPacketType.Task, true);
4359 4387
4360 // fpcnt++; 4388 // fpcnt++;
4361 // fbcnt++; 4389 // fbcnt++;
@@ -4727,7 +4755,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4727 4755
4728 if (landData.SimwideArea > 0) 4756 if (landData.SimwideArea > 0)
4729 { 4757 {
4730 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4758 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4759 // Never report more than sim total capacity
4760 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4761 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4731 updateMessage.SimWideMaxPrims = simulatorCapacity; 4762 updateMessage.SimWideMaxPrims = simulatorCapacity;
4732 } 4763 }
4733 else 4764 else
@@ -4856,14 +4887,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4856 4887
4857 if (notifyCount > 0) 4888 if (notifyCount > 0)
4858 { 4889 {
4859 if (notifyCount > 32) 4890// if (notifyCount > 32)
4860 { 4891// {
4861 m_log.InfoFormat( 4892// m_log.InfoFormat(
4862 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4893// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4863 + " - a developer might want to investigate whether this is a hard limit", 32); 4894// + " - a developer might want to investigate whether this is a hard limit", 32);
4864 4895//
4865 notifyCount = 32; 4896// notifyCount = 32;
4866 } 4897// }
4867 4898
4868 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4899 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4869 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4900 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4918,9 +4949,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4918 { 4949 {
4919 ScenePresence presence = (ScenePresence)entity; 4950 ScenePresence presence = (ScenePresence)entity;
4920 4951
4952 position = presence.OffsetPosition;
4953 rotation = presence.Rotation;
4954
4955 if (presence.ParentID != 0)
4956 {
4957 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4958 if (part != null && part != part.ParentGroup.RootPart)
4959 {
4960 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4961 rotation = part.RotationOffset * presence.Rotation;
4962 }
4963 }
4964
4921 attachPoint = 0; 4965 attachPoint = 0;
4922 collisionPlane = presence.CollisionPlane; 4966 collisionPlane = presence.CollisionPlane;
4923 position = presence.OffsetPosition;
4924 velocity = presence.Velocity; 4967 velocity = presence.Velocity;
4925 acceleration = Vector3.Zero; 4968 acceleration = Vector3.Zero;
4926 4969
@@ -5037,13 +5080,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5037 5080
5038 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5081 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5039 { 5082 {
5083 Vector3 offsetPosition = data.OffsetPosition;
5084 Quaternion rotation = data.Rotation;
5085 uint parentID = data.ParentID;
5086
5087 if (parentID != 0)
5088 {
5089 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5090 if (part != null && part != part.ParentGroup.RootPart)
5091 {
5092 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5093 rotation = part.RotationOffset * data.Rotation;
5094 parentID = part.ParentGroup.RootPart.LocalId;
5095 }
5096 }
5097
5040 byte[] objectData = new byte[76]; 5098 byte[] objectData = new byte[76];
5041 5099
5042 data.CollisionPlane.ToBytes(objectData, 0); 5100 data.CollisionPlane.ToBytes(objectData, 0);
5043 data.OffsetPosition.ToBytes(objectData, 16); 5101 offsetPosition.ToBytes(objectData, 16);
5044// data.Velocity.ToBytes(objectData, 28); 5102// data.Velocity.ToBytes(objectData, 28);
5045// data.Acceleration.ToBytes(objectData, 40); 5103// data.Acceleration.ToBytes(objectData, 40);
5046 data.Rotation.ToBytes(objectData, 52); 5104 rotation.ToBytes(objectData, 52);
5047 //data.AngularVelocity.ToBytes(objectData, 64); 5105 //data.AngularVelocity.ToBytes(objectData, 64);
5048 5106
5049 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5107 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5057,14 +5115,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5057 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5115 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5058 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5116 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5059 update.ObjectData = objectData; 5117 update.ObjectData = objectData;
5060 update.ParentID = data.ParentID; 5118 update.ParentID = parentID;
5061 update.PathCurve = 16; 5119 update.PathCurve = 16;
5062 update.PathScaleX = 100; 5120 update.PathScaleX = 100;
5063 update.PathScaleY = 100; 5121 update.PathScaleY = 100;
5064 update.PCode = (byte)PCode.Avatar; 5122 update.PCode = (byte)PCode.Avatar;
5065 update.ProfileCurve = 1; 5123 update.ProfileCurve = 1;
5066 update.PSBlock = Utils.EmptyBytes; 5124 update.PSBlock = Utils.EmptyBytes;
5067 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5125 update.Scale = data.Appearance.AvatarSize;
5126// update.Scale.Z -= 0.2f;
5127
5068 update.Text = Utils.EmptyBytes; 5128 update.Text = Utils.EmptyBytes;
5069 update.TextColor = new byte[4]; 5129 update.TextColor = new byte[4];
5070 5130
@@ -5075,10 +5135,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5075 update.TextureEntry = Utils.EmptyBytes; 5135 update.TextureEntry = Utils.EmptyBytes;
5076// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5136// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5077 5137
5138/* 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)
5078 update.UpdateFlags = (uint)( 5139 update.UpdateFlags = (uint)(
5079 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5140 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5080 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5141 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5081 PrimFlags.ObjectOwnerModify); 5142 PrimFlags.ObjectOwnerModify);
5143*/
5144 update.UpdateFlags = 0;
5082 5145
5083 return update; 5146 return update;
5084 } 5147 }
@@ -5249,8 +5312,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5249 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5312 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5250 // for each AgentUpdate packet. 5313 // for each AgentUpdate packet.
5251 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5314 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5252 5315
5253 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5316 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5317 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5318 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5254 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5319 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5255 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5320 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5256 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5321 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5402,6 +5467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5402 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5467 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5403 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5468 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5404 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5469 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5470 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5405 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5471 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5406 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5472 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5407 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5473 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5468,6 +5534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5468 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5534 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5469 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5535 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5470 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5536 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5537 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5471 5538
5472 AddGenericPacketHandler("autopilot", HandleAutopilot); 5539 AddGenericPacketHandler("autopilot", HandleAutopilot);
5473 } 5540 }
@@ -5506,6 +5573,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5506 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5573 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5507 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5574 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5508 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5575 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5576 (x.ControlFlags != 0) ||
5509 (x.Far != m_lastAgentUpdateArgs.Far) || 5577 (x.Far != m_lastAgentUpdateArgs.Far) ||
5510 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5578 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5511 (x.State != m_lastAgentUpdateArgs.State) || 5579 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5765,6 +5833,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5765 return true; 5833 return true;
5766 } 5834 }
5767 5835
5836 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5837 {
5838 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5839 if (p.AgentData.SessionID != SessionId ||
5840 p.AgentData.AgentID != AgentId)
5841 return true;
5842
5843 m_VelocityInterpolate = false;
5844 return true;
5845 }
5846
5847 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5848 {
5849 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5850 if (p.AgentData.SessionID != SessionId ||
5851 p.AgentData.AgentID != AgentId)
5852 return true;
5853
5854 m_VelocityInterpolate = true;
5855 return true;
5856 }
5857
5858
5768 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5859 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5769 { 5860 {
5770 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5861 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6185,17 +6276,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6185 // Temporarily protect ourselves from the mantis #951 failure. 6276 // Temporarily protect ourselves from the mantis #951 failure.
6186 // However, we could do this for several other handlers where a failure isn't terminal 6277 // However, we could do this for several other handlers where a failure isn't terminal
6187 // for the client session anyway, in order to protect ourselves against bad code in plugins 6278 // for the client session anyway, in order to protect ourselves against bad code in plugins
6279 Vector3 avSize = appear.AgentData.Size;
6188 try 6280 try
6189 { 6281 {
6190 byte[] visualparams = new byte[appear.VisualParam.Length]; 6282 byte[] visualparams = new byte[appear.VisualParam.Length];
6191 for (int i = 0; i < appear.VisualParam.Length; i++) 6283 for (int i = 0; i < appear.VisualParam.Length; i++)
6192 visualparams[i] = appear.VisualParam[i].ParamValue; 6284 visualparams[i] = appear.VisualParam[i].ParamValue;
6193 6285 //var b = appear.WearableData[0];
6286
6194 Primitive.TextureEntry te = null; 6287 Primitive.TextureEntry te = null;
6195 if (appear.ObjectData.TextureEntry.Length > 1) 6288 if (appear.ObjectData.TextureEntry.Length > 1)
6196 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6289 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6290
6291 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6292 for (int i=0; i<appear.WearableData.Length;i++)
6293 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6197 6294
6198 handlerSetAppearance(sender, te, visualparams); 6295
6296
6297 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6199 } 6298 }
6200 catch (Exception e) 6299 catch (Exception e)
6201 { 6300 {
@@ -6404,6 +6503,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6404 { 6503 {
6405 handlerCompleteMovementToRegion(sender, true); 6504 handlerCompleteMovementToRegion(sender, true);
6406 } 6505 }
6506 else
6507 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6508
6407 handlerCompleteMovementToRegion = null; 6509 handlerCompleteMovementToRegion = null;
6408 6510
6409 return true; 6511 return true;
@@ -6421,7 +6523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6421 return true; 6523 return true;
6422 } 6524 }
6423 #endregion 6525 #endregion
6424 6526/*
6425 StartAnim handlerStartAnim = null; 6527 StartAnim handlerStartAnim = null;
6426 StopAnim handlerStopAnim = null; 6528 StopAnim handlerStopAnim = null;
6427 6529
@@ -6445,6 +6547,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6445 } 6547 }
6446 } 6548 }
6447 return true; 6549 return true;
6550*/
6551 ChangeAnim handlerChangeAnim = null;
6552
6553 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6554 {
6555 handlerChangeAnim = OnChangeAnim;
6556 if (handlerChangeAnim != null)
6557 {
6558 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6559 }
6560 }
6561
6562 handlerChangeAnim = OnChangeAnim;
6563 if (handlerChangeAnim != null)
6564 {
6565 handlerChangeAnim(UUID.Zero, false, true);
6566 }
6567
6568 return true;
6448 } 6569 }
6449 6570
6450 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6571 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6670,6 +6791,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6670 #endregion 6791 #endregion
6671 6792
6672 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6793 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6794 GenericCall2 handler = OnUpdateThrottles;
6795 if (handler != null)
6796 {
6797 handler();
6798 }
6673 return true; 6799 return true;
6674 } 6800 }
6675 6801
@@ -7094,7 +7220,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7094 physdata.Bounce = phsblock.Restitution; 7220 physdata.Bounce = phsblock.Restitution;
7095 physdata.Density = phsblock.Density; 7221 physdata.Density = phsblock.Density;
7096 physdata.Friction = phsblock.Friction; 7222 physdata.Friction = phsblock.Friction;
7097 physdata.GravitationModifier = phsblock.GravityMultiplier; 7223 physdata.GravitationModifier = phsblock.GravityMultiplier;
7098 } 7224 }
7099 7225
7100 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7226 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7680,6 +7806,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7680 // surrounding scene 7806 // surrounding scene
7681 if ((ImageType)block.Type == ImageType.Baked) 7807 if ((ImageType)block.Type == ImageType.Baked)
7682 args.Priority *= 2.0f; 7808 args.Priority *= 2.0f;
7809 int wearableout = 0;
7683 7810
7684 ImageManager.EnqueueReq(args); 7811 ImageManager.EnqueueReq(args);
7685 } 7812 }
@@ -8698,16 +8825,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8698 8825
8699 #region Parcel related packets 8826 #region Parcel related packets
8700 8827
8828 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8829 // to be done with minimal resources as possible
8830 // variables temporary here while in test
8831
8832 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8833 bool RegionHandleRequestsInService = false;
8834
8701 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8835 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8702 { 8836 {
8703 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8837 UUID currentUUID;
8704 8838
8705 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8839 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8706 if (handlerRegionHandleRequest != null) 8840
8841 if (handlerRegionHandleRequest == null)
8842 return true;
8843
8844 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8845
8846 lock (RegionHandleRequests)
8707 { 8847 {
8708 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8848 if (RegionHandleRequestsInService)
8849 {
8850 // we are already busy doing a previus request
8851 // so enqueue it
8852 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8853 return true;
8854 }
8855
8856 // else do it
8857 currentUUID = rhrPack.RequestBlock.RegionID;
8858 RegionHandleRequestsInService = true;
8709 } 8859 }
8710 return true; 8860
8861 while (true)
8862 {
8863 handlerRegionHandleRequest(this, currentUUID);
8864
8865 lock (RegionHandleRequests)
8866 {
8867 // exit condition, nothing to do or closed
8868 // current code seems to assume we may loose the handler at anytime,
8869 // so keep checking it
8870 handlerRegionHandleRequest = OnRegionHandleRequest;
8871
8872 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8873 {
8874 RegionHandleRequests.Clear();
8875 RegionHandleRequestsInService = false;
8876 return true;
8877 }
8878 currentUUID = RegionHandleRequests.Dequeue();
8879 }
8880 }
8881
8882 return true; // actually unreached
8711 } 8883 }
8712 8884
8713 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8885 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9963,7 +10135,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9963 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10135 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9964 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10136 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9965 UpdateMuteListEntry.MuteData.MuteType, 10137 UpdateMuteListEntry.MuteData.MuteType,
9966 UpdateMuteListEntry.AgentData.AgentID); 10138 UpdateMuteListEntry.MuteData.MuteFlags);
9967 return true; 10139 return true;
9968 } 10140 }
9969 return false; 10141 return false;
@@ -9978,8 +10150,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9978 { 10150 {
9979 handlerRemoveMuteListEntry(this, 10151 handlerRemoveMuteListEntry(this,
9980 RemoveMuteListEntry.MuteData.MuteID, 10152 RemoveMuteListEntry.MuteData.MuteID,
9981 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10153 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9982 RemoveMuteListEntry.AgentData.AgentID);
9983 return true; 10154 return true;
9984 } 10155 }
9985 return false; 10156 return false;
@@ -10023,10 +10194,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10023 return false; 10194 return false;
10024 } 10195 }
10025 10196
10197 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10198 {
10199 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10200 (ChangeInventoryItemFlagsPacket)packet;
10201 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10202 if (handlerChangeInventoryItemFlags != null)
10203 {
10204 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10205 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10206 return true;
10207 }
10208 return false;
10209 }
10210
10026 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10211 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10027 { 10212 {
10028 return true; 10213 return true;
10029 } 10214 }
10215
10216 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10217 {
10218 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10219
10220 #region Packet Session and User Check
10221 if (m_checkPackets)
10222 {
10223 if (packet.AgentData.SessionID != SessionId ||
10224 packet.AgentData.AgentID != AgentId)
10225 return true;
10226 }
10227 #endregion
10228 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10229 List<InventoryItemBase> items = new List<InventoryItemBase>();
10230 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10231 {
10232 InventoryItemBase b = new InventoryItemBase();
10233 b.ID = n.OldItemID;
10234 b.Folder = n.OldFolderID;
10235 items.Add(b);
10236 }
10237
10238 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10239 if (handlerMoveItemsAndLeaveCopy != null)
10240 {
10241 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10242 }
10243
10244 return true;
10245 }
10030 10246
10031 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10247 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10032 { 10248 {
@@ -10453,6 +10669,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10453 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10669 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10454 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10670 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10455 10671
10672 Scene scene = (Scene)m_scene;
10673 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10674 {
10675 ScenePresence p;
10676 if (scene.TryGetScenePresence(sender.AgentId, out p))
10677 {
10678 if (p.GodLevel >= 200)
10679 {
10680 groupProfileReply.GroupData.OpenEnrollment = true;
10681 groupProfileReply.GroupData.MembershipFee = 0;
10682 }
10683 }
10684 }
10685
10456 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10686 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10457 } 10687 }
10458 return true; 10688 return true;
@@ -11026,11 +11256,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11026 11256
11027 StartLure handlerStartLure = OnStartLure; 11257 StartLure handlerStartLure = OnStartLure;
11028 if (handlerStartLure != null) 11258 if (handlerStartLure != null)
11029 handlerStartLure(startLureRequest.Info.LureType, 11259 {
11030 Utils.BytesToString( 11260 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11031 startLureRequest.Info.Message), 11261 {
11032 startLureRequest.TargetData[0].TargetID, 11262 handlerStartLure(startLureRequest.Info.LureType,
11033 this); 11263 Utils.BytesToString(
11264 startLureRequest.Info.Message),
11265 startLureRequest.TargetData[i].TargetID,
11266 this);
11267 }
11268 }
11034 return true; 11269 return true;
11035 } 11270 }
11036 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11271 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11144,10 +11379,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11144 } 11379 }
11145 #endregion 11380 #endregion
11146 11381
11147 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11382 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11148 if (handlerClassifiedGodDelete != null) 11383 if (handlerClassifiedGodDelete != null)
11149 handlerClassifiedGodDelete( 11384 handlerClassifiedGodDelete(
11150 classifiedGodDelete.Data.ClassifiedID, 11385 classifiedGodDelete.Data.ClassifiedID,
11386 classifiedGodDelete.Data.QueryID,
11151 this); 11387 this);
11152 return true; 11388 return true;
11153 } 11389 }
@@ -11460,6 +11696,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11460 11696
11461 if (cachedtex.AgentData.SessionID != SessionId) 11697 if (cachedtex.AgentData.SessionID != SessionId)
11462 return false; 11698 return false;
11699
11463 11700
11464 // TODO: don't create new blocks if recycling an old packet 11701 // TODO: don't create new blocks if recycling an old packet
11465 cachedresp.AgentData.AgentID = AgentId; 11702 cachedresp.AgentData.AgentID = AgentId;
@@ -11469,14 +11706,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11469 cachedresp.WearableData = 11706 cachedresp.WearableData =
11470 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11707 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11471 11708
11472 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11709 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11710 // var item = fac.GetBakedTextureFaces(AgentId);
11711 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11712
11713 IAssetService cache = m_scene.AssetService;
11714 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11715 //bakedTextureModule = null;
11716 int maxWearablesLoop = cachedtex.WearableData.Length;
11717 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11718 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11719
11720 if (bakedTextureModule != null && cache != null)
11473 { 11721 {
11474 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11722 // 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
11475 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11723
11476 cachedresp.WearableData[i].TextureID = UUID.Zero; 11724 WearableCacheItem[] cacheItems = null;
11477 cachedresp.WearableData[i].HostName = new byte[0]; 11725 ScenePresence p = m_scene.GetScenePresence(AgentId);
11726 if (p.Appearance != null)
11727 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11728 {
11729 try
11730 {
11731 cacheItems = bakedTextureModule.Get(AgentId);
11732 p.Appearance.WearableCacheItems = cacheItems;
11733 p.Appearance.WearableCacheItemsDirty = false;
11734 }
11735
11736 /*
11737 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11738 *
11739 catch (System.Net.Sockets.SocketException)
11740 {
11741 cacheItems = null;
11742 }
11743 catch (WebException)
11744 {
11745 cacheItems = null;
11746 }
11747 catch (InvalidOperationException)
11748 {
11749 cacheItems = null;
11750 } */
11751 catch (Exception)
11752 {
11753 cacheItems = null;
11754 }
11755
11756 }
11757 else if (p.Appearance.WearableCacheItems != null)
11758 {
11759 cacheItems = p.Appearance.WearableCacheItems;
11760 }
11761
11762 if (cache != null && cacheItems != null)
11763 {
11764 foreach (WearableCacheItem item in cacheItems)
11765 {
11766
11767 if (cache.GetCached(item.TextureID.ToString()) == null)
11768 {
11769 item.TextureAsset.Temporary = true;
11770 cache.Store(item.TextureAsset);
11771 }
11772
11773
11774 }
11775 }
11776
11777 if (cacheItems != null)
11778 {
11779
11780 for (int i = 0; i < maxWearablesLoop; i++)
11781 {
11782 WearableCacheItem item =
11783 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11784
11785 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11786 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11787 cachedresp.WearableData[i].HostName = new byte[0];
11788 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11789 {
11790
11791 cachedresp.WearableData[i].TextureID = item.TextureID;
11792 }
11793 else
11794 {
11795 cachedresp.WearableData[i].TextureID = UUID.Zero;
11796 }
11797 }
11798 }
11799 else
11800 {
11801 for (int i = 0; i < maxWearablesLoop; i++)
11802 {
11803 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11804 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11805 cachedresp.WearableData[i].TextureID = UUID.Zero;
11806 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11807 cachedresp.WearableData[i].HostName = new byte[0];
11808 }
11809 }
11478 } 11810 }
11811 else
11812 {
11813 if (cache == null)
11814 {
11815 for (int i = 0; i < maxWearablesLoop; i++)
11816 {
11817 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11818 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11819 cachedresp.WearableData[i].TextureID = UUID.Zero;
11820 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11821 cachedresp.WearableData[i].HostName = new byte[0];
11822 }
11823 }
11824 else
11825 {
11826 for (int i = 0; i < maxWearablesLoop; i++)
11827 {
11828 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11829 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11830
11479 11831
11832
11833 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11834 cachedresp.WearableData[i].TextureID = UUID.Zero;
11835 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11836 else
11837 cachedresp.WearableData[i].TextureID = UUID.Zero;
11838 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11839 cachedresp.WearableData[i].HostName = new byte[0];
11840 }
11841 }
11842 }
11480 cachedresp.Header.Zerocoded = true; 11843 cachedresp.Header.Zerocoded = true;
11481 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11844 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11482 11845
@@ -11513,209 +11876,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11513 } 11876 }
11514 else 11877 else
11515 { 11878 {
11516// m_log.DebugFormat( 11879 ClientChangeObject updatehandler = onClientChangeObject;
11517// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11518// i, block.Type, part.Name, part.LocalId);
11519 11880
11520// // Do this once since fetch parts creates a new array. 11881 if (updatehandler != null)
11521// SceneObjectPart[] parts = part.ParentGroup.Parts; 11882 {
11522// for (int j = 0; j < parts.Length; j++) 11883 ObjectChangeData udata = new ObjectChangeData();
11523// {
11524// part.StoreUndoState();
11525// parts[j].IgnoreUndoUpdate = true;
11526// }
11527 11884
11528 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11885 /*ubit from ll JIRA:
11886 * 0x01 position
11887 * 0x02 rotation
11888 * 0x04 scale
11889
11890 * 0x08 LINK_SET
11891 * 0x10 UNIFORM for scale
11892 */
11529 11893
11530 switch (block.Type) 11894 // translate to internal changes
11531 { 11895 // not all cases .. just the ones older code did
11532 case 1:
11533 Vector3 pos1 = new Vector3(block.Data, 0);
11534 11896
11535 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11897 switch (block.Type)
11536 if (handlerUpdatePrimSinglePosition != null) 11898 {
11537 { 11899 case 1: //change position sp
11538 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11900 udata.position = new Vector3(block.Data, 0);
11539 handlerUpdatePrimSinglePosition(localId, pos1, this);
11540 }
11541 break;
11542 11901
11543 case 2: 11902 udata.change = ObjectChangeType.primP;
11544 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11903 updatehandler(localId, udata, this);
11904 break;
11545 11905
11546 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11906 case 2: // rotation sp
11547 if (handlerUpdatePrimSingleRotation != null) 11907 udata.rotation = new Quaternion(block.Data, 0, true);
11548 {
11549 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11550 handlerUpdatePrimSingleRotation(localId, rot1, this);
11551 }
11552 break;
11553 11908
11554 case 3: 11909 udata.change = ObjectChangeType.primR;
11555 Vector3 rotPos = new Vector3(block.Data, 0); 11910 updatehandler(localId, udata, this);
11556 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11911 break;
11557 11912
11558 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11913 case 3: // position plus rotation
11559 if (handlerUpdatePrimSingleRotationPosition != null) 11914 udata.position = new Vector3(block.Data, 0);
11560 { 11915 udata.rotation = new Quaternion(block.Data, 12, true);
11561 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11562 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11563 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11564 }
11565 break;
11566 11916
11567 case 4: 11917 udata.change = ObjectChangeType.primPR;
11568 case 20: 11918 updatehandler(localId, udata, this);
11569 Vector3 scale4 = new Vector3(block.Data, 0); 11919 break;
11570 11920
11571 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11921 case 4: // scale sp
11572 if (handlerUpdatePrimScale != null) 11922 udata.scale = new Vector3(block.Data, 0);
11573 { 11923 udata.change = ObjectChangeType.primS;
11574 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11575 handlerUpdatePrimScale(localId, scale4, this);
11576 }
11577 break;
11578 11924
11579 case 5: 11925 updatehandler(localId, udata, this);
11580 Vector3 scale1 = new Vector3(block.Data, 12); 11926 break;
11581 Vector3 pos11 = new Vector3(block.Data, 0);
11582 11927
11583 handlerUpdatePrimScale = OnUpdatePrimScale; 11928 case 0x14: // uniform scale sp
11584 if (handlerUpdatePrimScale != null) 11929 udata.scale = new Vector3(block.Data, 0);
11585 {
11586 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11587 handlerUpdatePrimScale(localId, scale1, this);
11588 11930
11589 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11931 udata.change = ObjectChangeType.primUS;
11590 if (handlerUpdatePrimSinglePosition != null) 11932 updatehandler(localId, udata, this);
11591 { 11933 break;
11592 handlerUpdatePrimSinglePosition(localId, pos11, this);
11593 }
11594 }
11595 break;
11596 11934
11597 case 9: 11935 case 5: // scale and position sp
11598 Vector3 pos2 = new Vector3(block.Data, 0); 11936 udata.position = new Vector3(block.Data, 0);
11937 udata.scale = new Vector3(block.Data, 12);
11599 11938
11600 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11939 udata.change = ObjectChangeType.primPS;
11940 updatehandler(localId, udata, this);
11941 break;
11601 11942
11602 if (handlerUpdateVector != null) 11943 case 0x15: //uniform scale and position
11603 { 11944 udata.position = new Vector3(block.Data, 0);
11604 handlerUpdateVector(localId, pos2, this); 11945 udata.scale = new Vector3(block.Data, 12);
11605 }
11606 break;
11607 11946
11608 case 10: 11947 udata.change = ObjectChangeType.primPUS;
11609 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11948 updatehandler(localId, udata, this);
11949 break;
11610 11950
11611 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11951 // now group related (bit 4)
11612 if (handlerUpdatePrimRotation != null) 11952 case 9: //( 8 + 1 )group position
11613 { 11953 udata.position = new Vector3(block.Data, 0);
11614 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11615 handlerUpdatePrimRotation(localId, rot3, this);
11616 }
11617 break;
11618 11954
11619 case 11: 11955 udata.change = ObjectChangeType.groupP;
11620 Vector3 pos3 = new Vector3(block.Data, 0); 11956 updatehandler(localId, udata, this);
11621 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11957 break;
11622 11958
11623 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11959 case 0x0A: // (8 + 2) group rotation
11624 if (handlerUpdatePrimGroupRotation != null) 11960 udata.rotation = new Quaternion(block.Data, 0, true);
11625 {
11626 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11627 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11628 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11629 }
11630 break;
11631 case 12:
11632 case 28:
11633 Vector3 scale7 = new Vector3(block.Data, 0);
11634 11961
11635 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11962 udata.change = ObjectChangeType.groupR;
11636 if (handlerUpdatePrimGroupScale != null) 11963 updatehandler(localId, udata, this);
11637 { 11964 break;
11638 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11639 handlerUpdatePrimGroupScale(localId, scale7, this);
11640 }
11641 break;
11642 11965
11643 case 13: 11966 case 0x0B: //( 8 + 2 + 1) group rotation and position
11644 Vector3 scale2 = new Vector3(block.Data, 12); 11967 udata.position = new Vector3(block.Data, 0);
11645 Vector3 pos4 = new Vector3(block.Data, 0); 11968 udata.rotation = new Quaternion(block.Data, 12, true);
11646 11969
11647 handlerUpdatePrimScale = OnUpdatePrimScale; 11970 udata.change = ObjectChangeType.groupPR;
11648 if (handlerUpdatePrimScale != null) 11971 updatehandler(localId, udata, this);
11649 { 11972 break;
11650 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11651 handlerUpdatePrimScale(localId, scale2, this);
11652 11973
11653 // Change the position based on scale (for bug number 246) 11974 case 0x0C: // (8 + 4) group scale
11654 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11975 // only afects root prim and only sent by viewer editor object tab scaling
11655 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11976 // mouse edition only allows uniform scaling
11656 if (handlerUpdatePrimSinglePosition != null) 11977 // SL MAY CHANGE THIS in viewers
11657 {
11658 handlerUpdatePrimSinglePosition(localId, pos4, this);
11659 }
11660 }
11661 break;
11662 11978
11663 case 29: 11979 udata.scale = new Vector3(block.Data, 0);
11664 Vector3 scale5 = new Vector3(block.Data, 12);
11665 Vector3 pos5 = new Vector3(block.Data, 0);
11666 11980
11667 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11981 udata.change = ObjectChangeType.groupS;
11668 if (handlerUpdatePrimGroupScale != null) 11982 updatehandler(localId, udata, this);
11669 {
11670 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11671 part.StoreUndoState(true);
11672 part.IgnoreUndoUpdate = true;
11673 handlerUpdatePrimGroupScale(localId, scale5, this);
11674 handlerUpdateVector = OnUpdatePrimGroupPosition;
11675 11983
11676 if (handlerUpdateVector != null) 11984 break;
11677 {
11678 handlerUpdateVector(localId, pos5, this);
11679 }
11680 11985
11681 part.IgnoreUndoUpdate = false; 11986 case 0x0D: //(8 + 4 + 1) group scale and position
11682 } 11987 // exception as above
11683 11988
11684 break; 11989 udata.position = new Vector3(block.Data, 0);
11990 udata.scale = new Vector3(block.Data, 12);
11685 11991
11686 case 21: 11992 udata.change = ObjectChangeType.groupPS;
11687 Vector3 scale6 = new Vector3(block.Data, 12); 11993 updatehandler(localId, udata, this);
11688 Vector3 pos6 = new Vector3(block.Data, 0); 11994 break;
11689 11995
11690 handlerUpdatePrimScale = OnUpdatePrimScale; 11996 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11691 if (handlerUpdatePrimScale != null) 11997 udata.scale = new Vector3(block.Data, 0);
11692 {
11693 part.StoreUndoState(false);
11694 part.IgnoreUndoUpdate = true;
11695 11998
11696 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11999 udata.change = ObjectChangeType.groupUS;
11697 handlerUpdatePrimScale(localId, scale6, this); 12000 updatehandler(localId, udata, this);
11698 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12001 break;
11699 if (handlerUpdatePrimSinglePosition != null)
11700 {
11701 handlerUpdatePrimSinglePosition(localId, pos6, this);
11702 }
11703 12002
11704 part.IgnoreUndoUpdate = false; 12003 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11705 } 12004 udata.position = new Vector3(block.Data, 0);
11706 break; 12005 udata.scale = new Vector3(block.Data, 12);
11707 12006
11708 default: 12007 udata.change = ObjectChangeType.groupPUS;
11709 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12008 updatehandler(localId, udata, this);
11710 break; 12009 break;
12010
12011 default:
12012 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12013 break;
12014 }
11711 } 12015 }
11712 12016
11713// for (int j = 0; j < parts.Length; j++)
11714// parts[j].IgnoreUndoUpdate = false;
11715 } 12017 }
11716 } 12018 }
11717 } 12019 }
11718
11719 return true; 12020 return true;
11720 } 12021 }
11721 12022
@@ -11776,9 +12077,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11776 public void SetChildAgentThrottle(byte[] throttles) 12077 public void SetChildAgentThrottle(byte[] throttles)
11777 { 12078 {
11778 m_udpClient.SetThrottles(throttles); 12079 m_udpClient.SetThrottles(throttles);
12080 GenericCall2 handler = OnUpdateThrottles;
12081 if (handler != null)
12082 {
12083 handler();
12084 }
11779 } 12085 }
11780 12086
11781 /// <summary> 12087 /// <summary>
12088 /// Sets the throttles from values supplied by the client
12089 /// </summary>
12090 /// <param name="throttles"></param>
12091 public void SetAgentThrottleSilent(int throttle, int setting)
12092 {
12093 m_udpClient.ForceThrottleSetting(throttle,setting);
12094 //m_udpClient.SetThrottles(throttles);
12095
12096 }
12097
12098
12099 /// <summary>
11782 /// Get the current throttles for this client as a packed byte array 12100 /// Get the current throttles for this client as a packed byte array
11783 /// </summary> 12101 /// </summary>
11784 /// <param name="multiplier">Unused</param> 12102 /// <param name="multiplier">Unused</param>
@@ -12170,7 +12488,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12170// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12488// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12171// requestID, taskID, (SourceType)sourceType, Name); 12489// requestID, taskID, (SourceType)sourceType, Name);
12172 12490
12491
12492 //Note, the bool returned from the below function is useless since it is always false.
12173 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12493 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12494
12174 } 12495 }
12175 12496
12176 /// <summary> 12497 /// <summary>
@@ -12236,7 +12557,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12236 /// <returns></returns> 12557 /// <returns></returns>
12237 private static int CalculateNumPackets(byte[] data) 12558 private static int CalculateNumPackets(byte[] data)
12238 { 12559 {
12239 const uint m_maxPacketSize = 600; 12560// const uint m_maxPacketSize = 600;
12561 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12240 int numPackets = 1; 12562 int numPackets = 1;
12241 12563
12242 if (data == null) 12564 if (data == null)