aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1423
1 files changed, 1055 insertions, 368 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 967fa44..b17b822 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -34,11 +34,13 @@ using System.Text;
34using System.Threading; 34using System.Threading;
35using System.Timers; 35using System.Timers;
36using System.Xml; 36using System.Xml;
37
37using log4net; 38using log4net;
38using OpenMetaverse; 39using OpenMetaverse;
39using OpenMetaverse.Packets; 40using OpenMetaverse.Packets;
40using OpenMetaverse.Messages.Linden; 41using OpenMetaverse.Messages.Linden;
41using OpenMetaverse.StructuredData; 42using OpenMetaverse.StructuredData;
43
42using OpenSim.Framework; 44using OpenSim.Framework;
43using OpenSim.Framework.Client; 45using OpenSim.Framework.Client;
44using OpenSim.Framework.Monitoring; 46using OpenSim.Framework.Monitoring;
@@ -48,9 +50,9 @@ using OpenSim.Services.Interfaces;
48using Timer = System.Timers.Timer; 50using Timer = System.Timers.Timer;
49using AssetLandmark = OpenSim.Framework.AssetLandmark; 51using AssetLandmark = OpenSim.Framework.AssetLandmark;
50using RegionFlags = OpenMetaverse.RegionFlags; 52using RegionFlags = OpenMetaverse.RegionFlags;
51using Nini.Config;
52 53
53using System.IO; 54using System.IO;
55using PermissionMask = OpenSim.Framework.PermissionMask;
54 56
55namespace OpenSim.Region.ClientStack.LindenUDP 57namespace OpenSim.Region.ClientStack.LindenUDP
56{ 58{
@@ -69,7 +71,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
69 71
70 #region Events 72 #region Events
71 73
72 public event GenericMessage OnGenericMessage;
73 public event BinaryGenericMessage OnBinaryGenericMessage; 74 public event BinaryGenericMessage OnBinaryGenericMessage;
74 public event Action<IClientAPI> OnLogout; 75 public event Action<IClientAPI> OnLogout;
75 public event ObjectPermissions OnObjectPermissions; 76 public event ObjectPermissions OnObjectPermissions;
@@ -77,7 +78,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
77 public event ViewerEffectEventHandler OnViewerEffect; 78 public event ViewerEffectEventHandler OnViewerEffect;
78 public event ImprovedInstantMessage OnInstantMessage; 79 public event ImprovedInstantMessage OnInstantMessage;
79 public event ChatMessage OnChatFromClient; 80 public event ChatMessage OnChatFromClient;
80 public event TextureRequest OnRequestTexture;
81 public event RezObject OnRezObject; 81 public event RezObject OnRezObject;
82 public event DeRezObject OnDeRezObject; 82 public event DeRezObject OnDeRezObject;
83 public event ModifyTerrain OnModifyTerrain; 83 public event ModifyTerrain OnModifyTerrain;
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
94 public event Action<IClientAPI, bool> OnCompleteMovementToRegion; 94 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
95 public event UpdateAgent OnPreAgentUpdate; 95 public event UpdateAgent OnPreAgentUpdate;
96 public event UpdateAgent OnAgentUpdate; 96 public event UpdateAgent OnAgentUpdate;
97 public event UpdateAgent OnAgentCameraUpdate;
97 public event AgentRequestSit OnAgentRequestSit; 98 public event AgentRequestSit OnAgentRequestSit;
98 public event AgentSit OnAgentSit; 99 public event AgentSit OnAgentSit;
99 public event AvatarPickerRequest OnAvatarPickerRequest; 100 public event AvatarPickerRequest OnAvatarPickerRequest;
@@ -134,15 +135,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
134 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; 135 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
135 public event UpdateVector OnUpdatePrimScale; 136 public event UpdateVector OnUpdatePrimScale;
136 public event UpdateVector OnUpdatePrimGroupScale; 137 public event UpdateVector OnUpdatePrimGroupScale;
137 public event StatusChange OnChildAgentStatus;
138 public event GenericCall2 OnStopMovement;
139 public event Action<UUID> OnRemoveAvatar;
140 public event RequestMapBlocks OnRequestMapBlocks; 138 public event RequestMapBlocks OnRequestMapBlocks;
141 public event RequestMapName OnMapNameRequest; 139 public event RequestMapName OnMapNameRequest;
142 public event TeleportLocationRequest OnTeleportLocationRequest; 140 public event TeleportLocationRequest OnTeleportLocationRequest;
143 public event TeleportLandmarkRequest OnTeleportLandmarkRequest; 141 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
144 public event TeleportCancel OnTeleportCancel; 142 public event TeleportCancel OnTeleportCancel;
145 public event DisconnectUser OnDisconnectUser;
146 public event RequestAvatarProperties OnRequestAvatarProperties; 143 public event RequestAvatarProperties OnRequestAvatarProperties;
147 public event SetAlwaysRun OnSetAlwaysRun; 144 public event SetAlwaysRun OnSetAlwaysRun;
148 public event FetchInventory OnAgentDataUpdateRequest; 145 public event FetchInventory OnAgentDataUpdateRequest;
@@ -172,7 +169,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
172 public event UpdateTaskInventory OnUpdateTaskInventory; 169 public event UpdateTaskInventory OnUpdateTaskInventory;
173 public event MoveTaskInventory OnMoveTaskItem; 170 public event MoveTaskInventory OnMoveTaskItem;
174 public event RemoveTaskInventory OnRemoveTaskItem; 171 public event RemoveTaskInventory OnRemoveTaskItem;
175 public event RequestAsset OnRequestAsset;
176 public event UUIDNameRequest OnNameFromUUIDRequest; 172 public event UUIDNameRequest OnNameFromUUIDRequest;
177 public event ParcelAccessListRequest OnParcelAccessListRequest; 173 public event ParcelAccessListRequest OnParcelAccessListRequest;
178 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest; 174 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
@@ -203,7 +199,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
203 public event RequestPayPrice OnRequestPayPrice; 199 public event RequestPayPrice OnRequestPayPrice;
204 public event ObjectSaleInfo OnObjectSaleInfo; 200 public event ObjectSaleInfo OnObjectSaleInfo;
205 public event ObjectBuy OnObjectBuy; 201 public event ObjectBuy OnObjectBuy;
206 public event BuyObjectInventory OnBuyObjectInventory;
207 public event AgentSit OnUndo; 202 public event AgentSit OnUndo;
208 public event AgentSit OnRedo; 203 public event AgentSit OnRedo;
209 public event LandUndo OnLandUndo; 204 public event LandUndo OnLandUndo;
@@ -212,7 +207,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
212 public event RequestObjectPropertiesFamily OnObjectGroupRequest; 207 public event RequestObjectPropertiesFamily OnObjectGroupRequest;
213 public event DetailedEstateDataRequest OnDetailedEstateDataRequest; 208 public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
214 public event SetEstateFlagsRequest OnSetEstateFlagsRequest; 209 public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
215 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
216 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture; 210 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
217 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights; 211 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
218 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest; 212 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
@@ -235,7 +229,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
235 public event GetScriptRunning OnGetScriptRunning; 229 public event GetScriptRunning OnGetScriptRunning;
236 public event SetScriptRunning OnSetScriptRunning; 230 public event SetScriptRunning OnSetScriptRunning;
237 public event Action<Vector3, bool, bool> OnAutoPilotGo; 231 public event Action<Vector3, bool, bool> OnAutoPilotGo;
238 public event TerrainUnacked OnUnackedTerrain;
239 public event ActivateGesture OnActivateGesture; 232 public event ActivateGesture OnActivateGesture;
240 public event DeactivateGesture OnDeactivateGesture; 233 public event DeactivateGesture OnDeactivateGesture;
241 public event ObjectOwner OnObjectOwner; 234 public event ObjectOwner OnObjectOwner;
@@ -293,6 +286,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
293 public event GodlikeMessage onGodlikeMessage; 286 public event GodlikeMessage onGodlikeMessage;
294 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 287 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
295 288
289#pragma warning disable 0067
290 public event GenericMessage OnGenericMessage;
291 public event TextureRequest OnRequestTexture;
292 public event StatusChange OnChildAgentStatus;
293 public event GenericCall2 OnStopMovement;
294 public event Action<UUID> OnRemoveAvatar;
295 public event DisconnectUser OnDisconnectUser;
296 public event RequestAsset OnRequestAsset;
297 public event BuyObjectInventory OnBuyObjectInventory;
298 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
299 public event TerrainUnacked OnUnackedTerrain;
300 public event CachedTextureRequest OnCachedTextureRequest;
301#pragma warning restore 0067
302
296 #endregion Events 303 #endregion Events
297 304
298 #region Class Members 305 #region Class Members
@@ -304,6 +311,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
304 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; 311 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f;
305 312
306 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 313 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
314 private static string LogHeader = "[LLCLIENTVIEW]";
307 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients 315 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
308 316
309 /// <summary> 317 /// <summary>
@@ -325,7 +333,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 private PriorityQueue m_entityProps; 333 private PriorityQueue m_entityProps;
326 private Prioritizer m_prioritizer; 334 private Prioritizer m_prioritizer;
327 private bool m_disableFacelights = false; 335 private bool m_disableFacelights = false;
328 336 private volatile bool m_justEditedTerrain = false;
329 /// <value> 337 /// <value>
330 /// List used in construction of data blocks for an object update packet. This is to stop us having to 338 /// List used in construction of data blocks for an object update packet. This is to stop us having to
331 /// continually recreate it. 339 /// continually recreate it.
@@ -344,7 +352,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
344 352
345// protected HashSet<uint> m_attachmentsSent; 353// protected HashSet<uint> m_attachmentsSent;
346 354
347 private int m_moneyBalance;
348 private int m_animationSequenceNumber = 1; 355 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 356 private bool m_SendLogoutPacketWhenClosing = true;
350 357
@@ -357,7 +364,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
357 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods 364 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
358 /// cannot retain a reference to it outside of that method. 365 /// cannot retain a reference to it outside of that method.
359 /// </remarks> 366 /// </remarks>
360 private AgentUpdateArgs m_lastAgentUpdateArgs; 367 private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
361 368
362 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 369 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
363 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 370 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -393,9 +400,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
393 } 400 }
394 public UUID AgentId { get { return m_agentId; } } 401 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 402 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 403 public UUID ActiveGroupId { get { return m_activeGroupID; } private set { m_activeGroupID = value; } }
397 public string ActiveGroupName { get { return m_activeGroupName; } } 404 public string ActiveGroupName { get { return m_activeGroupName; } private set { m_activeGroupName = value; } }
398 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } 405 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } private set { m_activeGroupPowers = value; } }
399 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } 406 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
400 407
401 /// <summary> 408 /// <summary>
@@ -419,7 +426,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
419 public string Name { get { return FirstName + " " + LastName; } } 426 public string Name { get { return FirstName + " " + LastName; } }
420 427
421 public uint CircuitCode { get { return m_circuitCode; } } 428 public uint CircuitCode { get { return m_circuitCode; } }
422 public int MoneyBalance { get { return m_moneyBalance; } }
423 public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } 429 public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
424 430
425 /// <summary> 431 /// <summary>
@@ -447,7 +453,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
447 453
448// ~LLClientView() 454// ~LLClientView()
449// { 455// {
450// m_log.DebugFormat("[LLCLIENTVIEW]: Destructor called for {0}, circuit code {1}", Name, CircuitCode); 456// m_log.DebugFormat("{0} Destructor called for {1}, circuit code {2}", LogHeader, Name, CircuitCode);
451// } 457// }
452 458
453 /// <summary> 459 /// <summary>
@@ -482,11 +488,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
482 m_firstName = sessionInfo.LoginInfo.First; 488 m_firstName = sessionInfo.LoginInfo.First;
483 m_lastName = sessionInfo.LoginInfo.Last; 489 m_lastName = sessionInfo.LoginInfo.Last;
484 m_startpos = sessionInfo.LoginInfo.StartPos; 490 m_startpos = sessionInfo.LoginInfo.StartPos;
485 m_moneyBalance = 1000;
486 491
487 m_udpServer = udpServer; 492 m_udpServer = udpServer;
488 m_udpClient = udpClient; 493 m_udpClient = udpClient;
489 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 494 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
495 m_udpClient.HasUpdates += HandleHasUpdates;
490 m_udpClient.OnPacketStats += PopulateStats; 496 m_udpClient.OnPacketStats += PopulateStats;
491 497
492 m_prioritizer = new Prioritizer(m_scene); 498 m_prioritizer = new Prioritizer(m_scene);
@@ -512,7 +518,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
512 // We still perform a force close inside the sync lock since this is intended to attempt close where 518 // We still perform a force close inside the sync lock since this is intended to attempt close where
513 // there is some unidentified connection problem, not where we have issues due to deadlock 519 // there is some unidentified connection problem, not where we have issues due to deadlock
514 if (!IsActive && !force) 520 if (!IsActive && !force)
521 {
522 m_log.DebugFormat( "{0} Not attempting to close inactive client {1} in {2} since force flag is not set",
523 LogHeader, Name, m_scene.Name);
524
515 return; 525 return;
526 }
516 527
517 IsActive = false; 528 IsActive = false;
518 CloseWithoutChecks(); 529 CloseWithoutChecks();
@@ -637,12 +648,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
637 /// <returns>true if the handler was added. This is currently always the case.</returns> 648 /// <returns>true if the handler was added. This is currently always the case.</returns>
638 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) 649 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
639 { 650 {
651 return AddLocalPacketHandler(packetType, handler, doAsync, false);
652 }
653
654 /// <summary>
655 /// Add a handler for the given packet type.
656 /// </summary>
657 /// <param name="packetType"></param>
658 /// <param name="handler"></param>
659 /// <param name="doAsync">
660 /// If true, when the packet is received handle it on a different thread. Whether this is given direct to
661 /// a threadpool thread or placed in a queue depends on the inEngine parameter.
662 /// </param>
663 /// <param name="inEngine">
664 /// If async is false then this parameter is ignored.
665 /// If async is true and inEngine is false, then the packet is sent directly to a
666 /// threadpool thread.
667 /// If async is true and inEngine is true, then the packet is sent to the IncomingPacketAsyncHandlingEngine.
668 /// This may result in slower handling but reduces the risk of overloading the simulator when there are many
669 /// simultaneous async requests.
670 /// </param>
671 /// <returns>true if the handler was added. This is currently always the case.</returns>
672 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync, bool inEngine)
673 {
640 bool result = false; 674 bool result = false;
641 lock (m_packetHandlers) 675 lock (m_packetHandlers)
642 { 676 {
643 if (!m_packetHandlers.ContainsKey(packetType)) 677 if (!m_packetHandlers.ContainsKey(packetType))
644 { 678 {
645 m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync }); 679 m_packetHandlers.Add(
680 packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine });
646 result = true; 681 result = true;
647 } 682 }
648 } 683 }
@@ -677,15 +712,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
677 PacketProcessor pprocessor; 712 PacketProcessor pprocessor;
678 if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) 713 if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor))
679 { 714 {
715 ClientInfo cinfo = UDPClient.GetClientInfo();
716
680 //there is a local handler for this packet type 717 //there is a local handler for this packet type
681 if (pprocessor.Async) 718 if (pprocessor.Async)
682 { 719 {
720 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
721 cinfo.AsyncRequests[packet.Type.ToString()] = 0;
722 cinfo.AsyncRequests[packet.Type.ToString()]++;
723
683 object obj = new AsyncPacketProcess(this, pprocessor.method, packet); 724 object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
684 Util.FireAndForget(ProcessSpecificPacketAsync, obj); 725
726 if (pprocessor.InEngine)
727 m_udpServer.IpahEngine.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj));
728 else
729 Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString());
730
685 result = true; 731 result = true;
686 } 732 }
687 else 733 else
688 { 734 {
735 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
736 cinfo.SyncRequests[packet.Type.ToString()] = 0;
737 cinfo.SyncRequests[packet.Type.ToString()]++;
738
689 result = pprocessor.method(this, packet); 739 result = pprocessor.method(this, packet);
690 } 740 }
691 } 741 }
@@ -700,6 +750,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
700 } 750 }
701 if (found) 751 if (found)
702 { 752 {
753 ClientInfo cinfo = UDPClient.GetClientInfo();
754 if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString()))
755 cinfo.GenericRequests[packet.Type.ToString()] = 0;
756 cinfo.GenericRequests[packet.Type.ToString()]++;
757
703 result = method(this, packet); 758 result = method(this, packet);
704 } 759 }
705 } 760 }
@@ -717,9 +772,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
717 catch (Exception e) 772 catch (Exception e)
718 { 773 {
719 // Make sure that we see any exception caused by the asynchronous operation. 774 // Make sure that we see any exception caused by the asynchronous operation.
720 m_log.ErrorFormat( 775 m_log.Error(
721 "[LLCLIENTVIEW]: Caught exception while processing {0} for {1}, {2} {3}", 776 string.Format(
722 packetObject.Pack, Name, e.Message, e.StackTrace); 777 "[LLCLIENTVIEW]: Caught exception while processing {0} for {1} ", packetObject.Pack, Name),
778 e);
723 } 779 }
724 } 780 }
725 781
@@ -729,7 +785,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
729 785
730 public virtual void Start() 786 public virtual void Start()
731 { 787 {
732 m_scene.AddNewClient(this, PresenceType.User); 788 m_scene.AddNewAgent(this, PresenceType.User);
733 789
734 RefreshGroupMembership(); 790 RefreshGroupMembership();
735 } 791 }
@@ -791,9 +847,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 847 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
792 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 848 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
793 849
794 OutPacket(handshake, ThrottleOutPacketType.Task); 850 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[1];
851 handshake.RegionInfo4[0] = new RegionHandshakePacket.RegionInfo4Block();
852 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
853 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
854
855 OutPacket(handshake, ThrottleOutPacketType.Unknown);
795 } 856 }
796 857
858
797 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 859 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
798 { 860 {
799 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); 861 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
@@ -893,9 +955,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
893 } 955 }
894 } 956 }
895 957
896 public void SendGenericMessage(string method, List<string> message) 958 public void SendGenericMessage(string method, UUID invoice, List<string> message)
897 { 959 {
898 GenericMessagePacket gmp = new GenericMessagePacket(); 960 GenericMessagePacket gmp = new GenericMessagePacket();
961
962 gmp.AgentData.AgentID = AgentId;
963 gmp.AgentData.SessionID = m_sessionId;
964 gmp.AgentData.TransactionID = invoice;
965
899 gmp.MethodData.Method = Util.StringToBytes256(method); 966 gmp.MethodData.Method = Util.StringToBytes256(method);
900 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 967 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
901 int i = 0; 968 int i = 0;
@@ -908,9 +975,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
908 OutPacket(gmp, ThrottleOutPacketType.Task); 975 OutPacket(gmp, ThrottleOutPacketType.Task);
909 } 976 }
910 977
911 public void SendGenericMessage(string method, List<byte[]> message) 978 public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
912 { 979 {
913 GenericMessagePacket gmp = new GenericMessagePacket(); 980 GenericMessagePacket gmp = new GenericMessagePacket();
981
982 gmp.AgentData.AgentID = AgentId;
983 gmp.AgentData.SessionID = m_sessionId;
984 gmp.AgentData.TransactionID = invoice;
985
914 gmp.MethodData.Method = Util.StringToBytes256(method); 986 gmp.MethodData.Method = Util.StringToBytes256(method);
915 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 987 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
916 int i = 0; 988 int i = 0;
@@ -1112,11 +1184,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1112 1184
1113 /// <summary> 1185 /// <summary>
1114 /// Send the region heightmap to the client 1186 /// Send the region heightmap to the client
1187 /// This method is only called when not doing intellegent terrain patch sending and
1188 /// is only called when the scene presence is initially created and sends all of the
1189 /// region's patches to the client.
1115 /// </summary> 1190 /// </summary>
1116 /// <param name="map">heightmap</param> 1191 /// <param name="map">heightmap</param>
1117 public virtual void SendLayerData(float[] map) 1192 public virtual void SendLayerData(float[] map)
1118 { 1193 {
1119 Util.FireAndForget(DoSendLayerData, map); 1194 Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData(), "LLClientView.DoSendLayerData");
1120 } 1195 }
1121 1196
1122 /// <summary> 1197 /// <summary>
@@ -1125,10 +1200,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1125 /// <param name="o"></param> 1200 /// <param name="o"></param>
1126 private void DoSendLayerData(object o) 1201 private void DoSendLayerData(object o)
1127 { 1202 {
1128 float[] map = LLHeightFieldMoronize((float[])o); 1203 TerrainData map = (TerrainData)o;
1129 1204
1130 try 1205 try
1131 { 1206 {
1207 // Send LayerData in typerwriter pattern
1132 //for (int y = 0; y < 16; y++) 1208 //for (int y = 0; y < 16; y++)
1133 //{ 1209 //{
1134 // for (int x = 0; x < 16; x++) 1210 // for (int x = 0; x < 16; x++)
@@ -1138,7 +1214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1138 //} 1214 //}
1139 1215
1140 // Send LayerData in a spiral pattern. Fun! 1216 // Send LayerData in a spiral pattern. Fun!
1141 SendLayerTopRight(map, 0, 0, 15, 15); 1217 SendLayerTopRight(map, 0, 0, map.SizeX/Constants.TerrainPatchSize-1, map.SizeY/Constants.TerrainPatchSize-1);
1142 } 1218 }
1143 catch (Exception e) 1219 catch (Exception e)
1144 { 1220 {
@@ -1146,7 +1222,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 } 1222 }
1147 } 1223 }
1148 1224
1149 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2) 1225 private void SendLayerTopRight(TerrainData map, int x1, int y1, int x2, int y2)
1150 { 1226 {
1151 // Row 1227 // Row
1152 for (int i = x1; i <= x2; i++) 1228 for (int i = x1; i <= x2; i++)
@@ -1156,11 +1232,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1156 for (int j = y1 + 1; j <= y2; j++) 1232 for (int j = y1 + 1; j <= y2; j++)
1157 SendLayerData(x2, j, map); 1233 SendLayerData(x2, j, map);
1158 1234
1159 if (x2 - x1 > 0) 1235 if (x2 - x1 > 0 && y2 - y1 > 0)
1160 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2); 1236 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1161 } 1237 }
1162 1238
1163 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2) 1239 void SendLayerBottomLeft(TerrainData map, int x1, int y1, int x2, int y2)
1164 { 1240 {
1165 // Row in reverse 1241 // Row in reverse
1166 for (int i = x2; i >= x1; i--) 1242 for (int i = x2; i >= x1; i--)
@@ -1170,7 +1246,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1170 for (int j = y2 - 1; j >= y1; j--) 1246 for (int j = y2 - 1; j >= y1; j--)
1171 SendLayerData(x1, j, map); 1247 SendLayerData(x1, j, map);
1172 1248
1173 if (x2 - x1 > 0) 1249 if (x2 - x1 > 0 && y2 - y1 > 0)
1174 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); 1250 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1175 } 1251 }
1176 1252
@@ -1192,25 +1268,98 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1192 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1268 // OutPacket(layerpack, ThrottleOutPacketType.Land);
1193 // } 1269 // }
1194 1270
1271 // Legacy form of invocation that passes around a bare data array.
1272 // Just ignore what was passed and use the real terrain info that is part of the scene.
1273 // As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI,
1274 // there is a special form for specifying multiple terrain patches to send.
1275 // The form is to pass 'px' as negative the number of patches to send and to
1276 // pass the float array as pairs of patch X and Y coordinates. So, passing 'px'
1277 // as -2 and map= [3, 5, 8, 4] would mean to send two terrain heightmap patches
1278 // and the patches to send are <3,5> and <8,4>.
1279 public void SendLayerData(int px, int py, float[] map)
1280 {
1281 if (px >= 0)
1282 {
1283 SendLayerData(px, py, m_scene.Heightmap.GetTerrainData());
1284 }
1285 else
1286 {
1287 int numPatches = -px;
1288 int[] xPatches = new int[numPatches];
1289 int[] yPatches = new int[numPatches];
1290 for (int pp = 0; pp < numPatches; pp++)
1291 {
1292 xPatches[pp] = (int)map[pp * 2];
1293 yPatches[pp] = (int)map[pp * 2 + 1];
1294 }
1295
1296 // DebugSendingPatches("SendLayerData", xPatches, yPatches);
1297
1298 SendLayerData(xPatches, yPatches, m_scene.Heightmap.GetTerrainData());
1299 }
1300 }
1301
1302 private void DebugSendingPatches(string pWho, int[] pX, int[] pY)
1303 {
1304 if (m_log.IsDebugEnabled)
1305 {
1306 int numPatches = pX.Length;
1307 string Xs = "";
1308 string Ys = "";
1309 for (int pp = 0; pp < numPatches; pp++)
1310 {
1311 Xs += String.Format("{0}", (int)pX[pp]) + ",";
1312 Ys += String.Format("{0}", (int)pY[pp]) + ",";
1313 }
1314 m_log.DebugFormat("{0} {1}: numPatches={2}, X={3}, Y={4}", LogHeader, pWho, numPatches, Xs, Ys);
1315 }
1316 }
1317
1195 /// <summary> 1318 /// <summary>
1196 /// Sends a specified patch to a client 1319 /// Sends a terrain packet for the point specified.
1320 /// This is a legacy call that has refarbed the terrain into a flat map of floats.
1321 /// We just use the terrain from the region we know about.
1197 /// </summary> 1322 /// </summary>
1198 /// <param name="px">Patch coordinate (x) 0..15</param> 1323 /// <param name="px">Patch coordinate (x) 0..15</param>
1199 /// <param name="py">Patch coordinate (y) 0..15</param> 1324 /// <param name="py">Patch coordinate (y) 0..15</param>
1200 /// <param name="map">heightmap</param> 1325 /// <param name="map">heightmap</param>
1201 public void SendLayerData(int px, int py, float[] map) 1326 public void SendLayerData(int px, int py, TerrainData terrData)
1327 {
1328 int[] xPatches = new[] { px };
1329 int[] yPatches = new[] { py };
1330 SendLayerData(xPatches, yPatches, terrData);
1331 }
1332
1333 private void SendLayerData(int[] px, int[] py, TerrainData terrData)
1202 { 1334 {
1203 try 1335 try
1204 { 1336 {
1205 int[] patches = new int[] { py * 16 + px }; 1337 /* test code using the terrain compressor in libOpenMetaverse
1206 float[] heightmap = (map.Length == 65536) ? 1338 int[] patchInd = new int[1];
1207 map : 1339 patchInd[0] = px + (py * Constants.TerrainPatchSize);
1208 LLHeightFieldMoronize(map); 1340 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(terrData.GetFloatsSerialized(), patchInd);
1341 */
1342 // Many, many patches could have been passed to us. Since the patches will be compressed
1343 // into variable sized blocks, we cannot pre-compute how many will fit into one
1344 // packet. While some fancy packing algorithm is possible, 4 seems to always fit.
1345 int PatchesAssumedToFit = 4;
1346 for (int pcnt = 0; pcnt < px.Length; pcnt += PatchesAssumedToFit)
1347 {
1348 int remaining = Math.Min(px.Length - pcnt, PatchesAssumedToFit);
1349 int[] xPatches = new int[remaining];
1350 int[] yPatches = new int[remaining];
1351 for (int ii = 0; ii < remaining; ii++)
1352 {
1353 xPatches[ii] = px[pcnt + ii];
1354 yPatches[ii] = py[pcnt + ii];
1355 }
1356 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, xPatches, yPatches);
1357 // DebugSendingPatches("SendLayerDataInternal", xPatches, yPatches);
1209 1358
1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1359 SendTheLayerPacket(layerpack);
1211 layerpack.Header.Reliable = true; 1360 }
1361 // LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py);
1212 1362
1213 OutPacket(layerpack, ThrottleOutPacketType.Land);
1214 } 1363 }
1215 catch (Exception e) 1364 catch (Exception e)
1216 { 1365 {
@@ -1218,36 +1367,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1218 } 1367 }
1219 } 1368 }
1220 1369
1221 /// <summary> 1370 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a
1222 /// Munges heightfield into the LLUDP backed in restricted heightfield. 1371 // sub optimal editing experience. To alleviate this issue, when the user edits the terrain, we
1223 /// </summary> 1372 // start skipping the queues until they're done editing the terrain. We also make them
1224 /// <param name="map">float array in the base; Constants.RegionSize</param> 1373 // unreliable because it's extremely likely that multiple packets will be sent for a terrain patch
1225 /// <returns>float array in the base 256</returns> 1374 // area invalidating previous packets for that area.
1226 internal float[] LLHeightFieldMoronize(float[] map) 1375
1376 // It's possible for an editing user to flood themselves with edited packets but the majority
1377 // of use cases are such that only a tiny percentage of users will be editing the terrain.
1378 // Other, non-editing users will see the edits much slower.
1379
1380 // One last note on this topic, by the time users are going to be editing the terrain, it's
1381 // extremely likely that the sim will have rezzed already and therefore this is not likely going
1382 // to cause any additional issues with lost packets, objects or terrain patches.
1383
1384 // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we
1385 // only have one cache miss.
1386 private void SendTheLayerPacket(LayerDataPacket layerpack)
1227 { 1387 {
1228 if (map.Length == 65536) 1388 if (m_justEditedTerrain)
1229 return map; 1389 {
1390 layerpack.Header.Reliable = false;
1391 OutPacket(layerpack, ThrottleOutPacketType.Unknown );
1392 }
1230 else 1393 else
1231 { 1394 {
1232 float[] returnmap = new float[65536]; 1395 layerpack.Header.Reliable = true;
1233 1396 OutPacket(layerpack, ThrottleOutPacketType.Land);
1234 if (map.Length < 65535)
1235 {
1236 // rebase the vector stride to 256
1237 for (int i = 0; i < Constants.RegionSize; i++)
1238 Array.Copy(map, i * (int)Constants.RegionSize, returnmap, i * 256, (int)Constants.RegionSize);
1239 }
1240 else
1241 {
1242 for (int i = 0; i < 256; i++)
1243 Array.Copy(map, i * (int)Constants.RegionSize, returnmap, i * 256, 256);
1244 }
1245
1246 //Array.Copy(map,0,returnmap,0,(map.Length < 65536)? map.Length : 65536);
1247
1248 return returnmap;
1249 } 1397 }
1250
1251 } 1398 }
1252 1399
1253 /// <summary> 1400 /// <summary>
@@ -1256,7 +1403,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1256 /// <param name="windSpeeds">16x16 array of wind speeds</param> 1403 /// <param name="windSpeeds">16x16 array of wind speeds</param>
1257 public virtual void SendWindData(Vector2[] windSpeeds) 1404 public virtual void SendWindData(Vector2[] windSpeeds)
1258 { 1405 {
1259 Util.FireAndForget(DoSendWindData, windSpeeds); 1406 Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData");
1260 } 1407 }
1261 1408
1262 /// <summary> 1409 /// <summary>
@@ -1265,7 +1412,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1265 /// <param name="windSpeeds">16x16 array of cloud densities</param> 1412 /// <param name="windSpeeds">16x16 array of cloud densities</param>
1266 public virtual void SendCloudData(float[] cloudDensity) 1413 public virtual void SendCloudData(float[] cloudDensity)
1267 { 1414 {
1268 Util.FireAndForget(DoSendCloudData, cloudDensity); 1415 Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData");
1269 } 1416 }
1270 1417
1271 /// <summary> 1418 /// <summary>
@@ -1276,21 +1423,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1276 { 1423 {
1277 Vector2[] windSpeeds = (Vector2[])o; 1424 Vector2[] windSpeeds = (Vector2[])o;
1278 TerrainPatch[] patches = new TerrainPatch[2]; 1425 TerrainPatch[] patches = new TerrainPatch[2];
1279 patches[0] = new TerrainPatch(); 1426 patches[0] = new TerrainPatch { Data = new float[16 * 16] };
1280 patches[0].Data = new float[16 * 16]; 1427 patches[1] = new TerrainPatch { Data = new float[16 * 16] };
1281 patches[1] = new TerrainPatch();
1282 patches[1].Data = new float[16 * 16];
1283 1428
1284 for (int y = 0; y < 16; y++) 1429 for (int x = 0; x < 16 * 16; x++)
1285 { 1430 {
1286 for (int x = 0; x < 16; x++) 1431 patches[0].Data[x] = windSpeeds[x].X;
1287 { 1432 patches[1].Data[x] = windSpeeds[x].Y;
1288 patches[0].Data[y * 16 + x] = windSpeeds[y * 16 + x].X;
1289 patches[1].Data[y * 16 + x] = windSpeeds[y * 16 + x].Y;
1290 }
1291 } 1433 }
1292 1434
1293 LayerDataPacket layerpack = TerrainCompressor.CreateLayerDataPacket(patches, TerrainPatch.LayerType.Wind); 1435 byte layerType = (byte)TerrainPatch.LayerType.Wind;
1436 if (m_scene.RegionInfo.RegionSizeX > Constants.RegionSize || m_scene.RegionInfo.RegionSizeY > Constants.RegionSize)
1437 layerType = (byte)TerrainPatch.LayerType.WindExtended;
1438
1439 // LayerDataPacket layerpack = TerrainCompressor.CreateLayerDataPacket(patches, (TerrainPatch.LayerType)layerType);
1440 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacket(patches, layerType,
1441 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY);
1294 layerpack.Header.Zerocoded = true; 1442 layerpack.Header.Zerocoded = true;
1295 OutPacket(layerpack, ThrottleOutPacketType.Wind); 1443 OutPacket(layerpack, ThrottleOutPacketType.Wind);
1296 } 1444 }
@@ -1314,7 +1462,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1314 } 1462 }
1315 } 1463 }
1316 1464
1317 LayerDataPacket layerpack = TerrainCompressor.CreateLayerDataPacket(patches, TerrainPatch.LayerType.Cloud); 1465 byte layerType = (byte)TerrainPatch.LayerType.Cloud;
1466 if (m_scene.RegionInfo.RegionSizeX > Constants.RegionSize || m_scene.RegionInfo.RegionSizeY > Constants.RegionSize)
1467 layerType = (byte)TerrainPatch.LayerType.CloudExtended;
1468
1469 // LayerDataPacket layerpack = TerrainCompressor.CreateLayerDataPacket(patches, (TerrainPatch.LayerType)layerType);
1470 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacket(patches, layerType,
1471 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY);
1318 layerpack.Header.Zerocoded = true; 1472 layerpack.Header.Zerocoded = true;
1319 OutPacket(layerpack, ThrottleOutPacketType.Cloud); 1473 OutPacket(layerpack, ThrottleOutPacketType.Cloud);
1320 } 1474 }
@@ -1403,6 +1557,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1403 1557
1404 mapReply.AgentData.AgentID = AgentId; 1558 mapReply.AgentData.AgentID = AgentId;
1405 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks2.Length]; 1559 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks2.Length];
1560 mapReply.Size = new MapBlockReplyPacket.SizeBlock[mapBlocks2.Length];
1406 mapReply.AgentData.Flags = flag; 1561 mapReply.AgentData.Flags = flag;
1407 1562
1408 for (int i = 0; i < mapBlocks2.Length; i++) 1563 for (int i = 0; i < mapBlocks2.Length; i++)
@@ -1417,6 +1572,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1417 mapReply.Data[i].RegionFlags = mapBlocks2[i].RegionFlags; 1572 mapReply.Data[i].RegionFlags = mapBlocks2[i].RegionFlags;
1418 mapReply.Data[i].Access = mapBlocks2[i].Access; 1573 mapReply.Data[i].Access = mapBlocks2[i].Access;
1419 mapReply.Data[i].Agents = mapBlocks2[i].Agents; 1574 mapReply.Data[i].Agents = mapBlocks2[i].Agents;
1575
1576 mapReply.Size[i] = new MapBlockReplyPacket.SizeBlock();
1577 mapReply.Size[i].SizeX = mapBlocks2[i].SizeX;
1578 mapReply.Size[i].SizeY = mapBlocks2[i].SizeY;
1420 } 1579 }
1421 OutPacket(mapReply, ThrottleOutPacketType.Land); 1580 OutPacket(mapReply, ThrottleOutPacketType.Land);
1422 } 1581 }
@@ -1521,7 +1680,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1521 OutPacket(tpProgress, ThrottleOutPacketType.Unknown); 1680 OutPacket(tpProgress, ThrottleOutPacketType.Unknown);
1522 } 1681 }
1523 1682
1524 public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance) 1683 public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
1525 { 1684 {
1526 MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply); 1685 MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply);
1527 money.MoneyData.AgentID = AgentId; 1686 money.MoneyData.AgentID = AgentId;
@@ -1529,7 +1688,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1529 money.MoneyData.TransactionSuccess = success; 1688 money.MoneyData.TransactionSuccess = success;
1530 money.MoneyData.Description = description; 1689 money.MoneyData.Description = description;
1531 money.MoneyData.MoneyBalance = balance; 1690 money.MoneyData.MoneyBalance = balance;
1532 money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE"); 1691 money.TransactionInfo.TransactionType = transactionType;
1692 money.TransactionInfo.SourceID = sourceID;
1693 money.TransactionInfo.IsSourceGroup = sourceIsGroup;
1694 money.TransactionInfo.DestID = destID;
1695 money.TransactionInfo.IsDestGroup = destIsGroup;
1696 money.TransactionInfo.Amount = amount;
1697 money.TransactionInfo.ItemDescription = Util.StringToBytes256(item);
1698
1533 OutPacket(money, ThrottleOutPacketType.Task); 1699 OutPacket(money, ThrottleOutPacketType.Task);
1534 } 1700 }
1535 1701
@@ -1571,7 +1737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1571 OutPacket(pc, ThrottleOutPacketType.Unknown); 1737 OutPacket(pc, ThrottleOutPacketType.Unknown);
1572 } 1738 }
1573 1739
1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1740 public void SendKillObject(List<uint> localIDs)
1575 { 1741 {
1576// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1742// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1577 1743
@@ -1588,7 +1754,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1588 1754
1589 if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null) 1755 if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
1590 { 1756 {
1591 OutPacket(kill, ThrottleOutPacketType.State); 1757 OutPacket(kill, ThrottleOutPacketType.Task);
1592 } 1758 }
1593 else 1759 else
1594 { 1760 {
@@ -1700,6 +1866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1700 newBlock.Name = Util.StringToBytes256(folder.Name); 1866 newBlock.Name = Util.StringToBytes256(folder.Name);
1701 newBlock.ParentID = folder.ParentID; 1867 newBlock.ParentID = folder.ParentID;
1702 newBlock.Type = (sbyte)folder.Type; 1868 newBlock.Type = (sbyte)folder.Type;
1869 //if (newBlock.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
1870 // newBlock.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
1703 1871
1704 return newBlock; 1872 return newBlock;
1705 } 1873 }
@@ -1807,7 +1975,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1807 1975
1808 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) 1976 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
1809 { 1977 {
1810 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 1978 // Fudge this value. It's only needed to make the CRC anyway
1979 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
1811 1980
1812 FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); 1981 FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply);
1813 // TODO: don't create new blocks if recycling an old packet 1982 // TODO: don't create new blocks if recycling an old packet
@@ -1948,8 +2117,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1948 2117
1949 folderBlock.FolderID = folder.ID; 2118 folderBlock.FolderID = folder.ID;
1950 folderBlock.ParentID = folder.ParentID; 2119 folderBlock.ParentID = folder.ParentID;
1951 //folderBlock.Type = -1;
1952 folderBlock.Type = (sbyte)folder.Type; 2120 folderBlock.Type = (sbyte)folder.Type;
2121 // Leaving this here for now, just in case we need to do this for a while
2122 //if (folderBlock.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
2123 // folderBlock.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
1953 folderBlock.Name = Util.StringToBytes256(folder.Name); 2124 folderBlock.Name = Util.StringToBytes256(folder.Name);
1954 2125
1955 return folderBlock; 2126 return folderBlock;
@@ -2012,7 +2183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2012 2183
2013 protected void SendBulkUpdateInventoryItem(InventoryItemBase item) 2184 protected void SendBulkUpdateInventoryItem(InventoryItemBase item)
2014 { 2185 {
2015 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2186 const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff;
2016 2187
2017 BulkUpdateInventoryPacket bulkUpdate 2188 BulkUpdateInventoryPacket bulkUpdate
2018 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); 2189 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
@@ -2066,7 +2237,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2066 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see> 2237 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2067 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2238 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2068 { 2239 {
2069 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2240 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2070 2241
2071 UpdateCreateInventoryItemPacket InventoryReply 2242 UpdateCreateInventoryItemPacket InventoryReply
2072 = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket( 2243 = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket(
@@ -2212,9 +2383,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2212 2383
2213 public void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle) 2384 public void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
2214 { 2385 {
2215 m_activeGroupID = activegroupid; 2386 if (agentid == AgentId)
2216 m_activeGroupName = groupname; 2387 {
2217 m_activeGroupPowers = grouppowers; 2388 ActiveGroupId = activegroupid;
2389 ActiveGroupName = groupname;
2390 ActiveGroupPowers = grouppowers;
2391 }
2218 2392
2219 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); 2393 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate);
2220 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; 2394 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid;
@@ -2261,6 +2435,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2261 /// <returns></returns> 2435 /// <returns></returns>
2262 public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) 2436 public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal)
2263 { 2437 {
2438 // Prepend a slash to make the message come up in the top right
2439 // again.
2440 // Allow special formats to be sent from aware modules.
2441 if (!modal && !message.StartsWith("ALERT: ") && !message.StartsWith("NOTIFY: ") && message != "Home position set." && message != "You died and have been teleported to your home location")
2442 message = "/" + message;
2264 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); 2443 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
2265 alertPack.AgentData.AgentID = AgentId; 2444 alertPack.AgentData.AgentID = AgentId;
2266 alertPack.AlertData.Message = Util.StringToBytes256(message); 2445 alertPack.AlertData.Message = Util.StringToBytes256(message);
@@ -2556,11 +2735,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2556 { 2735 {
2557 AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); 2736 AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket();
2558 avatarSitResponse.SitObject.ID = TargetID; 2737 avatarSitResponse.SitObject.ID = TargetID;
2559 if (CameraAtOffset != Vector3.Zero) 2738 avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset;
2560 { 2739 avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset;
2561 avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset;
2562 avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset;
2563 }
2564 avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; 2740 avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook;
2565 avatarSitResponse.SitTransform.AutoPilot = autopilot; 2741 avatarSitResponse.SitTransform.AutoPilot = autopilot;
2566 avatarSitResponse.SitTransform.SitPosition = OffsetPos; 2742 avatarSitResponse.SitTransform.SitPosition = OffsetPos;
@@ -2627,6 +2803,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2627 } 2803 }
2628 } 2804 }
2629 2805
2806 public void SendPartPhysicsProprieties(ISceneEntity entity)
2807 {
2808 SceneObjectPart part = (SceneObjectPart)entity;
2809 if (part != null && AgentId != UUID.Zero)
2810 {
2811 try
2812 {
2813 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2814 if (eq != null)
2815 {
2816 uint localid = part.LocalId;
2817 byte physshapetype = part.PhysicsShapeType;
2818 float density = part.Density;
2819 float friction = part.Friction;
2820 float bounce = part.Restitution;
2821 float gravmod = part.GravityModifier;
2822 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2823 }
2824 }
2825 catch (Exception ex)
2826 {
2827 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2828 }
2829 part.UpdatePhysRequired = false;
2830 }
2831 }
2832
2833
2630 2834
2631 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2835 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2632 { 2836 {
@@ -2681,8 +2885,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2681 { 2885 {
2682 if (req.AssetInf.Data == null) 2886 if (req.AssetInf.Data == null)
2683 { 2887 {
2684 m_log.ErrorFormat("Cannot send asset {0} ({1}), asset data is null", 2888 m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset data is null",
2685 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2889 LogHeader, req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2686 return; 2890 return;
2687 } 2891 }
2688 2892
@@ -3530,7 +3734,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3530 3734
3531 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3735 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3532 // TODO: don't create new blocks if recycling an old packet 3736 // TODO: don't create new blocks if recycling an old packet
3533 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3737 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3534 avp.ObjectData.TextureEntry = textureEntry; 3738 avp.ObjectData.TextureEntry = textureEntry;
3535 3739
3536 AvatarAppearancePacket.VisualParamBlock avblock = null; 3740 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3543,6 +3747,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3543 3747
3544 avp.Sender.IsTrial = false; 3748 avp.Sender.IsTrial = false;
3545 avp.Sender.ID = agentID; 3749 avp.Sender.ID = agentID;
3750 avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0];
3751 avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0];
3546 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3752 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3547 OutPacket(avp, ThrottleOutPacketType.Task); 3753 OutPacket(avp, ThrottleOutPacketType.Task);
3548 } 3754 }
@@ -3660,11 +3866,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3660 /// </summary> 3866 /// </summary>
3661 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3867 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3662 { 3868 {
3663 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3869 if (entity.UUID == m_agentId && !updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3664 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3870 {
3871 ImprovedTerseObjectUpdatePacket packet
3872 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3665 3873
3666 lock (m_entityUpdates.SyncRoot) 3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3667 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3875 packet.RegionData.TimeDilation = Utils.FloatToUInt16(1, 0.0f, 1.0f);
3876 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
3877 packet.ObjectData[0] = CreateImprovedTerseBlock(entity, false);
3878 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3879 }
3880 else
3881 {
3882 //double priority = m_prioritizer.GetUpdatePriority(this, entity);
3883 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3884
3885 lock (m_entityUpdates.SyncRoot)
3886 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3887 }
3668 } 3888 }
3669 3889
3670 /// <summary> 3890 /// <summary>
@@ -3699,12 +3919,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3699 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); 3919 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
3700 3920
3701 // Count this as a resent packet since we are going to requeue all of the updates contained in it 3921 // Count this as a resent packet since we are going to requeue all of the updates contained in it
3702 Interlocked.Increment(ref m_udpClient.PacketsResent); 3922 Interlocked.Increment(ref m_udpClient.PacketsResent);
3923
3924 // We're not going to worry about interlock yet since its not currently critical that this total count
3925 // is 100% correct
3926 m_udpServer.PacketsResentCount++;
3703 3927
3704 foreach (EntityUpdate update in updates) 3928 foreach (EntityUpdate update in updates)
3705 ResendPrimUpdate(update); 3929 ResendPrimUpdate(update);
3706 } 3930 }
3707 3931
3932// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3933// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3934// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3935// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3936//
3937// OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3938// OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3939// OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3940// OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3941
3942
3708 private void ProcessEntityUpdates(int maxUpdates) 3943 private void ProcessEntityUpdates(int maxUpdates)
3709 { 3944 {
3710 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3945 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3717,6 +3952,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3717 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3952 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3718 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3953 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3719 3954
3955// objectUpdateBlocks.Value.Clear();
3956// compressedUpdateBlocks.Value.Clear();
3957// terseUpdateBlocks.Value.Clear();
3958// terseAgentUpdateBlocks.Value.Clear();
3959// objectUpdates.Value.Clear();
3960// compressedUpdates.Value.Clear();
3961// terseUpdates.Value.Clear();
3962// terseAgentUpdates.Value.Clear();
3963
3720 // Check to see if this is a flush 3964 // Check to see if this is a flush
3721 if (maxUpdates <= 0) 3965 if (maxUpdates <= 0)
3722 { 3966 {
@@ -3774,6 +4018,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3774 part.Shape.LightEntry = false; 4018 part.Shape.LightEntry = false;
3775 } 4019 }
3776 } 4020 }
4021
4022 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
4023 {
4024 // Ensure that mesh has at least 8 valid faces
4025 part.Shape.ProfileBegin = 12500;
4026 part.Shape.ProfileEnd = 0;
4027 part.Shape.ProfileHollow = 27500;
4028 }
3777 } 4029 }
3778 4030
3779 #region UpdateFlags to packet type conversion 4031 #region UpdateFlags to packet type conversion
@@ -3995,6 +4247,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3995 } 4247 }
3996 } 4248 }
3997 4249
4250// m_log.DebugFormat(
4251// "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}",
4252// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
4253//
3998 #endregion Packet Sending 4254 #endregion Packet Sending
3999 } 4255 }
4000 4256
@@ -4034,8 +4290,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4034 4290
4035 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 4291 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
4036 { 4292 {
4293// if (!m_udpServer.IsRunningOutbound)
4294// return;
4295
4037 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 4296 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4038 { 4297 {
4298// if (!m_udpServer.IsRunningOutbound)
4299// return;
4300
4039 if (m_maxUpdates == 0 || m_LastQueueFill == 0) 4301 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
4040 { 4302 {
4041 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; 4303 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
@@ -4061,6 +4323,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4061 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); 4323 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
4062 } 4324 }
4063 4325
4326 internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
4327 {
4328 bool hasUpdates = false;
4329
4330 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4331 {
4332 if (m_entityUpdates.Count > 0)
4333 hasUpdates = true;
4334 else if (m_entityProps.Count > 0)
4335 hasUpdates = true;
4336 }
4337
4338 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
4339 {
4340 if (ImageManager.HasUpdates())
4341 hasUpdates = true;
4342 }
4343
4344 return hasUpdates;
4345 }
4346
4064 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 4347 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
4065 { 4348 {
4066 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 4349 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
@@ -4156,7 +4439,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4156 pack.Stat = stats.StatsBlock; 4439 pack.Stat = stats.StatsBlock;
4157 4440
4158 pack.Header.Reliable = false; 4441 pack.Header.Reliable = false;
4159 4442 pack.RegionInfo = new SimStatsPacket.RegionInfoBlock[0];
4160 OutPacket(pack, ThrottleOutPacketType.Task); 4443 OutPacket(pack, ThrottleOutPacketType.Task);
4161 } 4444 }
4162 4445
@@ -4206,6 +4489,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4206 // Count this as a resent packet since we are going to requeue all of the updates contained in it 4489 // Count this as a resent packet since we are going to requeue all of the updates contained in it
4207 Interlocked.Increment(ref m_udpClient.PacketsResent); 4490 Interlocked.Increment(ref m_udpClient.PacketsResent);
4208 4491
4492 // We're not going to worry about interlock yet since its not currently critical that this total count
4493 // is 100% correct
4494 m_udpServer.PacketsResentCount++;
4495
4209 foreach (ObjectPropertyUpdate update in updates) 4496 foreach (ObjectPropertyUpdate update in updates)
4210 ResendPropertyUpdate(update); 4497 ResendPropertyUpdate(update);
4211 } 4498 }
@@ -4389,6 +4676,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4389 SceneObjectPart root = sop.ParentGroup.RootPart; 4676 SceneObjectPart root = sop.ParentGroup.RootPart;
4390 4677
4391 block.TouchName = Util.StringToBytes256(root.TouchName); 4678 block.TouchName = Util.StringToBytes256(root.TouchName);
4679
4680 // SL 3.3.4, at least, appears to read this information as a concatenated byte[] stream of UUIDs but
4681 // it's not yet clear whether this is actually used. If this is done in the future then a pre-cached
4682 // copy is really needed since it's less efficient to be constantly recreating this byte array.
4683// using (MemoryStream memStream = new MemoryStream())
4684// {
4685// using (BinaryWriter binWriter = new BinaryWriter(memStream))
4686// {
4687// for (int i = 0; i < sop.GetNumberOfSides(); i++)
4688// {
4689// Primitive.TextureEntryFace teFace = sop.Shape.Textures.FaceTextures[i];
4690//
4691// UUID textureID;
4692//
4693// if (teFace != null)
4694// textureID = teFace.TextureID;
4695// else
4696// textureID = sop.Shape.Textures.DefaultTexture.TextureID;
4697//
4698// binWriter.Write(textureID.GetBytes());
4699// }
4700//
4701// block.TextureID = memStream.ToArray();
4702// }
4703// }
4704
4392 block.TextureID = new byte[0]; // TextureID ??? 4705 block.TextureID = new byte[0]; // TextureID ???
4393 block.SitName = Util.StringToBytes256(root.SitName); 4706 block.SitName = Util.StringToBytes256(root.SitName);
4394 block.OwnerMask = root.OwnerMask; 4707 block.OwnerMask = root.OwnerMask;
@@ -4543,7 +4856,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4543 rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock(); 4856 rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock();
4544 rinfopack.AgentData.AgentID = AgentId; 4857 rinfopack.AgentData.AgentID = AgentId;
4545 rinfopack.AgentData.SessionID = SessionId; 4858 rinfopack.AgentData.SessionID = SessionId;
4546 4859 rinfopack.RegionInfo3 = new RegionInfoPacket.RegionInfo3Block[0];
4547 4860
4548 OutPacket(rinfopack, ThrottleOutPacketType.Task); 4861 OutPacket(rinfopack, ThrottleOutPacketType.Task);
4549 } 4862 }
@@ -4764,7 +5077,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4764 5077
4765 public void SendForceClientSelectObjects(List<uint> ObjectIDs) 5078 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
4766 { 5079 {
4767 m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); 5080// m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
4768 5081
4769 bool firstCall = true; 5082 bool firstCall = true;
4770 const int MAX_OBJECTS_PER_PACKET = 251; 5083 const int MAX_OBJECTS_PER_PACKET = 251;
@@ -4882,7 +5195,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4882 { 5195 {
4883 ScenePresence presence = (ScenePresence)entity; 5196 ScenePresence presence = (ScenePresence)entity;
4884 5197
4885 attachPoint = 0; 5198// m_log.DebugFormat(
5199// "[LLCLIENTVIEW]: Sending terse update to {0} with pos {1}, vel {2} in {3}",
5200// Name, presence.OffsetPosition, presence.Velocity, m_scene.Name);
5201
5202 attachPoint = presence.State;
4886 collisionPlane = presence.CollisionPlane; 5203 collisionPlane = presence.CollisionPlane;
4887 position = presence.OffsetPosition; 5204 position = presence.OffsetPosition;
4888 velocity = presence.Velocity; 5205 velocity = presence.Velocity;
@@ -4893,9 +5210,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4893 // may improve movement smoothness. 5210 // may improve movement smoothness.
4894// acceleration = new Vector3(1, 0, 0); 5211// acceleration = new Vector3(1, 0, 0);
4895 5212
4896 angularVelocity = Vector3.Zero; 5213 angularVelocity = presence.AngularVelocity;
5214
5215 // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis
5216 // it rotates around.
5217 // In mouselook, X and Y co-ordinate will also be sent but when used in Rotation, these cause unwanted
5218 // excessive up and down movements of the camera when looking up and down.
5219 // See http://opensimulator.org/mantis/view.php?id=3274
5220 // This does not affect head movement, since this is controlled entirely by camera movement rather than
5221 // body rotation. We still need to transmit X and Y for sitting avatars but mouselook does not change
5222 // the rotation in this case.
4897 rotation = presence.Rotation; 5223 rotation = presence.Rotation;
4898 5224
5225 if (!presence.IsSatOnObject)
5226 {
5227 rotation.X = 0;
5228 rotation.Y = 0;
5229 }
5230
4899 if (sendTexture) 5231 if (sendTexture)
4900 textureEntry = presence.Appearance.Texture.GetBytes(); 5232 textureEntry = presence.Appearance.Texture.GetBytes();
4901 else 5233 else
@@ -4906,7 +5238,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4906 SceneObjectPart part = (SceneObjectPart)entity; 5238 SceneObjectPart part = (SceneObjectPart)entity;
4907 5239
4908 attachPoint = part.ParentGroup.AttachmentPoint; 5240 attachPoint = part.ParentGroup.AttachmentPoint;
4909 5241 attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
4910// m_log.DebugFormat( 5242// m_log.DebugFormat(
4911// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", 5243// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
4912// attachPoint, part.Name, part.LocalId, Name); 5244// attachPoint, part.Name, part.LocalId, Name);
@@ -4934,7 +5266,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4934 pos += 4; 5266 pos += 4;
4935 5267
4936 // Avatar/CollisionPlane 5268 // Avatar/CollisionPlane
4937 data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ; 5269 data[pos++] = (byte) attachPoint;
4938 if (avatar) 5270 if (avatar)
4939 { 5271 {
4940 data[pos++] = 1; 5272 data[pos++] = 1;
@@ -5001,13 +5333,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5001 5333
5002 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5334 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5003 { 5335 {
5336// m_log.DebugFormat(
5337// "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name);
5338
5004 byte[] objectData = new byte[76]; 5339 byte[] objectData = new byte[76];
5005 5340
5006 data.CollisionPlane.ToBytes(objectData, 0); 5341 data.CollisionPlane.ToBytes(objectData, 0);
5007 data.OffsetPosition.ToBytes(objectData, 16); 5342 data.OffsetPosition.ToBytes(objectData, 16);
5008// data.Velocity.ToBytes(objectData, 28); 5343 data.Velocity.ToBytes(objectData, 28);
5009// data.Acceleration.ToBytes(objectData, 40); 5344// data.Acceleration.ToBytes(objectData, 40);
5010 data.Rotation.ToBytes(objectData, 52); 5345
5346 // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis
5347 // it rotates around.
5348 // In mouselook, X and Y co-ordinate will also be sent but when used in Rotation, these cause unwanted
5349 // excessive up and down movements of the camera when looking up and down.
5350 // See http://opensimulator.org/mantis/view.php?id=3274
5351 // This does not affect head movement, since this is controlled entirely by camera movement rather than
5352 // body rotation. We still need to transmit X and Y for sitting avatars but mouselook does not change
5353 // the rotation in this case.
5354 Quaternion rot = data.Rotation;
5355
5356 if (!data.IsSatOnObject)
5357 {
5358 rot.X = 0;
5359 rot.Y = 0;
5360 }
5361
5362 rot.ToBytes(objectData, 52);
5011 //data.AngularVelocity.ToBytes(objectData, 64); 5363 //data.AngularVelocity.ToBytes(objectData, 64);
5012 5364
5013 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5365 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5021,7 +5373,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5021 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5373 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5022 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5374 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5023 update.ObjectData = objectData; 5375 update.ObjectData = objectData;
5024 update.ParentID = data.ParentID; 5376
5377 SceneObjectPart parentPart = data.ParentPart;
5378 if (parentPart != null)
5379 update.ParentID = parentPart.ParentGroup.LocalId;
5380 else
5381 update.ParentID = 0;
5382
5025 update.PathCurve = 16; 5383 update.PathCurve = 16;
5026 update.PathScaleX = 100; 5384 update.PathScaleX = 100;
5027 update.PathScaleY = 100; 5385 update.PathScaleY = 100;
@@ -5075,10 +5433,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5075 //update.JointType = 0; 5433 //update.JointType = 0;
5076 update.Material = data.Material; 5434 update.Material = data.Material;
5077 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim 5435 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
5436
5078 if (data.ParentGroup.IsAttachment) 5437 if (data.ParentGroup.IsAttachment)
5079 { 5438 {
5080 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID); 5439 update.NameValue
5440 = Util.StringToBytes256(
5441 string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID));
5442
5081 update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); 5443 update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
5444
5445// m_log.DebugFormat(
5446// "[LLCLIENTVIEW]: Sending NameValue {0} for {1} {2} to {3}",
5447// Util.UTF8.GetString(update.NameValue), data.Name, data.LocalId, Name);
5448//
5449// m_log.DebugFormat(
5450// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}",
5451// update.State, data.Name, data.LocalId, Name);
5082 } 5452 }
5083 else 5453 else
5084 { 5454 {
@@ -5089,10 +5459,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5089 update.State = data.ParentGroup.RootPart.Shape.State; 5459 update.State = data.ParentGroup.RootPart.Shape.State;
5090 } 5460 }
5091 5461
5092// m_log.DebugFormat(
5093// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}",
5094// update.State, data.Name, data.LocalId, Name);
5095
5096 update.ObjectData = objectData; 5462 update.ObjectData = objectData;
5097 update.ParentID = data.ParentID; 5463 update.ParentID = data.ParentID;
5098 update.PathBegin = data.Shape.PathBegin; 5464 update.PathBegin = data.Shape.PathBegin;
@@ -5192,8 +5558,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5192 5558
5193 public ulong GetGroupPowers(UUID groupID) 5559 public ulong GetGroupPowers(UUID groupID)
5194 { 5560 {
5195 if (groupID == m_activeGroupID) 5561 if (groupID == ActiveGroupId)
5196 return m_activeGroupPowers; 5562 return ActiveGroupPowers;
5197 5563
5198 if (m_groupPowers.ContainsKey(groupID)) 5564 if (m_groupPowers.ContainsKey(groupID))
5199 return m_groupPowers[groupID]; 5565 return m_groupPowers[groupID];
@@ -5221,10 +5587,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5221 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); 5587 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
5222 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); 5588 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
5223 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); 5589 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
5224 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); 5590 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true);
5225 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); 5591 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true);
5226 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); 5592 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
5227 AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); 5593 AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true);
5228 AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); 5594 AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
5229 AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); 5595 AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
5230 AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); 5596 AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
@@ -5233,7 +5599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5233 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); 5599 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
5234 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); 5600 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
5235 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); 5601 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
5236 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply); 5602 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
5237 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); 5603 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
5238 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); 5604 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
5239 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing); 5605 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
@@ -5294,8 +5660,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5294 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false); 5660 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
5295 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); 5661 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
5296 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); 5662 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
5297 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage); 5663 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
5298 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); 5664 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
5299 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); 5665 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
5300 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); 5666 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
5301 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket); 5667 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
@@ -5327,7 +5693,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5327 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); 5693 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5328 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); 5694 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
5329 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); 5695 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
5330 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); 5696 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
5331 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); 5697 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
5332 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); 5698 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
5333 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false); 5699 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
@@ -5409,8 +5775,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5409 AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); 5775 AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete);
5410 AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); 5776 AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete);
5411 AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); 5777 AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate);
5412 AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate); 5778 AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true);
5413 AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate); 5779 AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true);
5414 AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); 5780 AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights);
5415 AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); 5781 AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery);
5416 AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); 5782 AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry);
@@ -5438,82 +5804,137 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5438 5804
5439 #region Packet Handlers 5805 #region Packet Handlers
5440 5806
5807 public int TotalAgentUpdates { get; set; }
5808
5441 #region Scene/Avatar 5809 #region Scene/Avatar
5442 5810
5443 private bool HandleAgentUpdate(IClientAPI sener, Packet packet) 5811 // Threshold for body rotation to be a significant agent update
5812 private const float QDELTA = 0.000001f;
5813 // Threshold for camera rotation to be a significant agent update
5814 private const float VDELTA = 0.01f;
5815
5816 /// <summary>
5817 /// This checks the update significance against the last update made.
5818 /// </summary>
5819 /// <remarks>Can only be called by one thread at a time</remarks>
5820 /// <returns></returns>
5821 /// <param name='x'></param>
5822 public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5444 { 5823 {
5445 if (OnAgentUpdate != null) 5824 return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
5446 { 5825 }
5447 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5448 5826
5449 #region Packet Session and User Check 5827 /// <summary>
5450 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId) 5828 /// This checks the movement/state update significance against the last update made.
5451 { 5829 /// </summary>
5452 PacketPool.Instance.ReturnPacket(packet); 5830 /// <remarks>Can only be called by one thread at a time</remarks>
5453 return false; 5831 /// <returns></returns>
5454 } 5832 /// <param name='x'></param>
5455 #endregion 5833 private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5834 {
5835 float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
5836 //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
5837
5838 bool movementSignificant =
5839 (qdelta1 > QDELTA) // significant if body rotation above threshold
5840 // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
5841 // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold
5842 || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
5843 || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands
5844 || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed
5845 || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
5846 || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
5847 ;
5848 //if (movementSignificant)
5849 //{
5850 //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}",
5851 // qdelta1, qdelta2);
5852 //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}",
5853 // x.ControlFlags, x.Flags, x.Far, x.State);
5854 //}
5855 return movementSignificant;
5856 }
5456 5857
5457 bool update = false; 5858 /// <summary>
5458 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; 5859 /// This checks the camera update significance against the last update made.
5459 5860 /// </summary>
5460 if (m_lastAgentUpdateArgs != null) 5861 /// <remarks>Can only be called by one thread at a time</remarks>
5461 { 5862 /// <returns></returns>
5462 // These should be ordered from most-likely to 5863 /// <param name='x'></param>
5463 // least likely to change. I've made an initial 5864 private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5464 // guess at that. 5865 {
5465 update = 5866 float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
5466 ( 5867 float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
5467 (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || 5868 float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
5468 (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || 5869 float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
5469 (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
5470 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5471 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5472 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5473 (x.Far != m_lastAgentUpdateArgs.Far) ||
5474 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5475 (x.State != m_lastAgentUpdateArgs.State) ||
5476 (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
5477 (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
5478 (x.AgentID != m_lastAgentUpdateArgs.AgentID)
5479 );
5480 }
5481 else
5482 {
5483 m_lastAgentUpdateArgs = new AgentUpdateArgs();
5484 update = true;
5485 }
5486 5870
5487 if (update) 5871 bool cameraSignificant =
5488 { 5872 (vdelta1 > VDELTA) ||
5489// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); 5873 (vdelta2 > VDELTA) ||
5874 (vdelta3 > VDELTA) ||
5875 (vdelta4 > VDELTA)
5876 ;
5490 5877
5491 m_lastAgentUpdateArgs.AgentID = x.AgentID; 5878 //if (cameraSignificant)
5492 m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; 5879 //{
5493 m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; 5880 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
5494 m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; 5881 // x.CameraAtAxis, x.CameraCenter);
5495 m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; 5882 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
5496 m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; 5883 // x.CameraLeftAxis, x.CameraUpAxis);
5497 m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; 5884 //}
5498 m_lastAgentUpdateArgs.Far = x.Far;
5499 m_lastAgentUpdateArgs.Flags = x.Flags;
5500 m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
5501 m_lastAgentUpdateArgs.SessionID = x.SessionID;
5502 m_lastAgentUpdateArgs.State = x.State;
5503 5885
5504 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 5886 return cameraSignificant;
5505 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; 5887 }
5506 5888
5507 if (handlerPreAgentUpdate != null) 5889 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5508 OnPreAgentUpdate(this, m_lastAgentUpdateArgs); 5890 {
5891 // We got here, which means that something in agent update was significant
5509 5892
5510 if (handlerAgentUpdate != null) 5893 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5511 OnAgentUpdate(this, m_lastAgentUpdateArgs); 5894 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5512 5895
5513 handlerAgentUpdate = null; 5896 if (x.AgentID != AgentId || x.SessionID != SessionId)
5514 handlerPreAgentUpdate = null; 5897 return false;
5515 } 5898
5516 } 5899 // Before we update the current m_thisAgentUpdateArgs, let's check this again
5900 // to see what exactly changed
5901 bool movement = CheckAgentMovementUpdateSignificance(x);
5902 bool camera = CheckAgentCameraUpdateSignificance(x);
5903
5904 m_thisAgentUpdateArgs.AgentID = x.AgentID;
5905 m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation;
5906 m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
5907 m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter;
5908 m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
5909 m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
5910 m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags;
5911 m_thisAgentUpdateArgs.Far = x.Far;
5912 m_thisAgentUpdateArgs.Flags = x.Flags;
5913 m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
5914 m_thisAgentUpdateArgs.SessionID = x.SessionID;
5915 m_thisAgentUpdateArgs.State = x.State;
5916
5917 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
5918 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
5919 UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
5920
5921 // Was there a significant movement/state change?
5922 if (movement)
5923 {
5924 if (handlerPreAgentUpdate != null)
5925 OnPreAgentUpdate(this, m_thisAgentUpdateArgs);
5926
5927 if (handlerAgentUpdate != null)
5928 OnAgentUpdate(this, m_thisAgentUpdateArgs);
5929 }
5930 // Was there a significant camera(s) change?
5931 if (camera)
5932 if (handlerAgentCameraUpdate != null)
5933 handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs);
5934
5935 handlerAgentUpdate = null;
5936 handlerPreAgentUpdate = null;
5937 handlerAgentCameraUpdate = null;
5517 5938
5518 PacketPool.Instance.ReturnPacket(packet); 5939 PacketPool.Instance.ReturnPacket(packet);
5519 5940
@@ -6080,6 +6501,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6080 //m_log.Info("[LAND]: LAND:" + modify.ToString()); 6501 //m_log.Info("[LAND]: LAND:" + modify.ToString());
6081 if (modify.ParcelData.Length > 0) 6502 if (modify.ParcelData.Length > 0)
6082 { 6503 {
6504 // Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore,
6505 // a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit.
6506 m_justEditedTerrain = true; // Prevent terrain packet (Land layer) from being queued, make it unreliable
6083 if (OnModifyTerrain != null) 6507 if (OnModifyTerrain != null)
6084 { 6508 {
6085 for (int i = 0; i < modify.ParcelData.Length; i++) 6509 for (int i = 0; i < modify.ParcelData.Length; i++)
@@ -6095,6 +6519,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6095 } 6519 }
6096 } 6520 }
6097 } 6521 }
6522 m_justEditedTerrain = false; // Queue terrain packet (Land layer) if necessary, make it reliable again
6098 } 6523 }
6099 6524
6100 return true; 6525 return true;
@@ -6149,17 +6574,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6149 // Temporarily protect ourselves from the mantis #951 failure. 6574 // Temporarily protect ourselves from the mantis #951 failure.
6150 // However, we could do this for several other handlers where a failure isn't terminal 6575 // However, we could do this for several other handlers where a failure isn't terminal
6151 // for the client session anyway, in order to protect ourselves against bad code in plugins 6576 // for the client session anyway, in order to protect ourselves against bad code in plugins
6577 Vector3 avSize = appear.AgentData.Size;
6152 try 6578 try
6153 { 6579 {
6154 byte[] visualparams = new byte[appear.VisualParam.Length]; 6580 byte[] visualparams = new byte[appear.VisualParam.Length];
6155 for (int i = 0; i < appear.VisualParam.Length; i++) 6581 for (int i = 0; i < appear.VisualParam.Length; i++)
6156 visualparams[i] = appear.VisualParam[i].ParamValue; 6582 visualparams[i] = appear.VisualParam[i].ParamValue;
6583 //var b = appear.WearableData[0];
6157 6584
6158 Primitive.TextureEntry te = null; 6585 Primitive.TextureEntry te = null;
6159 if (appear.ObjectData.TextureEntry.Length > 1) 6586 if (appear.ObjectData.TextureEntry.Length > 1)
6160 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6587 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6161 6588
6162 handlerSetAppearance(sender, te, visualparams); 6589 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6590 for (int i=0; i<appear.WearableData.Length;i++)
6591 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6592
6593
6594
6595 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6163 } 6596 }
6164 catch (Exception e) 6597 catch (Exception e)
6165 { 6598 {
@@ -6426,6 +6859,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6426 } 6859 }
6427 #endregion 6860 #endregion
6428 6861
6862 if (SceneAgent.IsChildAgent)
6863 {
6864 SendCantSitBecauseChildAgentResponse();
6865 return true;
6866 }
6867
6429 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; 6868 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit;
6430 6869
6431 if (handlerAgentRequestSit != null) 6870 if (handlerAgentRequestSit != null)
@@ -6450,6 +6889,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6450 } 6889 }
6451 #endregion 6890 #endregion
6452 6891
6892 if (SceneAgent.IsChildAgent)
6893 {
6894 SendCantSitBecauseChildAgentResponse();
6895 return true;
6896 }
6897
6453 AgentSit handlerAgentSit = OnAgentSit; 6898 AgentSit handlerAgentSit = OnAgentSit;
6454 if (handlerAgentSit != null) 6899 if (handlerAgentSit != null)
6455 { 6900 {
@@ -6459,6 +6904,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6459 return true; 6904 return true;
6460 } 6905 }
6461 6906
6907 /// <summary>
6908 /// Used when a child agent gets a sit response which should not be fulfilled.
6909 /// </summary>
6910 private void SendCantSitBecauseChildAgentResponse()
6911 {
6912 SendAlertMessage("Try moving closer. Can't sit on object because it is not in the same region as you.");
6913 }
6914
6462 private bool HandleSoundTrigger(IClientAPI sender, Packet Pack) 6915 private bool HandleSoundTrigger(IClientAPI sender, Packet Pack)
6463 { 6916 {
6464 SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack; 6917 SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack;
@@ -6856,7 +7309,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6856 { 7309 {
6857 handlerObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset, 7310 handlerObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset,
6858 dupe.SharedData.DuplicateFlags, AgentId, 7311 dupe.SharedData.DuplicateFlags, AgentId,
6859 m_activeGroupID); 7312 ActiveGroupId);
6860 } 7313 }
6861 } 7314 }
6862 7315
@@ -7031,14 +7484,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7031 7484
7032 if (handlerUpdatePrimFlags != null) 7485 if (handlerUpdatePrimFlags != null)
7033 { 7486 {
7034 byte[] data = Pack.ToBytes(); 7487// byte[] data = Pack.ToBytes();
7035 // 46,47,48 are special positions within the packet 7488 // 46,47,48 are special positions within the packet
7036 // This may change so perhaps we need a better way 7489 // This may change so perhaps we need a better way
7037 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7490 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7038 bool UsePhysics = (data[46] != 0) ? true : false; 7491 /*
7039 bool IsTemporary = (data[47] != 0) ? true : false; 7492 bool UsePhysics = (data[46] != 0) ? true : false;
7040 bool IsPhantom = (data[48] != 0) ? true : false; 7493 bool IsTemporary = (data[47] != 0) ? true : false;
7041 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7494 bool IsPhantom = (data[48] != 0) ? true : false;
7495 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7496 */
7497 bool UsePhysics = flags.AgentData.UsePhysics;
7498 bool IsPhantom = flags.AgentData.IsPhantom;
7499 bool IsTemporary = flags.AgentData.IsTemporary;
7500 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7501 ExtraPhysicsData physdata = new ExtraPhysicsData();
7502
7503 if (blocks == null || blocks.Length == 0)
7504 {
7505 physdata.PhysShapeType = PhysShapeType.invalid;
7506 }
7507 else
7508 {
7509 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7510 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7511 physdata.Bounce = phsblock.Restitution;
7512 physdata.Density = phsblock.Density;
7513 physdata.Friction = phsblock.Friction;
7514 physdata.GravitationModifier = phsblock.GravityMultiplier;
7515 }
7516
7517 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7042 } 7518 }
7043 return true; 7519 return true;
7044 } 7520 }
@@ -7446,7 +7922,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7446 if (handlerObjectDuplicateOnRay != null) 7922 if (handlerObjectDuplicateOnRay != null)
7447 { 7923 {
7448 handlerObjectDuplicateOnRay(dupeOnRay.ObjectData[i].ObjectLocalID, dupeOnRay.AgentData.DuplicateFlags, 7924 handlerObjectDuplicateOnRay(dupeOnRay.ObjectData[i].ObjectLocalID, dupeOnRay.AgentData.DuplicateFlags,
7449 AgentId, m_activeGroupID, dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd, 7925 AgentId, ActiveGroupId, dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd,
7450 dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast, dupeOnRay.AgentData.RayEndIsIntersection, 7926 dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast, dupeOnRay.AgentData.RayEndIsIntersection,
7451 dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates); 7927 dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates);
7452 } 7928 }
@@ -7640,129 +8116,146 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7640 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); 8116 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
7641 8117
7642 TransferRequestPacket transfer = (TransferRequestPacket)Pack; 8118 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
7643 //m_log.Debug("Transfer Request: " + transfer.ToString());
7644 // Validate inventory transfers
7645 // Has to be done here, because AssetCache can't do it
7646 //
7647 UUID taskID = UUID.Zero; 8119 UUID taskID = UUID.Zero;
7648 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) 8120 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
7649 { 8121 {
7650 taskID = new UUID(transfer.TransferInfo.Params, 48);
7651 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7652 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7653
7654// m_log.DebugFormat(
7655// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7656// requestID, itemID, taskID, Name);
7657
7658 if (!(((Scene)m_scene).Permissions.BypassPermissions())) 8122 if (!(((Scene)m_scene).Permissions.BypassPermissions()))
7659 { 8123 {
7660 if (taskID != UUID.Zero) // Prim 8124 // We're spawning a thread because the permissions check can block this thread
8125 Util.FireAndForget(delegate
7661 { 8126 {
7662 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); 8127 // This requests the asset if needed
8128 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
8129 }, null, "LLClientView.HandleTransferRequest");
7663 8130
7664 if (part == null) 8131 return true;
7665 { 8132 }
7666 m_log.WarnFormat( 8133 }
7667 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist", 8134 else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
7668 Name, requestID, itemID, taskID); 8135 {
7669 return true; 8136 //TransferRequestPacket does not include covenant uuid?
7670 } 8137 //get scene covenant uuid
8138 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
8139 }
7671 8140
7672 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); 8141 // This is non-blocking
7673 if (tii == null) 8142 MakeAssetRequest(transfer, taskID);
7674 {
7675 m_log.WarnFormat(
7676 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7677 Name, requestID, itemID, taskID);
7678 return true;
7679 }
7680 8143
7681 if (tii.Type == (int)AssetType.LSLText) 8144 return true;
7682 { 8145 }
7683 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
7684 return true;
7685 }
7686 else if (tii.Type == (int)AssetType.Notecard)
7687 {
7688 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
7689 return true;
7690 }
7691 else
7692 {
7693 // TODO: Change this code to allow items other than notecards and scripts to be successfully
7694 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
7695 if (part.OwnerID != AgentId)
7696 {
7697 m_log.WarnFormat(
7698 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
7699 Name, requestID, itemID, taskID, part.OwnerID);
7700 return true;
7701 }
7702 8146
7703 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) 8147 private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
7704 { 8148 {
7705 m_log.WarnFormat( 8149 UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
7706 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set", 8150 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7707 Name, requestID, itemID, taskID); 8151 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7708 return true;
7709 }
7710 8152
7711 if (tii.OwnerID != AgentId) 8153 //m_log.DebugFormat(
7712 { 8154 // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7713 m_log.WarnFormat( 8155 // requestID, itemID, taskID, Name);
7714 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
7715 Name, requestID, itemID, taskID, tii.OwnerID);
7716 return true;
7717 }
7718 8156
7719 if (( 8157 //m_log.Debug("Transfer Request: " + transfer.ToString());
7720 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8158 // Validate inventory transfers
7721 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8159 // Has to be done here, because AssetCache can't do it
7722 { 8160 //
7723 m_log.WarnFormat( 8161 if (taskID != UUID.Zero) // Prim
7724 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", 8162 {
7725 Name, requestID, itemID, taskID); 8163 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
7726 return true;
7727 }
7728 8164
7729 if (tii.AssetID != requestID) 8165 if (part == null)
7730 { 8166 {
7731 m_log.WarnFormat( 8167 m_log.WarnFormat(
7732 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", 8168 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7733 Name, requestID, itemID, taskID, tii.AssetID); 8169 Name, requestID, itemID, taskID);
7734 return true; 8170 return;
7735 } 8171 }
7736 } 8172
8173 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
8174 if (tii == null)
8175 {
8176 m_log.WarnFormat(
8177 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
8178 Name, requestID, itemID, taskID);
8179 return;
8180 }
8181
8182 if (tii.Type == (int)AssetType.LSLText)
8183 {
8184 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
8185 return;
8186 }
8187 else if (tii.Type == (int)AssetType.Notecard)
8188 {
8189 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
8190 return;
8191 }
8192 else
8193 {
8194 // TODO: Change this code to allow items other than notecards and scripts to be successfully
8195 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
8196 if (part.OwnerID != AgentId)
8197 {
8198 m_log.WarnFormat(
8199 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
8200 Name, requestID, itemID, taskID, part.OwnerID);
8201 return;
7737 } 8202 }
7738 else // Agent 8203
8204 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
7739 { 8205 {
7740 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 8206 m_log.WarnFormat(
7741 if (invAccess != null) 8207 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7742 { 8208 Name, requestID, itemID, taskID);
7743 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) 8209 return;
7744 return false; 8210 }
7745 } 8211
7746 else 8212 if (tii.OwnerID != AgentId)
7747 { 8213 {
7748 return false; 8214 m_log.WarnFormat(
7749 } 8215 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
8216 Name, requestID, itemID, taskID, tii.OwnerID);
8217 return;
8218 }
8219
8220 if ((
8221 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8222 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8223 {
8224 m_log.WarnFormat(
8225 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
8226 Name, requestID, itemID, taskID);
8227 return;
8228 }
8229
8230 if (tii.AssetID != requestID)
8231 {
8232 m_log.WarnFormat(
8233 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
8234 Name, requestID, itemID, taskID, tii.AssetID);
8235 return;
7750 } 8236 }
7751 } 8237 }
7752 } 8238 }
7753 else 8239 else // Agent
7754 if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) 8240 {
8241 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
8242 if (invAccess != null)
7755 { 8243 {
7756 //TransferRequestPacket does not include covenant uuid? 8244 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
7757 //get scene covenant uuid 8245 return;
7758 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
7759 } 8246 }
8247 else
8248 {
8249 return;
8250 }
8251 }
7760 8252
8253 // Permissions out of the way, let's request the asset
7761 MakeAssetRequest(transfer, taskID); 8254 MakeAssetRequest(transfer, taskID);
7762 8255
7763 return true;
7764 } 8256 }
7765 8257
8258
7766 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack) 8259 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
7767 { 8260 {
7768 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; 8261 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
@@ -8477,8 +8970,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8477 return true; 8970 return true;
8478 } 8971 }
8479 #endregion 8972 #endregion
8480 string mapName = Util.UTF8.GetString(map.NameData.Name, 0, 8973 string mapName = (map.NameData.Name.Length == 0) ? m_scene.RegionInfo.RegionName :
8481 map.NameData.Name.Length - 1); 8974 Util.UTF8.GetString(map.NameData.Name, 0, map.NameData.Name.Length - 1);
8482 RequestMapName handlerMapNameRequest = OnMapNameRequest; 8975 RequestMapName handlerMapNameRequest = OnMapNameRequest;
8483 if (handlerMapNameRequest != null) 8976 if (handlerMapNameRequest != null)
8484 { 8977 {
@@ -8583,7 +9076,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8583 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 9076 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
8584 { 9077 {
8585 string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 9078 string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
8586 return ((Scene)Scene).AssetService.Get(assetServer + "/" + id); 9079 if (!string.IsNullOrEmpty(assetServer))
9080 return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
8587 } 9081 }
8588 9082
8589 return null; 9083 return null;
@@ -8606,6 +9100,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8606 TeleportLocationRequest handlerTeleportLocationRequest = OnTeleportLocationRequest; 9100 TeleportLocationRequest handlerTeleportLocationRequest = OnTeleportLocationRequest;
8607 if (handlerTeleportLocationRequest != null) 9101 if (handlerTeleportLocationRequest != null)
8608 { 9102 {
9103 // Adjust teleport location to base of a larger region if requested to teleport to a sub-region
9104 uint locX, locY;
9105 Util.RegionHandleToWorldLoc(tpLocReq.Info.RegionHandle, out locX, out locY);
9106 if ((locX >= m_scene.RegionInfo.WorldLocX)
9107 && (locX < (m_scene.RegionInfo.WorldLocX + m_scene.RegionInfo.RegionSizeX))
9108 && (locY >= m_scene.RegionInfo.WorldLocY)
9109 && (locY < (m_scene.RegionInfo.WorldLocY + m_scene.RegionInfo.RegionSizeY)) )
9110 {
9111 tpLocReq.Info.RegionHandle = m_scene.RegionInfo.RegionHandle;
9112 tpLocReq.Info.Position.X += locX - m_scene.RegionInfo.WorldLocX;
9113 tpLocReq.Info.Position.Y += locY - m_scene.RegionInfo.WorldLocY;
9114 }
9115
8609 handlerTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, 9116 handlerTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position,
8610 tpLocReq.Info.LookAt, 16); 9117 tpLocReq.Info.LookAt, 16);
8611 } 9118 }
@@ -9399,6 +9906,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9399 } 9906 }
9400 return true; 9907 return true;
9401 9908
9909 case "kickestate":
9910
9911 if(((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9912 {
9913 UUID invoice = messagePacket.MethodData.Invoice;
9914 UUID SenderID = messagePacket.AgentData.AgentID;
9915 UUID Prey;
9916
9917 UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[0].Parameter), out Prey);
9918
9919 OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey);
9920 }
9921 return true;
9922
9402 default: 9923 default:
9403 m_log.WarnFormat( 9924 m_log.WarnFormat(
9404 "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}", 9925 "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
@@ -9604,7 +10125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9604 EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; 10125 EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest;
9605 if (handlerEconomoyDataRequest != null) 10126 if (handlerEconomoyDataRequest != null)
9606 { 10127 {
9607 handlerEconomoyDataRequest(AgentId); 10128 handlerEconomoyDataRequest(this);
9608 } 10129 }
9609 return true; 10130 return true;
9610 } 10131 }
@@ -10032,7 +10553,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10032 handlerDirFindQuery(this, 10553 handlerDirFindQuery(this,
10033 dirFindQueryPacket.QueryData.QueryID, 10554 dirFindQueryPacket.QueryData.QueryID,
10034 Utils.BytesToString( 10555 Utils.BytesToString(
10035 dirFindQueryPacket.QueryData.QueryText), 10556 dirFindQueryPacket.QueryData.QueryText).Trim(),
10036 dirFindQueryPacket.QueryData.QueryFlags, 10557 dirFindQueryPacket.QueryData.QueryFlags,
10037 dirFindQueryPacket.QueryData.QueryStart); 10558 dirFindQueryPacket.QueryData.QueryStart);
10038 } 10559 }
@@ -11384,8 +11905,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11384 } 11905 }
11385 11906
11386 /// <summary> 11907 /// <summary>
11387 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11388 /// its appearance texture cached.
11389 /// </summary> 11908 /// </summary>
11390 /// <remarks> 11909 /// <remarks>
11391 /// At the moment, we always reply that there is no cached texture. 11910 /// At the moment, we always reply that there is no cached texture.
@@ -11395,13 +11914,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11395 /// <returns></returns> 11914 /// <returns></returns>
11396 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11915 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11397 { 11916 {
11398 //m_log.Debug("texture cached: " + packet.ToString());
11399 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11917 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11400 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); 11918 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
11401 11919
11402 if (cachedtex.AgentData.SessionID != SessionId) 11920 if (cachedtex.AgentData.SessionID != SessionId)
11403 return false; 11921 return false;
11404 11922
11923
11405 // TODO: don't create new blocks if recycling an old packet 11924 // TODO: don't create new blocks if recycling an old packet
11406 cachedresp.AgentData.AgentID = AgentId; 11925 cachedresp.AgentData.AgentID = AgentId;
11407 cachedresp.AgentData.SessionID = m_sessionId; 11926 cachedresp.AgentData.SessionID = m_sessionId;
@@ -11410,19 +11929,127 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11410 cachedresp.WearableData = 11929 cachedresp.WearableData =
11411 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11930 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11412 11931
11413 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11932 int maxWearablesLoop = cachedtex.WearableData.Length;
11933 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11934 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11935
11936 // Find the cached baked textures for this user, if they're available
11937
11938 IAssetService cache = m_scene.AssetService;
11939 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11940
11941 WearableCacheItem[] cacheItems = null;
11942
11943 if (bakedTextureModule != null && cache != null)
11414 { 11944 {
11415 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11945 ScenePresence p = m_scene.GetScenePresence(AgentId);
11416 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11946 if (p.Appearance != null)
11417 cachedresp.WearableData[i].TextureID = UUID.Zero; 11947 {
11418 cachedresp.WearableData[i].HostName = new byte[0]; 11948 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11949 {
11950 try
11951 {
11952 cacheItems = bakedTextureModule.Get(AgentId);
11953 p.Appearance.WearableCacheItems = cacheItems;
11954 p.Appearance.WearableCacheItemsDirty = false;
11955 }
11956 catch (Exception)
11957 {
11958 cacheItems = null;
11959 }
11960
11961 }
11962 else if (p.Appearance.WearableCacheItems != null)
11963 {
11964 cacheItems = p.Appearance.WearableCacheItems;
11965 }
11966 }
11419 } 11967 }
11420 11968
11969 if (cacheItems != null)
11970 {
11971 // We need to make sure the asset stored in the bake is available on this server also by its assetid before we map it to a Cacheid.
11972 // Copy the baked textures to the sim's assets cache (local only).
11973 foreach (WearableCacheItem item in cacheItems)
11974 {
11975 if (cache.GetCached(item.TextureID.ToString()) == null)
11976 {
11977 item.TextureAsset.Temporary = true;
11978 item.TextureAsset.Local = true;
11979 cache.Store(item.TextureAsset);
11980 }
11981 }
11982
11983 // Return the cached textures
11984 for (int i = 0; i < maxWearablesLoop; i++)
11985 {
11986 WearableCacheItem item =
11987 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex, cacheItems);
11988
11989 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11990 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11991 cachedresp.WearableData[i].HostName = new byte[0];
11992 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11993 {
11994 cachedresp.WearableData[i].TextureID = item.TextureID;
11995 }
11996 else
11997 {
11998 cachedresp.WearableData[i].TextureID = UUID.Zero;
11999 }
12000 }
12001 }
12002 else
12003 {
12004 // Cached textures not available
12005 for (int i = 0; i < maxWearablesLoop; i++)
12006 {
12007 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12008 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12009 cachedresp.WearableData[i].TextureID = UUID.Zero;
12010 cachedresp.WearableData[i].HostName = new byte[0];
12011 }
12012 }
12013
11421 cachedresp.Header.Zerocoded = true; 12014 cachedresp.Header.Zerocoded = true;
11422 OutPacket(cachedresp, ThrottleOutPacketType.Task); 12015 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11423 12016
11424 return true; 12017 return true;
11425 } 12018 }
12019
12020 /// <summary>
12021 /// Send a response back to a client when it asks the asset server (via the region server) if it has
12022 /// its appearance texture cached.
12023 /// </summary>
12024 /// <param name="avatar"></param>
12025 /// <param name="serial"></param>
12026 /// <param name="cachedTextures"></param>
12027 /// <returns></returns>
12028 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
12029 {
12030 ScenePresence presence = avatar as ScenePresence;
12031 if (presence == null)
12032 return;
12033
12034 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
12035
12036 // TODO: don't create new blocks if recycling an old packet
12037 cachedresp.AgentData.AgentID = m_agentId;
12038 cachedresp.AgentData.SessionID = m_sessionId;
12039 cachedresp.AgentData.SerialNum = serial;
12040 cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedTextures.Count];
12041
12042 for (int i = 0; i < cachedTextures.Count; i++)
12043 {
12044 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12045 cachedresp.WearableData[i].TextureIndex = (byte)cachedTextures[i].BakedTextureIndex;
12046 cachedresp.WearableData[i].TextureID = cachedTextures[i].BakedTextureID;
12047 cachedresp.WearableData[i].HostName = new byte[0];
12048 }
12049
12050 cachedresp.Header.Zerocoded = true;
12051 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12052 }
11426 12053
11427 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) 12054 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
11428 { 12055 {
@@ -11449,8 +12076,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11449 if (part == null) 12076 if (part == null)
11450 { 12077 {
11451 // It's a ghost! tell the client to delete it from view. 12078 // It's a ghost! tell the client to delete it from view.
11452 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 12079 simClient.SendKillObject(new List<uint> { localId });
11453 new List<uint> { localId });
11454 } 12080 }
11455 else 12081 else
11456 { 12082 {
@@ -11777,6 +12403,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11777 /// provide your own method.</param> 12403 /// provide your own method.</param>
11778 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) 12404 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
11779 { 12405 {
12406 if (m_outPacketsToDrop != null)
12407 if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
12408 return;
12409
11780 if (DebugPacketLevel > 0) 12410 if (DebugPacketLevel > 0)
11781 { 12411 {
11782 bool logPacket = true; 12412 bool logPacket = true;
@@ -11811,17 +12441,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11811 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); 12441 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
11812 } 12442 }
11813 12443
11814 public bool AddMoney(int debit)
11815 {
11816 if (m_moneyBalance + debit >= 0)
11817 {
11818 m_moneyBalance += debit;
11819 SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance);
11820 return true;
11821 }
11822 return false;
11823 }
11824
11825 protected void HandleAutopilot(Object sender, string method, List<String> args) 12444 protected void HandleAutopilot(Object sender, string method, List<String> args)
11826 { 12445 {
11827 float locx = 0; 12446 float locx = 0;
@@ -11846,6 +12465,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11846 /// <param name="Pack">OpenMetaverse.packet</param> 12465 /// <param name="Pack">OpenMetaverse.packet</param>
11847 public void ProcessInPacket(Packet packet) 12466 public void ProcessInPacket(Packet packet)
11848 { 12467 {
12468 if (m_inPacketsToDrop != null)
12469 if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
12470 return;
12471
11849 if (DebugPacketLevel > 0) 12472 if (DebugPacketLevel > 0)
11850 { 12473 {
11851 bool logPacket = true; 12474 bool logPacket = true;
@@ -11880,6 +12503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11880 12503
11881 shape.PCode = addPacket.ObjectData.PCode; 12504 shape.PCode = addPacket.ObjectData.PCode;
11882 shape.State = addPacket.ObjectData.State; 12505 shape.State = addPacket.ObjectData.State;
12506 shape.LastAttachPoint = addPacket.ObjectData.State;
11883 shape.PathBegin = addPacket.ObjectData.PathBegin; 12507 shape.PathBegin = addPacket.ObjectData.PathBegin;
11884 shape.PathEnd = addPacket.ObjectData.PathEnd; 12508 shape.PathEnd = addPacket.ObjectData.PathEnd;
11885 shape.PathScaleX = addPacket.ObjectData.PathScaleX; 12509 shape.PathScaleX = addPacket.ObjectData.PathScaleX;
@@ -11910,7 +12534,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11910 ClientInfo info = m_udpClient.GetClientInfo(); 12534 ClientInfo info = m_udpClient.GetClientInfo();
11911 12535
11912 info.proxyEP = null; 12536 info.proxyEP = null;
11913 info.agentcircuit = RequestClientInfo(); 12537 if (info.agentcircuit == null)
12538 info.agentcircuit = RequestClientInfo();
11914 12539
11915 return info; 12540 return info;
11916 } 12541 }
@@ -12079,6 +12704,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12079 return String.Empty; 12704 return String.Empty;
12080 } 12705 }
12081 12706
12707 public OSDMap OReport(string uptime, string version)
12708 {
12709 return new OSDMap();
12710 }
12711
12082 /// <summary> 12712 /// <summary>
12083 /// Make an asset request to the asset service in response to a client request. 12713 /// Make an asset request to the asset service in response to a client request.
12084 /// </summary> 12714 /// </summary>
@@ -12126,16 +12756,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12126 12756
12127 if (asset == null) 12757 if (asset == null)
12128 { 12758 {
12129 req.AssetInf = null; 12759 // Try the user's asset server
12130 req.AssetRequestSource = source; 12760 IInventoryAccessModule inventoryAccessModule = Scene.RequestModuleInterface<IInventoryAccessModule>();
12131 req.IsTextureRequest = false; 12761
12132 req.NumPackets = 0; 12762 string assetServerURL = string.Empty;
12133 req.Params = transferRequest.TransferInfo.Params; 12763 if (inventoryAccessModule.IsForeignUser(AgentId, out assetServerURL) && !string.IsNullOrEmpty(assetServerURL))
12134 req.RequestAssetID = requestID; 12764 {
12135 req.TransferRequestID = transferRequest.TransferInfo.TransferID; 12765 if (!assetServerURL.EndsWith("/") && !assetServerURL.EndsWith("="))
12766 assetServerURL = assetServerURL + "/";
12767
12768 //m_log.DebugFormat("[LLCLIENTVIEW]: asset {0} not found in local storage. Trying user's storage.", assetServerURL + id);
12769 asset = m_scene.AssetService.Get(assetServerURL + id);
12770 }
12771
12772 if (asset == null)
12773 {
12774 req.AssetInf = null;
12775 req.AssetRequestSource = source;
12776 req.IsTextureRequest = false;
12777 req.NumPackets = 0;
12778 req.Params = transferRequest.TransferInfo.Params;
12779 req.RequestAssetID = requestID;
12780 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
12781
12782 SendAssetNotFound(req);
12783 return;
12784 }
12136 12785
12137 SendAssetNotFound(req);
12138 return;
12139 } 12786 }
12140 12787
12141 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) 12788 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
@@ -12201,8 +12848,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12201 12848
12202 public struct PacketProcessor 12849 public struct PacketProcessor
12203 { 12850 {
12204 public PacketMethod method; 12851 /// <summary>
12205 public bool Async; 12852 /// Packet handling method.
12853 /// </summary>
12854 public PacketMethod method { get; set; }
12855
12856 /// <summary>
12857 /// Should this packet be handled asynchronously?
12858 /// </summary>
12859 public bool Async { get; set; }
12860
12861 /// <summary>
12862 /// If async is true, should this packet be handled in the async engine or given directly to a threadpool
12863 /// thread?
12864 /// </summary>
12865 public bool InEngine { get; set; }
12206 } 12866 }
12207 12867
12208 public class AsyncPacketProcess 12868 public class AsyncPacketProcess
@@ -12284,11 +12944,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12284 OutPacket(dialog, ThrottleOutPacketType.Task); 12944 OutPacket(dialog, ThrottleOutPacketType.Task);
12285 } 12945 }
12286 12946
12287 public void StopFlying(ISceneEntity p) 12947 public void SendAgentTerseUpdate(ISceneEntity p)
12288 { 12948 {
12289 if (p is ScenePresence) 12949 if (p is ScenePresence)
12290 { 12950 {
12291 ScenePresence presence = p as ScenePresence; 12951// m_log.DebugFormat(
12952// "[LLCLIENTVIEW]: Immediately sending terse agent update for {0} to {1} in {2}",
12953// p.Name, Name, Scene.Name);
12954
12292 // It turns out to get the agent to stop flying, you have to feed it stop flying velocities 12955 // It turns out to get the agent to stop flying, you have to feed it stop flying velocities
12293 // There's no explicit message to send the client to tell it to stop flying.. it relies on the 12956 // There's no explicit message to send the client to tell it to stop flying.. it relies on the
12294 // velocity, collision plane and avatar height 12957 // velocity, collision plane and avatar height
@@ -12296,34 +12959,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12296 // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air 12959 // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air
12297 // when the avatar stands up 12960 // when the avatar stands up
12298 12961
12299 Vector3 pos = presence.AbsolutePosition;
12300
12301 if (presence.Appearance.AvatarHeight != 127.0f)
12302 pos += new Vector3(0f, 0f, (presence.Appearance.AvatarHeight/6f));
12303 else
12304 pos += new Vector3(0f, 0f, (1.56f/6f));
12305
12306 presence.AbsolutePosition = pos;
12307
12308 // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
12309 // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
12310 // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
12311 // certain amount.. because the LLClient wouldn't land in that situation anyway.
12312
12313 // why are we still testing for this really old height value default???
12314 if (presence.Appearance.AvatarHeight != 127.0f)
12315 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - presence.Appearance.AvatarHeight/6f);
12316 else
12317 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f/6f));
12318
12319
12320 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = 12962 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
12321 CreateImprovedTerseBlock(p, false); 12963 CreateImprovedTerseBlock(p, false);
12322 12964
12323 const float TIME_DILATION = 1.0f; 12965 const float TIME_DILATION = 1.0f;
12324 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 12966 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
12325 12967
12326
12327 ImprovedTerseObjectUpdatePacket packet 12968 ImprovedTerseObjectUpdatePacket packet
12328 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( 12969 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
12329 PacketType.ImprovedTerseObjectUpdate); 12970 PacketType.ImprovedTerseObjectUpdate);
@@ -12565,5 +13206,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12565 eq.Enqueue(BuildEvent("BulkUpdateInventory", 13206 eq.Enqueue(BuildEvent("BulkUpdateInventory",
12566 llsd), AgentId); 13207 llsd), AgentId);
12567 } 13208 }
13209
13210 private HashSet<string> m_outPacketsToDrop;
13211
13212 public bool AddOutPacketToDropSet(string packetName)
13213 {
13214 if (m_outPacketsToDrop == null)
13215 m_outPacketsToDrop = new HashSet<string>();
13216
13217 return m_outPacketsToDrop.Add(packetName);
13218 }
13219
13220 public bool RemoveOutPacketFromDropSet(string packetName)
13221 {
13222 if (m_outPacketsToDrop == null)
13223 return false;
13224
13225 return m_outPacketsToDrop.Remove(packetName);
13226 }
13227
13228 public HashSet<string> GetOutPacketDropSet()
13229 {
13230 return new HashSet<string>(m_outPacketsToDrop);
13231 }
13232
13233 private HashSet<string> m_inPacketsToDrop;
13234
13235 public bool AddInPacketToDropSet(string packetName)
13236 {
13237 if (m_inPacketsToDrop == null)
13238 m_inPacketsToDrop = new HashSet<string>();
13239
13240 return m_inPacketsToDrop.Add(packetName);
13241 }
13242
13243 public bool RemoveInPacketFromDropSet(string packetName)
13244 {
13245 if (m_inPacketsToDrop == null)
13246 return false;
13247
13248 return m_inPacketsToDrop.Remove(packetName);
13249 }
13250
13251 public HashSet<string> GetInPacketDropSet()
13252 {
13253 return new HashSet<string>(m_inPacketsToDrop);
13254 }
12568 } 13255 }
12569} 13256}