diff options
author | David Walter Seikel | 2016-11-03 21:44:39 +1000 |
---|---|---|
committer | David Walter Seikel | 2016-11-03 21:44:39 +1000 |
commit | 134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch) | |
tree | 216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |
parent | More changing to production grid. Double oops. (diff) | |
download | opensim-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.cs | 1423 |
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; | |||
34 | using System.Threading; | 34 | using System.Threading; |
35 | using System.Timers; | 35 | using System.Timers; |
36 | using System.Xml; | 36 | using System.Xml; |
37 | |||
37 | using log4net; | 38 | using log4net; |
38 | using OpenMetaverse; | 39 | using OpenMetaverse; |
39 | using OpenMetaverse.Packets; | 40 | using OpenMetaverse.Packets; |
40 | using OpenMetaverse.Messages.Linden; | 41 | using OpenMetaverse.Messages.Linden; |
41 | using OpenMetaverse.StructuredData; | 42 | using OpenMetaverse.StructuredData; |
43 | |||
42 | using OpenSim.Framework; | 44 | using OpenSim.Framework; |
43 | using OpenSim.Framework.Client; | 45 | using OpenSim.Framework.Client; |
44 | using OpenSim.Framework.Monitoring; | 46 | using OpenSim.Framework.Monitoring; |
@@ -48,9 +50,9 @@ using OpenSim.Services.Interfaces; | |||
48 | using Timer = System.Timers.Timer; | 50 | using Timer = System.Timers.Timer; |
49 | using AssetLandmark = OpenSim.Framework.AssetLandmark; | 51 | using AssetLandmark = OpenSim.Framework.AssetLandmark; |
50 | using RegionFlags = OpenMetaverse.RegionFlags; | 52 | using RegionFlags = OpenMetaverse.RegionFlags; |
51 | using Nini.Config; | ||
52 | 53 | ||
53 | using System.IO; | 54 | using System.IO; |
55 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
54 | 56 | ||
55 | namespace OpenSim.Region.ClientStack.LindenUDP | 57 | namespace 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 | } |