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.cs1494
1 files changed, 921 insertions, 573 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index e47397d..ef1d803 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -101,6 +101,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
101 public event AvatarPickerRequest OnAvatarPickerRequest; 101 public event AvatarPickerRequest OnAvatarPickerRequest;
102 public event StartAnim OnStartAnim; 102 public event StartAnim OnStartAnim;
103 public event StopAnim OnStopAnim; 103 public event StopAnim OnStopAnim;
104 public event ChangeAnim OnChangeAnim;
104 public event Action<IClientAPI> OnRequestAvatarsData; 105 public event Action<IClientAPI> OnRequestAvatarsData;
105 public event LinkObjects OnLinkObjects; 106 public event LinkObjects OnLinkObjects;
106 public event DelinkObjects OnDelinkObjects; 107 public event DelinkObjects OnDelinkObjects;
@@ -128,6 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
128 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 129 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
129 public event UpdatePrimFlags OnUpdatePrimFlags; 130 public event UpdatePrimFlags OnUpdatePrimFlags;
130 public event UpdatePrimTexture OnUpdatePrimTexture; 131 public event UpdatePrimTexture OnUpdatePrimTexture;
132 public event ClientChangeObject onClientChangeObject;
131 public event UpdateVector OnUpdatePrimGroupPosition; 133 public event UpdateVector OnUpdatePrimGroupPosition;
132 public event UpdateVector OnUpdatePrimSinglePosition; 134 public event UpdateVector OnUpdatePrimSinglePosition;
133 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 135 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -161,6 +163,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
161 public event RequestTaskInventory OnRequestTaskInventory; 163 public event RequestTaskInventory OnRequestTaskInventory;
162 public event UpdateInventoryItem OnUpdateInventoryItem; 164 public event UpdateInventoryItem OnUpdateInventoryItem;
163 public event CopyInventoryItem OnCopyInventoryItem; 165 public event CopyInventoryItem OnCopyInventoryItem;
166 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
164 public event MoveInventoryItem OnMoveInventoryItem; 167 public event MoveInventoryItem OnMoveInventoryItem;
165 public event RemoveInventoryItem OnRemoveInventoryItem; 168 public event RemoveInventoryItem OnRemoveInventoryItem;
166 public event RemoveInventoryFolder OnRemoveInventoryFolder; 169 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -259,7 +262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
259 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 262 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 263 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
261 public event ClassifiedDelete OnClassifiedDelete; 264 public event ClassifiedDelete OnClassifiedDelete;
262 public event ClassifiedDelete OnClassifiedGodDelete; 265 public event ClassifiedGodDelete OnClassifiedGodDelete;
263 public event EventNotificationAddRequest OnEventNotificationAddRequest; 266 public event EventNotificationAddRequest OnEventNotificationAddRequest;
264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 267 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
265 public event EventGodDelete OnEventGodDelete; 268 public event EventGodDelete OnEventGodDelete;
@@ -290,10 +293,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 293 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
291 public event SimWideDeletesDelegate OnSimWideDeletes; 294 public event SimWideDeletesDelegate OnSimWideDeletes;
292 public event SendPostcard OnSendPostcard; 295 public event SendPostcard OnSendPostcard;
296 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
293 public event MuteListEntryUpdate OnUpdateMuteListEntry; 297 public event MuteListEntryUpdate OnUpdateMuteListEntry;
294 public event MuteListEntryRemove OnRemoveMuteListEntry; 298 public event MuteListEntryRemove OnRemoveMuteListEntry;
295 public event GodlikeMessage onGodlikeMessage; 299 public event GodlikeMessage onGodlikeMessage;
296 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 300 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
301 public event GenericCall2 OnUpdateThrottles;
297 302
298 #endregion Events 303 #endregion Events
299 304
@@ -322,11 +327,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
322 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 327 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
323 private readonly IGroupsModule m_GroupsModule; 328 private readonly IGroupsModule m_GroupsModule;
324 329
330 private int m_cachedTextureSerial;
325 private PriorityQueue m_entityUpdates; 331 private PriorityQueue m_entityUpdates;
326 private PriorityQueue m_entityProps; 332 private PriorityQueue m_entityProps;
327 private Prioritizer m_prioritizer; 333 private Prioritizer m_prioritizer;
328 private bool m_disableFacelights = false; 334 private bool m_disableFacelights = false;
329 335
336 private bool m_VelocityInterpolate = false;
337 private const uint MaxTransferBytesPerPacket = 600;
338
339
330 /// <value> 340 /// <value>
331 /// List used in construction of data blocks for an object update packet. This is to stop us having to 341 /// List used in construction of data blocks for an object update packet. This is to stop us having to
332 /// continually recreate it. 342 /// continually recreate it.
@@ -338,13 +348,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 348 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
339 /// ownerless phantom. 349 /// ownerless phantom.
340 /// 350 ///
341 /// All manipulation of this set has to occur under a lock 351 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
342 /// 352 ///
343 /// </value> 353 /// </value>
344 protected HashSet<uint> m_killRecord; 354// protected HashSet<uint> m_killRecord;
345 355
346// protected HashSet<uint> m_attachmentsSent; 356// protected HashSet<uint> m_attachmentsSent;
347 357
358 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 359 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 360 private bool m_SendLogoutPacketWhenClosing = true;
350 361
@@ -391,6 +402,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 402 get { return m_startpos; }
392 set { m_startpos = value; } 403 set { m_startpos = value; }
393 } 404 }
405 public bool DeliverPackets
406 {
407 get { return m_deliverPackets; }
408 set {
409 m_deliverPackets = value;
410 m_udpClient.m_deliverPackets = value;
411 }
412 }
394 public UUID AgentId { get { return m_agentId; } } 413 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 414 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 415 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -441,6 +460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
441 } 460 }
442 461
443 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 462 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
463
444 464
445 #endregion Properties 465 #endregion Properties
446 466
@@ -467,7 +487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
467 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 487 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
468 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 488 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
469 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 489 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
470 m_killRecord = new HashSet<uint>(); 490// m_killRecord = new HashSet<uint>();
471// m_attachmentsSent = new HashSet<uint>(); 491// m_attachmentsSent = new HashSet<uint>();
472 492
473 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 493 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -496,12 +516,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
496 516
497 #region Client Methods 517 #region Client Methods
498 518
519
520 /// <summary>
521 /// Close down the client view
522 /// </summary>
499 public void Close() 523 public void Close()
500 { 524 {
501 Close(false); 525 Close(true, false);
502 } 526 }
503 527
504 public void Close(bool force) 528 public void Close(bool sendStop, bool force)
505 { 529 {
506 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 530 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
507 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 531 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -513,7 +537,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 return; 537 return;
514 538
515 IsActive = false; 539 IsActive = false;
516 CloseWithoutChecks(); 540 CloseWithoutChecks(sendStop);
517 } 541 }
518 } 542 }
519 543
@@ -526,12 +550,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
526 /// 550 ///
527 /// Callers must lock ClosingSyncLock before calling. 551 /// Callers must lock ClosingSyncLock before calling.
528 /// </remarks> 552 /// </remarks>
529 public void CloseWithoutChecks() 553 public void CloseWithoutChecks(bool sendStop)
530 { 554 {
531 m_log.DebugFormat( 555 m_log.DebugFormat(
532 "[CLIENT]: Close has been called for {0} attached to scene {1}", 556 "[CLIENT]: Close has been called for {0} attached to scene {1}",
533 Name, m_scene.RegionInfo.RegionName); 557 Name, m_scene.RegionInfo.RegionName);
534 558
559 if (sendStop)
560 {
561 // Send the STOP packet
562 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
563 OutPacket(disable, ThrottleOutPacketType.Unknown);
564 }
565
535 // Shutdown the image manager 566 // Shutdown the image manager
536 ImageManager.Close(); 567 ImageManager.Close();
537 568
@@ -554,6 +585,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
554 // Disable UDP handling for this client 585 // Disable UDP handling for this client
555 m_udpClient.Shutdown(); 586 m_udpClient.Shutdown();
556 587
588
557 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 589 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
558 //GC.Collect(); 590 //GC.Collect();
559 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 591 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -794,7 +826,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
794 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags; 826 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
795 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported 827 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
796 828
797 OutPacket(handshake, ThrottleOutPacketType.Task); 829 OutPacket(handshake, ThrottleOutPacketType.Unknown);
798 } 830 }
799 831
800 832
@@ -835,7 +867,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
835 reply.ChatData.OwnerID = ownerID; 867 reply.ChatData.OwnerID = ownerID;
836 reply.ChatData.SourceID = fromAgentID; 868 reply.ChatData.SourceID = fromAgentID;
837 869
838 OutPacket(reply, ThrottleOutPacketType.Task); 870 OutPacket(reply, ThrottleOutPacketType.Unknown);
839 } 871 }
840 872
841 /// <summary> 873 /// <summary>
@@ -868,32 +900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
868 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 900 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
869 msg.MessageBlock.BinaryBucket = im.binaryBucket; 901 msg.MessageBlock.BinaryBucket = im.binaryBucket;
870 902
871 if (im.message.StartsWith("[grouptest]")) 903 OutPacket(msg, ThrottleOutPacketType.Task);
872 { // this block is test code for implementing group IM - delete when group IM is finished
873 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
874 if (eq != null)
875 {
876 im.dialog = 17;
877
878 //eq.ChatterboxInvitation(
879 // new UUID("00000000-68f9-1111-024e-222222111123"),
880 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
881 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
882
883 eq.ChatterboxInvitation(
884 new UUID("00000000-68f9-1111-024e-222222111123"),
885 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
886 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
887
888 eq.ChatterBoxSessionAgentListUpdates(
889 new UUID("00000000-68f9-1111-024e-222222111123"),
890 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
891 }
892
893 Console.WriteLine("SendInstantMessage: " + msg);
894 }
895 else
896 OutPacket(msg, ThrottleOutPacketType.Task);
897 } 904 }
898 } 905 }
899 906
@@ -1131,6 +1138,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1131 public virtual void SendLayerData(float[] map) 1138 public virtual void SendLayerData(float[] map)
1132 { 1139 {
1133 Util.FireAndForget(DoSendLayerData, map); 1140 Util.FireAndForget(DoSendLayerData, map);
1141
1142 // Send it sync, and async. It's not that much data
1143 // and it improves user experience just so much!
1144 DoSendLayerData(map);
1134 } 1145 }
1135 1146
1136 /// <summary> 1147 /// <summary>
@@ -1143,16 +1154,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1143 1154
1144 try 1155 try
1145 { 1156 {
1146 //for (int y = 0; y < 16; y++) 1157 for (int y = 0; y < 16; y++)
1147 //{ 1158 {
1148 // for (int x = 0; x < 16; x++) 1159 for (int x = 0; x < 16; x+=4)
1149 // { 1160 {
1150 // SendLayerData(x, y, map); 1161 SendLayerPacket(x, y, map);
1151 // } 1162 }
1152 //} 1163 }
1153
1154 // Send LayerData in a spiral pattern. Fun!
1155 SendLayerTopRight(map, 0, 0, 15, 15);
1156 } 1164 }
1157 catch (Exception e) 1165 catch (Exception e)
1158 { 1166 {
@@ -1160,51 +1168,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1160 } 1168 }
1161 } 1169 }
1162 1170
1163 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1164 {
1165 // Row
1166 for (int i = x1; i <= x2; i++)
1167 SendLayerData(i, y1, map);
1168
1169 // Column
1170 for (int j = y1 + 1; j <= y2; j++)
1171 SendLayerData(x2, j, map);
1172
1173 if (x2 - x1 > 0)
1174 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1175 }
1176
1177 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1178 {
1179 // Row in reverse
1180 for (int i = x2; i >= x1; i--)
1181 SendLayerData(i, y2, map);
1182
1183 // Column in reverse
1184 for (int j = y2 - 1; j >= y1; j--)
1185 SendLayerData(x1, j, map);
1186
1187 if (x2 - x1 > 0)
1188 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1189 }
1190
1191 /// <summary> 1171 /// <summary>
1192 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1172 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1193 /// </summary> 1173 /// </summary>
1194 /// <param name="map">heightmap</param> 1174 /// <param name="map">heightmap</param>
1195 /// <param name="px">X coordinate for patches 0..12</param> 1175 /// <param name="px">X coordinate for patches 0..12</param>
1196 /// <param name="py">Y coordinate for patches 0..15</param> 1176 /// <param name="py">Y coordinate for patches 0..15</param>
1197 // private void SendLayerPacket(float[] map, int y, int x) 1177 private void SendLayerPacket(int x, int y, float[] map)
1198 // { 1178 {
1199 // int[] patches = new int[4]; 1179 int[] patches = new int[4];
1200 // patches[0] = x + 0 + y * 16; 1180 patches[0] = x + 0 + y * 16;
1201 // patches[1] = x + 1 + y * 16; 1181 patches[1] = x + 1 + y * 16;
1202 // patches[2] = x + 2 + y * 16; 1182 patches[2] = x + 2 + y * 16;
1203 // patches[3] = x + 3 + y * 16; 1183 patches[3] = x + 3 + y * 16;
1204 1184
1205 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1185 float[] heightmap = (map.Length == 65536) ?
1206 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1186 map :
1207 // } 1187 LLHeightFieldMoronize(map);
1188
1189 try
1190 {
1191 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1192 OutPacket(layerpack, ThrottleOutPacketType.Land);
1193 }
1194 catch
1195 {
1196 for (int px = x ; px < x + 4 ; px++)
1197 SendLayerData(px, y, map);
1198 }
1199 }
1208 1200
1209 /// <summary> 1201 /// <summary>
1210 /// Sends a specified patch to a client 1202 /// Sends a specified patch to a client
@@ -1224,7 +1216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1224 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1216 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1225 layerpack.Header.Reliable = true; 1217 layerpack.Header.Reliable = true;
1226 1218
1227 OutPacket(layerpack, ThrottleOutPacketType.Land); 1219 OutPacket(layerpack, ThrottleOutPacketType.Task);
1228 } 1220 }
1229 catch (Exception e) 1221 catch (Exception e)
1230 { 1222 {
@@ -1594,7 +1586,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1594 1586
1595 public void SendKillObject(List<uint> localIDs) 1587 public void SendKillObject(List<uint> localIDs)
1596 { 1588 {
1597// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1589// foreach (uint id in localIDs)
1590// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1598 1591
1599 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1592 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1600 // TODO: don't create new blocks if recycling an old packet 1593 // TODO: don't create new blocks if recycling an old packet
@@ -1616,17 +1609,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1616 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1609 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1617 // condition where a kill can be processed before an out-of-date update for the same object. 1610 // condition where a kill can be processed before an out-of-date update for the same object.
1618 // ProcessEntityUpdates() also takes the m_killRecord lock. 1611 // ProcessEntityUpdates() also takes the m_killRecord lock.
1619 lock (m_killRecord) 1612// lock (m_killRecord)
1620 { 1613// {
1621 foreach (uint localID in localIDs) 1614// foreach (uint localID in localIDs)
1622 m_killRecord.Add(localID); 1615// m_killRecord.Add(localID);
1623 1616
1624 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1617 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1625 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1618 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1626 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1619 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1627 // scene objects in a viewer until that viewer is relogged in. 1620 // scene objects in a viewer until that viewer is relogged in.
1628 OutPacket(kill, ThrottleOutPacketType.Task); 1621 OutPacket(kill, ThrottleOutPacketType.Task);
1629 } 1622// }
1630 } 1623 }
1631 } 1624 }
1632 1625
@@ -2085,9 +2078,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2085 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2078 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2086 } 2079 }
2087 2080
2088 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2089 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2081 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2090 { 2082 {
2083 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2084 }
2085
2086 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2087 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2088 {
2091 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2089 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2092 2090
2093 UpdateCreateInventoryItemPacket InventoryReply 2091 UpdateCreateInventoryItemPacket InventoryReply
@@ -2097,6 +2095,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2097 // TODO: don't create new blocks if recycling an old packet 2095 // TODO: don't create new blocks if recycling an old packet
2098 InventoryReply.AgentData.AgentID = AgentId; 2096 InventoryReply.AgentData.AgentID = AgentId;
2099 InventoryReply.AgentData.SimApproved = true; 2097 InventoryReply.AgentData.SimApproved = true;
2098 InventoryReply.AgentData.TransactionID = transactionID;
2100 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2099 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2101 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2100 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2102 InventoryReply.InventoryData[0].ItemID = Item.ID; 2101 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2166,16 +2165,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2166 replytask.InventoryData.TaskID = taskID; 2165 replytask.InventoryData.TaskID = taskID;
2167 replytask.InventoryData.Serial = serial; 2166 replytask.InventoryData.Serial = serial;
2168 replytask.InventoryData.Filename = fileName; 2167 replytask.InventoryData.Filename = fileName;
2169 OutPacket(replytask, ThrottleOutPacketType.Asset); 2168 OutPacket(replytask, ThrottleOutPacketType.Task);
2170 } 2169 }
2171 2170
2172 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2171 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2173 { 2172 {
2173 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2174 if (isTaskInventory)
2175 type = ThrottleOutPacketType.Task;
2176
2174 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2177 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2175 sendXfer.XferID.ID = xferID; 2178 sendXfer.XferID.ID = xferID;
2176 sendXfer.XferID.Packet = packet; 2179 sendXfer.XferID.Packet = packet;
2177 sendXfer.DataPacket.Data = data; 2180 sendXfer.DataPacket.Data = data;
2178 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2181 OutPacket(sendXfer, type);
2179 } 2182 }
2180 2183
2181 public void SendAbortXferPacket(ulong xferID) 2184 public void SendAbortXferPacket(ulong xferID)
@@ -2362,6 +2365,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2362 OutPacket(sound, ThrottleOutPacketType.Task); 2365 OutPacket(sound, ThrottleOutPacketType.Task);
2363 } 2366 }
2364 2367
2368 public void SendTransferAbort(TransferRequestPacket transferRequest)
2369 {
2370 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2371 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2372 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2373 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2374 OutPacket(abort, ThrottleOutPacketType.Task);
2375 }
2376
2365 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2377 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2366 { 2378 {
2367 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2379 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2670,6 +2682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2670 float friction = part.Friction; 2682 float friction = part.Friction;
2671 float bounce = part.Restitution; 2683 float bounce = part.Restitution;
2672 float gravmod = part.GravityModifier; 2684 float gravmod = part.GravityModifier;
2685
2673 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2686 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2674 } 2687 }
2675 } 2688 }
@@ -2740,8 +2753,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2740 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2753 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2741 return; 2754 return;
2742 } 2755 }
2756 int WearableOut = 0;
2757 bool isWearable = false;
2758
2759 if (req.AssetInf != null)
2760 isWearable =
2761 ((AssetType) req.AssetInf.Type ==
2762 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2743 2763
2744 //m_log.Debug("sending asset " + req.RequestAssetID); 2764
2765 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2766
2767
2768 //if (isWearable)
2769 // m_log.Debug((AssetType)req.AssetInf.Type);
2770
2745 TransferInfoPacket Transfer = new TransferInfoPacket(); 2771 TransferInfoPacket Transfer = new TransferInfoPacket();
2746 Transfer.TransferInfo.ChannelType = 2; 2772 Transfer.TransferInfo.ChannelType = 2;
2747 Transfer.TransferInfo.Status = 0; 2773 Transfer.TransferInfo.Status = 0;
@@ -2763,7 +2789,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2763 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2789 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2764 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2790 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2765 Transfer.Header.Zerocoded = true; 2791 Transfer.Header.Zerocoded = true;
2766 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2792 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2767 2793
2768 if (req.NumPackets == 1) 2794 if (req.NumPackets == 1)
2769 { 2795 {
@@ -2774,12 +2800,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2774 TransferPacket.TransferData.Data = req.AssetInf.Data; 2800 TransferPacket.TransferData.Data = req.AssetInf.Data;
2775 TransferPacket.TransferData.Status = 1; 2801 TransferPacket.TransferData.Status = 1;
2776 TransferPacket.Header.Zerocoded = true; 2802 TransferPacket.Header.Zerocoded = true;
2777 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2803 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2778 } 2804 }
2779 else 2805 else
2780 { 2806 {
2781 int processedLength = 0; 2807 int processedLength = 0;
2782 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2808// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2809
2810 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2783 int packetNumber = 0; 2811 int packetNumber = 0;
2784 2812
2785 while (processedLength < req.AssetInf.Data.Length) 2813 while (processedLength < req.AssetInf.Data.Length)
@@ -2805,7 +2833,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2805 TransferPacket.TransferData.Status = 1; 2833 TransferPacket.TransferData.Status = 1;
2806 } 2834 }
2807 TransferPacket.Header.Zerocoded = true; 2835 TransferPacket.Header.Zerocoded = true;
2808 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2836 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2809 2837
2810 processedLength += chunkSize; 2838 processedLength += chunkSize;
2811 packetNumber++; 2839 packetNumber++;
@@ -2850,7 +2878,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2850 reply.Data.ParcelID = parcelID; 2878 reply.Data.ParcelID = parcelID;
2851 reply.Data.OwnerID = land.OwnerID; 2879 reply.Data.OwnerID = land.OwnerID;
2852 reply.Data.Name = Utils.StringToBytes(land.Name); 2880 reply.Data.Name = Utils.StringToBytes(land.Name);
2853 reply.Data.Desc = Utils.StringToBytes(land.Description); 2881 if (land != null && land.Description != null && land.Description != String.Empty)
2882 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2883 else
2884 reply.Data.Desc = new Byte[0];
2854 reply.Data.ActualArea = land.Area; 2885 reply.Data.ActualArea = land.Area;
2855 reply.Data.BillableArea = land.Area; // TODO: what is this? 2886 reply.Data.BillableArea = land.Area; // TODO: what is this?
2856 2887
@@ -3557,24 +3588,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3557 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3588 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3558 AgentWearablesUpdatePacket.WearableDataBlock awb; 3589 AgentWearablesUpdatePacket.WearableDataBlock awb;
3559 int idx = 0; 3590 int idx = 0;
3560 for (int i = 0; i < wearables.Length; i++) 3591
3561 { 3592 for (int i = 0; i < wearables.Length; i++)
3562 for (int j = 0; j < wearables[i].Count; j++) 3593 {
3563 { 3594 for (int j = 0; j < wearables[i].Count; j++)
3564 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3595 {
3565 awb.WearableType = (byte)i; 3596 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3566 awb.AssetID = wearables[i][j].AssetID; 3597 awb.WearableType = (byte) i;
3567 awb.ItemID = wearables[i][j].ItemID; 3598 awb.AssetID = wearables[i][j].AssetID;
3568 aw.WearableData[idx] = awb; 3599 awb.ItemID = wearables[i][j].ItemID;
3569 idx++; 3600 aw.WearableData[idx] = awb;
3570 3601 idx++;
3571// m_log.DebugFormat( 3602
3572// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3603 // m_log.DebugFormat(
3573// awb.ItemID, awb.AssetID, i, Name); 3604 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3574 } 3605 // awb.ItemID, awb.AssetID, i, Name);
3575 } 3606 }
3607 }
3576 3608
3577 OutPacket(aw, ThrottleOutPacketType.Task); 3609 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3578 } 3610 }
3579 3611
3580 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3612 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3585,7 +3617,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3585 3617
3586 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3618 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3587 // TODO: don't create new blocks if recycling an old packet 3619 // TODO: don't create new blocks if recycling an old packet
3588 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3620 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3589 avp.ObjectData.TextureEntry = textureEntry; 3621 avp.ObjectData.TextureEntry = textureEntry;
3590 3622
3591 AvatarAppearancePacket.VisualParamBlock avblock = null; 3623 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3716,7 +3748,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3716 /// </summary> 3748 /// </summary>
3717 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3749 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3718 { 3750 {
3719 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3751 if (entity is SceneObjectPart)
3752 {
3753 SceneObjectPart e = (SceneObjectPart)entity;
3754 SceneObjectGroup g = e.ParentGroup;
3755 if (g.RootPart.Shape.State > 30) // HUD
3756 if (g.OwnerID != AgentId)
3757 return; // Don't send updates for other people's HUDs
3758 }
3759
3720 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3760 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3721 3761
3722 lock (m_entityUpdates.SyncRoot) 3762 lock (m_entityUpdates.SyncRoot)
@@ -3783,27 +3823,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3783 3823
3784 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3824 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3785 // condition where a kill can be processed before an out-of-date update for the same object. 3825 // condition where a kill can be processed before an out-of-date update for the same object.
3786 lock (m_killRecord) 3826 float avgTimeDilation = 1.0f;
3827 IEntityUpdate iupdate;
3828 Int32 timeinqueue; // this is just debugging code & can be dropped later
3829
3830 while (updatesThisCall < maxUpdates)
3787 { 3831 {
3788 float avgTimeDilation = 1.0f; 3832 lock (m_entityUpdates.SyncRoot)
3789 IEntityUpdate iupdate; 3833 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3790 Int32 timeinqueue; // this is just debugging code & can be dropped later 3834 break;
3791 3835
3792 while (updatesThisCall < maxUpdates) 3836 EntityUpdate update = (EntityUpdate)iupdate;
3837
3838 avgTimeDilation += update.TimeDilation;
3839 avgTimeDilation *= 0.5f;
3840
3841 if (update.Entity is SceneObjectPart)
3793 { 3842 {
3794 lock (m_entityUpdates.SyncRoot) 3843 SceneObjectPart part = (SceneObjectPart)update.Entity;
3795 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3796 break;
3797 3844
3798 EntityUpdate update = (EntityUpdate)iupdate; 3845 if (part.ParentGroup.IsDeleted)
3799 3846 continue;
3800 avgTimeDilation += update.TimeDilation;
3801 avgTimeDilation *= 0.5f;
3802 3847
3803 if (update.Entity is SceneObjectPart) 3848 if (part.ParentGroup.IsAttachment)
3849 { // Someone else's HUD, why are we getting these?
3850 if (part.ParentGroup.OwnerID != AgentId &&
3851 part.ParentGroup.RootPart.Shape.State > 30)
3852 continue;
3853 ScenePresence sp;
3854 // Owner is not in the sim, don't update it to
3855 // anyone
3856 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3857 continue;
3858
3859 List<SceneObjectGroup> atts = sp.GetAttachments();
3860 bool found = false;
3861 foreach (SceneObjectGroup att in atts)
3862 {
3863 if (att == part.ParentGroup)
3864 {
3865 found = true;
3866 break;
3867 }
3868 }
3869
3870 // It's an attachment of a valid avatar, but
3871 // doesn't seem to be attached, skip
3872 if (!found)
3873 continue;
3874
3875 // On vehicle crossing, the attachments are received
3876 // while the avatar is still a child. Don't send
3877 // updates here because the LocalId has not yet
3878 // been updated and the viewer will derender the
3879 // attachments until the avatar becomes root.
3880 if (sp.IsChildAgent)
3881 continue;
3882
3883 // If the object is an attachment we don't want it to be in the kill
3884 // record. Else attaching from inworld and subsequently dropping
3885 // it will no longer work.
3886// lock (m_killRecord)
3887// {
3888// m_killRecord.Remove(part.LocalId);
3889// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3890// }
3891 }
3892 else
3804 { 3893 {
3805 SceneObjectPart part = (SceneObjectPart)update.Entity;
3806
3807 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3894 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3808 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3895 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3809 // safety measure. 3896 // safety measure.
@@ -3814,21 +3901,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3814 // 3901 //
3815 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3902 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3816 // after the root prim has been deleted. 3903 // after the root prim has been deleted.
3817 if (m_killRecord.Contains(part.LocalId)) 3904 //
3818 { 3905 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3819 // m_log.WarnFormat( 3906// lock (m_killRecord)
3820 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3907// {
3821 // part.LocalId, Name); 3908// if (m_killRecord.Contains(part.LocalId))
3822 continue; 3909// continue;
3823 } 3910// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3824 3911// continue;
3825 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3912// }
3913 }
3914
3915 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3916 {
3917 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3918 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3826 { 3919 {
3827 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3920 part.Shape.LightEntry = false;
3828 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3829 {
3830 part.Shape.LightEntry = false;
3831 }
3832 } 3921 }
3833 3922
3834 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3923 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3839,224 +3928,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3839 part.Shape.ProfileHollow = 27500; 3928 part.Shape.ProfileHollow = 27500;
3840 } 3929 }
3841 } 3930 }
3842 3931
3843 #region UpdateFlags to packet type conversion 3932 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3844
3845 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3846
3847 bool canUseCompressed = true;
3848 bool canUseImproved = true;
3849
3850 // Compressed object updates only make sense for LL primitives
3851 if (!(update.Entity is SceneObjectPart))
3852 { 3933 {
3853 canUseCompressed = false; 3934 // Ensure that mesh has at least 8 valid faces
3935 part.Shape.ProfileBegin = 12500;
3936 part.Shape.ProfileEnd = 0;
3937 part.Shape.ProfileHollow = 27500;
3854 } 3938 }
3855 3939 }
3856 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3940
3941 ++updatesThisCall;
3942
3943 #region UpdateFlags to packet type conversion
3944
3945 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3946
3947 bool canUseCompressed = true;
3948 bool canUseImproved = true;
3949
3950 // Compressed object updates only make sense for LL primitives
3951 if (!(update.Entity is SceneObjectPart))
3952 {
3953 canUseCompressed = false;
3954 }
3955
3956 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3957 {
3958 canUseCompressed = false;
3959 canUseImproved = false;
3960 }
3961 else
3962 {
3963 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3964 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3965 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3966 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3857 { 3967 {
3858 canUseCompressed = false; 3968 canUseCompressed = false;
3859 canUseImproved = false;
3860 } 3969 }
3861 else 3970
3971 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3972 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3973 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3974 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3975 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3976 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3977 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3978 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3979 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3980 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3981 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3982 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3983 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3984 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3862 { 3985 {
3863 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3986 canUseImproved = false;
3864 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3866 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3867 {
3868 canUseCompressed = false;
3869 }
3870
3871 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3872 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3873 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3874 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3875 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3876 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3877 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3878 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3879 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3880 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3881 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3882 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3883 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3884 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3885 {
3886 canUseImproved = false;
3887 }
3888 } 3987 }
3988 }
3889 3989
3890 #endregion UpdateFlags to packet type conversion 3990 #endregion UpdateFlags to packet type conversion
3891
3892 #region Block Construction
3893
3894 // TODO: Remove this once we can build compressed updates
3895 canUseCompressed = false;
3896
3897 if (!canUseImproved && !canUseCompressed)
3898 {
3899 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3900 3991
3901 if (update.Entity is ScenePresence) 3992 #region Block Construction
3902 {
3903 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3904 }
3905 else
3906 {
3907 SceneObjectPart part = (SceneObjectPart)update.Entity;
3908 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3909
3910 // If the part has become a private hud since the update was scheduled then we do not
3911 // want to send it to other avatars.
3912 if (part.ParentGroup.IsAttachment
3913 && part.ParentGroup.HasPrivateAttachmentPoint
3914 && part.ParentGroup.AttachedAvatar != AgentId)
3915 continue;
3916
3917 // If the part has since been deleted, then drop the update. In the case of attachments,
3918 // this is to avoid spurious updates to other viewers since post-processing of attachments
3919 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3920 // of the test above).
3921 //
3922 // Actual deletions (kills) happen in another method.
3923 if (part.ParentGroup.IsDeleted)
3924 continue;
3925 }
3926 3993
3927 objectUpdateBlocks.Value.Add(updateBlock); 3994 // TODO: Remove this once we can build compressed updates
3928 objectUpdates.Value.Add(update); 3995 canUseCompressed = false;
3929 }
3930 else if (!canUseImproved)
3931 {
3932 SceneObjectPart part = (SceneObjectPart)update.Entity;
3933 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3934 = CreateCompressedUpdateBlock(part, updateFlags);
3935
3936 // If the part has since been deleted, then drop the update. In the case of attachments,
3937 // this is to avoid spurious updates to other viewers since post-processing of attachments
3938 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3939 // of the test above).
3940 //
3941 // Actual deletions (kills) happen in another method.
3942 if (part.ParentGroup.IsDeleted)
3943 continue;
3944 3996
3945 compressedUpdateBlocks.Value.Add(compressedBlock); 3997 if (!canUseImproved && !canUseCompressed)
3946 compressedUpdates.Value.Add(update); 3998 {
3999 if (update.Entity is ScenePresence)
4000 {
4001 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3947 } 4002 }
3948 else 4003 else
3949 { 4004 {
3950 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 4005 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3951 {
3952 // Self updates go into a special list
3953 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3954 terseAgentUpdates.Value.Add(update);
3955 }
3956 else
3957 {
3958 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3959 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3960
3961 // Everything else goes here
3962 if (update.Entity is SceneObjectPart)
3963 {
3964 SceneObjectPart part = (SceneObjectPart)update.Entity;
3965
3966 // If the part has become a private hud since the update was scheduled then we do not
3967 // want to send it to other avatars.
3968 if (part.ParentGroup.IsAttachment
3969 && part.ParentGroup.HasPrivateAttachmentPoint
3970 && part.ParentGroup.AttachedAvatar != AgentId)
3971 continue;
3972
3973 // If the part has since been deleted, then drop the update. In the case of attachments,
3974 // this is to avoid spurious updates to other viewers since post-processing of attachments
3975 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3976 // of the test above).
3977 //
3978 // Actual deletions (kills) happen in another method.
3979 if (part.ParentGroup.IsDeleted)
3980 continue;
3981 }
3982
3983 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3984 terseUpdates.Value.Add(update);
3985 }
3986 } 4006 }
3987
3988 ++updatesThisCall;
3989
3990 #endregion Block Construction
3991 } 4007 }
3992 4008 else if (!canUseImproved)
3993 #region Packet Sending 4009 {
3994 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 4010 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3995 4011 }
3996 if (terseAgentUpdateBlocks.IsValueCreated) 4012 else
3997 { 4013 {
3998 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4014 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4015 // Self updates go into a special list
4016 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4017 else
4018 // Everything else goes here
4019 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4020 }
3999 4021
4000 ImprovedTerseObjectUpdatePacket packet 4022 #endregion Block Construction
4001 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4023 }
4002 4024
4003 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4025 #region Packet Sending
4004 packet.RegionData.TimeDilation = timeDilation; 4026
4005 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4027 const float TIME_DILATION = 1.0f;
4028 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4029
4030 if (terseAgentUpdateBlocks.IsValueCreated)
4031 {
4032 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4006 4033
4007 for (int i = 0; i < blocks.Count; i++) 4034 ImprovedTerseObjectUpdatePacket packet
4008 packet.ObjectData[i] = blocks[i]; 4035 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4009 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4036 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4010 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4037 packet.RegionData.TimeDilation = timeDilation;
4011 } 4038 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4012 4039
4013 if (objectUpdateBlocks.IsValueCreated) 4040 for (int i = 0; i < blocks.Count; i++)
4014 { 4041 packet.ObjectData[i] = blocks[i];
4015 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4016
4017 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4018 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4019 packet.RegionData.TimeDilation = timeDilation;
4020 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4021
4022 for (int i = 0; i < blocks.Count; i++)
4023 packet.ObjectData[i] = blocks[i];
4024 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4025 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4026 }
4027
4028 if (compressedUpdateBlocks.IsValueCreated)
4029 {
4030 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4031
4032 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4033 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4034 packet.RegionData.TimeDilation = timeDilation;
4035 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4036
4037 for (int i = 0; i < blocks.Count; i++)
4038 packet.ObjectData[i] = blocks[i];
4039 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4040 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4041 }
4042 4042
4043 if (terseUpdateBlocks.IsValueCreated) 4043 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4044 { 4044 }
4045 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4046
4047 ImprovedTerseObjectUpdatePacket packet
4048 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4049 PacketType.ImprovedTerseObjectUpdate);
4050 4045
4051 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4046 if (objectUpdateBlocks.IsValueCreated)
4052 packet.RegionData.TimeDilation = timeDilation; 4047 {
4053 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4048 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4054 4049
4055 for (int i = 0; i < blocks.Count; i++) 4050 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4056 packet.ObjectData[i] = blocks[i]; 4051 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4057 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4052 packet.RegionData.TimeDilation = timeDilation;
4058 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4053 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4059 } 4054
4055 for (int i = 0; i < blocks.Count; i++)
4056 packet.ObjectData[i] = blocks[i];
4057
4058 OutPacket(packet, ThrottleOutPacketType.Task, true);
4059 }
4060
4061 if (compressedUpdateBlocks.IsValueCreated)
4062 {
4063 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4064
4065 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4066 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4067 packet.RegionData.TimeDilation = timeDilation;
4068 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4069
4070 for (int i = 0; i < blocks.Count; i++)
4071 packet.ObjectData[i] = blocks[i];
4072
4073 OutPacket(packet, ThrottleOutPacketType.Task, true);
4074 }
4075
4076 if (terseUpdateBlocks.IsValueCreated)
4077 {
4078 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4079
4080 ImprovedTerseObjectUpdatePacket packet
4081 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4082 PacketType.ImprovedTerseObjectUpdate);
4083 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4084 packet.RegionData.TimeDilation = timeDilation;
4085 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4086
4087 for (int i = 0; i < blocks.Count; i++)
4088 packet.ObjectData[i] = blocks[i];
4089
4090 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4060 } 4091 }
4061 4092
4062 #endregion Packet Sending 4093 #endregion Packet Sending
@@ -4349,11 +4380,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4349 4380
4350 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4381 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4351 // of the object rather than the properties when the packet was created 4382 // of the object rather than the properties when the packet was created
4352 OutPacket(packet, ThrottleOutPacketType.Task, true, 4383 // HACK : Remove intelligent resending until it's fixed in core
4353 delegate(OutgoingPacket oPacket) 4384 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4354 { 4385 // delegate(OutgoingPacket oPacket)
4355 ResendPropertyUpdates(updates, oPacket); 4386 // {
4356 }); 4387 // ResendPropertyUpdates(updates, oPacket);
4388 // });
4389 OutPacket(packet, ThrottleOutPacketType.Task, true);
4357 4390
4358 // pbcnt += blocks.Count; 4391 // pbcnt += blocks.Count;
4359 // ppcnt++; 4392 // ppcnt++;
@@ -4379,11 +4412,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4379 // of the object rather than the properties when the packet was created 4412 // of the object rather than the properties when the packet was created
4380 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4413 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4381 updates.Add(familyUpdates.Value[i]); 4414 updates.Add(familyUpdates.Value[i]);
4382 OutPacket(packet, ThrottleOutPacketType.Task, true, 4415 // HACK : Remove intelligent resending until it's fixed in core
4383 delegate(OutgoingPacket oPacket) 4416 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4384 { 4417 // delegate(OutgoingPacket oPacket)
4385 ResendPropertyUpdates(updates, oPacket); 4418 // {
4386 }); 4419 // ResendPropertyUpdates(updates, oPacket);
4420 // });
4421 OutPacket(packet, ThrottleOutPacketType.Task, true);
4387 4422
4388 // fpcnt++; 4423 // fpcnt++;
4389 // fbcnt++; 4424 // fbcnt++;
@@ -4755,7 +4790,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4755 4790
4756 if (landData.SimwideArea > 0) 4791 if (landData.SimwideArea > 0)
4757 { 4792 {
4758 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4793 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4794 // Never report more than sim total capacity
4795 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4796 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4759 updateMessage.SimWideMaxPrims = simulatorCapacity; 4797 updateMessage.SimWideMaxPrims = simulatorCapacity;
4760 } 4798 }
4761 else 4799 else
@@ -4884,14 +4922,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4884 4922
4885 if (notifyCount > 0) 4923 if (notifyCount > 0)
4886 { 4924 {
4887 if (notifyCount > 32) 4925// if (notifyCount > 32)
4888 { 4926// {
4889 m_log.InfoFormat( 4927// m_log.InfoFormat(
4890 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4928// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4891 + " - a developer might want to investigate whether this is a hard limit", 32); 4929// + " - a developer might want to investigate whether this is a hard limit", 32);
4892 4930//
4893 notifyCount = 32; 4931// notifyCount = 32;
4894 } 4932// }
4895 4933
4896 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4934 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4897 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4935 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4946,9 +4984,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4946 { 4984 {
4947 ScenePresence presence = (ScenePresence)entity; 4985 ScenePresence presence = (ScenePresence)entity;
4948 4986
4987 position = presence.OffsetPosition;
4988 rotation = presence.Rotation;
4989
4990 if (presence.ParentID != 0)
4991 {
4992 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4993 if (part != null && part != part.ParentGroup.RootPart)
4994 {
4995 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4996 rotation = part.RotationOffset * presence.Rotation;
4997 }
4998 angularVelocity = Vector3.Zero;
4999 }
5000 else
5001 {
5002 angularVelocity = presence.AngularVelocity;
5003 rotation = presence.Rotation;
5004 }
5005
4949 attachPoint = 0; 5006 attachPoint = 0;
4950 collisionPlane = presence.CollisionPlane; 5007 collisionPlane = presence.CollisionPlane;
4951 position = presence.OffsetPosition;
4952 velocity = presence.Velocity; 5008 velocity = presence.Velocity;
4953 acceleration = Vector3.Zero; 5009 acceleration = Vector3.Zero;
4954 5010
@@ -4957,9 +5013,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4957 // may improve movement smoothness. 5013 // may improve movement smoothness.
4958// acceleration = new Vector3(1, 0, 0); 5014// acceleration = new Vector3(1, 0, 0);
4959 5015
4960 angularVelocity = presence.AngularVelocity;
4961 rotation = presence.Rotation;
4962
4963 if (sendTexture) 5016 if (sendTexture)
4964 textureEntry = presence.Appearance.Texture.GetBytes(); 5017 textureEntry = presence.Appearance.Texture.GetBytes();
4965 else 5018 else
@@ -5065,13 +5118,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5065 5118
5066 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5119 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5067 { 5120 {
5121 Vector3 offsetPosition = data.OffsetPosition;
5122 Quaternion rotation = data.Rotation;
5123 uint parentID = data.ParentID;
5124
5125 if (parentID != 0)
5126 {
5127 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5128 if (part != null && part != part.ParentGroup.RootPart)
5129 {
5130 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5131 rotation = part.RotationOffset * data.Rotation;
5132 parentID = part.ParentGroup.RootPart.LocalId;
5133 }
5134 }
5135
5068 byte[] objectData = new byte[76]; 5136 byte[] objectData = new byte[76];
5069 5137
5070 data.CollisionPlane.ToBytes(objectData, 0); 5138 data.CollisionPlane.ToBytes(objectData, 0);
5071 data.OffsetPosition.ToBytes(objectData, 16); 5139 offsetPosition.ToBytes(objectData, 16);
5072// data.Velocity.ToBytes(objectData, 28); 5140// data.Velocity.ToBytes(objectData, 28);
5073// data.Acceleration.ToBytes(objectData, 40); 5141// data.Acceleration.ToBytes(objectData, 40);
5074 data.Rotation.ToBytes(objectData, 52); 5142 rotation.ToBytes(objectData, 52);
5075 //data.AngularVelocity.ToBytes(objectData, 64); 5143 //data.AngularVelocity.ToBytes(objectData, 64);
5076 5144
5077 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5145 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5085,14 +5153,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5085 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5153 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5086 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5154 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5087 update.ObjectData = objectData; 5155 update.ObjectData = objectData;
5088 update.ParentID = data.ParentID; 5156 update.ParentID = parentID;
5089 update.PathCurve = 16; 5157 update.PathCurve = 16;
5090 update.PathScaleX = 100; 5158 update.PathScaleX = 100;
5091 update.PathScaleY = 100; 5159 update.PathScaleY = 100;
5092 update.PCode = (byte)PCode.Avatar; 5160 update.PCode = (byte)PCode.Avatar;
5093 update.ProfileCurve = 1; 5161 update.ProfileCurve = 1;
5094 update.PSBlock = Utils.EmptyBytes; 5162 update.PSBlock = Utils.EmptyBytes;
5095 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5163 update.Scale = data.Appearance.AvatarSize;
5164// update.Scale.Z -= 0.2f;
5165
5096 update.Text = Utils.EmptyBytes; 5166 update.Text = Utils.EmptyBytes;
5097 update.TextColor = new byte[4]; 5167 update.TextColor = new byte[4];
5098 5168
@@ -5103,10 +5173,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5103 update.TextureEntry = Utils.EmptyBytes; 5173 update.TextureEntry = Utils.EmptyBytes;
5104// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5174// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5105 5175
5176/* 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)
5106 update.UpdateFlags = (uint)( 5177 update.UpdateFlags = (uint)(
5107 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5178 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5108 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5179 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5109 PrimFlags.ObjectOwnerModify); 5180 PrimFlags.ObjectOwnerModify);
5181*/
5182 update.UpdateFlags = 0;
5110 5183
5111 return update; 5184 return update;
5112 } 5185 }
@@ -5277,8 +5350,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5277 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5350 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5278 // for each AgentUpdate packet. 5351 // for each AgentUpdate packet.
5279 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5352 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5280 5353
5281 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5354 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5355 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5356 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5282 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5357 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5283 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5358 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5284 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5359 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5430,6 +5505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5430 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5505 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5431 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5506 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5432 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5507 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5508 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5433 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5509 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5434 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5510 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5435 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5511 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5496,6 +5572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5496 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5572 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5497 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5573 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5498 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5574 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5575 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5499 5576
5500 AddGenericPacketHandler("autopilot", HandleAutopilot); 5577 AddGenericPacketHandler("autopilot", HandleAutopilot);
5501 } 5578 }
@@ -5534,6 +5611,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5534 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5611 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5535 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5612 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5536 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5613 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5614 (x.ControlFlags != 0) ||
5537 (x.Far != m_lastAgentUpdateArgs.Far) || 5615 (x.Far != m_lastAgentUpdateArgs.Far) ||
5538 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5616 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5539 (x.State != m_lastAgentUpdateArgs.State) || 5617 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5793,6 +5871,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5793 return true; 5871 return true;
5794 } 5872 }
5795 5873
5874 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5875 {
5876 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5877 if (p.AgentData.SessionID != SessionId ||
5878 p.AgentData.AgentID != AgentId)
5879 return true;
5880
5881 m_VelocityInterpolate = false;
5882 return true;
5883 }
5884
5885 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5886 {
5887 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5888 if (p.AgentData.SessionID != SessionId ||
5889 p.AgentData.AgentID != AgentId)
5890 return true;
5891
5892 m_VelocityInterpolate = true;
5893 return true;
5894 }
5895
5896
5796 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5897 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5797 { 5898 {
5798 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5899 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6213,26 +6314,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6213 // Temporarily protect ourselves from the mantis #951 failure. 6314 // Temporarily protect ourselves from the mantis #951 failure.
6214 // However, we could do this for several other handlers where a failure isn't terminal 6315 // However, we could do this for several other handlers where a failure isn't terminal
6215 // for the client session anyway, in order to protect ourselves against bad code in plugins 6316 // for the client session anyway, in order to protect ourselves against bad code in plugins
6317 Vector3 avSize = appear.AgentData.Size;
6216 try 6318 try
6217 { 6319 {
6218 byte[] visualparams = new byte[appear.VisualParam.Length]; 6320 byte[] visualparams = new byte[appear.VisualParam.Length];
6219 for (int i = 0; i < appear.VisualParam.Length; i++) 6321 for (int i = 0; i < appear.VisualParam.Length; i++)
6220 visualparams[i] = appear.VisualParam[i].ParamValue; 6322 visualparams[i] = appear.VisualParam[i].ParamValue;
6221 6323 //var b = appear.WearableData[0];
6324
6222 Primitive.TextureEntry te = null; 6325 Primitive.TextureEntry te = null;
6223 if (appear.ObjectData.TextureEntry.Length > 1) 6326 if (appear.ObjectData.TextureEntry.Length > 1)
6224 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6327 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6328
6329 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6330 for (int i=0; i<appear.WearableData.Length;i++)
6331 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6225 6332
6226 List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); 6333
6227 for (int i = 0; i < appear.WearableData.Length; i++)
6228 {
6229 CachedTextureRequestArg arg = new CachedTextureRequestArg();
6230 arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
6231 arg.WearableHashID = appear.WearableData[i].CacheID;
6232 hashes.Add(arg);
6233 }
6234 6334
6235 handlerSetAppearance(sender, te, visualparams, hashes); 6335 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6236 } 6336 }
6237 catch (Exception e) 6337 catch (Exception e)
6238 { 6338 {
@@ -6441,6 +6541,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6441 { 6541 {
6442 handlerCompleteMovementToRegion(sender, true); 6542 handlerCompleteMovementToRegion(sender, true);
6443 } 6543 }
6544 else
6545 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6546
6444 handlerCompleteMovementToRegion = null; 6547 handlerCompleteMovementToRegion = null;
6445 6548
6446 return true; 6549 return true;
@@ -6458,7 +6561,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6458 return true; 6561 return true;
6459 } 6562 }
6460 #endregion 6563 #endregion
6461 6564/*
6462 StartAnim handlerStartAnim = null; 6565 StartAnim handlerStartAnim = null;
6463 StopAnim handlerStopAnim = null; 6566 StopAnim handlerStopAnim = null;
6464 6567
@@ -6482,6 +6585,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6482 } 6585 }
6483 } 6586 }
6484 return true; 6587 return true;
6588*/
6589 ChangeAnim handlerChangeAnim = null;
6590
6591 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6592 {
6593 handlerChangeAnim = OnChangeAnim;
6594 if (handlerChangeAnim != null)
6595 {
6596 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6597 }
6598 }
6599
6600 handlerChangeAnim = OnChangeAnim;
6601 if (handlerChangeAnim != null)
6602 {
6603 handlerChangeAnim(UUID.Zero, false, true);
6604 }
6605
6606 return true;
6485 } 6607 }
6486 6608
6487 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6609 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6707,6 +6829,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6707 #endregion 6829 #endregion
6708 6830
6709 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6831 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6832 GenericCall2 handler = OnUpdateThrottles;
6833 if (handler != null)
6834 {
6835 handler();
6836 }
6710 return true; 6837 return true;
6711 } 6838 }
6712 6839
@@ -7131,7 +7258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7131 physdata.Bounce = phsblock.Restitution; 7258 physdata.Bounce = phsblock.Restitution;
7132 physdata.Density = phsblock.Density; 7259 physdata.Density = phsblock.Density;
7133 physdata.Friction = phsblock.Friction; 7260 physdata.Friction = phsblock.Friction;
7134 physdata.GravitationModifier = phsblock.GravityMultiplier; 7261 physdata.GravitationModifier = phsblock.GravityMultiplier;
7135 } 7262 }
7136 7263
7137 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7264 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7717,6 +7844,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7717 // surrounding scene 7844 // surrounding scene
7718 if ((ImageType)block.Type == ImageType.Baked) 7845 if ((ImageType)block.Type == ImageType.Baked)
7719 args.Priority *= 2.0f; 7846 args.Priority *= 2.0f;
7847 int wearableout = 0;
7720 7848
7721 ImageManager.EnqueueReq(args); 7849 ImageManager.EnqueueReq(args);
7722 } 7850 }
@@ -8735,16 +8863,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8735 8863
8736 #region Parcel related packets 8864 #region Parcel related packets
8737 8865
8866 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8867 // to be done with minimal resources as possible
8868 // variables temporary here while in test
8869
8870 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8871 bool RegionHandleRequestsInService = false;
8872
8738 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8873 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8739 { 8874 {
8740 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8875 UUID currentUUID;
8741 8876
8742 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8877 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8743 if (handlerRegionHandleRequest != null) 8878
8879 if (handlerRegionHandleRequest == null)
8880 return true;
8881
8882 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8883
8884 lock (RegionHandleRequests)
8744 { 8885 {
8745 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8886 if (RegionHandleRequestsInService)
8887 {
8888 // we are already busy doing a previus request
8889 // so enqueue it
8890 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8891 return true;
8892 }
8893
8894 // else do it
8895 currentUUID = rhrPack.RequestBlock.RegionID;
8896 RegionHandleRequestsInService = true;
8746 } 8897 }
8747 return true; 8898
8899 while (true)
8900 {
8901 handlerRegionHandleRequest(this, currentUUID);
8902
8903 lock (RegionHandleRequests)
8904 {
8905 // exit condition, nothing to do or closed
8906 // current code seems to assume we may loose the handler at anytime,
8907 // so keep checking it
8908 handlerRegionHandleRequest = OnRegionHandleRequest;
8909
8910 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8911 {
8912 RegionHandleRequests.Clear();
8913 RegionHandleRequestsInService = false;
8914 return true;
8915 }
8916 currentUUID = RegionHandleRequests.Dequeue();
8917 }
8918 }
8919
8920 return true; // actually unreached
8748 } 8921 }
8749 8922
8750 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8923 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -10000,7 +10173,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10000 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10173 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10001 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10174 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10002 UpdateMuteListEntry.MuteData.MuteType, 10175 UpdateMuteListEntry.MuteData.MuteType,
10003 UpdateMuteListEntry.AgentData.AgentID); 10176 UpdateMuteListEntry.MuteData.MuteFlags);
10004 return true; 10177 return true;
10005 } 10178 }
10006 return false; 10179 return false;
@@ -10015,8 +10188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10015 { 10188 {
10016 handlerRemoveMuteListEntry(this, 10189 handlerRemoveMuteListEntry(this,
10017 RemoveMuteListEntry.MuteData.MuteID, 10190 RemoveMuteListEntry.MuteData.MuteID,
10018 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10191 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10019 RemoveMuteListEntry.AgentData.AgentID);
10020 return true; 10192 return true;
10021 } 10193 }
10022 return false; 10194 return false;
@@ -10060,10 +10232,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10060 return false; 10232 return false;
10061 } 10233 }
10062 10234
10235 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10236 {
10237 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10238 (ChangeInventoryItemFlagsPacket)packet;
10239 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10240 if (handlerChangeInventoryItemFlags != null)
10241 {
10242 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10243 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10244 return true;
10245 }
10246 return false;
10247 }
10248
10063 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10249 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10064 { 10250 {
10065 return true; 10251 return true;
10066 } 10252 }
10253
10254 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10255 {
10256 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10257
10258 #region Packet Session and User Check
10259 if (m_checkPackets)
10260 {
10261 if (packet.AgentData.SessionID != SessionId ||
10262 packet.AgentData.AgentID != AgentId)
10263 return true;
10264 }
10265 #endregion
10266 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10267 List<InventoryItemBase> items = new List<InventoryItemBase>();
10268 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10269 {
10270 InventoryItemBase b = new InventoryItemBase();
10271 b.ID = n.OldItemID;
10272 b.Folder = n.OldFolderID;
10273 items.Add(b);
10274 }
10275
10276 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10277 if (handlerMoveItemsAndLeaveCopy != null)
10278 {
10279 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10280 }
10281
10282 return true;
10283 }
10067 10284
10068 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10285 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10069 { 10286 {
@@ -10490,6 +10707,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10490 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10707 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10491 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10708 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10492 10709
10710 Scene scene = (Scene)m_scene;
10711 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10712 {
10713 ScenePresence p;
10714 if (scene.TryGetScenePresence(sender.AgentId, out p))
10715 {
10716 if (p.GodLevel >= 200)
10717 {
10718 groupProfileReply.GroupData.OpenEnrollment = true;
10719 groupProfileReply.GroupData.MembershipFee = 0;
10720 }
10721 }
10722 }
10723
10493 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10724 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10494 } 10725 }
10495 return true; 10726 return true;
@@ -11063,11 +11294,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11063 11294
11064 StartLure handlerStartLure = OnStartLure; 11295 StartLure handlerStartLure = OnStartLure;
11065 if (handlerStartLure != null) 11296 if (handlerStartLure != null)
11066 handlerStartLure(startLureRequest.Info.LureType, 11297 {
11067 Utils.BytesToString( 11298 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11068 startLureRequest.Info.Message), 11299 {
11069 startLureRequest.TargetData[0].TargetID, 11300 handlerStartLure(startLureRequest.Info.LureType,
11070 this); 11301 Utils.BytesToString(
11302 startLureRequest.Info.Message),
11303 startLureRequest.TargetData[i].TargetID,
11304 this);
11305 }
11306 }
11071 return true; 11307 return true;
11072 } 11308 }
11073 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11309 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11181,10 +11417,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11181 } 11417 }
11182 #endregion 11418 #endregion
11183 11419
11184 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11420 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11185 if (handlerClassifiedGodDelete != null) 11421 if (handlerClassifiedGodDelete != null)
11186 handlerClassifiedGodDelete( 11422 handlerClassifiedGodDelete(
11187 classifiedGodDelete.Data.ClassifiedID, 11423 classifiedGodDelete.Data.ClassifiedID,
11424 classifiedGodDelete.Data.QueryID,
11188 this); 11425 this);
11189 return true; 11426 return true;
11190 } 11427 }
@@ -11487,12 +11724,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11487 /// <param name="simclient"></param> 11724 /// <param name="simclient"></param>
11488 /// <param name="packet"></param> 11725 /// <param name="packet"></param>
11489 /// <returns></returns> 11726 /// <returns></returns>
11490 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11727 // TODO: Convert old handler to use new method
11728 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11491 { 11729 {
11492 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11730 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11493 11731
11494 if (cachedtex.AgentData.SessionID != SessionId) 11732 if (cachedtex.AgentData.SessionID != SessionId)
11495 return false; 11733 return false;
11734
11496 11735
11497 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); 11736 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11498 11737
@@ -11505,23 +11744,173 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11505 requestArgs.Add(arg); 11744 requestArgs.Add(arg);
11506 } 11745 }
11507 11746
11508 try 11747 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11748 if (handlerCachedTextureRequest != null)
11509 { 11749 {
11510 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11750 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11511 if (handlerCachedTextureRequest != null) 11751 }
11752
11753 return true;
11754 }*/
11755
11756 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11757 {
11758 //m_log.Debug("texture cached: " + packet.ToString());
11759 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11760 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
11761
11762 if (cachedtex.AgentData.SessionID != SessionId)
11763 return false;
11764
11765
11766 // TODO: don't create new blocks if recycling an old packet
11767 cachedresp.AgentData.AgentID = AgentId;
11768 cachedresp.AgentData.SessionID = m_sessionId;
11769 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
11770 m_cachedTextureSerial++;
11771 cachedresp.WearableData =
11772 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11773
11774 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11775 // var item = fac.GetBakedTextureFaces(AgentId);
11776 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11777
11778 IAssetService cache = m_scene.AssetService;
11779 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11780 //bakedTextureModule = null;
11781 int maxWearablesLoop = cachedtex.WearableData.Length;
11782 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11783 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11784
11785 if (bakedTextureModule != null && cache != null)
11786 {
11787 // 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
11788
11789 WearableCacheItem[] cacheItems = null;
11790 ScenePresence p = m_scene.GetScenePresence(AgentId);
11791 if (p.Appearance != null)
11792 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11793 {
11794 try
11795 {
11796 cacheItems = bakedTextureModule.Get(AgentId);
11797 p.Appearance.WearableCacheItems = cacheItems;
11798 p.Appearance.WearableCacheItemsDirty = false;
11799 }
11800
11801 /*
11802 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11803 *
11804 catch (System.Net.Sockets.SocketException)
11805 {
11806 cacheItems = null;
11807 }
11808 catch (WebException)
11809 {
11810 cacheItems = null;
11811 }
11812 catch (InvalidOperationException)
11813 {
11814 cacheItems = null;
11815 } */
11816 catch (Exception)
11817 {
11818 cacheItems = null;
11819 }
11820
11821 }
11822 else if (p.Appearance.WearableCacheItems != null)
11823 {
11824 cacheItems = p.Appearance.WearableCacheItems;
11825 }
11826
11827 if (cache != null && cacheItems != null)
11512 { 11828 {
11513 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 11829 foreach (WearableCacheItem item in cacheItems)
11830 {
11831
11832 if (cache.GetCached(item.TextureID.ToString()) == null)
11833 {
11834 item.TextureAsset.Temporary = true;
11835 cache.Store(item.TextureAsset);
11836 }
11837
11838
11839 }
11840 }
11841
11842 if (cacheItems != null)
11843 {
11844
11845 for (int i = 0; i < maxWearablesLoop; i++)
11846 {
11847 WearableCacheItem item =
11848 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11849
11850 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11851 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11852 cachedresp.WearableData[i].HostName = new byte[0];
11853 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11854 {
11855
11856 cachedresp.WearableData[i].TextureID = item.TextureID;
11857 }
11858 else
11859 {
11860 cachedresp.WearableData[i].TextureID = UUID.Zero;
11861 }
11862 }
11863 }
11864 else
11865 {
11866 for (int i = 0; i < maxWearablesLoop; i++)
11867 {
11868 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11869 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11870 cachedresp.WearableData[i].TextureID = UUID.Zero;
11871 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11872 cachedresp.WearableData[i].HostName = new byte[0];
11873 }
11514 } 11874 }
11515 } 11875 }
11516 catch (Exception e) 11876 else
11517 { 11877 {
11518 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); 11878 if (cache == null)
11519 return false; 11879 {
11880 for (int i = 0; i < maxWearablesLoop; i++)
11881 {
11882 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11883 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11884 cachedresp.WearableData[i].TextureID = UUID.Zero;
11885 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11886 cachedresp.WearableData[i].HostName = new byte[0];
11887 }
11888 }
11889 else
11890 {
11891 for (int i = 0; i < maxWearablesLoop; i++)
11892 {
11893 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11894 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11895
11896
11897
11898 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11899 cachedresp.WearableData[i].TextureID = UUID.Zero;
11900 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11901 else
11902 cachedresp.WearableData[i].TextureID = UUID.Zero;
11903 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11904 cachedresp.WearableData[i].HostName = new byte[0];
11905 }
11906 }
11520 } 11907 }
11521 11908 cachedresp.Header.Zerocoded = true;
11909 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11910
11522 return true; 11911 return true;
11523 } 11912 }
11524 11913
11525 /// <summary> 11914 /// <summary>
11526 /// Send a response back to a client when it asks the asset server (via the region server) if it has 11915 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11527 /// its appearance texture cached. 11916 /// its appearance texture cached.
@@ -11585,209 +11974,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11585 } 11974 }
11586 else 11975 else
11587 { 11976 {
11588// m_log.DebugFormat( 11977 ClientChangeObject updatehandler = onClientChangeObject;
11589// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11590// i, block.Type, part.Name, part.LocalId);
11591 11978
11592// // Do this once since fetch parts creates a new array. 11979 if (updatehandler != null)
11593// SceneObjectPart[] parts = part.ParentGroup.Parts; 11980 {
11594// for (int j = 0; j < parts.Length; j++) 11981 ObjectChangeData udata = new ObjectChangeData();
11595// {
11596// part.StoreUndoState();
11597// parts[j].IgnoreUndoUpdate = true;
11598// }
11599 11982
11600 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11983 /*ubit from ll JIRA:
11984 * 0x01 position
11985 * 0x02 rotation
11986 * 0x04 scale
11987
11988 * 0x08 LINK_SET
11989 * 0x10 UNIFORM for scale
11990 */
11601 11991
11602 switch (block.Type) 11992 // translate to internal changes
11603 { 11993 // not all cases .. just the ones older code did
11604 case 1:
11605 Vector3 pos1 = new Vector3(block.Data, 0);
11606 11994
11607 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11995 switch (block.Type)
11608 if (handlerUpdatePrimSinglePosition != null) 11996 {
11609 { 11997 case 1: //change position sp
11610 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11998 udata.position = new Vector3(block.Data, 0);
11611 handlerUpdatePrimSinglePosition(localId, pos1, this);
11612 }
11613 break;
11614 11999
11615 case 2: 12000 udata.change = ObjectChangeType.primP;
11616 Quaternion rot1 = new Quaternion(block.Data, 0, true); 12001 updatehandler(localId, udata, this);
12002 break;
11617 12003
11618 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 12004 case 2: // rotation sp
11619 if (handlerUpdatePrimSingleRotation != null) 12005 udata.rotation = new Quaternion(block.Data, 0, true);
11620 {
11621 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11622 handlerUpdatePrimSingleRotation(localId, rot1, this);
11623 }
11624 break;
11625 12006
11626 case 3: 12007 udata.change = ObjectChangeType.primR;
11627 Vector3 rotPos = new Vector3(block.Data, 0); 12008 updatehandler(localId, udata, this);
11628 Quaternion rot2 = new Quaternion(block.Data, 12, true); 12009 break;
11629 12010
11630 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 12011 case 3: // position plus rotation
11631 if (handlerUpdatePrimSingleRotationPosition != null) 12012 udata.position = new Vector3(block.Data, 0);
11632 { 12013 udata.rotation = new Quaternion(block.Data, 12, true);
11633 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11634 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11635 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11636 }
11637 break;
11638 12014
11639 case 4: 12015 udata.change = ObjectChangeType.primPR;
11640 case 20: 12016 updatehandler(localId, udata, this);
11641 Vector3 scale4 = new Vector3(block.Data, 0); 12017 break;
11642 12018
11643 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 12019 case 4: // scale sp
11644 if (handlerUpdatePrimScale != null) 12020 udata.scale = new Vector3(block.Data, 0);
11645 { 12021 udata.change = ObjectChangeType.primS;
11646 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11647 handlerUpdatePrimScale(localId, scale4, this);
11648 }
11649 break;
11650 12022
11651 case 5: 12023 updatehandler(localId, udata, this);
11652 Vector3 scale1 = new Vector3(block.Data, 12); 12024 break;
11653 Vector3 pos11 = new Vector3(block.Data, 0);
11654 12025
11655 handlerUpdatePrimScale = OnUpdatePrimScale; 12026 case 0x14: // uniform scale sp
11656 if (handlerUpdatePrimScale != null) 12027 udata.scale = new Vector3(block.Data, 0);
11657 {
11658 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11659 handlerUpdatePrimScale(localId, scale1, this);
11660 12028
11661 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12029 udata.change = ObjectChangeType.primUS;
11662 if (handlerUpdatePrimSinglePosition != null) 12030 updatehandler(localId, udata, this);
11663 { 12031 break;
11664 handlerUpdatePrimSinglePosition(localId, pos11, this);
11665 }
11666 }
11667 break;
11668 12032
11669 case 9: 12033 case 5: // scale and position sp
11670 Vector3 pos2 = new Vector3(block.Data, 0); 12034 udata.position = new Vector3(block.Data, 0);
12035 udata.scale = new Vector3(block.Data, 12);
11671 12036
11672 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 12037 udata.change = ObjectChangeType.primPS;
12038 updatehandler(localId, udata, this);
12039 break;
11673 12040
11674 if (handlerUpdateVector != null) 12041 case 0x15: //uniform scale and position
11675 { 12042 udata.position = new Vector3(block.Data, 0);
11676 handlerUpdateVector(localId, pos2, this); 12043 udata.scale = new Vector3(block.Data, 12);
11677 }
11678 break;
11679 12044
11680 case 10: 12045 udata.change = ObjectChangeType.primPUS;
11681 Quaternion rot3 = new Quaternion(block.Data, 0, true); 12046 updatehandler(localId, udata, this);
12047 break;
11682 12048
11683 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 12049 // now group related (bit 4)
11684 if (handlerUpdatePrimRotation != null) 12050 case 9: //( 8 + 1 )group position
11685 { 12051 udata.position = new Vector3(block.Data, 0);
11686 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11687 handlerUpdatePrimRotation(localId, rot3, this);
11688 }
11689 break;
11690 12052
11691 case 11: 12053 udata.change = ObjectChangeType.groupP;
11692 Vector3 pos3 = new Vector3(block.Data, 0); 12054 updatehandler(localId, udata, this);
11693 Quaternion rot4 = new Quaternion(block.Data, 12, true); 12055 break;
11694 12056
11695 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 12057 case 0x0A: // (8 + 2) group rotation
11696 if (handlerUpdatePrimGroupRotation != null) 12058 udata.rotation = new Quaternion(block.Data, 0, true);
11697 {
11698 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11699 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11700 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11701 }
11702 break;
11703 case 12:
11704 case 28:
11705 Vector3 scale7 = new Vector3(block.Data, 0);
11706 12059
11707 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12060 udata.change = ObjectChangeType.groupR;
11708 if (handlerUpdatePrimGroupScale != null) 12061 updatehandler(localId, udata, this);
11709 { 12062 break;
11710 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11711 handlerUpdatePrimGroupScale(localId, scale7, this);
11712 }
11713 break;
11714 12063
11715 case 13: 12064 case 0x0B: //( 8 + 2 + 1) group rotation and position
11716 Vector3 scale2 = new Vector3(block.Data, 12); 12065 udata.position = new Vector3(block.Data, 0);
11717 Vector3 pos4 = new Vector3(block.Data, 0); 12066 udata.rotation = new Quaternion(block.Data, 12, true);
11718 12067
11719 handlerUpdatePrimScale = OnUpdatePrimScale; 12068 udata.change = ObjectChangeType.groupPR;
11720 if (handlerUpdatePrimScale != null) 12069 updatehandler(localId, udata, this);
11721 { 12070 break;
11722 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11723 handlerUpdatePrimScale(localId, scale2, this);
11724 12071
11725 // Change the position based on scale (for bug number 246) 12072 case 0x0C: // (8 + 4) group scale
11726 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12073 // only afects root prim and only sent by viewer editor object tab scaling
11727 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12074 // mouse edition only allows uniform scaling
11728 if (handlerUpdatePrimSinglePosition != null) 12075 // SL MAY CHANGE THIS in viewers
11729 {
11730 handlerUpdatePrimSinglePosition(localId, pos4, this);
11731 }
11732 }
11733 break;
11734 12076
11735 case 29: 12077 udata.scale = new Vector3(block.Data, 0);
11736 Vector3 scale5 = new Vector3(block.Data, 12);
11737 Vector3 pos5 = new Vector3(block.Data, 0);
11738 12078
11739 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12079 udata.change = ObjectChangeType.groupS;
11740 if (handlerUpdatePrimGroupScale != null) 12080 updatehandler(localId, udata, this);
11741 {
11742 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11743 part.StoreUndoState(true);
11744 part.IgnoreUndoUpdate = true;
11745 handlerUpdatePrimGroupScale(localId, scale5, this);
11746 handlerUpdateVector = OnUpdatePrimGroupPosition;
11747 12081
11748 if (handlerUpdateVector != null) 12082 break;
11749 {
11750 handlerUpdateVector(localId, pos5, this);
11751 }
11752 12083
11753 part.IgnoreUndoUpdate = false; 12084 case 0x0D: //(8 + 4 + 1) group scale and position
11754 } 12085 // exception as above
11755 12086
11756 break; 12087 udata.position = new Vector3(block.Data, 0);
12088 udata.scale = new Vector3(block.Data, 12);
11757 12089
11758 case 21: 12090 udata.change = ObjectChangeType.groupPS;
11759 Vector3 scale6 = new Vector3(block.Data, 12); 12091 updatehandler(localId, udata, this);
11760 Vector3 pos6 = new Vector3(block.Data, 0); 12092 break;
11761 12093
11762 handlerUpdatePrimScale = OnUpdatePrimScale; 12094 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11763 if (handlerUpdatePrimScale != null) 12095 udata.scale = new Vector3(block.Data, 0);
11764 {
11765 part.StoreUndoState(false);
11766 part.IgnoreUndoUpdate = true;
11767 12096
11768 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12097 udata.change = ObjectChangeType.groupUS;
11769 handlerUpdatePrimScale(localId, scale6, this); 12098 updatehandler(localId, udata, this);
11770 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12099 break;
11771 if (handlerUpdatePrimSinglePosition != null)
11772 {
11773 handlerUpdatePrimSinglePosition(localId, pos6, this);
11774 }
11775 12100
11776 part.IgnoreUndoUpdate = false; 12101 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11777 } 12102 udata.position = new Vector3(block.Data, 0);
11778 break; 12103 udata.scale = new Vector3(block.Data, 12);
11779 12104
11780 default: 12105 udata.change = ObjectChangeType.groupPUS;
11781 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12106 updatehandler(localId, udata, this);
11782 break; 12107 break;
12108
12109 default:
12110 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12111 break;
12112 }
11783 } 12113 }
11784 12114
11785// for (int j = 0; j < parts.Length; j++)
11786// parts[j].IgnoreUndoUpdate = false;
11787 } 12115 }
11788 } 12116 }
11789 } 12117 }
11790
11791 return true; 12118 return true;
11792 } 12119 }
11793 12120
@@ -11848,9 +12175,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11848 public void SetChildAgentThrottle(byte[] throttles) 12175 public void SetChildAgentThrottle(byte[] throttles)
11849 { 12176 {
11850 m_udpClient.SetThrottles(throttles); 12177 m_udpClient.SetThrottles(throttles);
12178 GenericCall2 handler = OnUpdateThrottles;
12179 if (handler != null)
12180 {
12181 handler();
12182 }
11851 } 12183 }
11852 12184
11853 /// <summary> 12185 /// <summary>
12186 /// Sets the throttles from values supplied by the client
12187 /// </summary>
12188 /// <param name="throttles"></param>
12189 public void SetAgentThrottleSilent(int throttle, int setting)
12190 {
12191 m_udpClient.ForceThrottleSetting(throttle,setting);
12192 //m_udpClient.SetThrottles(throttles);
12193
12194 }
12195
12196
12197 /// <summary>
11854 /// Get the current throttles for this client as a packed byte array 12198 /// Get the current throttles for this client as a packed byte array
11855 /// </summary> 12199 /// </summary>
11856 /// <param name="multiplier">Unused</param> 12200 /// <param name="multiplier">Unused</param>
@@ -12231,7 +12575,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12231// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12575// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12232// requestID, taskID, (SourceType)sourceType, Name); 12576// requestID, taskID, (SourceType)sourceType, Name);
12233 12577
12578
12579 //Note, the bool returned from the below function is useless since it is always false.
12234 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12580 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12581
12235 } 12582 }
12236 12583
12237 /// <summary> 12584 /// <summary>
@@ -12297,7 +12644,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12297 /// <returns></returns> 12644 /// <returns></returns>
12298 private static int CalculateNumPackets(byte[] data) 12645 private static int CalculateNumPackets(byte[] data)
12299 { 12646 {
12300 const uint m_maxPacketSize = 600; 12647// const uint m_maxPacketSize = 600;
12648 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12301 int numPackets = 1; 12649 int numPackets = 1;
12302 12650
12303 if (data == null) 12651 if (data == null)