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.cs644
1 files changed, 437 insertions, 207 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index f4ea975..36edd0b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -84,6 +84,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
84 public event ModifyTerrain OnModifyTerrain; 84 public event ModifyTerrain OnModifyTerrain;
85 public event Action<IClientAPI> OnRegionHandShakeReply; 85 public event Action<IClientAPI> OnRegionHandShakeReply;
86 public event GenericCall1 OnRequestWearables; 86 public event GenericCall1 OnRequestWearables;
87 public event CachedTextureRequest OnCachedTextureRequest;
87 public event SetAppearance OnSetAppearance; 88 public event SetAppearance OnSetAppearance;
88 public event AvatarNowWearing OnAvatarNowWearing; 89 public event AvatarNowWearing OnAvatarNowWearing;
89 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; 90 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
95 public event Action<IClientAPI, bool> OnCompleteMovementToRegion; 96 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
96 public event UpdateAgent OnPreAgentUpdate; 97 public event UpdateAgent OnPreAgentUpdate;
97 public event UpdateAgent OnAgentUpdate; 98 public event UpdateAgent OnAgentUpdate;
99 public event UpdateAgent OnAgentCameraUpdate;
98 public event AgentRequestSit OnAgentRequestSit; 100 public event AgentRequestSit OnAgentRequestSit;
99 public event AgentSit OnAgentSit; 101 public event AgentSit OnAgentSit;
100 public event AvatarPickerRequest OnAvatarPickerRequest; 102 public event AvatarPickerRequest OnAvatarPickerRequest;
@@ -335,6 +337,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
335 private bool m_VelocityInterpolate = false; 337 private bool m_VelocityInterpolate = false;
336 private const uint MaxTransferBytesPerPacket = 600; 338 private const uint MaxTransferBytesPerPacket = 600;
337 339
340 private volatile bool m_justEditedTerrain = false;
338 341
339 /// <value> 342 /// <value>
340 /// List used in construction of data blocks for an object update packet. This is to stop us having to 343 /// List used in construction of data blocks for an object update packet. This is to stop us having to
@@ -367,7 +370,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
367 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods 370 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
368 /// cannot retain a reference to it outside of that method. 371 /// cannot retain a reference to it outside of that method.
369 /// </remarks> 372 /// </remarks>
370 private AgentUpdateArgs m_lastAgentUpdateArgs; 373 private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
371 374
372 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 375 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
373 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 376 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -504,6 +507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 m_udpServer = udpServer; 507 m_udpServer = udpServer;
505 m_udpClient = udpClient; 508 m_udpClient = udpClient;
506 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 509 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
510 m_udpClient.HasUpdates += HandleHasUpdates;
507 m_udpClient.OnPacketStats += PopulateStats; 511 m_udpClient.OnPacketStats += PopulateStats;
508 512
509 m_prioritizer = new Prioritizer(m_scene); 513 m_prioritizer = new Prioritizer(m_scene);
@@ -533,7 +537,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
533 // We still perform a force close inside the sync lock since this is intended to attempt close where 537 // We still perform a force close inside the sync lock since this is intended to attempt close where
534 // there is some unidentified connection problem, not where we have issues due to deadlock 538 // there is some unidentified connection problem, not where we have issues due to deadlock
535 if (!IsActive && !force) 539 if (!IsActive && !force)
540 {
541 m_log.DebugFormat(
542 "[CLIENT]: Not attempting to close inactive client {0} in {1} since force flag is not set",
543 Name, m_scene.Name);
544
536 return; 545 return;
546 }
537 547
538 IsActive = false; 548 IsActive = false;
539 CloseWithoutChecks(sendStop); 549 CloseWithoutChecks(sendStop);
@@ -709,12 +719,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
709 //there is a local handler for this packet type 719 //there is a local handler for this packet type
710 if (pprocessor.Async) 720 if (pprocessor.Async)
711 { 721 {
722 ClientInfo cinfo = UDPClient.GetClientInfo();
723 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
724 cinfo.AsyncRequests[packet.Type.ToString()] = 0;
725 cinfo.AsyncRequests[packet.Type.ToString()]++;
726
712 object obj = new AsyncPacketProcess(this, pprocessor.method, packet); 727 object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
713 Util.FireAndForget(ProcessSpecificPacketAsync, obj); 728 Util.FireAndForget(ProcessSpecificPacketAsync, obj);
714 result = true; 729 result = true;
715 } 730 }
716 else 731 else
717 { 732 {
733 ClientInfo cinfo = UDPClient.GetClientInfo();
734 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
735 cinfo.SyncRequests[packet.Type.ToString()] = 0;
736 cinfo.SyncRequests[packet.Type.ToString()]++;
737
718 result = pprocessor.method(this, packet); 738 result = pprocessor.method(this, packet);
719 } 739 }
720 } 740 }
@@ -729,6 +749,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
729 } 749 }
730 if (found) 750 if (found)
731 { 751 {
752 ClientInfo cinfo = UDPClient.GetClientInfo();
753 if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString()))
754 cinfo.GenericRequests[packet.Type.ToString()] = 0;
755 cinfo.GenericRequests[packet.Type.ToString()]++;
756
732 result = method(this, packet); 757 result = method(this, packet);
733 } 758 }
734 } 759 }
@@ -820,12 +845,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
820 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 845 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
821 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 846 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
822 847
823 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0]; 848 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[1];
824// OutPacket(handshake, ThrottleOutPacketType.Task); 849 handshake.RegionInfo4[0] = new RegionHandshakePacket.RegionInfo4Block();
825 // use same as MoveAgentIntoRegion (both should be task ) 850 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
851 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
852
826 OutPacket(handshake, ThrottleOutPacketType.Unknown); 853 OutPacket(handshake, ThrottleOutPacketType.Unknown);
827 } 854 }
828 855
856
829 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 857 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
830 { 858 {
831 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); 859 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
@@ -1210,9 +1238,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1210 LLHeightFieldMoronize(map); 1238 LLHeightFieldMoronize(map);
1211 1239
1212 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1240 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1213 layerpack.Header.Reliable = true; 1241
1242 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience.
1243 // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain.
1244 // We also make them unreliable because it's extremely likely that multiple packets will be sent for a terrain patch area
1245 // invalidating previous packets for that area.
1214 1246
1215 OutPacket(layerpack, ThrottleOutPacketType.Task); 1247 // It's possible for an editing user to flood themselves with edited packets but the majority of use cases are such that only a
1248 // tiny percentage of users will be editing the terrain. Other, non-editing users will see the edits much slower.
1249
1250 // One last note on this topic, by the time users are going to be editing the terrain, it's extremely likely that the sim will
1251 // have rezzed already and therefore this is not likely going to cause any additional issues with lost packets, objects or terrain
1252 // patches.
1253
1254 // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we only have one cache miss.
1255 if (m_justEditedTerrain)
1256 {
1257 layerpack.Header.Reliable = false;
1258 OutPacket(layerpack,
1259 ThrottleOutPacketType.Unknown );
1260 }
1261 else
1262 {
1263 layerpack.Header.Reliable = true;
1264 OutPacket(layerpack,
1265 ThrottleOutPacketType.Task);
1266 }
1216 } 1267 }
1217 catch (Exception e) 1268 catch (Exception e)
1218 { 1269 {
@@ -1580,7 +1631,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1580 OutPacket(pc, ThrottleOutPacketType.Unknown); 1631 OutPacket(pc, ThrottleOutPacketType.Unknown);
1581 } 1632 }
1582 1633
1583 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1634 public void SendKillObject(List<uint> localIDs)
1584 { 1635 {
1585// foreach (uint id in localIDs) 1636// foreach (uint id in localIDs)
1586// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); 1637// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
@@ -3797,6 +3848,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3797 ResendPrimUpdate(update); 3848 ResendPrimUpdate(update);
3798 } 3849 }
3799 3850
3851// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3852// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3853// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3854// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3855//
3856// OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3857// OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3858// OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3859// OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3860
3861
3800 private void ProcessEntityUpdates(int maxUpdates) 3862 private void ProcessEntityUpdates(int maxUpdates)
3801 { 3863 {
3802 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3864 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3809,6 +3871,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3809 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3871 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3810 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3872 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3811 3873
3874// objectUpdateBlocks.Value.Clear();
3875// compressedUpdateBlocks.Value.Clear();
3876// terseUpdateBlocks.Value.Clear();
3877// terseAgentUpdateBlocks.Value.Clear();
3878// objectUpdates.Value.Clear();
3879// compressedUpdates.Value.Clear();
3880// terseUpdates.Value.Clear();
3881// terseAgentUpdates.Value.Clear();
3882
3812 // Check to see if this is a flush 3883 // Check to see if this is a flush
3813 if (maxUpdates <= 0) 3884 if (maxUpdates <= 0)
3814 { 3885 {
@@ -4137,8 +4208,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4137 4208
4138 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 4209 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
4139 { 4210 {
4211// if (!m_udpServer.IsRunningOutbound)
4212// return;
4213
4140 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 4214 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4141 { 4215 {
4216// if (!m_udpServer.IsRunningOutbound)
4217// return;
4218
4142 if (m_maxUpdates == 0 || m_LastQueueFill == 0) 4219 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
4143 { 4220 {
4144 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; 4221 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
@@ -4164,6 +4241,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4164 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); 4241 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
4165 } 4242 }
4166 4243
4244 internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
4245 {
4246 bool hasUpdates = false;
4247
4248 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4249 {
4250 if (m_entityUpdates.Count > 0)
4251 hasUpdates = true;
4252 else if (m_entityProps.Count > 0)
4253 hasUpdates = true;
4254 }
4255
4256 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
4257 {
4258 if (ImageManager.HasUpdates())
4259 hasUpdates = true;
4260 }
4261
4262 return hasUpdates;
4263 }
4264
4167 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 4265 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
4168 { 4266 {
4169 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 4267 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
@@ -4874,7 +4972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4874 4972
4875 public void SendForceClientSelectObjects(List<uint> ObjectIDs) 4973 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
4876 { 4974 {
4877 m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); 4975// m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
4878 4976
4879 bool firstCall = true; 4977 bool firstCall = true;
4880 const int MAX_OBJECTS_PER_PACKET = 251; 4978 const int MAX_OBJECTS_PER_PACKET = 251;
@@ -5031,7 +5129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5031 SceneObjectPart part = (SceneObjectPart)entity; 5129 SceneObjectPart part = (SceneObjectPart)entity;
5032 5130
5033 attachPoint = part.ParentGroup.AttachmentPoint; 5131 attachPoint = part.ParentGroup.AttachmentPoint;
5034 5132 attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
5035// m_log.DebugFormat( 5133// m_log.DebugFormat(
5036// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", 5134// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
5037// attachPoint, part.Name, part.LocalId, Name); 5135// attachPoint, part.Name, part.LocalId, Name);
@@ -5059,7 +5157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5059 pos += 4; 5157 pos += 4;
5060 5158
5061 // Avatar/CollisionPlane 5159 // Avatar/CollisionPlane
5062 data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ; 5160 data[pos++] = (byte) attachPoint;
5063 if (avatar) 5161 if (avatar)
5064 { 5162 {
5065 data[pos++] = 1; 5163 data[pos++] = 1;
@@ -5384,7 +5482,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5384 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); 5482 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
5385 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); 5483 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
5386 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); 5484 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
5387 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply); 5485 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
5388 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); 5486 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
5389 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); 5487 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
5390 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing); 5488 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
@@ -5445,8 +5543,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5445 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false); 5543 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
5446 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); 5544 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
5447 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); 5545 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
5448 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage); 5546 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
5449 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); 5547 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
5450 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); 5548 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
5451 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); 5549 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
5452 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket); 5550 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
@@ -5478,7 +5576,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5478 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); 5576 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5479 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); 5577 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
5480 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); 5578 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
5481 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); 5579 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
5482 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); 5580 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
5483 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); 5581 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
5484 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false); 5582 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
@@ -5591,83 +5689,137 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5591 5689
5592 #region Packet Handlers 5690 #region Packet Handlers
5593 5691
5692 public int TotalAgentUpdates { get; set; }
5693
5594 #region Scene/Avatar 5694 #region Scene/Avatar
5595 5695
5596 private bool HandleAgentUpdate(IClientAPI sener, Packet packet) 5696 // Threshold for body rotation to be a significant agent update
5697 private const float QDELTA = 0.000001f;
5698 // Threshold for camera rotation to be a significant agent update
5699 private const float VDELTA = 0.01f;
5700
5701 /// <summary>
5702 /// This checks the update significance against the last update made.
5703 /// </summary>
5704 /// <remarks>Can only be called by one thread at a time</remarks>
5705 /// <returns></returns>
5706 /// <param name='x'></param>
5707 public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5597 { 5708 {
5598 if (OnAgentUpdate != null) 5709 return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
5599 { 5710 }
5600 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5601 5711
5602 #region Packet Session and User Check 5712 /// <summary>
5603 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId) 5713 /// This checks the movement/state update significance against the last update made.
5604 { 5714 /// </summary>
5605 PacketPool.Instance.ReturnPacket(packet); 5715 /// <remarks>Can only be called by one thread at a time</remarks>
5606 return false; 5716 /// <returns></returns>
5607 } 5717 /// <param name='x'></param>
5608 #endregion 5718 private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5719 {
5720 float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
5721 //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
5722
5723 bool movementSignificant =
5724 (qdelta1 > QDELTA) // significant if body rotation above threshold
5725 // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
5726 // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold
5727 || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
5728 || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands
5729 || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed
5730 || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
5731 || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
5732 ;
5733 //if (movementSignificant)
5734 //{
5735 //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}",
5736 // qdelta1, qdelta2);
5737 //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}",
5738 // x.ControlFlags, x.Flags, x.Far, x.State);
5739 //}
5740 return movementSignificant;
5741 }
5609 5742
5610 bool update = false; 5743 /// <summary>
5611 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; 5744 /// This checks the camera update significance against the last update made.
5612 5745 /// </summary>
5613 if (m_lastAgentUpdateArgs != null) 5746 /// <remarks>Can only be called by one thread at a time</remarks>
5614 { 5747 /// <returns></returns>
5615 // These should be ordered from most-likely to 5748 /// <param name='x'></param>
5616 // least likely to change. I've made an initial 5749 private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5617 // guess at that. 5750 {
5618 update = 5751 float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
5619 ( 5752 float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
5620 (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || 5753 float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
5621 (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || 5754 float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
5622 (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
5623 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5624 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5625 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5626 (x.ControlFlags != 0) ||
5627 (x.Far != m_lastAgentUpdateArgs.Far) ||
5628 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5629 (x.State != m_lastAgentUpdateArgs.State) ||
5630 (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
5631 (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
5632 (x.AgentID != m_lastAgentUpdateArgs.AgentID)
5633 );
5634 }
5635 else
5636 {
5637 m_lastAgentUpdateArgs = new AgentUpdateArgs();
5638 update = true;
5639 }
5640 5755
5641 if (update) 5756 bool cameraSignificant =
5642 { 5757 (vdelta1 > VDELTA) ||
5643// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); 5758 (vdelta2 > VDELTA) ||
5759 (vdelta3 > VDELTA) ||
5760 (vdelta4 > VDELTA)
5761 ;
5644 5762
5645 m_lastAgentUpdateArgs.AgentID = x.AgentID; 5763 //if (cameraSignificant)
5646 m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; 5764 //{
5647 m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; 5765 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
5648 m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; 5766 // x.CameraAtAxis, x.CameraCenter);
5649 m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; 5767 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
5650 m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; 5768 // x.CameraLeftAxis, x.CameraUpAxis);
5651 m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; 5769 //}
5652 m_lastAgentUpdateArgs.Far = x.Far;
5653 m_lastAgentUpdateArgs.Flags = x.Flags;
5654 m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
5655 m_lastAgentUpdateArgs.SessionID = x.SessionID;
5656 m_lastAgentUpdateArgs.State = x.State;
5657 5770
5658 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 5771 return cameraSignificant;
5659 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; 5772 }
5660 5773
5661 if (handlerPreAgentUpdate != null) 5774 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5662 OnPreAgentUpdate(this, m_lastAgentUpdateArgs); 5775 {
5776 // We got here, which means that something in agent update was significant
5663 5777
5664 if (handlerAgentUpdate != null) 5778 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5665 OnAgentUpdate(this, m_lastAgentUpdateArgs); 5779 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5666 5780
5667 handlerAgentUpdate = null; 5781 if (x.AgentID != AgentId || x.SessionID != SessionId)
5668 handlerPreAgentUpdate = null; 5782 return false;
5669 } 5783
5670 } 5784 // Before we update the current m_thisAgentUpdateArgs, let's check this again
5785 // to see what exactly changed
5786 bool movement = CheckAgentMovementUpdateSignificance(x);
5787 bool camera = CheckAgentCameraUpdateSignificance(x);
5788
5789 m_thisAgentUpdateArgs.AgentID = x.AgentID;
5790 m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation;
5791 m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
5792 m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter;
5793 m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
5794 m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
5795 m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags;
5796 m_thisAgentUpdateArgs.Far = x.Far;
5797 m_thisAgentUpdateArgs.Flags = x.Flags;
5798 m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
5799 m_thisAgentUpdateArgs.SessionID = x.SessionID;
5800 m_thisAgentUpdateArgs.State = x.State;
5801
5802 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
5803 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
5804 UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
5805
5806 // Was there a significant movement/state change?
5807 if (movement)
5808 {
5809 if (handlerPreAgentUpdate != null)
5810 OnPreAgentUpdate(this, m_thisAgentUpdateArgs);
5811
5812 if (handlerAgentUpdate != null)
5813 OnAgentUpdate(this, m_thisAgentUpdateArgs);
5814 }
5815 // Was there a significant camera(s) change?
5816 if (camera)
5817 if (handlerAgentCameraUpdate != null)
5818 handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs);
5819
5820 handlerAgentUpdate = null;
5821 handlerPreAgentUpdate = null;
5822 handlerAgentCameraUpdate = null;
5671 5823
5672 PacketPool.Instance.ReturnPacket(packet); 5824 PacketPool.Instance.ReturnPacket(packet);
5673 5825
@@ -6257,6 +6409,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6257 //m_log.Info("[LAND]: LAND:" + modify.ToString()); 6409 //m_log.Info("[LAND]: LAND:" + modify.ToString());
6258 if (modify.ParcelData.Length > 0) 6410 if (modify.ParcelData.Length > 0)
6259 { 6411 {
6412 // Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore,
6413 // a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit.
6414 m_justEditedTerrain = true; // Prevent terrain packet (Land layer) from being queued, make it unreliable
6260 if (OnModifyTerrain != null) 6415 if (OnModifyTerrain != null)
6261 { 6416 {
6262 for (int i = 0; i < modify.ParcelData.Length; i++) 6417 for (int i = 0; i < modify.ParcelData.Length; i++)
@@ -6272,6 +6427,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6272 } 6427 }
6273 } 6428 }
6274 } 6429 }
6430 m_justEditedTerrain = false; // Queue terrain packet (Land layer) if necessary, make it reliable again
6275 } 6431 }
6276 6432
6277 return true; 6433 return true;
@@ -6633,6 +6789,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6633 } 6789 }
6634 #endregion 6790 #endregion
6635 6791
6792 if (SceneAgent.IsChildAgent)
6793 {
6794 SendCantSitBecauseChildAgentResponse();
6795 return true;
6796 }
6797
6636 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; 6798 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit;
6637 6799
6638 if (handlerAgentRequestSit != null) 6800 if (handlerAgentRequestSit != null)
@@ -6657,6 +6819,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6657 } 6819 }
6658 #endregion 6820 #endregion
6659 6821
6822 if (SceneAgent.IsChildAgent)
6823 {
6824 SendCantSitBecauseChildAgentResponse();
6825 return true;
6826 }
6827
6660 AgentSit handlerAgentSit = OnAgentSit; 6828 AgentSit handlerAgentSit = OnAgentSit;
6661 if (handlerAgentSit != null) 6829 if (handlerAgentSit != null)
6662 { 6830 {
@@ -6666,6 +6834,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6666 return true; 6834 return true;
6667 } 6835 }
6668 6836
6837 /// <summary>
6838 /// Used when a child agent gets a sit response which should not be fulfilled.
6839 /// </summary>
6840 private void SendCantSitBecauseChildAgentResponse()
6841 {
6842 SendAlertMessage("Try moving closer. Can't sit on object because it is not in the same region as you.");
6843 }
6844
6669 private bool HandleSoundTrigger(IClientAPI sender, Packet Pack) 6845 private bool HandleSoundTrigger(IClientAPI sender, Packet Pack)
6670 { 6846 {
6671 SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack; 6847 SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack;
@@ -7876,129 +8052,145 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7876 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); 8052 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
7877 8053
7878 TransferRequestPacket transfer = (TransferRequestPacket)Pack; 8054 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
7879 //m_log.Debug("Transfer Request: " + transfer.ToString());
7880 // Validate inventory transfers
7881 // Has to be done here, because AssetCache can't do it
7882 //
7883 UUID taskID = UUID.Zero; 8055 UUID taskID = UUID.Zero;
7884 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) 8056 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
7885 { 8057 {
7886 taskID = new UUID(transfer.TransferInfo.Params, 48);
7887 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7888 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7889
7890// m_log.DebugFormat(
7891// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7892// requestID, itemID, taskID, Name);
7893
7894 if (!(((Scene)m_scene).Permissions.BypassPermissions())) 8058 if (!(((Scene)m_scene).Permissions.BypassPermissions()))
7895 { 8059 {
7896 if (taskID != UUID.Zero) // Prim 8060 // We're spawning a thread because the permissions check can block this thread
8061 Util.FireAndForget(delegate
7897 { 8062 {
7898 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); 8063 // This requests the asset if needed
8064 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
8065 });
8066 return true;
8067 }
8068 }
8069 else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
8070 {
8071 //TransferRequestPacket does not include covenant uuid?
8072 //get scene covenant uuid
8073 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
8074 }
7899 8075
7900 if (part == null) 8076 // This is non-blocking
7901 { 8077 MakeAssetRequest(transfer, taskID);
7902 m_log.WarnFormat(
7903 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7904 Name, requestID, itemID, taskID);
7905 return true;
7906 }
7907 8078
7908 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); 8079 return true;
7909 if (tii == null) 8080 }
7910 {
7911 m_log.WarnFormat(
7912 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7913 Name, requestID, itemID, taskID);
7914 return true;
7915 }
7916 8081
7917 if (tii.Type == (int)AssetType.LSLText) 8082 private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
7918 { 8083 {
7919 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId)) 8084 UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
7920 return true; 8085 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7921 } 8086 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7922 else if (tii.Type == (int)AssetType.Notecard)
7923 {
7924 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
7925 return true;
7926 }
7927 else
7928 {
7929 // TODO: Change this code to allow items other than notecards and scripts to be successfully
7930 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
7931 if (part.OwnerID != AgentId)
7932 {
7933 m_log.WarnFormat(
7934 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
7935 Name, requestID, itemID, taskID, part.OwnerID);
7936 return true;
7937 }
7938 8087
7939 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) 8088 //m_log.DebugFormat(
7940 { 8089 // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7941 m_log.WarnFormat( 8090 // requestID, itemID, taskID, Name);
7942 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7943 Name, requestID, itemID, taskID);
7944 return true;
7945 }
7946 8091
7947 if (tii.OwnerID != AgentId) 8092 //m_log.Debug("Transfer Request: " + transfer.ToString());
7948 { 8093 // Validate inventory transfers
7949 m_log.WarnFormat( 8094 // Has to be done here, because AssetCache can't do it
7950 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}", 8095 //
7951 Name, requestID, itemID, taskID, tii.OwnerID); 8096 if (taskID != UUID.Zero) // Prim
7952 return true; 8097 {
7953 } 8098 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
7954 8099
7955 if (( 8100 if (part == null)
7956 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8101 {
7957 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8102 m_log.WarnFormat(
7958 { 8103 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7959 m_log.WarnFormat( 8104 Name, requestID, itemID, taskID);
7960 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", 8105 return;
7961 Name, requestID, itemID, taskID); 8106 }
7962 return true;
7963 }
7964 8107
7965 if (tii.AssetID != requestID) 8108 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
7966 { 8109 if (tii == null)
7967 m_log.WarnFormat( 8110 {
7968 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", 8111 m_log.WarnFormat(
7969 Name, requestID, itemID, taskID, tii.AssetID); 8112 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7970 return true; 8113 Name, requestID, itemID, taskID);
7971 } 8114 return;
7972 } 8115 }
8116
8117 if (tii.Type == (int)AssetType.LSLText)
8118 {
8119 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
8120 return;
8121 }
8122 else if (tii.Type == (int)AssetType.Notecard)
8123 {
8124 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
8125 return;
8126 }
8127 else
8128 {
8129 // TODO: Change this code to allow items other than notecards and scripts to be successfully
8130 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
8131 if (part.OwnerID != AgentId)
8132 {
8133 m_log.WarnFormat(
8134 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
8135 Name, requestID, itemID, taskID, part.OwnerID);
8136 return;
7973 } 8137 }
7974 else // Agent 8138
8139 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
7975 { 8140 {
7976 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 8141 m_log.WarnFormat(
7977 if (invAccess != null) 8142 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7978 { 8143 Name, requestID, itemID, taskID);
7979 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) 8144 return;
7980 return false; 8145 }
7981 } 8146
7982 else 8147 if (tii.OwnerID != AgentId)
7983 { 8148 {
7984 return false; 8149 m_log.WarnFormat(
7985 } 8150 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
8151 Name, requestID, itemID, taskID, tii.OwnerID);
8152 return;
8153 }
8154
8155 if ((
8156 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8157 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8158 {
8159 m_log.WarnFormat(
8160 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
8161 Name, requestID, itemID, taskID);
8162 return;
8163 }
8164
8165 if (tii.AssetID != requestID)
8166 {
8167 m_log.WarnFormat(
8168 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
8169 Name, requestID, itemID, taskID, tii.AssetID);
8170 return;
7986 } 8171 }
7987 } 8172 }
7988 } 8173 }
7989 else 8174 else // Agent
7990 if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) 8175 {
8176 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
8177 if (invAccess != null)
8178 {
8179 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
8180 return;
8181 }
8182 else
7991 { 8183 {
7992 //TransferRequestPacket does not include covenant uuid? 8184 return;
7993 //get scene covenant uuid
7994 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
7995 } 8185 }
8186 }
7996 8187
8188 // Permissions out of the way, let's request the asset
7997 MakeAssetRequest(transfer, taskID); 8189 MakeAssetRequest(transfer, taskID);
7998 8190
7999 return true;
8000 } 8191 }
8001 8192
8193
8002 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack) 8194 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
8003 { 8195 {
8004 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; 8196 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
@@ -11729,8 +11921,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11729 } 11921 }
11730 11922
11731 /// <summary> 11923 /// <summary>
11732 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11733 /// its appearance texture cached.
11734 /// </summary> 11924 /// </summary>
11735 /// <remarks> 11925 /// <remarks>
11736 /// At the moment, we always reply that there is no cached texture. 11926 /// At the moment, we always reply that there is no cached texture.
@@ -11738,6 +11928,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11738 /// <param name="simclient"></param> 11928 /// <param name="simclient"></param>
11739 /// <param name="packet"></param> 11929 /// <param name="packet"></param>
11740 /// <returns></returns> 11930 /// <returns></returns>
11931 // TODO: Convert old handler to use new method
11932 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11933 {
11934 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11935
11936 if (cachedtex.AgentData.SessionID != SessionId)
11937 return false;
11938
11939
11940 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11941
11942 for (int i = 0; i < cachedtex.WearableData.Length; i++)
11943 {
11944 CachedTextureRequestArg arg = new CachedTextureRequestArg();
11945 arg.BakedTextureIndex = cachedtex.WearableData[i].TextureIndex;
11946 arg.WearableHashID = cachedtex.WearableData[i].ID;
11947
11948 requestArgs.Add(arg);
11949 }
11950
11951 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11952 if (handlerCachedTextureRequest != null)
11953 {
11954 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11955 }
11956
11957 return true;
11958 }*/
11959
11741 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11960 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11742 { 11961 {
11743 //m_log.Debug("texture cached: " + packet.ToString()); 11962 //m_log.Debug("texture cached: " + packet.ToString());
@@ -11896,6 +12115,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11896 return true; 12115 return true;
11897 } 12116 }
11898 12117
12118 /// <summary>
12119 /// Send a response back to a client when it asks the asset server (via the region server) if it has
12120 /// its appearance texture cached.
12121 /// </summary>
12122 /// <param name="avatar"></param>
12123 /// <param name="serial"></param>
12124 /// <param name="cachedTextures"></param>
12125 /// <returns></returns>
12126 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
12127 {
12128 ScenePresence presence = avatar as ScenePresence;
12129 if (presence == null)
12130 return;
12131
12132 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
12133
12134 // TODO: don't create new blocks if recycling an old packet
12135 cachedresp.AgentData.AgentID = m_agentId;
12136 cachedresp.AgentData.SessionID = m_sessionId;
12137 cachedresp.AgentData.SerialNum = serial;
12138 cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedTextures.Count];
12139
12140 for (int i = 0; i < cachedTextures.Count; i++)
12141 {
12142 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12143 cachedresp.WearableData[i].TextureIndex = (byte)cachedTextures[i].BakedTextureIndex;
12144 cachedresp.WearableData[i].TextureID = cachedTextures[i].BakedTextureID;
12145 cachedresp.WearableData[i].HostName = new byte[0];
12146 }
12147
12148 cachedresp.Header.Zerocoded = true;
12149 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12150 }
12151
11899 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) 12152 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
11900 { 12153 {
11901 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; 12154 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
@@ -11921,8 +12174,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11921 if (part == null) 12174 if (part == null)
11922 { 12175 {
11923 // It's a ghost! tell the client to delete it from view. 12176 // It's a ghost! tell the client to delete it from view.
11924 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 12177 simClient.SendKillObject(new List<uint> { localId });
11925 new List<uint> { localId });
11926 } 12178 }
11927 else 12179 else
11928 { 12180 {
@@ -12326,7 +12578,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12326 ClientInfo info = m_udpClient.GetClientInfo(); 12578 ClientInfo info = m_udpClient.GetClientInfo();
12327 12579
12328 info.proxyEP = null; 12580 info.proxyEP = null;
12329 info.agentcircuit = RequestClientInfo(); 12581 if (info.agentcircuit == null)
12582 info.agentcircuit = RequestClientInfo();
12330 12583
12331 return info; 12584 return info;
12332 } 12585 }
@@ -12709,11 +12962,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12709 OutPacket(dialog, ThrottleOutPacketType.Task); 12962 OutPacket(dialog, ThrottleOutPacketType.Task);
12710 } 12963 }
12711 12964
12712 public void StopFlying(ISceneEntity p) 12965 public void SendAgentTerseUpdate(ISceneEntity p)
12713 { 12966 {
12714 if (p is ScenePresence) 12967 if (p is ScenePresence)
12715 { 12968 {
12716 ScenePresence presence = p as ScenePresence;
12717 // It turns out to get the agent to stop flying, you have to feed it stop flying velocities 12969 // It turns out to get the agent to stop flying, you have to feed it stop flying velocities
12718 // There's no explicit message to send the client to tell it to stop flying.. it relies on the 12970 // There's no explicit message to send the client to tell it to stop flying.. it relies on the
12719 // velocity, collision plane and avatar height 12971 // velocity, collision plane and avatar height
@@ -12721,34 +12973,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12721 // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air 12973 // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air
12722 // when the avatar stands up 12974 // when the avatar stands up
12723 12975
12724 Vector3 pos = presence.AbsolutePosition;
12725
12726 if (presence.Appearance.AvatarHeight != 127.0f)
12727 pos += new Vector3(0f, 0f, (presence.Appearance.AvatarHeight/6f));
12728 else
12729 pos += new Vector3(0f, 0f, (1.56f/6f));
12730
12731 presence.AbsolutePosition = pos;
12732
12733 // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
12734 // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
12735 // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
12736 // certain amount.. because the LLClient wouldn't land in that situation anyway.
12737
12738 // why are we still testing for this really old height value default???
12739 if (presence.Appearance.AvatarHeight != 127.0f)
12740 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - presence.Appearance.AvatarHeight/6f);
12741 else
12742 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f/6f));
12743
12744
12745 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = 12976 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
12746 CreateImprovedTerseBlock(p, false); 12977 CreateImprovedTerseBlock(p, false);
12747 12978
12748 const float TIME_DILATION = 1.0f; 12979 const float TIME_DILATION = 1.0f;
12749 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 12980 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
12750 12981
12751
12752 ImprovedTerseObjectUpdatePacket packet 12982 ImprovedTerseObjectUpdatePacket packet
12753 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( 12983 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
12754 PacketType.ImprovedTerseObjectUpdate); 12984 PacketType.ImprovedTerseObjectUpdate);