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.cs582
1 files changed, 381 insertions, 201 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index eebb8ae..0e20e38 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;
@@ -367,7 +369,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 369 /// 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. 370 /// cannot retain a reference to it outside of that method.
369 /// </remarks> 371 /// </remarks>
370 private AgentUpdateArgs m_lastAgentUpdateArgs; 372 private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
371 373
372 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 374 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 375 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -504,6 +506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 m_udpServer = udpServer; 506 m_udpServer = udpServer;
505 m_udpClient = udpClient; 507 m_udpClient = udpClient;
506 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 508 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
509 m_udpClient.HasUpdates += HandleHasUpdates;
507 m_udpClient.OnPacketStats += PopulateStats; 510 m_udpClient.OnPacketStats += PopulateStats;
508 511
509 m_prioritizer = new Prioritizer(m_scene); 512 m_prioritizer = new Prioritizer(m_scene);
@@ -709,12 +712,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
709 //there is a local handler for this packet type 712 //there is a local handler for this packet type
710 if (pprocessor.Async) 713 if (pprocessor.Async)
711 { 714 {
715 ClientInfo cinfo = UDPClient.GetClientInfo();
716 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
717 cinfo.AsyncRequests[packet.Type.ToString()] = 0;
718 cinfo.AsyncRequests[packet.Type.ToString()]++;
719
712 object obj = new AsyncPacketProcess(this, pprocessor.method, packet); 720 object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
713 Util.FireAndForget(ProcessSpecificPacketAsync, obj); 721 Util.FireAndForget(ProcessSpecificPacketAsync, obj);
714 result = true; 722 result = true;
715 } 723 }
716 else 724 else
717 { 725 {
726 ClientInfo cinfo = UDPClient.GetClientInfo();
727 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
728 cinfo.SyncRequests[packet.Type.ToString()] = 0;
729 cinfo.SyncRequests[packet.Type.ToString()]++;
730
718 result = pprocessor.method(this, packet); 731 result = pprocessor.method(this, packet);
719 } 732 }
720 } 733 }
@@ -729,6 +742,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
729 } 742 }
730 if (found) 743 if (found)
731 { 744 {
745 ClientInfo cinfo = UDPClient.GetClientInfo();
746 if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString()))
747 cinfo.GenericRequests[packet.Type.ToString()] = 0;
748 cinfo.GenericRequests[packet.Type.ToString()]++;
749
732 result = method(this, packet); 750 result = method(this, packet);
733 } 751 }
734 } 752 }
@@ -820,12 +838,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
820 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 838 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
821 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 839 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
822 840
823 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0]; 841 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[1];
824// OutPacket(handshake, ThrottleOutPacketType.Task); 842 handshake.RegionInfo4[0] = new RegionHandshakePacket.RegionInfo4Block();
825 // use same as MoveAgentIntoRegion (both should be task ) 843 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
844 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
845
826 OutPacket(handshake, ThrottleOutPacketType.Unknown); 846 OutPacket(handshake, ThrottleOutPacketType.Unknown);
827 } 847 }
828 848
849
829 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 850 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
830 { 851 {
831 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); 852 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
@@ -1580,7 +1601,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1580 OutPacket(pc, ThrottleOutPacketType.Unknown); 1601 OutPacket(pc, ThrottleOutPacketType.Unknown);
1581 } 1602 }
1582 1603
1583 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1604 public void SendKillObject(List<uint> localIDs)
1584 { 1605 {
1585// foreach (uint id in localIDs) 1606// foreach (uint id in localIDs)
1586// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); 1607// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
@@ -3797,6 +3818,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3797 ResendPrimUpdate(update); 3818 ResendPrimUpdate(update);
3798 } 3819 }
3799 3820
3821// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3822// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3823// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3824// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3825//
3826// OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3827// OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3828// OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3829// OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3830
3831
3800 private void ProcessEntityUpdates(int maxUpdates) 3832 private void ProcessEntityUpdates(int maxUpdates)
3801 { 3833 {
3802 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3834 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3809,6 +3841,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3809 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3841 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>>(); 3842 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3811 3843
3844// objectUpdateBlocks.Value.Clear();
3845// compressedUpdateBlocks.Value.Clear();
3846// terseUpdateBlocks.Value.Clear();
3847// terseAgentUpdateBlocks.Value.Clear();
3848// objectUpdates.Value.Clear();
3849// compressedUpdates.Value.Clear();
3850// terseUpdates.Value.Clear();
3851// terseAgentUpdates.Value.Clear();
3852
3812 // Check to see if this is a flush 3853 // Check to see if this is a flush
3813 if (maxUpdates <= 0) 3854 if (maxUpdates <= 0)
3814 { 3855 {
@@ -4125,8 +4166,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4125 4166
4126 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 4167 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
4127 { 4168 {
4169// if (!m_udpServer.IsRunningOutbound)
4170// return;
4171
4128 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 4172 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4129 { 4173 {
4174// if (!m_udpServer.IsRunningOutbound)
4175// return;
4176
4130 if (m_maxUpdates == 0 || m_LastQueueFill == 0) 4177 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
4131 { 4178 {
4132 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; 4179 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
@@ -4152,6 +4199,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4152 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); 4199 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
4153 } 4200 }
4154 4201
4202 internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
4203 {
4204 bool hasUpdates = false;
4205
4206 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4207 {
4208 if (m_entityUpdates.Count > 0)
4209 hasUpdates = true;
4210 else if (m_entityProps.Count > 0)
4211 hasUpdates = true;
4212 }
4213
4214 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
4215 {
4216 if (ImageManager.HasUpdates())
4217 hasUpdates = true;
4218 }
4219
4220 return hasUpdates;
4221 }
4222
4155 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 4223 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
4156 { 4224 {
4157 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 4225 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
@@ -4862,7 +4930,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4862 4930
4863 public void SendForceClientSelectObjects(List<uint> ObjectIDs) 4931 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
4864 { 4932 {
4865 m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); 4933// m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
4866 4934
4867 bool firstCall = true; 4935 bool firstCall = true;
4868 const int MAX_OBJECTS_PER_PACKET = 251; 4936 const int MAX_OBJECTS_PER_PACKET = 251;
@@ -5019,7 +5087,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5019 SceneObjectPart part = (SceneObjectPart)entity; 5087 SceneObjectPart part = (SceneObjectPart)entity;
5020 5088
5021 attachPoint = part.ParentGroup.AttachmentPoint; 5089 attachPoint = part.ParentGroup.AttachmentPoint;
5022 5090 attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
5023// m_log.DebugFormat( 5091// m_log.DebugFormat(
5024// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", 5092// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
5025// attachPoint, part.Name, part.LocalId, Name); 5093// attachPoint, part.Name, part.LocalId, Name);
@@ -5047,7 +5115,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5047 pos += 4; 5115 pos += 4;
5048 5116
5049 // Avatar/CollisionPlane 5117 // Avatar/CollisionPlane
5050 data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ; 5118 data[pos++] = (byte) attachPoint;
5051 if (avatar) 5119 if (avatar)
5052 { 5120 {
5053 data[pos++] = 1; 5121 data[pos++] = 1;
@@ -5372,7 +5440,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5372 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); 5440 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
5373 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); 5441 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
5374 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); 5442 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
5375 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply); 5443 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
5376 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); 5444 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
5377 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); 5445 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
5378 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing); 5446 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
@@ -5433,8 +5501,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5433 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false); 5501 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
5434 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); 5502 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
5435 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); 5503 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
5436 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage); 5504 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
5437 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); 5505 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
5438 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); 5506 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
5439 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); 5507 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
5440 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket); 5508 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
@@ -5466,7 +5534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5466 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); 5534 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5467 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); 5535 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
5468 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); 5536 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
5469 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); 5537 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
5470 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); 5538 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
5471 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); 5539 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
5472 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false); 5540 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
@@ -5579,83 +5647,137 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5579 5647
5580 #region Packet Handlers 5648 #region Packet Handlers
5581 5649
5650 public int TotalAgentUpdates { get; set; }
5651
5582 #region Scene/Avatar 5652 #region Scene/Avatar
5583 5653
5584 private bool HandleAgentUpdate(IClientAPI sener, Packet packet) 5654 // Threshold for body rotation to be a significant agent update
5655 private const float QDELTA = 0.000001f;
5656 // Threshold for camera rotation to be a significant agent update
5657 private const float VDELTA = 0.01f;
5658
5659 /// <summary>
5660 /// This checks the update significance against the last update made.
5661 /// </summary>
5662 /// <remarks>Can only be called by one thread at a time</remarks>
5663 /// <returns></returns>
5664 /// <param name='x'></param>
5665 public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5585 { 5666 {
5586 if (OnAgentUpdate != null) 5667 return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
5587 { 5668 }
5588 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5589 5669
5590 #region Packet Session and User Check 5670 /// <summary>
5591 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId) 5671 /// This checks the movement/state update significance against the last update made.
5592 { 5672 /// </summary>
5593 PacketPool.Instance.ReturnPacket(packet); 5673 /// <remarks>Can only be called by one thread at a time</remarks>
5594 return false; 5674 /// <returns></returns>
5595 } 5675 /// <param name='x'></param>
5596 #endregion 5676 private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5677 {
5678 float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
5679 //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
5680
5681 bool movementSignificant =
5682 (qdelta1 > QDELTA) // significant if body rotation above threshold
5683 // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
5684 // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold
5685 || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
5686 || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands
5687 || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed
5688 || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
5689 || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
5690 ;
5691 //if (movementSignificant)
5692 //{
5693 //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}",
5694 // qdelta1, qdelta2);
5695 //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}",
5696 // x.ControlFlags, x.Flags, x.Far, x.State);
5697 //}
5698 return movementSignificant;
5699 }
5597 5700
5598 bool update = false; 5701 /// <summary>
5599 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; 5702 /// This checks the camera update significance against the last update made.
5600 5703 /// </summary>
5601 if (m_lastAgentUpdateArgs != null) 5704 /// <remarks>Can only be called by one thread at a time</remarks>
5602 { 5705 /// <returns></returns>
5603 // These should be ordered from most-likely to 5706 /// <param name='x'></param>
5604 // least likely to change. I've made an initial 5707 private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5605 // guess at that. 5708 {
5606 update = 5709 float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
5607 ( 5710 float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
5608 (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || 5711 float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
5609 (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || 5712 float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
5610 (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
5611 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5612 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5613 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5614 (x.ControlFlags != 0) ||
5615 (x.Far != m_lastAgentUpdateArgs.Far) ||
5616 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5617 (x.State != m_lastAgentUpdateArgs.State) ||
5618 (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
5619 (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
5620 (x.AgentID != m_lastAgentUpdateArgs.AgentID)
5621 );
5622 }
5623 else
5624 {
5625 m_lastAgentUpdateArgs = new AgentUpdateArgs();
5626 update = true;
5627 }
5628 5713
5629 if (update) 5714 bool cameraSignificant =
5630 { 5715 (vdelta1 > VDELTA) ||
5631// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); 5716 (vdelta2 > VDELTA) ||
5717 (vdelta3 > VDELTA) ||
5718 (vdelta4 > VDELTA)
5719 ;
5632 5720
5633 m_lastAgentUpdateArgs.AgentID = x.AgentID; 5721 //if (cameraSignificant)
5634 m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; 5722 //{
5635 m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; 5723 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
5636 m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; 5724 // x.CameraAtAxis, x.CameraCenter);
5637 m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; 5725 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
5638 m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; 5726 // x.CameraLeftAxis, x.CameraUpAxis);
5639 m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; 5727 //}
5640 m_lastAgentUpdateArgs.Far = x.Far;
5641 m_lastAgentUpdateArgs.Flags = x.Flags;
5642 m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
5643 m_lastAgentUpdateArgs.SessionID = x.SessionID;
5644 m_lastAgentUpdateArgs.State = x.State;
5645 5728
5646 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 5729 return cameraSignificant;
5647 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; 5730 }
5648 5731
5649 if (handlerPreAgentUpdate != null) 5732 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5650 OnPreAgentUpdate(this, m_lastAgentUpdateArgs); 5733 {
5734 // We got here, which means that something in agent update was significant
5651 5735
5652 if (handlerAgentUpdate != null) 5736 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5653 OnAgentUpdate(this, m_lastAgentUpdateArgs); 5737 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5654 5738
5655 handlerAgentUpdate = null; 5739 if (x.AgentID != AgentId || x.SessionID != SessionId)
5656 handlerPreAgentUpdate = null; 5740 return false;
5657 } 5741
5658 } 5742 // Before we update the current m_thisAgentUpdateArgs, let's check this again
5743 // to see what exactly changed
5744 bool movement = CheckAgentMovementUpdateSignificance(x);
5745 bool camera = CheckAgentCameraUpdateSignificance(x);
5746
5747 m_thisAgentUpdateArgs.AgentID = x.AgentID;
5748 m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation;
5749 m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
5750 m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter;
5751 m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
5752 m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
5753 m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags;
5754 m_thisAgentUpdateArgs.Far = x.Far;
5755 m_thisAgentUpdateArgs.Flags = x.Flags;
5756 m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
5757 m_thisAgentUpdateArgs.SessionID = x.SessionID;
5758 m_thisAgentUpdateArgs.State = x.State;
5759
5760 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
5761 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
5762 UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
5763
5764 // Was there a significant movement/state change?
5765 if (movement)
5766 {
5767 if (handlerPreAgentUpdate != null)
5768 OnPreAgentUpdate(this, m_thisAgentUpdateArgs);
5769
5770 if (handlerAgentUpdate != null)
5771 OnAgentUpdate(this, m_thisAgentUpdateArgs);
5772 }
5773 // Was there a significant camera(s) change?
5774 if (camera)
5775 if (handlerAgentCameraUpdate != null)
5776 handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs);
5777
5778 handlerAgentUpdate = null;
5779 handlerPreAgentUpdate = null;
5780 handlerAgentCameraUpdate = null;
5659 5781
5660 PacketPool.Instance.ReturnPacket(packet); 5782 PacketPool.Instance.ReturnPacket(packet);
5661 5783
@@ -7864,129 +7986,145 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7864 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); 7986 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
7865 7987
7866 TransferRequestPacket transfer = (TransferRequestPacket)Pack; 7988 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
7867 //m_log.Debug("Transfer Request: " + transfer.ToString());
7868 // Validate inventory transfers
7869 // Has to be done here, because AssetCache can't do it
7870 //
7871 UUID taskID = UUID.Zero; 7989 UUID taskID = UUID.Zero;
7872 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) 7990 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
7873 { 7991 {
7874 taskID = new UUID(transfer.TransferInfo.Params, 48);
7875 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7876 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7877
7878// m_log.DebugFormat(
7879// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7880// requestID, itemID, taskID, Name);
7881
7882 if (!(((Scene)m_scene).Permissions.BypassPermissions())) 7992 if (!(((Scene)m_scene).Permissions.BypassPermissions()))
7883 { 7993 {
7884 if (taskID != UUID.Zero) // Prim 7994 // We're spawning a thread because the permissions check can block this thread
7995 Util.FireAndForget(delegate
7885 { 7996 {
7886 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); 7997 // This requests the asset if needed
7998 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
7999 });
8000 return true;
8001 }
8002 }
8003 else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
8004 {
8005 //TransferRequestPacket does not include covenant uuid?
8006 //get scene covenant uuid
8007 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
8008 }
7887 8009
7888 if (part == null) 8010 // This is non-blocking
7889 { 8011 MakeAssetRequest(transfer, taskID);
7890 m_log.WarnFormat(
7891 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7892 Name, requestID, itemID, taskID);
7893 return true;
7894 }
7895 8012
7896 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); 8013 return true;
7897 if (tii == null) 8014 }
7898 {
7899 m_log.WarnFormat(
7900 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7901 Name, requestID, itemID, taskID);
7902 return true;
7903 }
7904 8015
7905 if (tii.Type == (int)AssetType.LSLText) 8016 private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
7906 { 8017 {
7907 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId)) 8018 UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
7908 return true; 8019 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7909 } 8020 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7910 else if (tii.Type == (int)AssetType.Notecard)
7911 {
7912 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
7913 return true;
7914 }
7915 else
7916 {
7917 // TODO: Change this code to allow items other than notecards and scripts to be successfully
7918 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
7919 if (part.OwnerID != AgentId)
7920 {
7921 m_log.WarnFormat(
7922 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
7923 Name, requestID, itemID, taskID, part.OwnerID);
7924 return true;
7925 }
7926 8021
7927 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) 8022 //m_log.DebugFormat(
7928 { 8023 // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7929 m_log.WarnFormat( 8024 // requestID, itemID, taskID, Name);
7930 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7931 Name, requestID, itemID, taskID);
7932 return true;
7933 }
7934 8025
7935 if (tii.OwnerID != AgentId) 8026 //m_log.Debug("Transfer Request: " + transfer.ToString());
7936 { 8027 // Validate inventory transfers
7937 m_log.WarnFormat( 8028 // Has to be done here, because AssetCache can't do it
7938 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}", 8029 //
7939 Name, requestID, itemID, taskID, tii.OwnerID); 8030 if (taskID != UUID.Zero) // Prim
7940 return true; 8031 {
7941 } 8032 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
7942 8033
7943 if (( 8034 if (part == null)
7944 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8035 {
7945 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8036 m_log.WarnFormat(
7946 { 8037 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7947 m_log.WarnFormat( 8038 Name, requestID, itemID, taskID);
7948 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", 8039 return;
7949 Name, requestID, itemID, taskID); 8040 }
7950 return true;
7951 }
7952 8041
7953 if (tii.AssetID != requestID) 8042 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
7954 { 8043 if (tii == null)
7955 m_log.WarnFormat( 8044 {
7956 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", 8045 m_log.WarnFormat(
7957 Name, requestID, itemID, taskID, tii.AssetID); 8046 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7958 return true; 8047 Name, requestID, itemID, taskID);
7959 } 8048 return;
7960 } 8049 }
8050
8051 if (tii.Type == (int)AssetType.LSLText)
8052 {
8053 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
8054 return;
8055 }
8056 else if (tii.Type == (int)AssetType.Notecard)
8057 {
8058 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
8059 return;
8060 }
8061 else
8062 {
8063 // TODO: Change this code to allow items other than notecards and scripts to be successfully
8064 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
8065 if (part.OwnerID != AgentId)
8066 {
8067 m_log.WarnFormat(
8068 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
8069 Name, requestID, itemID, taskID, part.OwnerID);
8070 return;
7961 } 8071 }
7962 else // Agent 8072
8073 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
7963 { 8074 {
7964 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 8075 m_log.WarnFormat(
7965 if (invAccess != null) 8076 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7966 { 8077 Name, requestID, itemID, taskID);
7967 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) 8078 return;
7968 return false; 8079 }
7969 } 8080
7970 else 8081 if (tii.OwnerID != AgentId)
7971 { 8082 {
7972 return false; 8083 m_log.WarnFormat(
7973 } 8084 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
8085 Name, requestID, itemID, taskID, tii.OwnerID);
8086 return;
8087 }
8088
8089 if ((
8090 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8091 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8092 {
8093 m_log.WarnFormat(
8094 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
8095 Name, requestID, itemID, taskID);
8096 return;
8097 }
8098
8099 if (tii.AssetID != requestID)
8100 {
8101 m_log.WarnFormat(
8102 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
8103 Name, requestID, itemID, taskID, tii.AssetID);
8104 return;
7974 } 8105 }
7975 } 8106 }
7976 } 8107 }
7977 else 8108 else // Agent
7978 if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) 8109 {
8110 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
8111 if (invAccess != null)
7979 { 8112 {
7980 //TransferRequestPacket does not include covenant uuid? 8113 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
7981 //get scene covenant uuid 8114 return;
7982 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
7983 } 8115 }
8116 else
8117 {
8118 return;
8119 }
8120 }
7984 8121
8122 // Permissions out of the way, let's request the asset
7985 MakeAssetRequest(transfer, taskID); 8123 MakeAssetRequest(transfer, taskID);
7986 8124
7987 return true;
7988 } 8125 }
7989 8126
8127
7990 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack) 8128 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
7991 { 8129 {
7992 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; 8130 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
@@ -11717,8 +11855,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11717 } 11855 }
11718 11856
11719 /// <summary> 11857 /// <summary>
11720 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11721 /// its appearance texture cached.
11722 /// </summary> 11858 /// </summary>
11723 /// <remarks> 11859 /// <remarks>
11724 /// At the moment, we always reply that there is no cached texture. 11860 /// At the moment, we always reply that there is no cached texture.
@@ -11726,6 +11862,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11726 /// <param name="simclient"></param> 11862 /// <param name="simclient"></param>
11727 /// <param name="packet"></param> 11863 /// <param name="packet"></param>
11728 /// <returns></returns> 11864 /// <returns></returns>
11865 // TODO: Convert old handler to use new method
11866 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11867 {
11868 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11869
11870 if (cachedtex.AgentData.SessionID != SessionId)
11871 return false;
11872
11873
11874 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11875
11876 for (int i = 0; i < cachedtex.WearableData.Length; i++)
11877 {
11878 CachedTextureRequestArg arg = new CachedTextureRequestArg();
11879 arg.BakedTextureIndex = cachedtex.WearableData[i].TextureIndex;
11880 arg.WearableHashID = cachedtex.WearableData[i].ID;
11881
11882 requestArgs.Add(arg);
11883 }
11884
11885 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11886 if (handlerCachedTextureRequest != null)
11887 {
11888 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11889 }
11890
11891 return true;
11892 }*/
11893
11729 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11894 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11730 { 11895 {
11731 //m_log.Debug("texture cached: " + packet.ToString()); 11896 //m_log.Debug("texture cached: " + packet.ToString());
@@ -11884,6 +12049,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11884 return true; 12049 return true;
11885 } 12050 }
11886 12051
12052 /// <summary>
12053 /// Send a response back to a client when it asks the asset server (via the region server) if it has
12054 /// its appearance texture cached.
12055 /// </summary>
12056 /// <param name="avatar"></param>
12057 /// <param name="serial"></param>
12058 /// <param name="cachedTextures"></param>
12059 /// <returns></returns>
12060 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
12061 {
12062 ScenePresence presence = avatar as ScenePresence;
12063 if (presence == null)
12064 return;
12065
12066 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
12067
12068 // TODO: don't create new blocks if recycling an old packet
12069 cachedresp.AgentData.AgentID = m_agentId;
12070 cachedresp.AgentData.SessionID = m_sessionId;
12071 cachedresp.AgentData.SerialNum = serial;
12072 cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedTextures.Count];
12073
12074 for (int i = 0; i < cachedTextures.Count; i++)
12075 {
12076 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12077 cachedresp.WearableData[i].TextureIndex = (byte)cachedTextures[i].BakedTextureIndex;
12078 cachedresp.WearableData[i].TextureID = cachedTextures[i].BakedTextureID;
12079 cachedresp.WearableData[i].HostName = new byte[0];
12080 }
12081
12082 cachedresp.Header.Zerocoded = true;
12083 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12084 }
12085
11887 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) 12086 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
11888 { 12087 {
11889 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; 12088 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
@@ -11909,8 +12108,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11909 if (part == null) 12108 if (part == null)
11910 { 12109 {
11911 // It's a ghost! tell the client to delete it from view. 12110 // It's a ghost! tell the client to delete it from view.
11912 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 12111 simClient.SendKillObject(new List<uint> { localId });
11913 new List<uint> { localId });
11914 } 12112 }
11915 else 12113 else
11916 { 12114 {
@@ -12314,7 +12512,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12314 ClientInfo info = m_udpClient.GetClientInfo(); 12512 ClientInfo info = m_udpClient.GetClientInfo();
12315 12513
12316 info.proxyEP = null; 12514 info.proxyEP = null;
12317 info.agentcircuit = RequestClientInfo(); 12515 if (info.agentcircuit == null)
12516 info.agentcircuit = RequestClientInfo();
12318 12517
12319 return info; 12518 return info;
12320 } 12519 }
@@ -12697,7 +12896,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12697 OutPacket(dialog, ThrottleOutPacketType.Task); 12896 OutPacket(dialog, ThrottleOutPacketType.Task);
12698 } 12897 }
12699 12898
12700 public void StopFlying(ISceneEntity p) 12899 public void SendAgentTerseUpdate(ISceneEntity p)
12701 { 12900 {
12702 if (p is ScenePresence) 12901 if (p is ScenePresence)
12703 { 12902 {
@@ -12711,25 +12910,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12711 12910
12712 Vector3 pos = presence.AbsolutePosition; 12911 Vector3 pos = presence.AbsolutePosition;
12713 12912
12714 if (presence.Appearance.AvatarHeight != 127.0f)
12715 pos += new Vector3(0f, 0f, (presence.Appearance.AvatarHeight/6f));
12716 else
12717 pos += new Vector3(0f, 0f, (1.56f/6f));
12718
12719 presence.AbsolutePosition = pos;
12720
12721 // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
12722 // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
12723 // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
12724 // certain amount.. because the LLClient wouldn't land in that situation anyway.
12725
12726 // why are we still testing for this really old height value default???
12727 if (presence.Appearance.AvatarHeight != 127.0f)
12728 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - presence.Appearance.AvatarHeight/6f);
12729 else
12730 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f/6f));
12731
12732
12733 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = 12913 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
12734 CreateImprovedTerseBlock(p, false); 12914 CreateImprovedTerseBlock(p, false);
12735 12915