aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs13256
1 files changed, 13256 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
new file mode 100644
index 0000000..e7dd9d3
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -0,0 +1,13256 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using System.Threading;
35using System.Timers;
36using System.Xml;
37
38using log4net;
39using OpenMetaverse;
40using OpenMetaverse.Packets;
41using OpenMetaverse.Messages.Linden;
42using OpenMetaverse.StructuredData;
43
44using OpenSim.Framework;
45using OpenSim.Framework.Client;
46using OpenSim.Framework.Monitoring;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Services.Interfaces;
50using Timer = System.Timers.Timer;
51using AssetLandmark = OpenSim.Framework.AssetLandmark;
52using RegionFlags = OpenMetaverse.RegionFlags;
53
54using System.IO;
55using PermissionMask = OpenSim.Framework.PermissionMask;
56
57namespace OpenSim.Region.ClientStack.LindenUDP
58{
59 public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
60
61 /// <summary>
62 /// Handles new client connections
63 /// Constructor takes a single Packet and authenticates everything
64 /// </summary>
65 public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector
66 {
67 /// <value>
68 /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
69 /// </value>
70 public int DebugPacketLevel { get; set; }
71
72 #region Events
73
74 public event BinaryGenericMessage OnBinaryGenericMessage;
75 public event Action<IClientAPI> OnLogout;
76 public event ObjectPermissions OnObjectPermissions;
77 public event Action<IClientAPI> OnConnectionClosed;
78 public event ViewerEffectEventHandler OnViewerEffect;
79 public event ImprovedInstantMessage OnInstantMessage;
80 public event ChatMessage OnChatFromClient;
81 public event RezObject OnRezObject;
82 public event DeRezObject OnDeRezObject;
83 public event ModifyTerrain OnModifyTerrain;
84 public event Action<IClientAPI> OnRegionHandShakeReply;
85 public event GenericCall1 OnRequestWearables;
86 public event SetAppearance OnSetAppearance;
87 public event AvatarNowWearing OnAvatarNowWearing;
88 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
89 public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;
90 public event UUIDNameRequest OnDetachAttachmentIntoInv;
91 public event ObjectAttach OnObjectAttach;
92 public event ObjectDeselect OnObjectDetach;
93 public event ObjectDrop OnObjectDrop;
94 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
95 public event UpdateAgent OnPreAgentUpdate;
96 public event UpdateAgent OnAgentUpdate;
97 public event UpdateAgent OnAgentCameraUpdate;
98 public event AgentRequestSit OnAgentRequestSit;
99 public event AgentSit OnAgentSit;
100 public event AvatarPickerRequest OnAvatarPickerRequest;
101 public event StartAnim OnStartAnim;
102 public event StopAnim OnStopAnim;
103 public event Action<IClientAPI> OnRequestAvatarsData;
104 public event LinkObjects OnLinkObjects;
105 public event DelinkObjects OnDelinkObjects;
106 public event GrabObject OnGrabObject;
107 public event DeGrabObject OnDeGrabObject;
108 public event SpinStart OnSpinStart;
109 public event SpinStop OnSpinStop;
110 public event ObjectDuplicate OnObjectDuplicate;
111 public event ObjectDuplicateOnRay OnObjectDuplicateOnRay;
112 public event MoveObject OnGrabUpdate;
113 public event SpinObject OnSpinUpdate;
114 public event AddNewPrim OnAddPrim;
115 public event RequestGodlikePowers OnRequestGodlikePowers;
116 public event GodKickUser OnGodKickUser;
117 public event ObjectExtraParams OnUpdateExtraParams;
118 public event UpdateShape OnUpdatePrimShape;
119 public event ObjectRequest OnObjectRequest;
120 public event ObjectSelect OnObjectSelect;
121 public event ObjectDeselect OnObjectDeselect;
122 public event GenericCall7 OnObjectDescription;
123 public event GenericCall7 OnObjectName;
124 public event GenericCall7 OnObjectClickAction;
125 public event GenericCall7 OnObjectMaterial;
126 public event ObjectIncludeInSearch OnObjectIncludeInSearch;
127 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
128 public event UpdatePrimFlags OnUpdatePrimFlags;
129 public event UpdatePrimTexture OnUpdatePrimTexture;
130 public event UpdateVector OnUpdatePrimGroupPosition;
131 public event UpdateVector OnUpdatePrimSinglePosition;
132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
133 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
134 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
135 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
136 public event UpdateVector OnUpdatePrimScale;
137 public event UpdateVector OnUpdatePrimGroupScale;
138 public event RequestMapBlocks OnRequestMapBlocks;
139 public event RequestMapName OnMapNameRequest;
140 public event TeleportLocationRequest OnTeleportLocationRequest;
141 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
142 public event TeleportCancel OnTeleportCancel;
143 public event RequestAvatarProperties OnRequestAvatarProperties;
144 public event SetAlwaysRun OnSetAlwaysRun;
145 public event FetchInventory OnAgentDataUpdateRequest;
146 public event TeleportLocationRequest OnSetStartLocationRequest;
147 public event UpdateAvatarProperties OnUpdateAvatarProperties;
148 public event CreateNewInventoryItem OnCreateNewInventoryItem;
149 public event LinkInventoryItem OnLinkInventoryItem;
150 public event CreateInventoryFolder OnCreateNewInventoryFolder;
151 public event UpdateInventoryFolder OnUpdateInventoryFolder;
152 public event MoveInventoryFolder OnMoveInventoryFolder;
153 public event FetchInventoryDescendents OnFetchInventoryDescendents;
154 public event PurgeInventoryDescendents OnPurgeInventoryDescendents;
155 public event FetchInventory OnFetchInventory;
156 public event RequestTaskInventory OnRequestTaskInventory;
157 public event UpdateInventoryItem OnUpdateInventoryItem;
158 public event CopyInventoryItem OnCopyInventoryItem;
159 public event MoveInventoryItem OnMoveInventoryItem;
160 public event RemoveInventoryItem OnRemoveInventoryItem;
161 public event RemoveInventoryFolder OnRemoveInventoryFolder;
162 public event UDPAssetUploadRequest OnAssetUploadRequest;
163 public event XferReceive OnXferReceive;
164 public event RequestXfer OnRequestXfer;
165 public event ConfirmXfer OnConfirmXfer;
166 public event AbortXfer OnAbortXfer;
167 public event RequestTerrain OnRequestTerrain;
168 public event RezScript OnRezScript;
169 public event UpdateTaskInventory OnUpdateTaskInventory;
170 public event MoveTaskInventory OnMoveTaskItem;
171 public event RemoveTaskInventory OnRemoveTaskItem;
172 public event UUIDNameRequest OnNameFromUUIDRequest;
173 public event ParcelAccessListRequest OnParcelAccessListRequest;
174 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
175 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
176 public event ParcelDivideRequest OnParcelDivideRequest;
177 public event ParcelJoinRequest OnParcelJoinRequest;
178 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
179 public event ParcelSelectObjects OnParcelSelectObjects;
180 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
181 public event ParcelAbandonRequest OnParcelAbandonRequest;
182 public event ParcelGodForceOwner OnParcelGodForceOwner;
183 public event ParcelReclaim OnParcelReclaim;
184 public event ParcelReturnObjectsRequest OnParcelReturnObjectsRequest;
185 public event ParcelDeedToGroup OnParcelDeedToGroup;
186 public event RegionInfoRequest OnRegionInfoRequest;
187 public event EstateCovenantRequest OnEstateCovenantRequest;
188 public event FriendActionDelegate OnApproveFriendRequest;
189 public event FriendActionDelegate OnDenyFriendRequest;
190 public event FriendshipTermination OnTerminateFriendship;
191 public event GrantUserFriendRights OnGrantUserRights;
192 public event MoneyTransferRequest OnMoneyTransferRequest;
193 public event EconomyDataRequest OnEconomyDataRequest;
194 public event MoneyBalanceRequest OnMoneyBalanceRequest;
195 public event ParcelBuy OnParcelBuy;
196 public event UUIDNameRequest OnTeleportHomeRequest;
197 public event UUIDNameRequest OnUUIDGroupNameRequest;
198 public event ScriptAnswer OnScriptAnswer;
199 public event RequestPayPrice OnRequestPayPrice;
200 public event ObjectSaleInfo OnObjectSaleInfo;
201 public event ObjectBuy OnObjectBuy;
202 public event AgentSit OnUndo;
203 public event AgentSit OnRedo;
204 public event LandUndo OnLandUndo;
205 public event ForceReleaseControls OnForceReleaseControls;
206 public event GodLandStatRequest OnLandStatRequest;
207 public event RequestObjectPropertiesFamily OnObjectGroupRequest;
208 public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
209 public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
210 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
211 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
212 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
213 public event SetRegionTerrainSettings OnSetRegionTerrainSettings;
214 public event BakeTerrain OnBakeTerrain;
215 public event RequestTerrain OnUploadTerrain;
216 public event EstateChangeInfo OnEstateChangeInfo;
217 public event EstateManageTelehub OnEstateManageTelehub;
218 public event EstateRestartSimRequest OnEstateRestartSimRequest;
219 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
220 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
221 public event SimulatorBlueBoxMessageRequest OnSimulatorBlueBoxMessageRequest;
222 public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
223 public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
224 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
225 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
226 public event RegionHandleRequest OnRegionHandleRequest;
227 public event ParcelInfoRequest OnParcelInfoRequest;
228 public event ScriptReset OnScriptReset;
229 public event GetScriptRunning OnGetScriptRunning;
230 public event SetScriptRunning OnSetScriptRunning;
231 public event Action<Vector3, bool, bool> OnAutoPilotGo;
232 public event ActivateGesture OnActivateGesture;
233 public event DeactivateGesture OnDeactivateGesture;
234 public event ObjectOwner OnObjectOwner;
235 public event DirPlacesQuery OnDirPlacesQuery;
236 public event DirFindQuery OnDirFindQuery;
237 public event DirLandQuery OnDirLandQuery;
238 public event DirPopularQuery OnDirPopularQuery;
239 public event DirClassifiedQuery OnDirClassifiedQuery;
240 public event EventInfoRequest OnEventInfoRequest;
241 public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime;
242 public event MapItemRequest OnMapItemRequest;
243 public event OfferCallingCard OnOfferCallingCard;
244 public event AcceptCallingCard OnAcceptCallingCard;
245 public event DeclineCallingCard OnDeclineCallingCard;
246 public event SoundTrigger OnSoundTrigger;
247 public event StartLure OnStartLure;
248 public event TeleportLureRequest OnTeleportLureRequest;
249 public event NetworkStats OnNetworkStatsUpdate;
250 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
251 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
252 public event ClassifiedDelete OnClassifiedDelete;
253 public event ClassifiedDelete OnClassifiedGodDelete;
254 public event EventNotificationAddRequest OnEventNotificationAddRequest;
255 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
256 public event EventGodDelete OnEventGodDelete;
257 public event ParcelDwellRequest OnParcelDwellRequest;
258 public event UserInfoRequest OnUserInfoRequest;
259 public event UpdateUserInfo OnUpdateUserInfo;
260 public event RetrieveInstantMessages OnRetrieveInstantMessages;
261 public event PickDelete OnPickDelete;
262 public event PickGodDelete OnPickGodDelete;
263 public event PickInfoUpdate OnPickInfoUpdate;
264 public event AvatarNotesUpdate OnAvatarNotesUpdate;
265 public event MuteListRequest OnMuteListRequest;
266 public event AvatarInterestUpdate OnAvatarInterestUpdate;
267 public event PlacesQuery OnPlacesQuery;
268 public event AgentFOV OnAgentFOV;
269 public event FindAgentUpdate OnFindAgent;
270 public event TrackAgentUpdate OnTrackAgent;
271 public event NewUserReport OnUserReport;
272 public event SaveStateHandler OnSaveState;
273 public event GroupAccountSummaryRequest OnGroupAccountSummaryRequest;
274 public event GroupAccountDetailsRequest OnGroupAccountDetailsRequest;
275 public event GroupAccountTransactionsRequest OnGroupAccountTransactionsRequest;
276 public event FreezeUserUpdate OnParcelFreezeUser;
277 public event EjectUserUpdate OnParcelEjectUser;
278 public event ParcelBuyPass OnParcelBuyPass;
279 public event ParcelGodMark OnParcelGodMark;
280 public event GroupActiveProposalsRequest OnGroupActiveProposalsRequest;
281 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
282 public event SimWideDeletesDelegate OnSimWideDeletes;
283 public event SendPostcard OnSendPostcard;
284 public event MuteListEntryUpdate OnUpdateMuteListEntry;
285 public event MuteListEntryRemove OnRemoveMuteListEntry;
286 public event GodlikeMessage onGodlikeMessage;
287 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
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
303 #endregion Events
304
305 #region Class Members
306
307 // LLClientView Only
308 public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args);
309
310 /// <summary>Used to adjust Sun Orbit values so Linden based viewers properly position sun</summary>
311 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f;
312
313 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
314 private static string LogHeader = "[LLCLIENTVIEW]";
315 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
316
317 /// <summary>
318 /// Handles UDP texture download.
319 /// </summary>
320 public LLImageManager ImageManager { get; private set; }
321
322 private readonly LLUDPServer m_udpServer;
323 private readonly LLUDPClient m_udpClient;
324 private readonly UUID m_sessionId;
325 private readonly UUID m_secureSessionId;
326 protected readonly UUID m_agentId;
327 private readonly uint m_circuitCode;
328 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
329 private readonly IGroupsModule m_GroupsModule;
330
331 private int m_cachedTextureSerial;
332 private PriorityQueue m_entityUpdates;
333 private PriorityQueue m_entityProps;
334 private Prioritizer m_prioritizer;
335 private bool m_disableFacelights = false;
336 private volatile bool m_justEditedTerrain = false;
337 /// <value>
338 /// List used in construction of data blocks for an object update packet. This is to stop us having to
339 /// continually recreate it.
340 /// </value>
341 protected List<ObjectUpdatePacket.ObjectDataBlock> m_fullUpdateDataBlocksBuilder;
342
343 /// <value>
344 /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the
345 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
346 /// ownerless phantom.
347 ///
348 /// All manipulation of this set has to occur under a lock
349 ///
350 /// </value>
351 protected HashSet<uint> m_killRecord;
352
353// protected HashSet<uint> m_attachmentsSent;
354
355 private int m_animationSequenceNumber = 1;
356 private bool m_SendLogoutPacketWhenClosing = true;
357
358 /// <summary>
359 /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
360 /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
361 /// is doing absolutely nothing.
362 /// </summary>
363 /// <remarks>
364 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
365 /// cannot retain a reference to it outside of that method.
366 /// </remarks>
367 private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
368
369 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
370 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
371 protected Scene m_scene;
372 protected string m_firstName;
373 protected string m_lastName;
374 protected Thread m_clientThread;
375 protected Vector3 m_startpos;
376 protected UUID m_activeGroupID;
377 protected string m_activeGroupName = String.Empty;
378 protected ulong m_activeGroupPowers;
379 protected Dictionary<UUID, ulong> m_groupPowers = new Dictionary<UUID, ulong>();
380 protected int m_terrainCheckerCount;
381 protected uint m_agentFOVCounter;
382
383 protected IAssetService m_assetService;
384 private const bool m_checkPackets = true;
385
386 #endregion Class Members
387
388 #region Properties
389
390 public LLUDPClient UDPClient { get { return m_udpClient; } }
391 public LLUDPServer UDPServer { get { return m_udpServer; } }
392 public IPEndPoint RemoteEndPoint { get { return m_udpClient.RemoteEndPoint; } }
393 public UUID SecureSessionId { get { return m_secureSessionId; } }
394 public IScene Scene { get { return m_scene; } }
395 public UUID SessionId { get { return m_sessionId; } }
396 public Vector3 StartPos
397 {
398 get { return m_startpos; }
399 set { m_startpos = value; }
400 }
401 public UUID AgentId { get { return m_agentId; } }
402 public ISceneAgent SceneAgent { get; set; }
403 public UUID ActiveGroupId { get { return m_activeGroupID; } private set { m_activeGroupID = value; } }
404 public string ActiveGroupName { get { return m_activeGroupName; } private set { m_activeGroupName = value; } }
405 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } private set { m_activeGroupPowers = value; } }
406 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
407
408 /// <summary>
409 /// Entity update queues
410 /// </summary>
411 public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } }
412
413 /// <summary>
414 /// First name of the agent/avatar represented by the client
415 /// </summary>
416 public string FirstName { get { return m_firstName; } }
417
418 /// <summary>
419 /// Last name of the agent/avatar represented by the client
420 /// </summary>
421 public string LastName { get { return m_lastName; } }
422
423 /// <summary>
424 /// Full name of the client (first name and last name)
425 /// </summary>
426 public string Name { get { return FirstName + " " + LastName; } }
427
428 public uint CircuitCode { get { return m_circuitCode; } }
429 public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
430
431 /// <summary>
432 /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
433 /// prevent race conditions by different threads calling Close().
434 /// </summary>
435 public bool IsActive { get; set; }
436
437 /// <summary>
438 /// Used to synchronise threads when client is being closed.
439 /// </summary>
440 public Object CloseSyncLock { get; private set; }
441
442 public bool IsLoggingOut { get; set; }
443
444 public bool DisableFacelights
445 {
446 get { return m_disableFacelights; }
447 set { m_disableFacelights = value; }
448 }
449
450 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
451
452 #endregion Properties
453
454// ~LLClientView()
455// {
456// m_log.DebugFormat("{0} Destructor called for {1}, circuit code {2}", LogHeader, Name, CircuitCode);
457// }
458
459 /// <summary>
460 /// Constructor
461 /// </summary>
462 public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
463 UUID agentId, UUID sessionId, uint circuitCode)
464 {
465// DebugPacketLevel = 1;
466
467 CloseSyncLock = new Object();
468
469 RegisterInterface<IClientIM>(this);
470 RegisterInterface<IClientInventory>(this);
471 RegisterInterface<IClientChat>(this);
472
473 m_scene = scene;
474 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
475 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
476 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
477 m_killRecord = new HashSet<uint>();
478// m_attachmentsSent = new HashSet<uint>();
479
480 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
481 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
482 ImageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
483 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
484 m_agentId = agentId;
485 m_sessionId = sessionId;
486 m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
487 m_circuitCode = circuitCode;
488 m_firstName = sessionInfo.LoginInfo.First;
489 m_lastName = sessionInfo.LoginInfo.Last;
490 m_startpos = sessionInfo.LoginInfo.StartPos;
491
492 m_udpServer = udpServer;
493 m_udpClient = udpClient;
494 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
495 m_udpClient.HasUpdates += HandleHasUpdates;
496 m_udpClient.OnPacketStats += PopulateStats;
497
498 m_prioritizer = new Prioritizer(m_scene);
499
500 RegisterLocalPacketHandlers();
501
502 IsActive = true;
503 }
504
505 #region Client Methods
506
507 public void Close()
508 {
509 Close(false);
510 }
511
512 public void Close(bool force)
513 {
514 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
515 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
516 lock (CloseSyncLock)
517 {
518 // We still perform a force close inside the sync lock since this is intended to attempt close where
519 // there is some unidentified connection problem, not where we have issues due to deadlock
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
525 return;
526 }
527
528 IsActive = false;
529 CloseWithoutChecks();
530 }
531 }
532
533 /// <summary>
534 /// Closes down the client view without first checking whether it is active.
535 /// </summary>
536 /// <remarks>
537 /// This exists because LLUDPServer has to set IsActive = false in earlier synchronous code before calling
538 /// CloseWithoutIsActiveCheck asynchronously.
539 ///
540 /// Callers must lock ClosingSyncLock before calling.
541 /// </remarks>
542 public void CloseWithoutChecks()
543 {
544 m_log.DebugFormat(
545 "[CLIENT]: Close has been called for {0} attached to scene {1}",
546 Name, m_scene.RegionInfo.RegionName);
547
548 // Shutdown the image manager
549 ImageManager.Close();
550
551 // Fire the callback for this connection closing
552 if (OnConnectionClosed != null)
553 OnConnectionClosed(this);
554
555 // Flush all of the packets out of the UDP server for this client
556 if (m_udpServer != null)
557 m_udpServer.Flush(m_udpClient);
558
559 // Remove ourselves from the scene
560 m_scene.RemoveClient(AgentId, true);
561 SceneAgent = null;
562
563 // We can't reach into other scenes and close the connection
564 // We need to do this over grid communications
565 //m_scene.CloseAllAgents(CircuitCode);
566
567 // Disable UDP handling for this client
568 m_udpClient.Shutdown();
569
570 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
571 //GC.Collect();
572 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
573 }
574
575 public void Kick(string message)
576 {
577 if (!SceneAgent.IsChildAgent)
578 {
579 KickUserPacket kupack = (KickUserPacket)PacketPool.Instance.GetPacket(PacketType.KickUser);
580 kupack.UserInfo.AgentID = AgentId;
581 kupack.UserInfo.SessionID = SessionId;
582 kupack.TargetBlock.TargetIP = 0;
583 kupack.TargetBlock.TargetPort = 0;
584 kupack.UserInfo.Reason = Util.StringToBytes256(message);
585 OutPacket(kupack, ThrottleOutPacketType.Task);
586 // You must sleep here or users get no message!
587 Thread.Sleep(500);
588 }
589 }
590
591 public void Stop()
592 {
593
594 }
595
596 #endregion Client Methods
597
598 #region Packet Handling
599
600 public void PopulateStats(int inPackets, int outPackets, int unAckedBytes)
601 {
602 NetworkStats handlerNetworkStatsUpdate = OnNetworkStatsUpdate;
603 if (handlerNetworkStatsUpdate != null)
604 {
605 handlerNetworkStatsUpdate(inPackets, outPackets, unAckedBytes);
606 }
607 }
608
609 public static bool AddPacketHandler(PacketType packetType, PacketMethod handler)
610 {
611 bool result = false;
612 lock (PacketHandlers)
613 {
614 if (!PacketHandlers.ContainsKey(packetType))
615 {
616 PacketHandlers.Add(packetType, handler);
617 result = true;
618 }
619 }
620 return result;
621 }
622
623 /// <summary>
624 /// Add a handler for the given packet type.
625 /// </summary>
626 /// <remarks>
627 /// The packet is handled on its own thread. If packets must be handled in the order in which they
628 /// are received then please use the synchronous version of this method.
629 /// </remarks>
630 /// <param name="packetType"></param>
631 /// <param name="handler"></param>
632 /// <returns>true if the handler was added. This is currently always the case.</returns>
633 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
634 {
635 return AddLocalPacketHandler(packetType, handler, true);
636 }
637
638 /// <summary>
639 /// Add a handler for the given packet type.
640 /// </summary>
641 /// <param name="packetType"></param>
642 /// <param name="handler"></param>
643 /// <param name="doAsync">
644 /// If true, when the packet is received it is handled on its own thread rather than on the main inward bound
645 /// packet handler thread. This vastly increases respnosiveness but some packets need to be handled
646 /// synchronously.
647 /// </param>
648 /// <returns>true if the handler was added. This is currently always the case.</returns>
649 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
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 {
674 bool result = false;
675 lock (m_packetHandlers)
676 {
677 if (!m_packetHandlers.ContainsKey(packetType))
678 {
679 m_packetHandlers.Add(
680 packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine });
681 result = true;
682 }
683 }
684
685 return result;
686 }
687
688 public bool AddGenericPacketHandler(string MethodName, GenericMessage handler)
689 {
690 MethodName = MethodName.ToLower().Trim();
691
692 bool result = false;
693 lock (m_genericPacketHandlers)
694 {
695 if (!m_genericPacketHandlers.ContainsKey(MethodName))
696 {
697 m_genericPacketHandlers.Add(MethodName, handler);
698 result = true;
699 }
700 }
701 return result;
702 }
703
704 /// <summary>
705 /// Try to process a packet using registered packet handlers
706 /// </summary>
707 /// <param name="packet"></param>
708 /// <returns>True if a handler was found which successfully processed the packet.</returns>
709 protected virtual bool ProcessPacketMethod(Packet packet)
710 {
711 bool result = false;
712 PacketProcessor pprocessor;
713 if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor))
714 {
715 ClientInfo cinfo = UDPClient.GetClientInfo();
716
717 //there is a local handler for this packet type
718 if (pprocessor.Async)
719 {
720 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
721 cinfo.AsyncRequests[packet.Type.ToString()] = 0;
722 cinfo.AsyncRequests[packet.Type.ToString()]++;
723
724 object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
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
731 result = true;
732 }
733 else
734 {
735 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
736 cinfo.SyncRequests[packet.Type.ToString()] = 0;
737 cinfo.SyncRequests[packet.Type.ToString()]++;
738
739 result = pprocessor.method(this, packet);
740 }
741 }
742 else
743 {
744 //there is not a local handler so see if there is a Global handler
745 PacketMethod method = null;
746 bool found;
747 lock (PacketHandlers)
748 {
749 found = PacketHandlers.TryGetValue(packet.Type, out method);
750 }
751 if (found)
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
758 result = method(this, packet);
759 }
760 }
761 return result;
762 }
763
764 public void ProcessSpecificPacketAsync(object state)
765 {
766 AsyncPacketProcess packetObject = (AsyncPacketProcess)state;
767
768 try
769 {
770 packetObject.result = packetObject.Method(packetObject.ClientView, packetObject.Pack);
771 }
772 catch (Exception e)
773 {
774 // Make sure that we see any exception caused by the asynchronous operation.
775 m_log.Error(
776 string.Format(
777 "[LLCLIENTVIEW]: Caught exception while processing {0} for {1} ", packetObject.Pack, Name),
778 e);
779 }
780 }
781
782 #endregion Packet Handling
783
784 # region Setup
785
786 public virtual void Start()
787 {
788 m_scene.AddNewAgent(this, PresenceType.User);
789
790 RefreshGroupMembership();
791 }
792
793 # endregion
794
795 public void ActivateGesture(UUID assetId, UUID gestureId)
796 {
797 }
798
799 public void DeactivateGesture(UUID assetId, UUID gestureId)
800 {
801 }
802
803 // Sound
804 public void SoundTrigger(UUID soundId, UUID owerid, UUID Objectid, UUID ParentId, float Gain, Vector3 Position, UInt64 Handle)
805 {
806 }
807
808 #region Scene/Avatar to Client
809
810 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
811 {
812 RegionHandshakePacket handshake = (RegionHandshakePacket)PacketPool.Instance.GetPacket(PacketType.RegionHandshake);
813 handshake.RegionInfo = new RegionHandshakePacket.RegionInfoBlock();
814 handshake.RegionInfo.BillableFactor = args.billableFactor;
815 handshake.RegionInfo.IsEstateManager = args.isEstateManager;
816 handshake.RegionInfo.TerrainHeightRange00 = args.terrainHeightRange0;
817 handshake.RegionInfo.TerrainHeightRange01 = args.terrainHeightRange1;
818 handshake.RegionInfo.TerrainHeightRange10 = args.terrainHeightRange2;
819 handshake.RegionInfo.TerrainHeightRange11 = args.terrainHeightRange3;
820 handshake.RegionInfo.TerrainStartHeight00 = args.terrainStartHeight0;
821 handshake.RegionInfo.TerrainStartHeight01 = args.terrainStartHeight1;
822 handshake.RegionInfo.TerrainStartHeight10 = args.terrainStartHeight2;
823 handshake.RegionInfo.TerrainStartHeight11 = args.terrainStartHeight3;
824 handshake.RegionInfo.SimAccess = args.simAccess;
825 handshake.RegionInfo.WaterHeight = args.waterHeight;
826
827 handshake.RegionInfo.RegionFlags = args.regionFlags;
828 handshake.RegionInfo.SimName = Util.StringToBytes256(args.regionName);
829 handshake.RegionInfo.SimOwner = args.SimOwner;
830 handshake.RegionInfo.TerrainBase0 = args.terrainBase0;
831 handshake.RegionInfo.TerrainBase1 = args.terrainBase1;
832 handshake.RegionInfo.TerrainBase2 = args.terrainBase2;
833 handshake.RegionInfo.TerrainBase3 = args.terrainBase3;
834 handshake.RegionInfo.TerrainDetail0 = args.terrainDetail0;
835 handshake.RegionInfo.TerrainDetail1 = args.terrainDetail1;
836 handshake.RegionInfo.TerrainDetail2 = args.terrainDetail2;
837 handshake.RegionInfo.TerrainDetail3 = args.terrainDetail3;
838 handshake.RegionInfo.CacheID = UUID.Random(); //I guess this is for the client to remember an old setting?
839 handshake.RegionInfo2 = new RegionHandshakePacket.RegionInfo2Block();
840 handshake.RegionInfo2.RegionID = regionInfo.RegionID;
841
842 handshake.RegionInfo3 = new RegionHandshakePacket.RegionInfo3Block();
843 handshake.RegionInfo3.CPUClassID = 9;
844 handshake.RegionInfo3.CPURatio = 1;
845
846 handshake.RegionInfo3.ColoName = Utils.EmptyBytes;
847 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
848 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
849
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);
856 }
857
858
859 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
860 {
861 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
862 mov.SimData.ChannelVersion = m_channelVersion;
863 mov.AgentData.SessionID = m_sessionId;
864 mov.AgentData.AgentID = AgentId;
865 mov.Data.RegionHandle = regInfo.RegionHandle;
866 mov.Data.Timestamp = (uint)Util.UnixTimeSinceEpoch();
867
868 if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0))
869 {
870 mov.Data.Position = m_startpos;
871 }
872 else
873 {
874 mov.Data.Position = pos;
875 }
876 mov.Data.LookAt = look;
877
878 // Hack to get this out immediately and skip the throttles
879 OutPacket(mov, ThrottleOutPacketType.Unknown);
880 }
881
882 public void SendChatMessage(
883 string message, byte type, Vector3 fromPos, string fromName,
884 UUID fromAgentID, UUID ownerID, byte source, byte audible)
885 {
886 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
887 reply.ChatData.Audible = audible;
888 reply.ChatData.Message = Util.StringToBytes1024(message);
889 reply.ChatData.ChatType = type;
890 reply.ChatData.SourceType = source;
891 reply.ChatData.Position = fromPos;
892 reply.ChatData.FromName = Util.StringToBytes256(fromName);
893 reply.ChatData.OwnerID = ownerID;
894 reply.ChatData.SourceID = fromAgentID;
895
896 OutPacket(reply, ThrottleOutPacketType.Task);
897 }
898
899 /// <summary>
900 /// Send an instant message to this client
901 /// </summary>
902 //
903 // Don't remove transaction ID! Groups and item gives need to set it!
904 public void SendInstantMessage(GridInstantMessage im)
905 {
906 if (((Scene)(m_scene)).Permissions.CanInstantMessage(new UUID(im.fromAgentID), new UUID(im.toAgentID)))
907 {
908 ImprovedInstantMessagePacket msg
909 = (ImprovedInstantMessagePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedInstantMessage);
910
911 msg.AgentData.AgentID = new UUID(im.fromAgentID);
912 msg.AgentData.SessionID = UUID.Zero;
913 msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName);
914 msg.MessageBlock.Dialog = im.dialog;
915 msg.MessageBlock.FromGroup = im.fromGroup;
916 if (im.imSessionID == UUID.Zero.Guid)
917 msg.MessageBlock.ID = new UUID(im.fromAgentID) ^ new UUID(im.toAgentID);
918 else
919 msg.MessageBlock.ID = new UUID(im.imSessionID);
920 msg.MessageBlock.Offline = im.offline;
921 msg.MessageBlock.ParentEstateID = im.ParentEstateID;
922 msg.MessageBlock.Position = im.Position;
923 msg.MessageBlock.RegionID = new UUID(im.RegionID);
924 msg.MessageBlock.Timestamp = im.timestamp;
925 msg.MessageBlock.ToAgentID = new UUID(im.toAgentID);
926 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
927 msg.MessageBlock.BinaryBucket = im.binaryBucket;
928
929 if (im.message.StartsWith("[grouptest]"))
930 { // this block is test code for implementing group IM - delete when group IM is finished
931 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
932 if (eq != null)
933 {
934 im.dialog = 17;
935
936 //eq.ChatterboxInvitation(
937 // new UUID("00000000-68f9-1111-024e-222222111123"),
938 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
939 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
940
941 eq.ChatterboxInvitation(
942 new UUID("00000000-68f9-1111-024e-222222111123"),
943 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
944 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
945
946 eq.ChatterBoxSessionAgentListUpdates(
947 new UUID("00000000-68f9-1111-024e-222222111123"),
948 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
949 }
950
951 Console.WriteLine("SendInstantMessage: " + msg);
952 }
953 else
954 OutPacket(msg, ThrottleOutPacketType.Task);
955 }
956 }
957
958 public void SendGenericMessage(string method, UUID invoice, List<string> message)
959 {
960 GenericMessagePacket gmp = new GenericMessagePacket();
961
962 gmp.AgentData.AgentID = AgentId;
963 gmp.AgentData.SessionID = m_sessionId;
964 gmp.AgentData.TransactionID = invoice;
965
966 gmp.MethodData.Method = Util.StringToBytes256(method);
967 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
968 int i = 0;
969 foreach (string val in message)
970 {
971 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
972 gmp.ParamList[i++].Parameter = Util.StringToBytes256(val);
973 }
974
975 OutPacket(gmp, ThrottleOutPacketType.Task);
976 }
977
978 public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
979 {
980 GenericMessagePacket gmp = new GenericMessagePacket();
981
982 gmp.AgentData.AgentID = AgentId;
983 gmp.AgentData.SessionID = m_sessionId;
984 gmp.AgentData.TransactionID = invoice;
985
986 gmp.MethodData.Method = Util.StringToBytes256(method);
987 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
988 int i = 0;
989 foreach (byte[] val in message)
990 {
991 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
992 gmp.ParamList[i++].Parameter = val;
993 }
994
995 OutPacket(gmp, ThrottleOutPacketType.Task);
996 }
997
998 public void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals)
999 {
1000 int i = 0;
1001 foreach (GroupActiveProposals Proposal in Proposals)
1002 {
1003 GroupActiveProposalItemReplyPacket GAPIRP = new GroupActiveProposalItemReplyPacket();
1004
1005 GAPIRP.AgentData.AgentID = AgentId;
1006 GAPIRP.AgentData.GroupID = groupID;
1007 GAPIRP.TransactionData.TransactionID = transactionID;
1008 GAPIRP.TransactionData.TotalNumItems = ((uint)i+1);
1009 GroupActiveProposalItemReplyPacket.ProposalDataBlock ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock();
1010 GAPIRP.ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock[1];
1011 ProposalData.VoteCast = Utils.StringToBytes("false");
1012 ProposalData.VoteID = new UUID(Proposal.VoteID);
1013 ProposalData.VoteInitiator = new UUID(Proposal.VoteInitiator);
1014 ProposalData.Majority = (float)Convert.ToInt32(Proposal.Majority);
1015 ProposalData.Quorum = Convert.ToInt32(Proposal.Quorum);
1016 ProposalData.TerseDateID = Utils.StringToBytes(Proposal.TerseDateID);
1017 ProposalData.StartDateTime = Utils.StringToBytes(Proposal.StartDateTime);
1018 ProposalData.EndDateTime = Utils.StringToBytes(Proposal.EndDateTime);
1019 ProposalData.ProposalText = Utils.StringToBytes(Proposal.ProposalText);
1020 ProposalData.AlreadyVoted = false;
1021 GAPIRP.ProposalData[i] = ProposalData;
1022 OutPacket(GAPIRP, ThrottleOutPacketType.Task);
1023 i++;
1024 }
1025 if (Proposals.Length == 0)
1026 {
1027 GroupActiveProposalItemReplyPacket GAPIRP = new GroupActiveProposalItemReplyPacket();
1028
1029 GAPIRP.AgentData.AgentID = AgentId;
1030 GAPIRP.AgentData.GroupID = groupID;
1031 GAPIRP.TransactionData.TransactionID = transactionID;
1032 GAPIRP.TransactionData.TotalNumItems = 1;
1033 GroupActiveProposalItemReplyPacket.ProposalDataBlock ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock();
1034 GAPIRP.ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock[1];
1035 ProposalData.VoteCast = Utils.StringToBytes("false");
1036 ProposalData.VoteID = UUID.Zero;
1037 ProposalData.VoteInitiator = UUID.Zero;
1038 ProposalData.Majority = 0;
1039 ProposalData.Quorum = 0;
1040 ProposalData.TerseDateID = Utils.StringToBytes("");
1041 ProposalData.StartDateTime = Utils.StringToBytes("");
1042 ProposalData.EndDateTime = Utils.StringToBytes("");
1043 ProposalData.ProposalText = Utils.StringToBytes("");
1044 ProposalData.AlreadyVoted = false;
1045 GAPIRP.ProposalData[0] = ProposalData;
1046 OutPacket(GAPIRP, ThrottleOutPacketType.Task);
1047 }
1048 }
1049
1050 public void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes)
1051 {
1052 int i = 0;
1053 foreach (GroupVoteHistory Vote in Votes)
1054 {
1055 GroupVoteHistoryItemReplyPacket GVHIRP = new GroupVoteHistoryItemReplyPacket();
1056
1057 GVHIRP.AgentData.AgentID = AgentId;
1058 GVHIRP.AgentData.GroupID = groupID;
1059 GVHIRP.TransactionData.TransactionID = transactionID;
1060 GVHIRP.TransactionData.TotalNumItems = ((uint)i+1);
1061 GVHIRP.HistoryItemData.VoteID = new UUID(Vote.VoteID);
1062 GVHIRP.HistoryItemData.VoteInitiator = new UUID(Vote.VoteInitiator);
1063 GVHIRP.HistoryItemData.Majority = (float)Convert.ToInt32(Vote.Majority);
1064 GVHIRP.HistoryItemData.Quorum = Convert.ToInt32(Vote.Quorum);
1065 GVHIRP.HistoryItemData.TerseDateID = Utils.StringToBytes(Vote.TerseDateID);
1066 GVHIRP.HistoryItemData.StartDateTime = Utils.StringToBytes(Vote.StartDateTime);
1067 GVHIRP.HistoryItemData.EndDateTime = Utils.StringToBytes(Vote.EndDateTime);
1068 GVHIRP.HistoryItemData.VoteType = Utils.StringToBytes(Vote.VoteType);
1069 GVHIRP.HistoryItemData.VoteResult = Utils.StringToBytes(Vote.VoteResult);
1070 GVHIRP.HistoryItemData.ProposalText = Utils.StringToBytes(Vote.ProposalText);
1071 GroupVoteHistoryItemReplyPacket.VoteItemBlock VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock();
1072 GVHIRP.VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock[1];
1073 VoteItem.CandidateID = UUID.Zero;
1074 VoteItem.NumVotes = 0; //TODO: FIX THIS!!!
1075 VoteItem.VoteCast = Utils.StringToBytes("Yes");
1076 GVHIRP.VoteItem[i] = VoteItem;
1077 OutPacket(GVHIRP, ThrottleOutPacketType.Task);
1078 i++;
1079 }
1080 if (Votes.Length == 0)
1081 {
1082 GroupVoteHistoryItemReplyPacket GVHIRP = new GroupVoteHistoryItemReplyPacket();
1083
1084 GVHIRP.AgentData.AgentID = AgentId;
1085 GVHIRP.AgentData.GroupID = groupID;
1086 GVHIRP.TransactionData.TransactionID = transactionID;
1087 GVHIRP.TransactionData.TotalNumItems = 0;
1088 GVHIRP.HistoryItemData.VoteID = UUID.Zero;
1089 GVHIRP.HistoryItemData.VoteInitiator = UUID.Zero;
1090 GVHIRP.HistoryItemData.Majority = 0;
1091 GVHIRP.HistoryItemData.Quorum = 0;
1092 GVHIRP.HistoryItemData.TerseDateID = Utils.StringToBytes("");
1093 GVHIRP.HistoryItemData.StartDateTime = Utils.StringToBytes("");
1094 GVHIRP.HistoryItemData.EndDateTime = Utils.StringToBytes("");
1095 GVHIRP.HistoryItemData.VoteType = Utils.StringToBytes("");
1096 GVHIRP.HistoryItemData.VoteResult = Utils.StringToBytes("");
1097 GVHIRP.HistoryItemData.ProposalText = Utils.StringToBytes("");
1098 GroupVoteHistoryItemReplyPacket.VoteItemBlock VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock();
1099 GVHIRP.VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock[1];
1100 VoteItem.CandidateID = UUID.Zero;
1101 VoteItem.NumVotes = 0; //TODO: FIX THIS!!!
1102 VoteItem.VoteCast = Utils.StringToBytes("No");
1103 GVHIRP.VoteItem[0] = VoteItem;
1104 OutPacket(GVHIRP, ThrottleOutPacketType.Task);
1105 }
1106 }
1107
1108 public void SendGroupAccountingDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
1109 {
1110 GroupAccountDetailsReplyPacket GADRP = new GroupAccountDetailsReplyPacket();
1111 GADRP.AgentData = new GroupAccountDetailsReplyPacket.AgentDataBlock();
1112 GADRP.AgentData.AgentID = sender.AgentId;
1113 GADRP.AgentData.GroupID = groupID;
1114 GADRP.HistoryData = new GroupAccountDetailsReplyPacket.HistoryDataBlock[1];
1115 GroupAccountDetailsReplyPacket.HistoryDataBlock History = new GroupAccountDetailsReplyPacket.HistoryDataBlock();
1116 GADRP.MoneyData = new GroupAccountDetailsReplyPacket.MoneyDataBlock();
1117 GADRP.MoneyData.CurrentInterval = 0;
1118 GADRP.MoneyData.IntervalDays = 7;
1119 GADRP.MoneyData.RequestID = transactionID;
1120 GADRP.MoneyData.StartDate = Utils.StringToBytes(DateTime.Today.ToString());
1121 History.Amount = amt;
1122 History.Description = Utils.StringToBytes("");
1123 GADRP.HistoryData[0] = History;
1124 OutPacket(GADRP, ThrottleOutPacketType.Task);
1125 }
1126
1127 public void SendGroupAccountingSummary(IClientAPI sender,UUID groupID, uint moneyAmt, int totalTier, int usedTier)
1128 {
1129 GroupAccountSummaryReplyPacket GASRP =
1130 (GroupAccountSummaryReplyPacket)PacketPool.Instance.GetPacket(
1131 PacketType.GroupAccountSummaryReply);
1132
1133 GASRP.AgentData = new GroupAccountSummaryReplyPacket.AgentDataBlock();
1134 GASRP.AgentData.AgentID = sender.AgentId;
1135 GASRP.AgentData.GroupID = groupID;
1136 GASRP.MoneyData = new GroupAccountSummaryReplyPacket.MoneyDataBlock();
1137 GASRP.MoneyData.Balance = (int)moneyAmt;
1138 GASRP.MoneyData.TotalCredits = totalTier;
1139 GASRP.MoneyData.TotalDebits = usedTier;
1140 GASRP.MoneyData.StartDate = new byte[1];
1141 GASRP.MoneyData.CurrentInterval = 1;
1142 GASRP.MoneyData.GroupTaxCurrent = 0;
1143 GASRP.MoneyData.GroupTaxEstimate = 0;
1144 GASRP.MoneyData.IntervalDays = 0;
1145 GASRP.MoneyData.LandTaxCurrent = 0;
1146 GASRP.MoneyData.LandTaxEstimate = 0;
1147 GASRP.MoneyData.LastTaxDate = new byte[1];
1148 GASRP.MoneyData.LightTaxCurrent = 0;
1149 GASRP.MoneyData.TaxDate = new byte[1];
1150 GASRP.MoneyData.RequestID = sender.AgentId;
1151 GASRP.MoneyData.ParcelDirFeeEstimate = 0;
1152 GASRP.MoneyData.ParcelDirFeeCurrent = 0;
1153 GASRP.MoneyData.ObjectTaxEstimate = 0;
1154 GASRP.MoneyData.NonExemptMembers = 0;
1155 GASRP.MoneyData.ObjectTaxCurrent = 0;
1156 GASRP.MoneyData.LightTaxEstimate = 0;
1157 OutPacket(GASRP, ThrottleOutPacketType.Task);
1158 }
1159
1160 public void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
1161 {
1162 GroupAccountTransactionsReplyPacket GATRP =
1163 (GroupAccountTransactionsReplyPacket)PacketPool.Instance.GetPacket(
1164 PacketType.GroupAccountTransactionsReply);
1165
1166 GATRP.AgentData = new GroupAccountTransactionsReplyPacket.AgentDataBlock();
1167 GATRP.AgentData.AgentID = sender.AgentId;
1168 GATRP.AgentData.GroupID = groupID;
1169 GATRP.MoneyData = new GroupAccountTransactionsReplyPacket.MoneyDataBlock();
1170 GATRP.MoneyData.CurrentInterval = 0;
1171 GATRP.MoneyData.IntervalDays = 7;
1172 GATRP.MoneyData.RequestID = transactionID;
1173 GATRP.MoneyData.StartDate = Utils.StringToBytes(DateTime.Today.ToString());
1174 GATRP.HistoryData = new GroupAccountTransactionsReplyPacket.HistoryDataBlock[1];
1175 GroupAccountTransactionsReplyPacket.HistoryDataBlock History = new GroupAccountTransactionsReplyPacket.HistoryDataBlock();
1176 History.Amount = 0;
1177 History.Item = Utils.StringToBytes("");
1178 History.Time = Utils.StringToBytes("");
1179 History.Type = 0;
1180 History.User = Utils.StringToBytes("");
1181 GATRP.HistoryData[0] = History;
1182 OutPacket(GATRP, ThrottleOutPacketType.Task);
1183 }
1184
1185 /// <summary>
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.
1190 /// </summary>
1191 /// <param name="map">heightmap</param>
1192 public virtual void SendLayerData(float[] map)
1193 {
1194 Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData(), "LLClientView.DoSendLayerData");
1195 }
1196
1197 /// <summary>
1198 /// Send terrain layer information to the client.
1199 /// </summary>
1200 /// <param name="o"></param>
1201 private void DoSendLayerData(object o)
1202 {
1203 TerrainData map = (TerrainData)o;
1204
1205 try
1206 {
1207 // Send LayerData in typerwriter pattern
1208 //for (int y = 0; y < 16; y++)
1209 //{
1210 // for (int x = 0; x < 16; x++)
1211 // {
1212 // SendLayerData(x, y, map);
1213 // }
1214 //}
1215
1216 // Send LayerData in a spiral pattern. Fun!
1217 SendLayerTopRight(map, 0, 0, map.SizeX/Constants.TerrainPatchSize-1, map.SizeY/Constants.TerrainPatchSize-1);
1218 }
1219 catch (Exception e)
1220 {
1221 m_log.Error("[CLIENT]: SendLayerData() Failed with exception: " + e.Message, e);
1222 }
1223 }
1224
1225 private void SendLayerTopRight(TerrainData map, int x1, int y1, int x2, int y2)
1226 {
1227 // Row
1228 for (int i = x1; i <= x2; i++)
1229 SendLayerData(i, y1, map);
1230
1231 // Column
1232 for (int j = y1 + 1; j <= y2; j++)
1233 SendLayerData(x2, j, map);
1234
1235 if (x2 - x1 > 0 && y2 - y1 > 0)
1236 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1237 }
1238
1239 void SendLayerBottomLeft(TerrainData map, int x1, int y1, int x2, int y2)
1240 {
1241 // Row in reverse
1242 for (int i = x2; i >= x1; i--)
1243 SendLayerData(i, y2, map);
1244
1245 // Column in reverse
1246 for (int j = y2 - 1; j >= y1; j--)
1247 SendLayerData(x1, j, map);
1248
1249 if (x2 - x1 > 0 && y2 - y1 > 0)
1250 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1251 }
1252
1253 /// <summary>
1254 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1255 /// </summary>
1256 /// <param name="map">heightmap</param>
1257 /// <param name="px">X coordinate for patches 0..12</param>
1258 /// <param name="py">Y coordinate for patches 0..15</param>
1259 // private void SendLayerPacket(float[] map, int y, int x)
1260 // {
1261 // int[] patches = new int[4];
1262 // patches[0] = x + 0 + y * 16;
1263 // patches[1] = x + 1 + y * 16;
1264 // patches[2] = x + 2 + y * 16;
1265 // patches[3] = x + 3 + y * 16;
1266
1267 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches);
1268 // OutPacket(layerpack, ThrottleOutPacketType.Land);
1269 // }
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
1318 /// <summary>
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.
1322 /// </summary>
1323 /// <param name="px">Patch coordinate (x) 0..15</param>
1324 /// <param name="py">Patch coordinate (y) 0..15</param>
1325 /// <param name="map">heightmap</param>
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)
1334 {
1335 try
1336 {
1337 /* test code using the terrain compressor in libOpenMetaverse
1338 int[] patchInd = new int[1];
1339 patchInd[0] = px + (py * Constants.TerrainPatchSize);
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);
1358
1359 SendTheLayerPacket(layerpack);
1360 }
1361 // LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py);
1362
1363 }
1364 catch (Exception e)
1365 {
1366 m_log.Error("[CLIENT]: SendLayerData() Failed with exception: " + e.Message, e);
1367 }
1368 }
1369
1370 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a
1371 // sub optimal editing experience. To alleviate this issue, when the user edits the terrain, we
1372 // start skipping the queues until they're done editing the terrain. We also make them
1373 // unreliable because it's extremely likely that multiple packets will be sent for a terrain patch
1374 // area invalidating previous packets for that area.
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)
1387 {
1388 if (m_justEditedTerrain)
1389 {
1390 layerpack.Header.Reliable = false;
1391 OutPacket(layerpack, ThrottleOutPacketType.Unknown );
1392 }
1393 else
1394 {
1395 layerpack.Header.Reliable = true;
1396 OutPacket(layerpack, ThrottleOutPacketType.Land);
1397 }
1398 }
1399
1400 /// <summary>
1401 /// Send the wind matrix to the client
1402 /// </summary>
1403 /// <param name="windSpeeds">16x16 array of wind speeds</param>
1404 public virtual void SendWindData(Vector2[] windSpeeds)
1405 {
1406 Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData");
1407 }
1408
1409 /// <summary>
1410 /// Send the cloud matrix to the client
1411 /// </summary>
1412 /// <param name="windSpeeds">16x16 array of cloud densities</param>
1413 public virtual void SendCloudData(float[] cloudDensity)
1414 {
1415 Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData");
1416 }
1417
1418 /// <summary>
1419 /// Send wind layer information to the client.
1420 /// </summary>
1421 /// <param name="o"></param>
1422 private void DoSendWindData(object o)
1423 {
1424 Vector2[] windSpeeds = (Vector2[])o;
1425 TerrainPatch[] patches = new TerrainPatch[2];
1426 patches[0] = new TerrainPatch { Data = new float[16 * 16] };
1427 patches[1] = new TerrainPatch { Data = new float[16 * 16] };
1428
1429 for (int x = 0; x < 16 * 16; x++)
1430 {
1431 patches[0].Data[x] = windSpeeds[x].X;
1432 patches[1].Data[x] = windSpeeds[x].Y;
1433 }
1434
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);
1442 layerpack.Header.Zerocoded = true;
1443 OutPacket(layerpack, ThrottleOutPacketType.Wind);
1444 }
1445
1446 /// <summary>
1447 /// Send cloud layer information to the client.
1448 /// </summary>
1449 /// <param name="o"></param>
1450 private void DoSendCloudData(object o)
1451 {
1452 float[] cloudCover = (float[])o;
1453 TerrainPatch[] patches = new TerrainPatch[1];
1454 patches[0] = new TerrainPatch();
1455 patches[0].Data = new float[16 * 16];
1456
1457 for (int y = 0; y < 16; y++)
1458 {
1459 for (int x = 0; x < 16; x++)
1460 {
1461 patches[0].Data[y * 16 + x] = cloudCover[y * 16 + x];
1462 }
1463 }
1464
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);
1472 layerpack.Header.Zerocoded = true;
1473 OutPacket(layerpack, ThrottleOutPacketType.Cloud);
1474 }
1475
1476 /// <summary>
1477 /// Tell the client that the given neighbour region is ready to receive a child agent.
1478 /// </summary>
1479 public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourEndPoint)
1480 {
1481 IPAddress neighbourIP = neighbourEndPoint.Address;
1482 ushort neighbourPort = (ushort)neighbourEndPoint.Port;
1483
1484 EnableSimulatorPacket enablesimpacket = (EnableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.EnableSimulator);
1485 // TODO: don't create new blocks if recycling an old packet
1486 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
1487 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
1488
1489 byte[] byteIP = neighbourIP.GetAddressBytes();
1490 enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24;
1491 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16;
1492 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8;
1493 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0];
1494 enablesimpacket.SimulatorInfo.Port = neighbourPort;
1495
1496 enablesimpacket.Header.Reliable = true; // ESP's should be reliable.
1497
1498 OutPacket(enablesimpacket, ThrottleOutPacketType.Task);
1499 }
1500
1501 public AgentCircuitData RequestClientInfo()
1502 {
1503 AgentCircuitData agentData = new AgentCircuitData();
1504 agentData.AgentID = AgentId;
1505 agentData.SessionID = m_sessionId;
1506 agentData.SecureSessionID = SecureSessionId;
1507 agentData.circuitcode = m_circuitCode;
1508 agentData.child = false;
1509 agentData.firstname = m_firstName;
1510 agentData.lastname = m_lastName;
1511
1512 ICapabilitiesModule capsModule = m_scene.RequestModuleInterface<ICapabilitiesModule>();
1513
1514 if (capsModule == null) // can happen when shutting down.
1515 return agentData;
1516
1517 agentData.CapsPath = capsModule.GetCapsPath(m_agentId);
1518 agentData.ChildrenCapSeeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(m_agentId));
1519
1520 return agentData;
1521 }
1522
1523 public virtual void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt, IPEndPoint externalIPEndPoint,
1524 string capsURL)
1525 {
1526 Vector3 look = new Vector3(lookAt.X * 10, lookAt.Y * 10, lookAt.Z * 10);
1527
1528 //CrossedRegionPacket newSimPack = (CrossedRegionPacket)PacketPool.Instance.GetPacket(PacketType.CrossedRegion);
1529 CrossedRegionPacket newSimPack = new CrossedRegionPacket();
1530 // TODO: don't create new blocks if recycling an old packet
1531 newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock();
1532 newSimPack.AgentData.AgentID = AgentId;
1533 newSimPack.AgentData.SessionID = m_sessionId;
1534 newSimPack.Info = new CrossedRegionPacket.InfoBlock();
1535 newSimPack.Info.Position = pos;
1536 newSimPack.Info.LookAt = look;
1537 newSimPack.RegionData = new CrossedRegionPacket.RegionDataBlock();
1538 newSimPack.RegionData.RegionHandle = newRegionHandle;
1539 byte[] byteIP = externalIPEndPoint.Address.GetAddressBytes();
1540 newSimPack.RegionData.SimIP = (uint)byteIP[3] << 24;
1541 newSimPack.RegionData.SimIP += (uint)byteIP[2] << 16;
1542 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8;
1543 newSimPack.RegionData.SimIP += (uint)byteIP[0];
1544 newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port;
1545 newSimPack.RegionData.SeedCapability = Util.StringToBytes256(capsURL);
1546
1547 // Hack to get this out immediately and skip throttles
1548 OutPacket(newSimPack, ThrottleOutPacketType.Unknown);
1549 }
1550
1551 internal void SendMapBlockSplit(List<MapBlockData> mapBlocks, uint flag)
1552 {
1553 MapBlockReplyPacket mapReply = (MapBlockReplyPacket)PacketPool.Instance.GetPacket(PacketType.MapBlockReply);
1554 // TODO: don't create new blocks if recycling an old packet
1555
1556 MapBlockData[] mapBlocks2 = mapBlocks.ToArray();
1557
1558 mapReply.AgentData.AgentID = AgentId;
1559 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks2.Length];
1560 mapReply.Size = new MapBlockReplyPacket.SizeBlock[mapBlocks2.Length];
1561 mapReply.AgentData.Flags = flag;
1562
1563 for (int i = 0; i < mapBlocks2.Length; i++)
1564 {
1565 mapReply.Data[i] = new MapBlockReplyPacket.DataBlock();
1566 mapReply.Data[i].MapImageID = mapBlocks2[i].MapImageId;
1567 //m_log.Warn(mapBlocks2[i].MapImageId.ToString());
1568 mapReply.Data[i].X = mapBlocks2[i].X;
1569 mapReply.Data[i].Y = mapBlocks2[i].Y;
1570 mapReply.Data[i].WaterHeight = mapBlocks2[i].WaterHeight;
1571 mapReply.Data[i].Name = Utils.StringToBytes(mapBlocks2[i].Name);
1572 mapReply.Data[i].RegionFlags = mapBlocks2[i].RegionFlags;
1573 mapReply.Data[i].Access = mapBlocks2[i].Access;
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;
1579 }
1580 OutPacket(mapReply, ThrottleOutPacketType.Land);
1581 }
1582
1583 public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
1584 {
1585 MapBlockData[] mapBlocks2 = mapBlocks.ToArray();
1586
1587 int maxsend = 10;
1588
1589 //int packets = Math.Ceiling(mapBlocks2.Length / maxsend);
1590
1591 List<MapBlockData> sendingBlocks = new List<MapBlockData>();
1592
1593 for (int i = 0; i < mapBlocks2.Length; i++)
1594 {
1595 sendingBlocks.Add(mapBlocks2[i]);
1596 if (((i + 1) == mapBlocks2.Length) || (((i + 1) % maxsend) == 0))
1597 {
1598 SendMapBlockSplit(sendingBlocks, flag);
1599 sendingBlocks = new List<MapBlockData>();
1600 }
1601 }
1602 }
1603
1604 public void SendLocalTeleport(Vector3 position, Vector3 lookAt, uint flags)
1605 {
1606 TeleportLocalPacket tpLocal = (TeleportLocalPacket)PacketPool.Instance.GetPacket(PacketType.TeleportLocal);
1607 tpLocal.Info.AgentID = AgentId;
1608 tpLocal.Info.TeleportFlags = flags;
1609 tpLocal.Info.LocationID = 2;
1610 tpLocal.Info.LookAt = lookAt;
1611 tpLocal.Info.Position = position;
1612
1613 // Hack to get this out immediately and skip throttles
1614 OutPacket(tpLocal, ThrottleOutPacketType.Unknown);
1615 }
1616
1617 public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID,
1618 uint flags, string capsURL)
1619 {
1620 //TeleportFinishPacket teleport = (TeleportFinishPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFinish);
1621
1622 TeleportFinishPacket teleport = new TeleportFinishPacket();
1623 teleport.Info.AgentID = AgentId;
1624 teleport.Info.RegionHandle = regionHandle;
1625 teleport.Info.SimAccess = simAccess;
1626
1627 teleport.Info.SeedCapability = Util.StringToBytes256(capsURL);
1628
1629 IPAddress oIP = newRegionEndPoint.Address;
1630 byte[] byteIP = oIP.GetAddressBytes();
1631 uint ip = (uint)byteIP[3] << 24;
1632 ip += (uint)byteIP[2] << 16;
1633 ip += (uint)byteIP[1] << 8;
1634 ip += (uint)byteIP[0];
1635
1636 teleport.Info.SimIP = ip;
1637 teleport.Info.SimPort = (ushort)newRegionEndPoint.Port;
1638 teleport.Info.LocationID = 4;
1639 teleport.Info.TeleportFlags = 1 << 4;
1640
1641 // Hack to get this out immediately and skip throttles.
1642 OutPacket(teleport, ThrottleOutPacketType.Unknown);
1643 }
1644
1645 /// <summary>
1646 /// Inform the client that a teleport attempt has failed
1647 /// </summary>
1648 public void SendTeleportFailed(string reason)
1649 {
1650 TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed);
1651 tpFailed.Info.AgentID = AgentId;
1652 tpFailed.Info.Reason = Util.StringToBytes256(reason);
1653 tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0];
1654
1655 // Hack to get this out immediately and skip throttles
1656 OutPacket(tpFailed, ThrottleOutPacketType.Unknown);
1657 }
1658
1659 /// <summary>
1660 ///
1661 /// </summary>
1662 public void SendTeleportStart(uint flags)
1663 {
1664 TeleportStartPacket tpStart = (TeleportStartPacket)PacketPool.Instance.GetPacket(PacketType.TeleportStart);
1665 //TeleportStartPacket tpStart = new TeleportStartPacket();
1666 tpStart.Info.TeleportFlags = flags; //16; // Teleport via location
1667
1668 // Hack to get this out immediately and skip throttles
1669 OutPacket(tpStart, ThrottleOutPacketType.Unknown);
1670 }
1671
1672 public void SendTeleportProgress(uint flags, string message)
1673 {
1674 TeleportProgressPacket tpProgress = (TeleportProgressPacket)PacketPool.Instance.GetPacket(PacketType.TeleportProgress);
1675 tpProgress.AgentData.AgentID = this.AgentId;
1676 tpProgress.Info.TeleportFlags = flags;
1677 tpProgress.Info.Message = Util.StringToBytes256(message);
1678
1679 // Hack to get this out immediately and skip throttles
1680 OutPacket(tpProgress, ThrottleOutPacketType.Unknown);
1681 }
1682
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)
1684 {
1685 MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply);
1686 money.MoneyData.AgentID = AgentId;
1687 money.MoneyData.TransactionID = transaction;
1688 money.MoneyData.TransactionSuccess = success;
1689 money.MoneyData.Description = description;
1690 money.MoneyData.MoneyBalance = balance;
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
1699 OutPacket(money, ThrottleOutPacketType.Task);
1700 }
1701
1702 public void SendPayPrice(UUID objectID, int[] payPrice)
1703 {
1704 if (payPrice[0] == 0 &&
1705 payPrice[1] == 0 &&
1706 payPrice[2] == 0 &&
1707 payPrice[3] == 0 &&
1708 payPrice[4] == 0)
1709 return;
1710
1711 PayPriceReplyPacket payPriceReply = (PayPriceReplyPacket)PacketPool.Instance.GetPacket(PacketType.PayPriceReply);
1712 payPriceReply.ObjectData.ObjectID = objectID;
1713 payPriceReply.ObjectData.DefaultPayPrice = payPrice[0];
1714
1715 payPriceReply.ButtonData = new PayPriceReplyPacket.ButtonDataBlock[4];
1716 payPriceReply.ButtonData[0] = new PayPriceReplyPacket.ButtonDataBlock();
1717 payPriceReply.ButtonData[0].PayButton = payPrice[1];
1718 payPriceReply.ButtonData[1] = new PayPriceReplyPacket.ButtonDataBlock();
1719 payPriceReply.ButtonData[1].PayButton = payPrice[2];
1720 payPriceReply.ButtonData[2] = new PayPriceReplyPacket.ButtonDataBlock();
1721 payPriceReply.ButtonData[2].PayButton = payPrice[3];
1722 payPriceReply.ButtonData[3] = new PayPriceReplyPacket.ButtonDataBlock();
1723 payPriceReply.ButtonData[3].PayButton = payPrice[4];
1724
1725 OutPacket(payPriceReply, ThrottleOutPacketType.Task);
1726 }
1727
1728 public void SendStartPingCheck(byte seq)
1729 {
1730 StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck);
1731 pc.Header.Reliable = false;
1732
1733 pc.PingID.PingID = seq;
1734 // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
1735 pc.PingID.OldestUnacked = 0;
1736
1737 OutPacket(pc, ThrottleOutPacketType.Unknown);
1738 }
1739
1740 public void SendKillObject(List<uint> localIDs)
1741 {
1742// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1743
1744 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1745 // TODO: don't create new blocks if recycling an old packet
1746 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1747 for (int i = 0 ; i < localIDs.Count ; i++ )
1748 {
1749 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1750 kill.ObjectData[i].ID = localIDs[i];
1751 }
1752 kill.Header.Reliable = true;
1753 kill.Header.Zerocoded = true;
1754
1755 if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
1756 {
1757 OutPacket(kill, ThrottleOutPacketType.Task);
1758 }
1759 else
1760 {
1761 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1762 // condition where a kill can be processed before an out-of-date update for the same object.
1763 // ProcessEntityUpdates() also takes the m_killRecord lock.
1764 lock (m_killRecord)
1765 {
1766 foreach (uint localID in localIDs)
1767 m_killRecord.Add(localID);
1768
1769 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1770 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1771 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1772 // scene objects in a viewer until that viewer is relogged in.
1773 OutPacket(kill, ThrottleOutPacketType.Task);
1774 }
1775 }
1776 }
1777
1778 /// <summary>
1779 /// Send information about the items contained in a folder to the client.
1780 /// </summary>
1781 /// <remarks>
1782 /// XXX This method needs some refactoring loving
1783 /// </remarks>
1784 /// <param name="ownerID">The owner of the folder</param>
1785 /// <param name="folderID">The id of the folder</param>
1786 /// <param name="items">The items contained in the folder identified by folderID</param>
1787 /// <param name="folders"></param>
1788 /// <param name="fetchFolders">Do we need to send folder information?</param>
1789 /// <param name="fetchItems">Do we need to send item information?</param>
1790 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
1791 List<InventoryFolderBase> folders, int version,
1792 bool fetchFolders, bool fetchItems)
1793 {
1794 // An inventory descendents packet consists of a single agent section and an inventory details
1795 // section for each inventory item. The size of each inventory item is approximately 550 bytes.
1796 // In theory, UDP has a maximum packet size of 64k, so it should be possible to send descendent
1797 // packets containing metadata for in excess of 100 items. But in practice, there may be other
1798 // factors (e.g. firewalls) restraining the maximum UDP packet size. See,
1799 //
1800 // http://opensimulator.org/mantis/view.php?id=226
1801 //
1802 // for one example of this kind of thing. In fact, the Linden servers appear to only send about
1803 // 6 to 7 items at a time, so let's stick with 6
1804 int MAX_ITEMS_PER_PACKET = 5;
1805 int MAX_FOLDERS_PER_PACKET = 6;
1806
1807 int totalItems = fetchItems ? items.Count : 0;
1808 int totalFolders = fetchFolders ? folders.Count : 0;
1809 int itemsSent = 0;
1810 int foldersSent = 0;
1811 int foldersToSend = 0;
1812 int itemsToSend = 0;
1813
1814 InventoryDescendentsPacket currentPacket = null;
1815
1816 // Handle empty folders
1817 //
1818 if (totalItems == 0 && totalFolders == 0)
1819 currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, items.Count + folders.Count, 0, 0);
1820
1821 // To preserve SL compatibility, we will NOT combine folders and items in one packet
1822 //
1823 while (itemsSent < totalItems || foldersSent < totalFolders)
1824 {
1825 if (currentPacket == null) // Start a new packet
1826 {
1827 foldersToSend = totalFolders - foldersSent;
1828 if (foldersToSend > MAX_FOLDERS_PER_PACKET)
1829 foldersToSend = MAX_FOLDERS_PER_PACKET;
1830
1831 if (foldersToSend == 0)
1832 {
1833 itemsToSend = totalItems - itemsSent;
1834 if (itemsToSend > MAX_ITEMS_PER_PACKET)
1835 itemsToSend = MAX_ITEMS_PER_PACKET;
1836 }
1837
1838 currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, items.Count + folders.Count, foldersToSend, itemsToSend);
1839 }
1840
1841 if (foldersToSend-- > 0)
1842 currentPacket.FolderData[foldersSent % MAX_FOLDERS_PER_PACKET] = CreateFolderDataBlock(folders[foldersSent++]);
1843 else if (itemsToSend-- > 0)
1844 currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]);
1845 else
1846 {
1847// m_log.DebugFormat(
1848// "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
1849 OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
1850 currentPacket = null;
1851 }
1852 }
1853
1854 if (currentPacket != null)
1855 {
1856// m_log.DebugFormat(
1857// "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
1858 OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
1859 }
1860 }
1861
1862 private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder)
1863 {
1864 InventoryDescendentsPacket.FolderDataBlock newBlock = new InventoryDescendentsPacket.FolderDataBlock();
1865 newBlock.FolderID = folder.ID;
1866 newBlock.Name = Util.StringToBytes256(folder.Name);
1867 newBlock.ParentID = folder.ParentID;
1868 newBlock.Type = (sbyte)folder.Type;
1869 //if (newBlock.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
1870 // newBlock.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
1871
1872 return newBlock;
1873 }
1874
1875 private InventoryDescendentsPacket.ItemDataBlock CreateItemDataBlock(InventoryItemBase item)
1876 {
1877 InventoryDescendentsPacket.ItemDataBlock newBlock = new InventoryDescendentsPacket.ItemDataBlock();
1878 newBlock.ItemID = item.ID;
1879 newBlock.AssetID = item.AssetID;
1880 newBlock.CreatorID = item.CreatorIdAsUuid;
1881 newBlock.BaseMask = item.BasePermissions;
1882 newBlock.Description = Util.StringToBytes256(item.Description);
1883 newBlock.EveryoneMask = item.EveryOnePermissions;
1884 newBlock.OwnerMask = item.CurrentPermissions;
1885 newBlock.FolderID = item.Folder;
1886 newBlock.InvType = (sbyte)item.InvType;
1887 newBlock.Name = Util.StringToBytes256(item.Name);
1888 newBlock.NextOwnerMask = item.NextPermissions;
1889 newBlock.OwnerID = item.Owner;
1890 newBlock.Type = (sbyte)item.AssetType;
1891
1892 newBlock.GroupID = item.GroupID;
1893 newBlock.GroupOwned = item.GroupOwned;
1894 newBlock.GroupMask = item.GroupPermissions;
1895 newBlock.CreationDate = item.CreationDate;
1896 newBlock.SalePrice = item.SalePrice;
1897 newBlock.SaleType = item.SaleType;
1898 newBlock.Flags = item.Flags;
1899
1900 newBlock.CRC =
1901 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
1902 newBlock.InvType, newBlock.Type,
1903 newBlock.AssetID, newBlock.GroupID,
1904 newBlock.SalePrice,
1905 newBlock.OwnerID, newBlock.CreatorID,
1906 newBlock.ItemID, newBlock.FolderID,
1907 newBlock.EveryoneMask,
1908 newBlock.Flags, newBlock.OwnerMask,
1909 newBlock.GroupMask, newBlock.NextOwnerMask);
1910
1911 return newBlock;
1912 }
1913
1914 private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet)
1915 {
1916 packet.FolderData = new InventoryDescendentsPacket.FolderDataBlock[1];
1917 packet.FolderData[0] = new InventoryDescendentsPacket.FolderDataBlock();
1918 packet.FolderData[0].FolderID = UUID.Zero;
1919 packet.FolderData[0].ParentID = UUID.Zero;
1920 packet.FolderData[0].Type = -1;
1921 packet.FolderData[0].Name = new byte[0];
1922 }
1923
1924 private void AddNullItemBlockToDescendentsPacket(ref InventoryDescendentsPacket packet)
1925 {
1926 packet.ItemData = new InventoryDescendentsPacket.ItemDataBlock[1];
1927 packet.ItemData[0] = new InventoryDescendentsPacket.ItemDataBlock();
1928 packet.ItemData[0].ItemID = UUID.Zero;
1929 packet.ItemData[0].AssetID = UUID.Zero;
1930 packet.ItemData[0].CreatorID = UUID.Zero;
1931 packet.ItemData[0].BaseMask = 0;
1932 packet.ItemData[0].Description = new byte[0];
1933 packet.ItemData[0].EveryoneMask = 0;
1934 packet.ItemData[0].OwnerMask = 0;
1935 packet.ItemData[0].FolderID = UUID.Zero;
1936 packet.ItemData[0].InvType = (sbyte)0;
1937 packet.ItemData[0].Name = new byte[0];
1938 packet.ItemData[0].NextOwnerMask = 0;
1939 packet.ItemData[0].OwnerID = UUID.Zero;
1940 packet.ItemData[0].Type = -1;
1941
1942 packet.ItemData[0].GroupID = UUID.Zero;
1943 packet.ItemData[0].GroupOwned = false;
1944 packet.ItemData[0].GroupMask = 0;
1945 packet.ItemData[0].CreationDate = 0;
1946 packet.ItemData[0].SalePrice = 0;
1947 packet.ItemData[0].SaleType = 0;
1948 packet.ItemData[0].Flags = 0;
1949
1950 // No need to add CRC
1951 }
1952
1953 private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID, int version, int descendents, int folders, int items)
1954 {
1955 InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents);
1956 descend.Header.Zerocoded = true;
1957 descend.AgentData.AgentID = AgentId;
1958 descend.AgentData.OwnerID = ownerID;
1959 descend.AgentData.FolderID = folderID;
1960 descend.AgentData.Version = version;
1961 descend.AgentData.Descendents = descendents;
1962
1963 if (folders > 0)
1964 descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders];
1965 else
1966 AddNullFolderBlockToDecendentsPacket(ref descend);
1967
1968 if (items > 0)
1969 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items];
1970 else
1971 AddNullItemBlockToDescendentsPacket(ref descend);
1972
1973 return descend;
1974 }
1975
1976 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
1977 {
1978 // Fudge this value. It's only needed to make the CRC anyway
1979 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
1980
1981 FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply);
1982 // TODO: don't create new blocks if recycling an old packet
1983 inventoryReply.AgentData.AgentID = AgentId;
1984 inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1];
1985 inventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock();
1986 inventoryReply.InventoryData[0].ItemID = item.ID;
1987 inventoryReply.InventoryData[0].AssetID = item.AssetID;
1988 inventoryReply.InventoryData[0].CreatorID = item.CreatorIdAsUuid;
1989 inventoryReply.InventoryData[0].BaseMask = item.BasePermissions;
1990 inventoryReply.InventoryData[0].CreationDate = item.CreationDate;
1991
1992 inventoryReply.InventoryData[0].Description = Util.StringToBytes256(item.Description);
1993 inventoryReply.InventoryData[0].EveryoneMask = item.EveryOnePermissions;
1994 inventoryReply.InventoryData[0].FolderID = item.Folder;
1995 inventoryReply.InventoryData[0].InvType = (sbyte)item.InvType;
1996 inventoryReply.InventoryData[0].Name = Util.StringToBytes256(item.Name);
1997 inventoryReply.InventoryData[0].NextOwnerMask = item.NextPermissions;
1998 inventoryReply.InventoryData[0].OwnerID = item.Owner;
1999 inventoryReply.InventoryData[0].OwnerMask = item.CurrentPermissions;
2000 inventoryReply.InventoryData[0].Type = (sbyte)item.AssetType;
2001
2002 inventoryReply.InventoryData[0].GroupID = item.GroupID;
2003 inventoryReply.InventoryData[0].GroupOwned = item.GroupOwned;
2004 inventoryReply.InventoryData[0].GroupMask = item.GroupPermissions;
2005 inventoryReply.InventoryData[0].Flags = item.Flags;
2006 inventoryReply.InventoryData[0].SalePrice = item.SalePrice;
2007 inventoryReply.InventoryData[0].SaleType = item.SaleType;
2008
2009 inventoryReply.InventoryData[0].CRC =
2010 Helpers.InventoryCRC(
2011 1000, 0, inventoryReply.InventoryData[0].InvType,
2012 inventoryReply.InventoryData[0].Type, inventoryReply.InventoryData[0].AssetID,
2013 inventoryReply.InventoryData[0].GroupID, 100,
2014 inventoryReply.InventoryData[0].OwnerID, inventoryReply.InventoryData[0].CreatorID,
2015 inventoryReply.InventoryData[0].ItemID, inventoryReply.InventoryData[0].FolderID,
2016 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
2017 FULL_MASK_PERMISSIONS);
2018 inventoryReply.Header.Zerocoded = true;
2019 OutPacket(inventoryReply, ThrottleOutPacketType.Asset);
2020 }
2021
2022 protected void SendBulkUpdateInventoryFolder(InventoryFolderBase folderBase)
2023 {
2024 // We will use the same transaction id for all the separate packets to be sent out in this update.
2025 UUID transactionId = UUID.Random();
2026
2027 List<BulkUpdateInventoryPacket.FolderDataBlock> folderDataBlocks
2028 = new List<BulkUpdateInventoryPacket.FolderDataBlock>();
2029
2030 SendBulkUpdateInventoryFolderRecursive(folderBase, ref folderDataBlocks, transactionId);
2031
2032 if (folderDataBlocks.Count > 0)
2033 {
2034 // We'll end up with some unsent folder blocks if there were some empty folders at the end of the list
2035 // Send these now
2036 BulkUpdateInventoryPacket bulkUpdate
2037 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
2038 bulkUpdate.Header.Zerocoded = true;
2039
2040 bulkUpdate.AgentData.AgentID = AgentId;
2041 bulkUpdate.AgentData.TransactionID = transactionId;
2042 bulkUpdate.FolderData = folderDataBlocks.ToArray();
2043 List<BulkUpdateInventoryPacket.ItemDataBlock> foo = new List<BulkUpdateInventoryPacket.ItemDataBlock>();
2044 bulkUpdate.ItemData = foo.ToArray();
2045
2046 //m_log.Debug("SendBulkUpdateInventory :" + bulkUpdate);
2047 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2048 }
2049 }
2050
2051 /// <summary>
2052 /// Recursively construct bulk update packets to send folders and items
2053 /// </summary>
2054 /// <param name="folder"></param>
2055 /// <param name="folderDataBlocks"></param>
2056 /// <param name="transactionId"></param>
2057 private void SendBulkUpdateInventoryFolderRecursive(
2058 InventoryFolderBase folder, ref List<BulkUpdateInventoryPacket.FolderDataBlock> folderDataBlocks,
2059 UUID transactionId)
2060 {
2061 folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder));
2062
2063 const int MAX_ITEMS_PER_PACKET = 5;
2064
2065 IInventoryService invService = m_scene.RequestModuleInterface<IInventoryService>();
2066 // If there are any items then we have to start sending them off in this packet - the next folder will have
2067 // to be in its own bulk update packet. Also, we can only fit 5 items in a packet (at least this was the limit
2068 // being used on the Linden grid at 20081203).
2069 InventoryCollection contents = invService.GetFolderContent(AgentId, folder.ID); // folder.RequestListOfItems();
2070 List<InventoryItemBase> items = contents.Items;
2071 while (items.Count > 0)
2072 {
2073 BulkUpdateInventoryPacket bulkUpdate
2074 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
2075 bulkUpdate.Header.Zerocoded = true;
2076
2077 bulkUpdate.AgentData.AgentID = AgentId;
2078 bulkUpdate.AgentData.TransactionID = transactionId;
2079 bulkUpdate.FolderData = folderDataBlocks.ToArray();
2080
2081 int itemsToSend = (items.Count > MAX_ITEMS_PER_PACKET ? MAX_ITEMS_PER_PACKET : items.Count);
2082 bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[itemsToSend];
2083
2084 for (int i = 0; i < itemsToSend; i++)
2085 {
2086 // Remove from the end of the list so that we don't incur a performance penalty
2087 bulkUpdate.ItemData[i] = GenerateBulkUpdateItemDataBlock(items[items.Count - 1]);
2088 items.RemoveAt(items.Count - 1);
2089 }
2090
2091 //m_log.Debug("SendBulkUpdateInventoryRecursive :" + bulkUpdate);
2092 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2093
2094 folderDataBlocks = new List<BulkUpdateInventoryPacket.FolderDataBlock>();
2095
2096 // If we're going to be sending another items packet then it needs to contain just the folder to which those
2097 // items belong.
2098 if (items.Count > 0)
2099 folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder));
2100 }
2101
2102 List<InventoryFolderBase> subFolders = contents.Folders;
2103 foreach (InventoryFolderBase subFolder in subFolders)
2104 {
2105 SendBulkUpdateInventoryFolderRecursive(subFolder, ref folderDataBlocks, transactionId);
2106 }
2107 }
2108
2109 /// <summary>
2110 /// Generate a bulk update inventory data block for the given folder
2111 /// </summary>
2112 /// <param name="folder"></param>
2113 /// <returns></returns>
2114 private BulkUpdateInventoryPacket.FolderDataBlock GenerateBulkUpdateFolderDataBlock(InventoryFolderBase folder)
2115 {
2116 BulkUpdateInventoryPacket.FolderDataBlock folderBlock = new BulkUpdateInventoryPacket.FolderDataBlock();
2117
2118 folderBlock.FolderID = folder.ID;
2119 folderBlock.ParentID = folder.ParentID;
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;
2124 folderBlock.Name = Util.StringToBytes256(folder.Name);
2125
2126 return folderBlock;
2127 }
2128
2129 /// <summary>
2130 /// Generate a bulk update inventory data block for the given item
2131 /// </summary>
2132 /// <param name="item"></param>
2133 /// <returns></returns>
2134 private BulkUpdateInventoryPacket.ItemDataBlock GenerateBulkUpdateItemDataBlock(InventoryItemBase item)
2135 {
2136 BulkUpdateInventoryPacket.ItemDataBlock itemBlock = new BulkUpdateInventoryPacket.ItemDataBlock();
2137
2138 itemBlock.ItemID = item.ID;
2139 itemBlock.AssetID = item.AssetID;
2140 itemBlock.CreatorID = item.CreatorIdAsUuid;
2141 itemBlock.BaseMask = item.BasePermissions;
2142 itemBlock.Description = Util.StringToBytes256(item.Description);
2143 itemBlock.EveryoneMask = item.EveryOnePermissions;
2144 itemBlock.FolderID = item.Folder;
2145 itemBlock.InvType = (sbyte)item.InvType;
2146 itemBlock.Name = Util.StringToBytes256(item.Name);
2147 itemBlock.NextOwnerMask = item.NextPermissions;
2148 itemBlock.OwnerID = item.Owner;
2149 itemBlock.OwnerMask = item.CurrentPermissions;
2150 itemBlock.Type = (sbyte)item.AssetType;
2151 itemBlock.GroupID = item.GroupID;
2152 itemBlock.GroupOwned = item.GroupOwned;
2153 itemBlock.GroupMask = item.GroupPermissions;
2154 itemBlock.Flags = item.Flags;
2155 itemBlock.SalePrice = item.SalePrice;
2156 itemBlock.SaleType = item.SaleType;
2157 itemBlock.CreationDate = item.CreationDate;
2158
2159 itemBlock.CRC =
2160 Helpers.InventoryCRC(
2161 1000, 0, itemBlock.InvType,
2162 itemBlock.Type, itemBlock.AssetID,
2163 itemBlock.GroupID, 100,
2164 itemBlock.OwnerID, itemBlock.CreatorID,
2165 itemBlock.ItemID, itemBlock.FolderID,
2166 (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
2167 (uint)PermissionMask.All);
2168
2169 return itemBlock;
2170 }
2171
2172 public void SendBulkUpdateInventory(InventoryNodeBase node)
2173 {
2174 if (node is InventoryItemBase)
2175 SendBulkUpdateInventoryItem((InventoryItemBase)node);
2176 else if (node is InventoryFolderBase)
2177 SendBulkUpdateInventoryFolder((InventoryFolderBase)node);
2178 else if (node != null)
2179 m_log.ErrorFormat("[CLIENT]: {0} sent unknown inventory node named {1}", Name, node.Name);
2180 else
2181 m_log.ErrorFormat("[CLIENT]: {0} sent null inventory node", Name);
2182 }
2183
2184 protected void SendBulkUpdateInventoryItem(InventoryItemBase item)
2185 {
2186 const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff;
2187
2188 BulkUpdateInventoryPacket bulkUpdate
2189 = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
2190
2191 bulkUpdate.AgentData.AgentID = AgentId;
2192 bulkUpdate.AgentData.TransactionID = UUID.Random();
2193
2194 bulkUpdate.FolderData = new BulkUpdateInventoryPacket.FolderDataBlock[1];
2195 bulkUpdate.FolderData[0] = new BulkUpdateInventoryPacket.FolderDataBlock();
2196 bulkUpdate.FolderData[0].FolderID = UUID.Zero;
2197 bulkUpdate.FolderData[0].ParentID = UUID.Zero;
2198 bulkUpdate.FolderData[0].Type = -1;
2199 bulkUpdate.FolderData[0].Name = new byte[0];
2200
2201 bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[1];
2202 bulkUpdate.ItemData[0] = new BulkUpdateInventoryPacket.ItemDataBlock();
2203 bulkUpdate.ItemData[0].ItemID = item.ID;
2204 bulkUpdate.ItemData[0].AssetID = item.AssetID;
2205 bulkUpdate.ItemData[0].CreatorID = item.CreatorIdAsUuid;
2206 bulkUpdate.ItemData[0].BaseMask = item.BasePermissions;
2207 bulkUpdate.ItemData[0].CreationDate = item.CreationDate;
2208 bulkUpdate.ItemData[0].Description = Util.StringToBytes256(item.Description);
2209 bulkUpdate.ItemData[0].EveryoneMask = item.EveryOnePermissions;
2210 bulkUpdate.ItemData[0].FolderID = item.Folder;
2211 bulkUpdate.ItemData[0].InvType = (sbyte)item.InvType;
2212 bulkUpdate.ItemData[0].Name = Util.StringToBytes256(item.Name);
2213 bulkUpdate.ItemData[0].NextOwnerMask = item.NextPermissions;
2214 bulkUpdate.ItemData[0].OwnerID = item.Owner;
2215 bulkUpdate.ItemData[0].OwnerMask = item.CurrentPermissions;
2216 bulkUpdate.ItemData[0].Type = (sbyte)item.AssetType;
2217
2218 bulkUpdate.ItemData[0].GroupID = item.GroupID;
2219 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned;
2220 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions;
2221 bulkUpdate.ItemData[0].Flags = item.Flags;
2222 bulkUpdate.ItemData[0].SalePrice = item.SalePrice;
2223 bulkUpdate.ItemData[0].SaleType = item.SaleType;
2224
2225 bulkUpdate.ItemData[0].CRC =
2226 Helpers.InventoryCRC(1000, 0, bulkUpdate.ItemData[0].InvType,
2227 bulkUpdate.ItemData[0].Type, bulkUpdate.ItemData[0].AssetID,
2228 bulkUpdate.ItemData[0].GroupID, 100,
2229 bulkUpdate.ItemData[0].OwnerID, bulkUpdate.ItemData[0].CreatorID,
2230 bulkUpdate.ItemData[0].ItemID, bulkUpdate.ItemData[0].FolderID,
2231 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
2232 FULL_MASK_PERMISSIONS);
2233 bulkUpdate.Header.Zerocoded = true;
2234 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2235 }
2236
2237 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2238 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2239 {
2240 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2241
2242 UpdateCreateInventoryItemPacket InventoryReply
2243 = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket(
2244 PacketType.UpdateCreateInventoryItem);
2245
2246 // TODO: don't create new blocks if recycling an old packet
2247 InventoryReply.AgentData.AgentID = AgentId;
2248 InventoryReply.AgentData.SimApproved = true;
2249 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2250 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2251 InventoryReply.InventoryData[0].ItemID = Item.ID;
2252 InventoryReply.InventoryData[0].AssetID = Item.AssetID;
2253 InventoryReply.InventoryData[0].CreatorID = Item.CreatorIdAsUuid;
2254 InventoryReply.InventoryData[0].BaseMask = Item.BasePermissions;
2255 InventoryReply.InventoryData[0].Description = Util.StringToBytes256(Item.Description);
2256 InventoryReply.InventoryData[0].EveryoneMask = Item.EveryOnePermissions;
2257 InventoryReply.InventoryData[0].FolderID = Item.Folder;
2258 InventoryReply.InventoryData[0].InvType = (sbyte)Item.InvType;
2259 InventoryReply.InventoryData[0].Name = Util.StringToBytes256(Item.Name);
2260 InventoryReply.InventoryData[0].NextOwnerMask = Item.NextPermissions;
2261 InventoryReply.InventoryData[0].OwnerID = Item.Owner;
2262 InventoryReply.InventoryData[0].OwnerMask = Item.CurrentPermissions;
2263 InventoryReply.InventoryData[0].Type = (sbyte)Item.AssetType;
2264 InventoryReply.InventoryData[0].CallbackID = callbackId;
2265
2266 InventoryReply.InventoryData[0].GroupID = Item.GroupID;
2267 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned;
2268 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions;
2269 InventoryReply.InventoryData[0].Flags = Item.Flags;
2270 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice;
2271 InventoryReply.InventoryData[0].SaleType = Item.SaleType;
2272 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate;
2273
2274 InventoryReply.InventoryData[0].CRC =
2275 Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType,
2276 InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID,
2277 InventoryReply.InventoryData[0].GroupID, 100,
2278 InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID,
2279 InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID,
2280 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
2281 FULL_MASK_PERMISSIONS);
2282 InventoryReply.Header.Zerocoded = true;
2283 OutPacket(InventoryReply, ThrottleOutPacketType.Asset);
2284 }
2285
2286 public void SendRemoveInventoryItem(UUID itemID)
2287 {
2288 RemoveInventoryItemPacket remove = (RemoveInventoryItemPacket)PacketPool.Instance.GetPacket(PacketType.RemoveInventoryItem);
2289 // TODO: don't create new blocks if recycling an old packet
2290 remove.AgentData.AgentID = AgentId;
2291 remove.AgentData.SessionID = m_sessionId;
2292 remove.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1];
2293 remove.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock();
2294 remove.InventoryData[0].ItemID = itemID;
2295 remove.Header.Zerocoded = true;
2296 OutPacket(remove, ThrottleOutPacketType.Asset);
2297 }
2298
2299 public void SendTakeControls(int controls, bool passToAgent, bool TakeControls)
2300 {
2301 ScriptControlChangePacket scriptcontrol = (ScriptControlChangePacket)PacketPool.Instance.GetPacket(PacketType.ScriptControlChange);
2302 ScriptControlChangePacket.DataBlock[] data = new ScriptControlChangePacket.DataBlock[1];
2303 ScriptControlChangePacket.DataBlock ddata = new ScriptControlChangePacket.DataBlock();
2304 ddata.Controls = (uint)controls;
2305 ddata.PassToAgent = passToAgent;
2306 ddata.TakeControls = TakeControls;
2307 data[0] = ddata;
2308 scriptcontrol.Data = data;
2309 OutPacket(scriptcontrol, ThrottleOutPacketType.Task);
2310 }
2311
2312 public void SendTaskInventory(UUID taskID, short serial, byte[] fileName)
2313 {
2314 ReplyTaskInventoryPacket replytask = (ReplyTaskInventoryPacket)PacketPool.Instance.GetPacket(PacketType.ReplyTaskInventory);
2315 replytask.InventoryData.TaskID = taskID;
2316 replytask.InventoryData.Serial = serial;
2317 replytask.InventoryData.Filename = fileName;
2318 OutPacket(replytask, ThrottleOutPacketType.Asset);
2319 }
2320
2321 public void SendXferPacket(ulong xferID, uint packet, byte[] data)
2322 {
2323 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2324 sendXfer.XferID.ID = xferID;
2325 sendXfer.XferID.Packet = packet;
2326 sendXfer.DataPacket.Data = data;
2327 OutPacket(sendXfer, ThrottleOutPacketType.Asset);
2328 }
2329
2330 public void SendAbortXferPacket(ulong xferID)
2331 {
2332 AbortXferPacket xferItem = (AbortXferPacket)PacketPool.Instance.GetPacket(PacketType.AbortXfer);
2333 xferItem.XferID.ID = xferID;
2334 OutPacket(xferItem, ThrottleOutPacketType.Asset);
2335 }
2336
2337 public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit,
2338 int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor,
2339 int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay,
2340 int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent)
2341 {
2342 EconomyDataPacket economyData = (EconomyDataPacket)PacketPool.Instance.GetPacket(PacketType.EconomyData);
2343 economyData.Info.EnergyEfficiency = EnergyEfficiency;
2344 economyData.Info.ObjectCapacity = ObjectCapacity;
2345 economyData.Info.ObjectCount = ObjectCount;
2346 economyData.Info.PriceEnergyUnit = PriceEnergyUnit;
2347 economyData.Info.PriceGroupCreate = PriceGroupCreate;
2348 economyData.Info.PriceObjectClaim = PriceObjectClaim;
2349 economyData.Info.PriceObjectRent = PriceObjectRent;
2350 economyData.Info.PriceObjectScaleFactor = PriceObjectScaleFactor;
2351 economyData.Info.PriceParcelClaim = PriceParcelClaim;
2352 economyData.Info.PriceParcelClaimFactor = PriceParcelClaimFactor;
2353 economyData.Info.PriceParcelRent = PriceParcelRent;
2354 economyData.Info.PricePublicObjectDecay = PricePublicObjectDecay;
2355 economyData.Info.PricePublicObjectDelete = PricePublicObjectDelete;
2356 economyData.Info.PriceRentLight = PriceRentLight;
2357 economyData.Info.PriceUpload = PriceUpload;
2358 economyData.Info.TeleportMinPrice = TeleportMinPrice;
2359 economyData.Info.TeleportPriceExponent = TeleportPriceExponent;
2360 economyData.Header.Reliable = true;
2361 OutPacket(economyData, ThrottleOutPacketType.Task);
2362 }
2363
2364 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
2365 {
2366 //construct the AvatarPickerReply packet.
2367 AvatarPickerReplyPacket replyPacket = new AvatarPickerReplyPacket();
2368 replyPacket.AgentData.AgentID = AgentData.AgentID;
2369 replyPacket.AgentData.QueryID = AgentData.QueryID;
2370 //int i = 0;
2371 List<AvatarPickerReplyPacket.DataBlock> data_block = new List<AvatarPickerReplyPacket.DataBlock>();
2372 foreach (AvatarPickerReplyDataArgs arg in Data)
2373 {
2374 AvatarPickerReplyPacket.DataBlock db = new AvatarPickerReplyPacket.DataBlock();
2375 db.AvatarID = arg.AvatarID;
2376 db.FirstName = arg.FirstName;
2377 db.LastName = arg.LastName;
2378 data_block.Add(db);
2379 }
2380 replyPacket.Data = data_block.ToArray();
2381 OutPacket(replyPacket, ThrottleOutPacketType.Task);
2382 }
2383
2384 public void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
2385 {
2386 if (agentid == AgentId)
2387 {
2388 ActiveGroupId = activegroupid;
2389 ActiveGroupName = groupname;
2390 ActiveGroupPowers = grouppowers;
2391 }
2392
2393 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate);
2394 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid;
2395 sendAgentDataUpdate.AgentData.AgentID = agentid;
2396 sendAgentDataUpdate.AgentData.FirstName = Util.StringToBytes256(firstname);
2397 sendAgentDataUpdate.AgentData.GroupName = Util.StringToBytes256(groupname);
2398 sendAgentDataUpdate.AgentData.GroupPowers = grouppowers;
2399 sendAgentDataUpdate.AgentData.GroupTitle = Util.StringToBytes256(grouptitle);
2400 sendAgentDataUpdate.AgentData.LastName = Util.StringToBytes256(lastname);
2401 OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task);
2402 }
2403
2404 /// <summary>
2405 /// Send an alert message to the client. On the Linden client (tested 1.19.1.4), this pops up a brief duration
2406 /// blue information box in the bottom right hand corner.
2407 /// </summary>
2408 /// <param name="message"></param>
2409 public void SendAlertMessage(string message)
2410 {
2411 AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage);
2412 alertPack.AlertData = new AlertMessagePacket.AlertDataBlock();
2413 alertPack.AlertData.Message = Util.StringToBytes256(message);
2414 alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0];
2415 OutPacket(alertPack, ThrottleOutPacketType.Task);
2416 }
2417
2418 /// <summary>
2419 /// Send an agent alert message to the client.
2420 /// </summary>
2421 /// <param name="message"></param>
2422 /// <param name="modal">On the linden client, if this true then it displays a one button text box placed in the
2423 /// middle of the window. If false, the message is displayed in a brief duration blue information box (as for
2424 /// the AlertMessage packet).</param>
2425 public void SendAgentAlertMessage(string message, bool modal)
2426 {
2427 OutPacket(BuildAgentAlertPacket(message, modal), ThrottleOutPacketType.Task);
2428 }
2429
2430 /// <summary>
2431 /// Construct an agent alert packet
2432 /// </summary>
2433 /// <param name="message"></param>
2434 /// <param name="modal"></param>
2435 /// <returns></returns>
2436 public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal)
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;
2443 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
2444 alertPack.AgentData.AgentID = AgentId;
2445 alertPack.AlertData.Message = Util.StringToBytes256(message);
2446 alertPack.AlertData.Modal = modal;
2447
2448 return alertPack;
2449 }
2450
2451 public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message,
2452 string url)
2453 {
2454 LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL);
2455 loadURL.Data.ObjectName = Util.StringToBytes256(objectname);
2456 loadURL.Data.ObjectID = objectID;
2457 loadURL.Data.OwnerID = ownerID;
2458 loadURL.Data.OwnerIsGroup = groupOwned;
2459 loadURL.Data.Message = Util.StringToBytes256(message);
2460 loadURL.Data.URL = Util.StringToBytes256(url);
2461 OutPacket(loadURL, ThrottleOutPacketType.Task);
2462 }
2463
2464 public void SendDialog(
2465 string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
2466 UUID textureID, int ch, string[] buttonlabels)
2467 {
2468 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
2469 dialog.Data.ObjectID = objectID;
2470 dialog.Data.ObjectName = Util.StringToBytes256(objectname);
2471 // this is the username of the *owner*
2472 dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName);
2473 dialog.Data.LastName = Util.StringToBytes256(ownerLastName);
2474 dialog.Data.Message = Util.StringToBytes1024(msg);
2475 dialog.Data.ImageID = textureID;
2476 dialog.Data.ChatChannel = ch;
2477 ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length];
2478 for (int i = 0; i < buttonlabels.Length; i++)
2479 {
2480 buttons[i] = new ScriptDialogPacket.ButtonsBlock();
2481 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
2482 }
2483 dialog.Buttons = buttons;
2484
2485 dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
2486 dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
2487 dialog.OwnerData[0].OwnerID = ownerID;
2488
2489 OutPacket(dialog, ThrottleOutPacketType.Task);
2490 }
2491
2492 public void SendPreLoadSound(UUID objectID, UUID ownerID, UUID soundID)
2493 {
2494 PreloadSoundPacket preSound = (PreloadSoundPacket)PacketPool.Instance.GetPacket(PacketType.PreloadSound);
2495 // TODO: don't create new blocks if recycling an old packet
2496 preSound.DataBlock = new PreloadSoundPacket.DataBlockBlock[1];
2497 preSound.DataBlock[0] = new PreloadSoundPacket.DataBlockBlock();
2498 preSound.DataBlock[0].ObjectID = objectID;
2499 preSound.DataBlock[0].OwnerID = ownerID;
2500 preSound.DataBlock[0].SoundID = soundID;
2501 preSound.Header.Zerocoded = true;
2502 OutPacket(preSound, ThrottleOutPacketType.Task);
2503 }
2504
2505 public void SendPlayAttachedSound(UUID soundID, UUID objectID, UUID ownerID, float gain, byte flags)
2506 {
2507 AttachedSoundPacket sound = (AttachedSoundPacket)PacketPool.Instance.GetPacket(PacketType.AttachedSound);
2508 sound.DataBlock.SoundID = soundID;
2509 sound.DataBlock.ObjectID = objectID;
2510 sound.DataBlock.OwnerID = ownerID;
2511 sound.DataBlock.Gain = gain;
2512 sound.DataBlock.Flags = flags;
2513
2514 OutPacket(sound, ThrottleOutPacketType.Task);
2515 }
2516
2517 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2518 {
2519 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
2520 sound.SoundData.SoundID = soundID;
2521 sound.SoundData.OwnerID = ownerID;
2522 sound.SoundData.ObjectID = objectID;
2523 sound.SoundData.ParentID = parentID;
2524 sound.SoundData.Handle = handle;
2525 sound.SoundData.Position = position;
2526 sound.SoundData.Gain = gain;
2527
2528 OutPacket(sound, ThrottleOutPacketType.Task);
2529 }
2530
2531 public void SendAttachedSoundGainChange(UUID objectID, float gain)
2532 {
2533 AttachedSoundGainChangePacket sound = (AttachedSoundGainChangePacket)PacketPool.Instance.GetPacket(PacketType.AttachedSoundGainChange);
2534 sound.DataBlock.ObjectID = objectID;
2535 sound.DataBlock.Gain = gain;
2536
2537 OutPacket(sound, ThrottleOutPacketType.Task);
2538 }
2539
2540 public void SendSunPos(Vector3 Position, Vector3 Velocity, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition)
2541 {
2542 // Viewers based on the Linden viwer code, do wacky things for oribital positions from Midnight to Sunrise
2543 // So adjust for that
2544 // Contributed by: Godfrey
2545
2546 if (OrbitalPosition > m_sunPainDaHalfOrbitalCutoff) // things get weird from midnight to sunrise
2547 {
2548 OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
2549 }
2550
2551 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
2552 viewertime.TimeInfo.SunDirection = Position;
2553 viewertime.TimeInfo.SunAngVelocity = Velocity;
2554
2555 // Sun module used to add 6 hours to adjust for linden sun hour, adding here
2556 // to prevent existing code from breaking if it assumed that 6 hours were included.
2557 // 21600 == 6 hours * 60 minutes * 60 Seconds
2558 viewertime.TimeInfo.UsecSinceStart = CurrentTime + 21600;
2559
2560 viewertime.TimeInfo.SecPerDay = SecondsPerSunCycle;
2561 viewertime.TimeInfo.SecPerYear = SecondsPerYear;
2562 viewertime.TimeInfo.SunPhase = OrbitalPosition;
2563 viewertime.Header.Reliable = false;
2564 viewertime.Header.Zerocoded = true;
2565 OutPacket(viewertime, ThrottleOutPacketType.Task);
2566 }
2567
2568 // Currently Deprecated
2569 public void SendViewerTime(int phase)
2570 {
2571 /*
2572 Console.WriteLine("SunPhase: {0}", phase);
2573 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
2574 //viewertime.TimeInfo.SecPerDay = 86400;
2575 //viewertime.TimeInfo.SecPerYear = 31536000;
2576 viewertime.TimeInfo.SecPerDay = 1000;
2577 viewertime.TimeInfo.SecPerYear = 365000;
2578 viewertime.TimeInfo.SunPhase = 1;
2579 int sunPhase = (phase + 2) / 2;
2580 if ((sunPhase < 6) || (sunPhase > 36))
2581 {
2582 viewertime.TimeInfo.SunDirection = new Vector3(0f, 0.8f, -0.8f);
2583 Console.WriteLine("sending night");
2584 }
2585 else
2586 {
2587 if (sunPhase < 12)
2588 {
2589 sunPhase = 12;
2590 }
2591 sunPhase = sunPhase - 12;
2592
2593 float yValue = 0.1f * (sunPhase);
2594 Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue);
2595 if (yValue > 1.2f)
2596 {
2597 yValue = yValue - 1.2f;
2598 }
2599
2600 yValue = Util.Clip(yValue, 0, 1);
2601
2602 if (sunPhase < 14)
2603 {
2604 yValue = 1 - yValue;
2605 }
2606 if (sunPhase < 12)
2607 {
2608 yValue *= -1;
2609 }
2610 viewertime.TimeInfo.SunDirection = new Vector3(0f, yValue, 0.3f);
2611 Console.WriteLine("sending sun update " + yValue);
2612 }
2613 viewertime.TimeInfo.SunAngVelocity = new Vector3(0, 0.0f, 10.0f);
2614 viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch();
2615 viewertime.Header.Reliable = false;
2616 OutPacket(viewertime, ThrottleOutPacketType.Task);
2617 */
2618 }
2619
2620 public void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks)
2621 {
2622 ViewerEffectPacket packet = (ViewerEffectPacket)PacketPool.Instance.GetPacket(PacketType.ViewerEffect);
2623 packet.Header.Reliable = false;
2624 packet.Header.Zerocoded = true;
2625
2626 packet.AgentData.AgentID = AgentId;
2627 packet.AgentData.SessionID = SessionId;
2628
2629 packet.Effect = effectBlocks;
2630
2631 // OutPacket(packet, ThrottleOutPacketType.State);
2632 OutPacket(packet, ThrottleOutPacketType.Task);
2633 }
2634
2635 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember,
2636 string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL,
2637 UUID partnerID)
2638 {
2639 AvatarPropertiesReplyPacket avatarReply = (AvatarPropertiesReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPropertiesReply);
2640 avatarReply.AgentData.AgentID = AgentId;
2641 avatarReply.AgentData.AvatarID = avatarID;
2642 if (aboutText != null)
2643 avatarReply.PropertiesData.AboutText = Util.StringToBytes1024(aboutText);
2644 else
2645 avatarReply.PropertiesData.AboutText = Utils.EmptyBytes;
2646 avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn);
2647 avatarReply.PropertiesData.CharterMember = charterMember;
2648 if (flAbout != null)
2649 avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout);
2650 else
2651 avatarReply.PropertiesData.FLAboutText = Utils.EmptyBytes;
2652 avatarReply.PropertiesData.Flags = flags;
2653 avatarReply.PropertiesData.FLImageID = flImageID;
2654 avatarReply.PropertiesData.ImageID = imageID;
2655 avatarReply.PropertiesData.ProfileURL = Util.StringToBytes256(profileURL);
2656 avatarReply.PropertiesData.PartnerID = partnerID;
2657 OutPacket(avatarReply, ThrottleOutPacketType.Task);
2658 }
2659
2660 /// <summary>
2661 /// Send the client an Estate message blue box pop-down with a single OK button
2662 /// </summary>
2663 /// <param name="FromAvatarID"></param>
2664 /// <param name="fromSessionID"></param>
2665 /// <param name="FromAvatarName"></param>
2666 /// <param name="Message"></param>
2667 public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message)
2668 {
2669 if (!SceneAgent.IsChildAgent)
2670 SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3()));
2671
2672 //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch());
2673 }
2674
2675 public void SendLogoutPacket()
2676 {
2677 // I know this is a bit of a hack, however there are times when you don't
2678 // want to send this, but still need to do the rest of the shutdown process
2679 // this method gets called from the packet server.. which makes it practically
2680 // impossible to do any other way.
2681
2682 if (m_SendLogoutPacketWhenClosing)
2683 {
2684 LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply);
2685 // TODO: don't create new blocks if recycling an old packet
2686 logReply.AgentData.AgentID = AgentId;
2687 logReply.AgentData.SessionID = SessionId;
2688 logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
2689 logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
2690 logReply.InventoryData[0].ItemID = UUID.Zero;
2691
2692 OutPacket(logReply, ThrottleOutPacketType.Task);
2693 }
2694 }
2695
2696 public void SendHealth(float health)
2697 {
2698 HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage);
2699 healthpacket.HealthData.Health = health;
2700 OutPacket(healthpacket, ThrottleOutPacketType.Task);
2701 }
2702
2703 public void SendAgentOnline(UUID[] agentIDs)
2704 {
2705 OnlineNotificationPacket onp = new OnlineNotificationPacket();
2706 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length];
2707 for (int i = 0; i < agentIDs.Length; i++)
2708 {
2709 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock();
2710 onpbl.AgentID = agentIDs[i];
2711 onpb[i] = onpbl;
2712 }
2713 onp.AgentBlock = onpb;
2714 onp.Header.Reliable = true;
2715 OutPacket(onp, ThrottleOutPacketType.Task);
2716 }
2717
2718 public void SendAgentOffline(UUID[] agentIDs)
2719 {
2720 OfflineNotificationPacket offp = new OfflineNotificationPacket();
2721 OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length];
2722 for (int i = 0; i < agentIDs.Length; i++)
2723 {
2724 OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock();
2725 onpbl.AgentID = agentIDs[i];
2726 offpb[i] = onpbl;
2727 }
2728 offp.AgentBlock = offpb;
2729 offp.Header.Reliable = true;
2730 OutPacket(offp, ThrottleOutPacketType.Task);
2731 }
2732
2733 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot,
2734 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
2735 {
2736 AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket();
2737 avatarSitResponse.SitObject.ID = TargetID;
2738 avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset;
2739 avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset;
2740 avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook;
2741 avatarSitResponse.SitTransform.AutoPilot = autopilot;
2742 avatarSitResponse.SitTransform.SitPosition = OffsetPos;
2743 avatarSitResponse.SitTransform.SitRotation = SitOrientation;
2744
2745 OutPacket(avatarSitResponse, ThrottleOutPacketType.Task);
2746 }
2747
2748 public void SendAdminResponse(UUID Token, uint AdminLevel)
2749 {
2750 GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket();
2751 GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock();
2752 GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock();
2753
2754 adb.AgentID = AgentId;
2755 adb.SessionID = SessionId; // More security
2756 gdb.GodLevel = (byte)AdminLevel;
2757 gdb.Token = Token;
2758 //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock;
2759 respondPacket.GrantData = gdb;
2760 respondPacket.AgentData = adb;
2761 OutPacket(respondPacket, ThrottleOutPacketType.Task);
2762 }
2763
2764 public void SendGroupMembership(GroupMembershipData[] GroupMembership)
2765 {
2766 m_groupPowers.Clear();
2767
2768 AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket();
2769 AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length];
2770 for (int i = 0; i < GroupMembership.Length; i++)
2771 {
2772 m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers;
2773
2774 AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock();
2775 Group.AcceptNotices = GroupMembership[i].AcceptNotices;
2776 Group.Contribution = GroupMembership[i].Contribution;
2777 Group.GroupID = GroupMembership[i].GroupID;
2778 Group.GroupInsigniaID = GroupMembership[i].GroupPicture;
2779 Group.GroupName = Util.StringToBytes256(GroupMembership[i].GroupName);
2780 Group.GroupPowers = GroupMembership[i].GroupPowers;
2781 Groups[i] = Group;
2782
2783
2784 }
2785 Groupupdate.GroupData = Groups;
2786 Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock();
2787 Groupupdate.AgentData.AgentID = AgentId;
2788 OutPacket(Groupupdate, ThrottleOutPacketType.Task);
2789
2790 try
2791 {
2792 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2793 if (eq != null)
2794 {
2795 eq.GroupMembership(Groupupdate, this.AgentId);
2796 }
2797 }
2798 catch (Exception ex)
2799 {
2800 m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString());
2801 m_log.Warn("sending group membership data via UDP");
2802 OutPacket(Groupupdate, ThrottleOutPacketType.Task);
2803 }
2804 }
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
2834
2835 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2836 {
2837 UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket();
2838 UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1];
2839 UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock();
2840 uidnamebloc.ID = groupLLUID;
2841 uidnamebloc.GroupName = Util.StringToBytes256(GroupName);
2842 uidnameblock[0] = uidnamebloc;
2843 pack.UUIDNameBlock = uidnameblock;
2844 OutPacket(pack, ThrottleOutPacketType.Task);
2845 }
2846
2847 public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia)
2848 {
2849 LandStatReplyPacket lsrp = new LandStatReplyPacket();
2850 // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock();
2851 LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length];
2852 //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock();
2853 // lsrepdb.
2854 lsrp.RequestData.ReportType = reportType;
2855 lsrp.RequestData.RequestFlags = requestFlags;
2856 lsrp.RequestData.TotalObjectCount = resultCount;
2857 for (int i = 0; i < lsrpia.Length; i++)
2858 {
2859 LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock();
2860 lsrepdb.LocationX = lsrpia[i].LocationX;
2861 lsrepdb.LocationY = lsrpia[i].LocationY;
2862 lsrepdb.LocationZ = lsrpia[i].LocationZ;
2863 lsrepdb.Score = lsrpia[i].Score;
2864 lsrepdb.TaskID = lsrpia[i].TaskID;
2865 lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID;
2866 lsrepdb.TaskName = Util.StringToBytes256(lsrpia[i].TaskName);
2867 lsrepdb.OwnerName = Util.StringToBytes256(lsrpia[i].OwnerName);
2868 lsrepdba[i] = lsrepdb;
2869 }
2870 lsrp.ReportData = lsrepdba;
2871 OutPacket(lsrp, ThrottleOutPacketType.Task);
2872 }
2873
2874 public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running)
2875 {
2876 ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket();
2877 scriptRunningReply.Script.ObjectID = objectID;
2878 scriptRunningReply.Script.ItemID = itemID;
2879 scriptRunningReply.Script.Running = running;
2880
2881 OutPacket(scriptRunningReply, ThrottleOutPacketType.Task);
2882 }
2883
2884 public void SendAsset(AssetRequestToClient req)
2885 {
2886 if (req.AssetInf.Data == null)
2887 {
2888 m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset data is null",
2889 LogHeader, req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2890 return;
2891 }
2892
2893 //m_log.Debug("sending asset " + req.RequestAssetID);
2894 TransferInfoPacket Transfer = new TransferInfoPacket();
2895 Transfer.TransferInfo.ChannelType = 2;
2896 Transfer.TransferInfo.Status = 0;
2897 Transfer.TransferInfo.TargetType = 0;
2898 if (req.AssetRequestSource == 2)
2899 {
2900 Transfer.TransferInfo.Params = new byte[20];
2901 Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
2902 int assType = req.AssetInf.Type;
2903 Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
2904 }
2905 else if (req.AssetRequestSource == 3)
2906 {
2907 Transfer.TransferInfo.Params = req.Params;
2908 // Transfer.TransferInfo.Params = new byte[100];
2909 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
2910 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
2911 }
2912 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2913 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2914 Transfer.Header.Zerocoded = true;
2915 OutPacket(Transfer, ThrottleOutPacketType.Asset);
2916
2917 if (req.NumPackets == 1)
2918 {
2919 TransferPacketPacket TransferPacket = new TransferPacketPacket();
2920 TransferPacket.TransferData.Packet = 0;
2921 TransferPacket.TransferData.ChannelType = 2;
2922 TransferPacket.TransferData.TransferID = req.TransferRequestID;
2923 TransferPacket.TransferData.Data = req.AssetInf.Data;
2924 TransferPacket.TransferData.Status = 1;
2925 TransferPacket.Header.Zerocoded = true;
2926 OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
2927 }
2928 else
2929 {
2930 int processedLength = 0;
2931 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2932 int packetNumber = 0;
2933
2934 while (processedLength < req.AssetInf.Data.Length)
2935 {
2936 TransferPacketPacket TransferPacket = new TransferPacketPacket();
2937 TransferPacket.TransferData.Packet = packetNumber;
2938 TransferPacket.TransferData.ChannelType = 2;
2939 TransferPacket.TransferData.TransferID = req.TransferRequestID;
2940
2941 int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
2942 byte[] chunk = new byte[chunkSize];
2943 Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
2944
2945 TransferPacket.TransferData.Data = chunk;
2946
2947 // 0 indicates more packets to come, 1 indicates last packet
2948 if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
2949 {
2950 TransferPacket.TransferData.Status = 0;
2951 }
2952 else
2953 {
2954 TransferPacket.TransferData.Status = 1;
2955 }
2956 TransferPacket.Header.Zerocoded = true;
2957 OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
2958
2959 processedLength += chunkSize;
2960 packetNumber++;
2961 }
2962 }
2963 }
2964
2965 public void SendAssetNotFound(AssetRequestToClient req)
2966 {
2967 TransferInfoPacket Transfer = new TransferInfoPacket();
2968 Transfer.TransferInfo.ChannelType = 2;
2969 Transfer.TransferInfo.Status = -2;
2970 Transfer.TransferInfo.TargetType = 0;
2971 Transfer.TransferInfo.Params = req.Params;
2972 Transfer.TransferInfo.Size = 0;
2973 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2974 Transfer.Header.Zerocoded = true;
2975 OutPacket(Transfer, ThrottleOutPacketType.Asset);
2976 }
2977
2978 public void SendTexture(AssetBase TextureAsset)
2979 {
2980
2981 }
2982
2983 public void SendRegionHandle(UUID regionID, ulong handle)
2984 {
2985 RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply);
2986 reply.ReplyBlock.RegionID = regionID;
2987 reply.ReplyBlock.RegionHandle = handle;
2988 OutPacket(reply, ThrottleOutPacketType.Land);
2989 }
2990
2991 public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
2992 {
2993 float dwell = 0.0f;
2994 IDwellModule dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
2995 if (dwellModule != null)
2996 dwell = dwellModule.GetDwell(land.GlobalID);
2997 ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply);
2998 reply.AgentData.AgentID = m_agentId;
2999 reply.Data.ParcelID = parcelID;
3000 reply.Data.OwnerID = land.OwnerID;
3001 reply.Data.Name = Utils.StringToBytes(land.Name);
3002 reply.Data.Desc = Utils.StringToBytes(land.Description);
3003 reply.Data.ActualArea = land.Area;
3004 reply.Data.BillableArea = land.Area; // TODO: what is this?
3005
3006 // Bit 0: Mature, bit 7: on sale, other bits: no idea
3007 reply.Data.Flags = (byte)(
3008 (info.AccessLevel > 13 ? (1 << 0) : 0) +
3009 ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0));
3010
3011 Vector3 pos = land.UserLocation;
3012 if (pos.Equals(Vector3.Zero))
3013 {
3014 pos = (land.AABBMax + land.AABBMin) * 0.5f;
3015 }
3016 reply.Data.GlobalX = info.RegionLocX + x;
3017 reply.Data.GlobalY = info.RegionLocY + y;
3018 reply.Data.GlobalZ = pos.Z;
3019 reply.Data.SimName = Utils.StringToBytes(info.RegionName);
3020 reply.Data.SnapshotID = land.SnapshotID;
3021 reply.Data.Dwell = dwell;
3022 reply.Data.SalePrice = land.SalePrice;
3023 reply.Data.AuctionID = (int)land.AuctionID;
3024
3025 OutPacket(reply, ThrottleOutPacketType.Land);
3026 }
3027
3028 public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt)
3029 {
3030 ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest);
3031
3032 packet.Data.ObjectName = Utils.StringToBytes(objName);
3033 packet.Data.SimName = Utils.StringToBytes(simName);
3034 packet.Data.SimPosition = pos;
3035 packet.Data.LookAt = lookAt;
3036
3037 OutPacket(packet, ThrottleOutPacketType.Task);
3038 }
3039
3040 public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data)
3041 {
3042 DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply);
3043
3044 packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock();
3045
3046 packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1];
3047 packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock();
3048
3049 packet.AgentData.AgentID = AgentId;
3050
3051 packet.QueryData[0].QueryID = queryID;
3052
3053 DirPlacesReplyPacket.QueryRepliesBlock[] replies =
3054 new DirPlacesReplyPacket.QueryRepliesBlock[0];
3055 DirPlacesReplyPacket.StatusDataBlock[] status =
3056 new DirPlacesReplyPacket.StatusDataBlock[0];
3057
3058 packet.QueryReplies = replies;
3059 packet.StatusData = status;
3060
3061 foreach (DirPlacesReplyData d in data)
3062 {
3063 int idx = replies.Length;
3064 Array.Resize(ref replies, idx + 1);
3065 Array.Resize(ref status, idx + 1);
3066
3067 replies[idx] = new DirPlacesReplyPacket.QueryRepliesBlock();
3068 status[idx] = new DirPlacesReplyPacket.StatusDataBlock();
3069 replies[idx].ParcelID = d.parcelID;
3070 replies[idx].Name = Utils.StringToBytes(d.name);
3071 replies[idx].ForSale = d.forSale;
3072 replies[idx].Auction = d.auction;
3073 replies[idx].Dwell = d.dwell;
3074 status[idx].Status = d.Status;
3075
3076 packet.QueryReplies = replies;
3077 packet.StatusData = status;
3078
3079 if (packet.Length >= 1000)
3080 {
3081 OutPacket(packet, ThrottleOutPacketType.Task);
3082
3083 packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply);
3084
3085 packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock();
3086
3087 packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1];
3088 packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock();
3089
3090 packet.AgentData.AgentID = AgentId;
3091
3092 packet.QueryData[0].QueryID = queryID;
3093
3094 replies = new DirPlacesReplyPacket.QueryRepliesBlock[0];
3095 status = new DirPlacesReplyPacket.StatusDataBlock[0];
3096 }
3097 }
3098
3099 if (replies.Length > 0 || data.Length == 0)
3100 OutPacket(packet, ThrottleOutPacketType.Task);
3101 }
3102
3103 public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data)
3104 {
3105 DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply);
3106
3107 packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock();
3108 packet.AgentData.AgentID = AgentId;
3109
3110 packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock();
3111 packet.QueryData.QueryID = queryID;
3112
3113 packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[
3114 data.Length];
3115
3116 int i = 0;
3117 foreach (DirPeopleReplyData d in data)
3118 {
3119 packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock();
3120 packet.QueryReplies[i].AgentID = d.agentID;
3121 packet.QueryReplies[i].FirstName =
3122 Utils.StringToBytes(d.firstName);
3123 packet.QueryReplies[i].LastName =
3124 Utils.StringToBytes(d.lastName);
3125 packet.QueryReplies[i].Group =
3126 Utils.StringToBytes(d.group);
3127 packet.QueryReplies[i].Online = d.online;
3128 packet.QueryReplies[i].Reputation = d.reputation;
3129 i++;
3130 }
3131
3132 OutPacket(packet, ThrottleOutPacketType.Task);
3133 }
3134
3135 public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data)
3136 {
3137 DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply);
3138
3139 packet.AgentData = new DirEventsReplyPacket.AgentDataBlock();
3140 packet.AgentData.AgentID = AgentId;
3141
3142 packet.QueryData = new DirEventsReplyPacket.QueryDataBlock();
3143 packet.QueryData.QueryID = queryID;
3144
3145 packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[
3146 data.Length];
3147
3148 packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[
3149 data.Length];
3150
3151 int i = 0;
3152 foreach (DirEventsReplyData d in data)
3153 {
3154 packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock();
3155 packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock();
3156 packet.QueryReplies[i].OwnerID = d.ownerID;
3157 packet.QueryReplies[i].Name =
3158 Utils.StringToBytes(d.name);
3159 packet.QueryReplies[i].EventID = d.eventID;
3160 packet.QueryReplies[i].Date =
3161 Utils.StringToBytes(d.date);
3162 packet.QueryReplies[i].UnixTime = d.unixTime;
3163 packet.QueryReplies[i].EventFlags = d.eventFlags;
3164 packet.StatusData[i].Status = d.Status;
3165 i++;
3166 }
3167
3168 OutPacket(packet, ThrottleOutPacketType.Task);
3169 }
3170
3171 public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data)
3172 {
3173 DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply);
3174
3175 packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock();
3176 packet.AgentData.AgentID = AgentId;
3177
3178 packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock();
3179 packet.QueryData.QueryID = queryID;
3180
3181 packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[
3182 data.Length];
3183
3184 int i = 0;
3185 foreach (DirGroupsReplyData d in data)
3186 {
3187 packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock();
3188 packet.QueryReplies[i].GroupID = d.groupID;
3189 packet.QueryReplies[i].GroupName =
3190 Utils.StringToBytes(d.groupName);
3191 packet.QueryReplies[i].Members = d.members;
3192 packet.QueryReplies[i].SearchOrder = d.searchOrder;
3193 i++;
3194 }
3195
3196 OutPacket(packet, ThrottleOutPacketType.Task);
3197 }
3198
3199 public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data)
3200 {
3201 DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply);
3202
3203 packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock();
3204 packet.AgentData.AgentID = AgentId;
3205
3206 packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock();
3207 packet.QueryData.QueryID = queryID;
3208
3209 packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[
3210 data.Length];
3211 packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[
3212 data.Length];
3213
3214 int i = 0;
3215 foreach (DirClassifiedReplyData d in data)
3216 {
3217 packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock();
3218 packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock();
3219 packet.QueryReplies[i].ClassifiedID = d.classifiedID;
3220 packet.QueryReplies[i].Name =
3221 Utils.StringToBytes(d.name);
3222 packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags;
3223 packet.QueryReplies[i].CreationDate = d.creationDate;
3224 packet.QueryReplies[i].ExpirationDate = d.expirationDate;
3225 packet.QueryReplies[i].PriceForListing = d.price;
3226 packet.StatusData[i].Status = d.Status;
3227 i++;
3228 }
3229
3230 OutPacket(packet, ThrottleOutPacketType.Task);
3231 }
3232
3233 public void SendDirLandReply(UUID queryID, DirLandReplyData[] data)
3234 {
3235 DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply);
3236
3237 packet.AgentData = new DirLandReplyPacket.AgentDataBlock();
3238 packet.AgentData.AgentID = AgentId;
3239
3240 packet.QueryData = new DirLandReplyPacket.QueryDataBlock();
3241 packet.QueryData.QueryID = queryID;
3242
3243 packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[
3244 data.Length];
3245
3246 int i = 0;
3247 foreach (DirLandReplyData d in data)
3248 {
3249 packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock();
3250 packet.QueryReplies[i].ParcelID = d.parcelID;
3251 packet.QueryReplies[i].Name =
3252 Utils.StringToBytes(d.name);
3253 packet.QueryReplies[i].Auction = d.auction;
3254 packet.QueryReplies[i].ForSale = d.forSale;
3255 packet.QueryReplies[i].SalePrice = d.salePrice;
3256 packet.QueryReplies[i].ActualArea = d.actualArea;
3257 i++;
3258 }
3259
3260 OutPacket(packet, ThrottleOutPacketType.Task);
3261 }
3262
3263 public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data)
3264 {
3265 DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply);
3266
3267 packet.AgentData = new DirPopularReplyPacket.AgentDataBlock();
3268 packet.AgentData.AgentID = AgentId;
3269
3270 packet.QueryData = new DirPopularReplyPacket.QueryDataBlock();
3271 packet.QueryData.QueryID = queryID;
3272
3273 packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[
3274 data.Length];
3275
3276 int i = 0;
3277 foreach (DirPopularReplyData d in data)
3278 {
3279 packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock();
3280 packet.QueryReplies[i].ParcelID = d.parcelID;
3281 packet.QueryReplies[i].Name =
3282 Utils.StringToBytes(d.name);
3283 packet.QueryReplies[i].Dwell = d.dwell;
3284 i++;
3285 }
3286
3287 OutPacket(packet, ThrottleOutPacketType.Task);
3288 }
3289
3290 public void SendEventInfoReply(EventData data)
3291 {
3292 EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply);
3293
3294 packet.AgentData = new EventInfoReplyPacket.AgentDataBlock();
3295 packet.AgentData.AgentID = AgentId;
3296
3297 packet.EventData = new EventInfoReplyPacket.EventDataBlock();
3298 packet.EventData.EventID = data.eventID;
3299 packet.EventData.Creator = Utils.StringToBytes(data.creator);
3300 packet.EventData.Name = Utils.StringToBytes(data.name);
3301 packet.EventData.Category = Utils.StringToBytes(data.category);
3302 packet.EventData.Desc = Utils.StringToBytes(data.description);
3303 packet.EventData.Date = Utils.StringToBytes(data.date);
3304 packet.EventData.DateUTC = data.dateUTC;
3305 packet.EventData.Duration = data.duration;
3306 packet.EventData.Cover = data.cover;
3307 packet.EventData.Amount = data.amount;
3308 packet.EventData.SimName = Utils.StringToBytes(data.simName);
3309 packet.EventData.GlobalPos = new Vector3d(data.globalPos);
3310 packet.EventData.EventFlags = data.eventFlags;
3311
3312 OutPacket(packet, ThrottleOutPacketType.Task);
3313 }
3314
3315 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
3316 {
3317 MapItemReplyPacket mirplk = new MapItemReplyPacket();
3318 mirplk.AgentData.AgentID = AgentId;
3319 mirplk.RequestData.ItemType = mapitemtype;
3320 mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length];
3321 for (int i = 0; i < replies.Length; i++)
3322 {
3323 MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock();
3324 mrdata.X = replies[i].x;
3325 mrdata.Y = replies[i].y;
3326 mrdata.ID = replies[i].id;
3327 mrdata.Extra = replies[i].Extra;
3328 mrdata.Extra2 = replies[i].Extra2;
3329 mrdata.Name = Utils.StringToBytes(replies[i].name);
3330 mirplk.Data[i] = mrdata;
3331 }
3332 //m_log.Debug(mirplk.ToString());
3333 OutPacket(mirplk, ThrottleOutPacketType.Task);
3334
3335 }
3336
3337 public void SendOfferCallingCard(UUID srcID, UUID transactionID)
3338 {
3339 // a bit special, as this uses AgentID to store the source instead
3340 // of the destination. The destination (the receiver) goes into destID
3341 OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard);
3342 p.AgentData.AgentID = srcID;
3343 p.AgentData.SessionID = UUID.Zero;
3344 p.AgentBlock.DestID = AgentId;
3345 p.AgentBlock.TransactionID = transactionID;
3346 OutPacket(p, ThrottleOutPacketType.Task);
3347 }
3348
3349 public void SendAcceptCallingCard(UUID transactionID)
3350 {
3351 AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard);
3352 p.AgentData.AgentID = AgentId;
3353 p.AgentData.SessionID = UUID.Zero;
3354 p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1];
3355 p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock();
3356 p.FolderData[0].FolderID = UUID.Zero;
3357 OutPacket(p, ThrottleOutPacketType.Task);
3358 }
3359
3360 public void SendDeclineCallingCard(UUID transactionID)
3361 {
3362 DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard);
3363 p.AgentData.AgentID = AgentId;
3364 p.AgentData.SessionID = UUID.Zero;
3365 p.TransactionBlock.TransactionID = transactionID;
3366 OutPacket(p, ThrottleOutPacketType.Task);
3367 }
3368
3369 public void SendTerminateFriend(UUID exFriendID)
3370 {
3371 TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship);
3372 p.AgentData.AgentID = AgentId;
3373 p.AgentData.SessionID = SessionId;
3374 p.ExBlock.OtherID = exFriendID;
3375 OutPacket(p, ThrottleOutPacketType.Task);
3376 }
3377
3378 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
3379 {
3380 OSDMap llsd = new OSDMap(3);
3381 OSDArray AgentData = new OSDArray(1);
3382 OSDMap AgentDataMap = new OSDMap(1);
3383 AgentDataMap.Add("AgentID", OSD.FromUUID(this.AgentId));
3384 AgentDataMap.Add("AvatarID", OSD.FromUUID(avatarID));
3385 AgentData.Add(AgentDataMap);
3386 llsd.Add("AgentData", AgentData);
3387 OSDArray GroupData = new OSDArray(data.Length);
3388 OSDArray NewGroupData = new OSDArray(data.Length);
3389 foreach (GroupMembershipData m in data)
3390 {
3391 OSDMap GroupDataMap = new OSDMap(6);
3392 OSDMap NewGroupDataMap = new OSDMap(1);
3393 GroupDataMap.Add("GroupPowers", OSD.FromULong(m.GroupPowers));
3394 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(m.AcceptNotices));
3395 GroupDataMap.Add("GroupTitle", OSD.FromString(m.GroupTitle));
3396 GroupDataMap.Add("GroupID", OSD.FromUUID(m.GroupID));
3397 GroupDataMap.Add("GroupName", OSD.FromString(m.GroupName));
3398 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(m.GroupPicture));
3399 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(m.ListInProfile));
3400 GroupData.Add(GroupDataMap);
3401 NewGroupData.Add(NewGroupDataMap);
3402 }
3403 llsd.Add("GroupData", GroupData);
3404 llsd.Add("NewGroupData", NewGroupData);
3405
3406 IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>();
3407 if (eq != null)
3408 {
3409 eq.Enqueue(BuildEvent("AvatarGroupsReply", llsd), this.AgentId);
3410 }
3411 }
3412
3413 public void SendJoinGroupReply(UUID groupID, bool success)
3414 {
3415 JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply);
3416
3417 p.AgentData = new JoinGroupReplyPacket.AgentDataBlock();
3418 p.AgentData.AgentID = AgentId;
3419
3420 p.GroupData = new JoinGroupReplyPacket.GroupDataBlock();
3421 p.GroupData.GroupID = groupID;
3422 p.GroupData.Success = success;
3423
3424 OutPacket(p, ThrottleOutPacketType.Task);
3425 }
3426
3427 public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success)
3428 {
3429 EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply);
3430
3431 p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock();
3432 p.AgentData.AgentID = agentID;
3433
3434 p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock();
3435 p.GroupData.GroupID = groupID;
3436
3437 p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock();
3438 p.EjectData.Success = success;
3439
3440 OutPacket(p, ThrottleOutPacketType.Task);
3441 }
3442
3443 public void SendLeaveGroupReply(UUID groupID, bool success)
3444 {
3445 LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply);
3446
3447 p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock();
3448 p.AgentData.AgentID = AgentId;
3449
3450 p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock();
3451 p.GroupData.GroupID = groupID;
3452 p.GroupData.Success = success;
3453
3454 OutPacket(p, ThrottleOutPacketType.Task);
3455 }
3456
3457 public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name)
3458 {
3459 if (classifiedID.Length != name.Length)
3460 return;
3461
3462 AvatarClassifiedReplyPacket ac =
3463 (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket(
3464 PacketType.AvatarClassifiedReply);
3465
3466 ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock();
3467 ac.AgentData.AgentID = AgentId;
3468 ac.AgentData.TargetID = targetID;
3469
3470 ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length];
3471 int i;
3472 for (i = 0; i < classifiedID.Length; i++)
3473 {
3474 ac.Data[i].ClassifiedID = classifiedID[i];
3475 ac.Data[i].Name = Utils.StringToBytes(name[i]);
3476 }
3477
3478 OutPacket(ac, ThrottleOutPacketType.Task);
3479 }
3480
3481 public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price)
3482 {
3483 ClassifiedInfoReplyPacket cr =
3484 (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket(
3485 PacketType.ClassifiedInfoReply);
3486
3487 cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock();
3488 cr.AgentData.AgentID = AgentId;
3489
3490 cr.Data = new ClassifiedInfoReplyPacket.DataBlock();
3491 cr.Data.ClassifiedID = classifiedID;
3492 cr.Data.CreatorID = creatorID;
3493 cr.Data.CreationDate = creationDate;
3494 cr.Data.ExpirationDate = expirationDate;
3495 cr.Data.Category = category;
3496 cr.Data.Name = Utils.StringToBytes(name);
3497 cr.Data.Desc = Utils.StringToBytes(description);
3498 cr.Data.ParcelID = parcelID;
3499 cr.Data.ParentEstate = parentEstate;
3500 cr.Data.SnapshotID = snapshotID;
3501 cr.Data.SimName = Utils.StringToBytes(simName);
3502 cr.Data.PosGlobal = new Vector3d(globalPos);
3503 cr.Data.ParcelName = Utils.StringToBytes(parcelName);
3504 cr.Data.ClassifiedFlags = classifiedFlags;
3505 cr.Data.PriceForListing = price;
3506
3507 OutPacket(cr, ThrottleOutPacketType.Task);
3508 }
3509
3510 public void SendAgentDropGroup(UUID groupID)
3511 {
3512 AgentDropGroupPacket dg =
3513 (AgentDropGroupPacket)PacketPool.Instance.GetPacket(
3514 PacketType.AgentDropGroup);
3515
3516 dg.AgentData = new AgentDropGroupPacket.AgentDataBlock();
3517 dg.AgentData.AgentID = AgentId;
3518 dg.AgentData.GroupID = groupID;
3519
3520 OutPacket(dg, ThrottleOutPacketType.Task);
3521 }
3522
3523 public void SendAvatarNotesReply(UUID targetID, string text)
3524 {
3525 AvatarNotesReplyPacket an =
3526 (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket(
3527 PacketType.AvatarNotesReply);
3528
3529 an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock();
3530 an.AgentData.AgentID = AgentId;
3531
3532 an.Data = new AvatarNotesReplyPacket.DataBlock();
3533 an.Data.TargetID = targetID;
3534 an.Data.Notes = Utils.StringToBytes(text);
3535
3536 OutPacket(an, ThrottleOutPacketType.Task);
3537 }
3538
3539 public void SendAvatarPicksReply(UUID targetID, Dictionary<UUID, string> picks)
3540 {
3541 AvatarPicksReplyPacket ap =
3542 (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket(
3543 PacketType.AvatarPicksReply);
3544
3545 ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock();
3546 ap.AgentData.AgentID = AgentId;
3547 ap.AgentData.TargetID = targetID;
3548
3549 ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count];
3550
3551 int i = 0;
3552 foreach (KeyValuePair<UUID, string> pick in picks)
3553 {
3554 ap.Data[i] = new AvatarPicksReplyPacket.DataBlock();
3555 ap.Data[i].PickID = pick.Key;
3556 ap.Data[i].PickName = Utils.StringToBytes(pick.Value);
3557 i++;
3558 }
3559
3560 OutPacket(ap, ThrottleOutPacketType.Task);
3561 }
3562
3563 public void SendAvatarClassifiedReply(UUID targetID, Dictionary<UUID, string> classifieds)
3564 {
3565 AvatarClassifiedReplyPacket ac =
3566 (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket(
3567 PacketType.AvatarClassifiedReply);
3568
3569 ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock();
3570 ac.AgentData.AgentID = AgentId;
3571 ac.AgentData.TargetID = targetID;
3572
3573 ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count];
3574
3575 int i = 0;
3576 foreach (KeyValuePair<UUID, string> classified in classifieds)
3577 {
3578 ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock();
3579 ac.Data[i].ClassifiedID = classified.Key;
3580 ac.Data[i].Name = Utils.StringToBytes(classified.Value);
3581 i++;
3582 }
3583
3584 OutPacket(ac, ThrottleOutPacketType.Task);
3585 }
3586
3587 public void SendParcelDwellReply(int localID, UUID parcelID, float dwell)
3588 {
3589 ParcelDwellReplyPacket pd =
3590 (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket(
3591 PacketType.ParcelDwellReply);
3592
3593 pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock();
3594 pd.AgentData.AgentID = AgentId;
3595
3596 pd.Data = new ParcelDwellReplyPacket.DataBlock();
3597 pd.Data.LocalID = localID;
3598 pd.Data.ParcelID = parcelID;
3599 pd.Data.Dwell = dwell;
3600
3601 OutPacket(pd, ThrottleOutPacketType.Land);
3602 }
3603
3604 public void SendUserInfoReply(bool imViaEmail, bool visible, string email)
3605 {
3606 UserInfoReplyPacket ur =
3607 (UserInfoReplyPacket)PacketPool.Instance.GetPacket(
3608 PacketType.UserInfoReply);
3609
3610 string Visible = "hidden";
3611 if (visible)
3612 Visible = "default";
3613
3614 ur.AgentData = new UserInfoReplyPacket.AgentDataBlock();
3615 ur.AgentData.AgentID = AgentId;
3616
3617 ur.UserData = new UserInfoReplyPacket.UserDataBlock();
3618 ur.UserData.IMViaEMail = imViaEmail;
3619 ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible);
3620 ur.UserData.EMail = Utils.StringToBytes(email);
3621
3622 OutPacket(ur, ThrottleOutPacketType.Task);
3623 }
3624
3625 public void SendCreateGroupReply(UUID groupID, bool success, string message)
3626 {
3627 CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply);
3628
3629 createGroupReply.AgentData =
3630 new CreateGroupReplyPacket.AgentDataBlock();
3631 createGroupReply.ReplyData =
3632 new CreateGroupReplyPacket.ReplyDataBlock();
3633
3634 createGroupReply.AgentData.AgentID = AgentId;
3635 createGroupReply.ReplyData.GroupID = groupID;
3636
3637 createGroupReply.ReplyData.Success = success;
3638 createGroupReply.ReplyData.Message = Utils.StringToBytes(message);
3639 OutPacket(createGroupReply, ThrottleOutPacketType.Task);
3640 }
3641
3642 public void SendUseCachedMuteList()
3643 {
3644 UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList);
3645
3646 useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock();
3647 useCachedMuteList.AgentData.AgentID = AgentId;
3648
3649 OutPacket(useCachedMuteList, ThrottleOutPacketType.Task);
3650 }
3651
3652 public void SendMuteListUpdate(string filename)
3653 {
3654 MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate);
3655
3656 muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock();
3657 muteListUpdate.MuteData.AgentID = AgentId;
3658 muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename);
3659
3660 OutPacket(muteListUpdate, ThrottleOutPacketType.Task);
3661 }
3662
3663 public void SendPickInfoReply(UUID pickID, UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled)
3664 {
3665 PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply);
3666
3667 pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock();
3668 pickInfoReply.AgentData.AgentID = AgentId;
3669
3670 pickInfoReply.Data = new PickInfoReplyPacket.DataBlock();
3671 pickInfoReply.Data.PickID = pickID;
3672 pickInfoReply.Data.CreatorID = creatorID;
3673 pickInfoReply.Data.TopPick = topPick;
3674 pickInfoReply.Data.ParcelID = parcelID;
3675 pickInfoReply.Data.Name = Utils.StringToBytes(name);
3676 pickInfoReply.Data.Desc = Utils.StringToBytes(desc);
3677 pickInfoReply.Data.SnapshotID = snapshotID;
3678 pickInfoReply.Data.User = Utils.StringToBytes(user);
3679 pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName);
3680 pickInfoReply.Data.SimName = Utils.StringToBytes(simName);
3681 pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal);
3682 pickInfoReply.Data.SortOrder = sortOrder;
3683 pickInfoReply.Data.Enabled = enabled;
3684
3685 OutPacket(pickInfoReply, ThrottleOutPacketType.Task);
3686 }
3687
3688 #endregion Scene/Avatar to Client
3689
3690 // Gesture
3691
3692 #region Appearance/ Wearables Methods
3693
3694 public void SendWearables(AvatarWearable[] wearables, int serial)
3695 {
3696 AgentWearablesUpdatePacket aw = (AgentWearablesUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentWearablesUpdate);
3697 aw.AgentData.AgentID = AgentId;
3698 aw.AgentData.SerialNum = (uint)serial;
3699 aw.AgentData.SessionID = m_sessionId;
3700
3701 int count = 0;
3702 for (int i = 0; i < wearables.Length; i++)
3703 count += wearables[i].Count;
3704
3705 // TODO: don't create new blocks if recycling an old packet
3706 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3707 AgentWearablesUpdatePacket.WearableDataBlock awb;
3708 int idx = 0;
3709 for (int i = 0; i < wearables.Length; i++)
3710 {
3711 for (int j = 0; j < wearables[i].Count; j++)
3712 {
3713 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3714 awb.WearableType = (byte)i;
3715 awb.AssetID = wearables[i][j].AssetID;
3716 awb.ItemID = wearables[i][j].ItemID;
3717 aw.WearableData[idx] = awb;
3718 idx++;
3719
3720// m_log.DebugFormat(
3721// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3722// awb.ItemID, awb.AssetID, i, Name);
3723 }
3724 }
3725
3726 OutPacket(aw, ThrottleOutPacketType.Task);
3727 }
3728
3729 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
3730 {
3731// m_log.DebugFormat(
3732// "[LLCLIENTVIEW]: Sending avatar appearance for {0} with {1} bytes to {2} {3}",
3733// agentID, textureEntry.Length, Name, AgentId);
3734
3735 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3736 // TODO: don't create new blocks if recycling an old packet
3737 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3738 avp.ObjectData.TextureEntry = textureEntry;
3739
3740 AvatarAppearancePacket.VisualParamBlock avblock = null;
3741 for (int i = 0; i < visualParams.Length; i++)
3742 {
3743 avblock = new AvatarAppearancePacket.VisualParamBlock();
3744 avblock.ParamValue = visualParams[i];
3745 avp.VisualParam[i] = avblock;
3746 }
3747
3748 avp.Sender.IsTrial = false;
3749 avp.Sender.ID = agentID;
3750 avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0];
3751 avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0];
3752 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3753 OutPacket(avp, ThrottleOutPacketType.Task);
3754 }
3755
3756 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
3757 {
3758// m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name);
3759
3760 AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation);
3761 // TODO: don't create new blocks if recycling an old packet
3762 ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[animations.Length];
3763 ani.Sender = new AvatarAnimationPacket.SenderBlock();
3764 ani.Sender.ID = sourceAgentId;
3765 ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[animations.Length];
3766 ani.PhysicalAvatarEventList = new AvatarAnimationPacket.PhysicalAvatarEventListBlock[0];
3767
3768 for (int i = 0; i < animations.Length; ++i)
3769 {
3770 ani.AnimationList[i] = new AvatarAnimationPacket.AnimationListBlock();
3771 ani.AnimationList[i].AnimID = animations[i];
3772 ani.AnimationList[i].AnimSequenceID = seqs[i];
3773
3774 ani.AnimationSourceList[i] = new AvatarAnimationPacket.AnimationSourceListBlock();
3775 if (objectIDs[i].Equals(sourceAgentId))
3776 ani.AnimationSourceList[i].ObjectID = UUID.Zero;
3777 else
3778 ani.AnimationSourceList[i].ObjectID = objectIDs[i];
3779 }
3780 ani.Header.Reliable = false;
3781 OutPacket(ani, ThrottleOutPacketType.Task);
3782 }
3783
3784 #endregion
3785
3786 #region Avatar Packet/Data Sending Methods
3787
3788 /// <summary>
3789 /// Send an ObjectUpdate packet with information about an avatar
3790 /// </summary>
3791 public void SendAvatarDataImmediate(ISceneEntity avatar)
3792 {
3793// m_log.DebugFormat(
3794// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}",
3795// avatar.Name, avatar.UUID, Name, AgentId);
3796
3797 ScenePresence presence = avatar as ScenePresence;
3798 if (presence == null)
3799 return;
3800
3801 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3802 objupdate.Header.Zerocoded = true;
3803
3804 objupdate.RegionData.RegionHandle = presence.RegionHandle;
3805 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3806
3807 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3808 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
3809
3810 OutPacket(objupdate, ThrottleOutPacketType.Task);
3811
3812 // We need to record the avatar local id since the root prim of an attachment points to this.
3813// m_attachmentsSent.Add(avatar.LocalId);
3814 }
3815
3816 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
3817 {
3818 // We don't need to update inactive clients.
3819 if (!IsActive)
3820 return;
3821
3822 CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
3823 loc.Header.Reliable = false;
3824
3825 // Each packet can only hold around 60 avatar positions and the client clears the mini-map each time
3826 // a CoarseLocationUpdate packet is received. Oh well.
3827 int total = Math.Min(CoarseLocations.Count, 60);
3828
3829 CoarseLocationUpdatePacket.IndexBlock ib = new CoarseLocationUpdatePacket.IndexBlock();
3830
3831 loc.Location = new CoarseLocationUpdatePacket.LocationBlock[total];
3832 loc.AgentData = new CoarseLocationUpdatePacket.AgentDataBlock[total];
3833
3834 int selfindex = -1;
3835 for (int i = 0; i < total; i++)
3836 {
3837 CoarseLocationUpdatePacket.LocationBlock lb =
3838 new CoarseLocationUpdatePacket.LocationBlock();
3839
3840 lb.X = (byte)CoarseLocations[i].X;
3841 lb.Y = (byte)CoarseLocations[i].Y;
3842
3843 lb.Z = CoarseLocations[i].Z > 1024 ? (byte)0 : (byte)(CoarseLocations[i].Z * 0.25f);
3844 loc.Location[i] = lb;
3845 loc.AgentData[i] = new CoarseLocationUpdatePacket.AgentDataBlock();
3846 loc.AgentData[i].AgentID = users[i];
3847 if (users[i] == AgentId)
3848 selfindex = i;
3849 }
3850
3851 ib.You = (short)selfindex;
3852 ib.Prey = -1;
3853 loc.Index = ib;
3854
3855 OutPacket(loc, ThrottleOutPacketType.Task);
3856 }
3857
3858 #endregion Avatar Packet/Data Sending Methods
3859
3860 #region Primitive Packet/Data Sending Methods
3861
3862
3863 /// <summary>
3864 /// Generate one of the object update packets based on PrimUpdateFlags
3865 /// and broadcast the packet to clients
3866 /// </summary>
3867 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3868 {
3869 if (entity.UUID == m_agentId && !updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3870 {
3871 ImprovedTerseObjectUpdatePacket packet
3872 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3873
3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
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 }
3888 }
3889
3890 /// <summary>
3891 /// Requeue an EntityUpdate when it was not acknowledged by the client.
3892 /// We will update the priority and put it in the correct queue, merging update flags
3893 /// with any other updates that may be queued for the same entity.
3894 /// The original update time is used for the merged update.
3895 /// </summary>
3896 private void ResendPrimUpdate(EntityUpdate update)
3897 {
3898 // If the update exists in priority queue, it will be updated.
3899 // If it does not exist then it will be added with the current (rather than its original) priority
3900 uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
3901
3902 lock (m_entityUpdates.SyncRoot)
3903 m_entityUpdates.Enqueue(priority, update);
3904 }
3905
3906 /// <summary>
3907 /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
3908 /// We will update the priority and put it in the correct queue, merging update flags
3909 /// with any other updates that may be queued for the same entity.
3910 /// The original update time is used for the merged update.
3911 /// </summary>
3912 private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
3913 {
3914 // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
3915
3916 // Remove the update packet from the list of packets waiting for acknowledgement
3917 // because we are requeuing the list of updates. They will be resent in new packets
3918 // with the most recent state and priority.
3919 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
3920
3921 // Count this as a resent packet since we are going to requeue all of the updates contained in it
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++;
3927
3928 foreach (EntityUpdate update in updates)
3929 ResendPrimUpdate(update);
3930 }
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
3943 private void ProcessEntityUpdates(int maxUpdates)
3944 {
3945 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3946 OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3947 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3948 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3949
3950 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3951 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3952 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3953 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
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
3964 // Check to see if this is a flush
3965 if (maxUpdates <= 0)
3966 {
3967 maxUpdates = Int32.MaxValue;
3968 }
3969
3970 int updatesThisCall = 0;
3971
3972 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3973 // condition where a kill can be processed before an out-of-date update for the same object.
3974 lock (m_killRecord)
3975 {
3976 float avgTimeDilation = 1.0f;
3977 IEntityUpdate iupdate;
3978 Int32 timeinqueue; // this is just debugging code & can be dropped later
3979
3980 while (updatesThisCall < maxUpdates)
3981 {
3982 lock (m_entityUpdates.SyncRoot)
3983 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3984 break;
3985
3986 EntityUpdate update = (EntityUpdate)iupdate;
3987
3988 avgTimeDilation += update.TimeDilation;
3989 avgTimeDilation *= 0.5f;
3990
3991 if (update.Entity is SceneObjectPart)
3992 {
3993 SceneObjectPart part = (SceneObjectPart)update.Entity;
3994
3995 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3996 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3997 // safety measure.
3998 //
3999 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
4000 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
4001 // updates and kills on different threads with different scheduling strategies, hence this protection.
4002 //
4003 // This doesn't appear to apply to child prims - a client will happily ignore these updates
4004 // after the root prim has been deleted.
4005 if (m_killRecord.Contains(part.LocalId))
4006 {
4007 // m_log.WarnFormat(
4008 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
4009 // part.LocalId, Name);
4010 continue;
4011 }
4012
4013 if (part.ParentGroup.IsAttachment && m_disableFacelights)
4014 {
4015 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
4016 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
4017 {
4018 part.Shape.LightEntry = false;
4019 }
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 }
4029 }
4030
4031 #region UpdateFlags to packet type conversion
4032
4033 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
4034
4035 bool canUseCompressed = true;
4036 bool canUseImproved = true;
4037
4038 // Compressed object updates only make sense for LL primitives
4039 if (!(update.Entity is SceneObjectPart))
4040 {
4041 canUseCompressed = false;
4042 }
4043
4044 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
4045 {
4046 canUseCompressed = false;
4047 canUseImproved = false;
4048 }
4049 else
4050 {
4051 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
4052 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
4053 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
4054 updateFlags.HasFlag(PrimUpdateFlags.Joint))
4055 {
4056 canUseCompressed = false;
4057 }
4058
4059 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
4060 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
4061 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
4062 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
4063 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
4064 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
4065 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
4066 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
4067 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
4068 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
4069 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
4070 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
4071 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
4072 updateFlags.HasFlag(PrimUpdateFlags.Joint))
4073 {
4074 canUseImproved = false;
4075 }
4076 }
4077
4078 #endregion UpdateFlags to packet type conversion
4079
4080 #region Block Construction
4081
4082 // TODO: Remove this once we can build compressed updates
4083 canUseCompressed = false;
4084
4085 if (!canUseImproved && !canUseCompressed)
4086 {
4087 ObjectUpdatePacket.ObjectDataBlock updateBlock;
4088
4089 if (update.Entity is ScenePresence)
4090 {
4091 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
4092 }
4093 else
4094 {
4095 SceneObjectPart part = (SceneObjectPart)update.Entity;
4096 updateBlock = CreatePrimUpdateBlock(part, AgentId);
4097
4098 // If the part has become a private hud since the update was scheduled then we do not
4099 // want to send it to other avatars.
4100 if (part.ParentGroup.IsAttachment
4101 && part.ParentGroup.HasPrivateAttachmentPoint
4102 && part.ParentGroup.AttachedAvatar != AgentId)
4103 continue;
4104
4105 // If the part has since been deleted, then drop the update. In the case of attachments,
4106 // this is to avoid spurious updates to other viewers since post-processing of attachments
4107 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4108 // of the test above).
4109 //
4110 // Actual deletions (kills) happen in another method.
4111 if (part.ParentGroup.IsDeleted)
4112 continue;
4113 }
4114
4115 objectUpdateBlocks.Value.Add(updateBlock);
4116 objectUpdates.Value.Add(update);
4117 }
4118 else if (!canUseImproved)
4119 {
4120 SceneObjectPart part = (SceneObjectPart)update.Entity;
4121 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
4122 = CreateCompressedUpdateBlock(part, updateFlags);
4123
4124 // If the part has since been deleted, then drop the update. In the case of attachments,
4125 // this is to avoid spurious updates to other viewers since post-processing of attachments
4126 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4127 // of the test above).
4128 //
4129 // Actual deletions (kills) happen in another method.
4130 if (part.ParentGroup.IsDeleted)
4131 continue;
4132
4133 compressedUpdateBlocks.Value.Add(compressedBlock);
4134 compressedUpdates.Value.Add(update);
4135 }
4136 else
4137 {
4138 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4139 {
4140 // Self updates go into a special list
4141 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4142 terseAgentUpdates.Value.Add(update);
4143 }
4144 else
4145 {
4146 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
4147 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4148
4149 // Everything else goes here
4150 if (update.Entity is SceneObjectPart)
4151 {
4152 SceneObjectPart part = (SceneObjectPart)update.Entity;
4153
4154 // If the part has become a private hud since the update was scheduled then we do not
4155 // want to send it to other avatars.
4156 if (part.ParentGroup.IsAttachment
4157 && part.ParentGroup.HasPrivateAttachmentPoint
4158 && part.ParentGroup.AttachedAvatar != AgentId)
4159 continue;
4160
4161 // If the part has since been deleted, then drop the update. In the case of attachments,
4162 // this is to avoid spurious updates to other viewers since post-processing of attachments
4163 // has to change the IsAttachment flag for various reasons (which will end up in a pass
4164 // of the test above).
4165 //
4166 // Actual deletions (kills) happen in another method.
4167 if (part.ParentGroup.IsDeleted)
4168 continue;
4169 }
4170
4171 terseUpdateBlocks.Value.Add(terseUpdateBlock);
4172 terseUpdates.Value.Add(update);
4173 }
4174 }
4175
4176 ++updatesThisCall;
4177
4178 #endregion Block Construction
4179 }
4180
4181 #region Packet Sending
4182 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4183
4184 if (terseAgentUpdateBlocks.IsValueCreated)
4185 {
4186 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4187
4188 ImprovedTerseObjectUpdatePacket packet
4189 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4190
4191 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4192 packet.RegionData.TimeDilation = timeDilation;
4193 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4194
4195 for (int i = 0; i < blocks.Count; i++)
4196 packet.ObjectData[i] = blocks[i];
4197 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4198 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
4199 }
4200
4201 if (objectUpdateBlocks.IsValueCreated)
4202 {
4203 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4204
4205 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4206 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4207 packet.RegionData.TimeDilation = timeDilation;
4208 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4209
4210 for (int i = 0; i < blocks.Count; i++)
4211 packet.ObjectData[i] = blocks[i];
4212 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4213 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4214 }
4215
4216 if (compressedUpdateBlocks.IsValueCreated)
4217 {
4218 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4219
4220 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4221 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4222 packet.RegionData.TimeDilation = timeDilation;
4223 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4224
4225 for (int i = 0; i < blocks.Count; i++)
4226 packet.ObjectData[i] = blocks[i];
4227 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4228 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4229 }
4230
4231 if (terseUpdateBlocks.IsValueCreated)
4232 {
4233 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4234
4235 ImprovedTerseObjectUpdatePacket packet
4236 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4237 PacketType.ImprovedTerseObjectUpdate);
4238
4239 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4240 packet.RegionData.TimeDilation = timeDilation;
4241 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4242
4243 for (int i = 0; i < blocks.Count; i++)
4244 packet.ObjectData[i] = blocks[i];
4245 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4246 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4247 }
4248 }
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//
4254 #endregion Packet Sending
4255 }
4256
4257 public void ReprioritizeUpdates()
4258 {
4259 lock (m_entityUpdates.SyncRoot)
4260 m_entityUpdates.Reprioritize(UpdatePriorityHandler);
4261 }
4262
4263 private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity)
4264 {
4265 if (entity != null)
4266 {
4267 priority = m_prioritizer.GetUpdatePriority(this, entity);
4268 return true;
4269 }
4270
4271 return false;
4272 }
4273
4274 public void FlushPrimUpdates()
4275 {
4276 m_log.WarnFormat("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
4277
4278 while (m_entityUpdates.Count > 0)
4279 ProcessEntityUpdates(-1);
4280 }
4281
4282 #endregion Primitive Packet/Data Sending Methods
4283
4284 // These are used to implement an adaptive backoff in the number
4285 // of updates converted to packets. Since we don't want packets
4286 // to sit in the queue with old data, only convert enough updates
4287 // to packets that can be sent in 200ms.
4288 private Int32 m_LastQueueFill = 0;
4289 private Int32 m_maxUpdates = 0;
4290
4291 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
4292 {
4293// if (!m_udpServer.IsRunningOutbound)
4294// return;
4295
4296 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4297 {
4298// if (!m_udpServer.IsRunningOutbound)
4299// return;
4300
4301 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
4302 {
4303 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
4304 }
4305 else
4306 {
4307 if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
4308 m_maxUpdates += 5;
4309 else
4310 m_maxUpdates = m_maxUpdates >> 1;
4311 }
4312 m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500);
4313 m_LastQueueFill = Util.EnvironmentTickCount();
4314
4315 if (m_entityUpdates.Count > 0)
4316 ProcessEntityUpdates(m_maxUpdates);
4317
4318 if (m_entityProps.Count > 0)
4319 ProcessEntityPropertyRequests(m_maxUpdates);
4320 }
4321
4322 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
4323 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
4324 }
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
4347 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
4348 {
4349 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
4350 newPack.AssetBlock.Type = AssetType;
4351 newPack.AssetBlock.Success = Success;
4352 newPack.AssetBlock.UUID = AssetFullID;
4353 newPack.Header.Zerocoded = true;
4354 OutPacket(newPack, ThrottleOutPacketType.Asset);
4355 }
4356
4357 public void SendXferRequest(ulong XferID, short AssetType, UUID vFileID, byte FilePath, byte[] FileName)
4358 {
4359 RequestXferPacket newPack = new RequestXferPacket();
4360 newPack.XferID.ID = XferID;
4361 newPack.XferID.VFileType = AssetType;
4362 newPack.XferID.VFileID = vFileID;
4363 newPack.XferID.FilePath = FilePath;
4364 newPack.XferID.Filename = FileName;
4365 newPack.Header.Zerocoded = true;
4366 OutPacket(newPack, ThrottleOutPacketType.Asset);
4367 }
4368
4369 public void SendConfirmXfer(ulong xferID, uint PacketID)
4370 {
4371 ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
4372 newPack.XferID.ID = xferID;
4373 newPack.XferID.Packet = PacketID;
4374 newPack.Header.Zerocoded = true;
4375 OutPacket(newPack, ThrottleOutPacketType.Asset);
4376 }
4377
4378 public void SendInitiateDownload(string simFileName, string clientFileName)
4379 {
4380 InitiateDownloadPacket newPack = new InitiateDownloadPacket();
4381 newPack.AgentData.AgentID = AgentId;
4382 newPack.FileData.SimFilename = Utils.StringToBytes(simFileName);
4383 newPack.FileData.ViewerFilename = Utils.StringToBytes(clientFileName);
4384 OutPacket(newPack, ThrottleOutPacketType.Asset);
4385 }
4386
4387 public void SendImageFirstPart(
4388 ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec)
4389 {
4390 ImageDataPacket im = new ImageDataPacket();
4391 im.Header.Reliable = false;
4392 im.ImageID.Packets = numParts;
4393 im.ImageID.ID = ImageUUID;
4394
4395 if (ImageSize > 0)
4396 im.ImageID.Size = ImageSize;
4397
4398 im.ImageData.Data = ImageData;
4399 im.ImageID.Codec = imageCodec;
4400 im.Header.Zerocoded = true;
4401 OutPacket(im, ThrottleOutPacketType.Texture);
4402 }
4403
4404 public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData)
4405 {
4406 ImagePacketPacket im = new ImagePacketPacket();
4407 im.Header.Reliable = false;
4408 im.ImageID.Packet = partNumber;
4409 im.ImageID.ID = imageUuid;
4410 im.ImageData.Data = imageData;
4411
4412 OutPacket(im, ThrottleOutPacketType.Texture);
4413 }
4414
4415 public void SendImageNotFound(UUID imageid)
4416 {
4417 ImageNotInDatabasePacket notFoundPacket
4418 = (ImageNotInDatabasePacket)PacketPool.Instance.GetPacket(PacketType.ImageNotInDatabase);
4419
4420 notFoundPacket.ImageID.ID = imageid;
4421
4422 OutPacket(notFoundPacket, ThrottleOutPacketType.Texture);
4423 }
4424
4425 public void SendShutdownConnectionNotice()
4426 {
4427 OutPacket(PacketPool.Instance.GetPacket(PacketType.DisableSimulator), ThrottleOutPacketType.Unknown);
4428 }
4429
4430 public void SendSimStats(SimStats stats)
4431 {
4432 SimStatsPacket pack = new SimStatsPacket();
4433 pack.Region = new SimStatsPacket.RegionBlock();
4434 pack.Region.RegionX = stats.RegionX;
4435 pack.Region.RegionY = stats.RegionY;
4436 pack.Region.RegionFlags = stats.RegionFlags;
4437 pack.Region.ObjectCapacity = stats.ObjectCapacity;
4438 //pack.Region = //stats.RegionBlock;
4439 pack.Stat = stats.StatsBlock;
4440
4441 pack.Header.Reliable = false;
4442 pack.RegionInfo = new SimStatsPacket.RegionInfoBlock[0];
4443 OutPacket(pack, ThrottleOutPacketType.Task);
4444 }
4445
4446 private class ObjectPropertyUpdate : IEntityUpdate
4447 {
4448 internal bool SendFamilyProps;
4449 internal bool SendObjectProps;
4450
4451 public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj)
4452 : base(entity,flags)
4453 {
4454 SendFamilyProps = sendfam;
4455 SendObjectProps = sendobj;
4456 }
4457 public void Update(ObjectPropertyUpdate update)
4458 {
4459 SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
4460 SendObjectProps = SendObjectProps || update.SendObjectProps;
4461 // other properties may need to be updated by base class
4462 base.Update(update);
4463 }
4464 }
4465
4466 public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags)
4467 {
4468 uint priority = 0; // time based ordering only
4469 lock (m_entityProps.SyncRoot)
4470 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
4471 }
4472
4473 private void ResendPropertyUpdate(ObjectPropertyUpdate update)
4474 {
4475 uint priority = 0;
4476 lock (m_entityProps.SyncRoot)
4477 m_entityProps.Enqueue(priority, update);
4478 }
4479
4480 private void ResendPropertyUpdates(List<ObjectPropertyUpdate> updates, OutgoingPacket oPacket)
4481 {
4482 // m_log.WarnFormat("[CLIENT] resending object property {0}",updates[0].UpdateTime);
4483
4484 // Remove the update packet from the list of packets waiting for acknowledgement
4485 // because we are requeuing the list of updates. They will be resent in new packets
4486 // with the most recent state.
4487 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
4488
4489 // Count this as a resent packet since we are going to requeue all of the updates contained in it
4490 Interlocked.Increment(ref m_udpClient.PacketsResent);
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
4496 foreach (ObjectPropertyUpdate update in updates)
4497 ResendPropertyUpdate(update);
4498 }
4499
4500 public void SendObjectPropertiesReply(ISceneEntity entity)
4501 {
4502 uint priority = 0; // time based ordering only
4503 lock (m_entityProps.SyncRoot)
4504 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
4505 }
4506
4507 private void ProcessEntityPropertyRequests(int maxUpdates)
4508 {
4509 OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks =
4510 new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>();
4511
4512 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
4513 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
4514
4515 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
4516 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4517
4518 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4519 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4520
4521 IEntityUpdate iupdate;
4522 Int32 timeinqueue; // this is just debugging code & can be dropped later
4523
4524 int updatesThisCall = 0;
4525 while (updatesThisCall < m_maxUpdates)
4526 {
4527 lock (m_entityProps.SyncRoot)
4528 if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
4529 break;
4530
4531 ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
4532 if (update.SendFamilyProps)
4533 {
4534 if (update.Entity is SceneObjectPart)
4535 {
4536 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4537 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4538 objectFamilyBlocks.Value.Add(objPropDB);
4539 familyUpdates.Value.Add(update);
4540 }
4541 }
4542
4543 if (update.SendObjectProps)
4544 {
4545 if (update.Entity is SceneObjectPart)
4546 {
4547 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4548 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4549 objectPropertiesBlocks.Value.Add(objPropDB);
4550 propertyUpdates.Value.Add(update);
4551 }
4552 }
4553
4554 updatesThisCall++;
4555 }
4556
4557
4558 // Int32 ppcnt = 0;
4559 // Int32 pbcnt = 0;
4560
4561 if (objectPropertiesBlocks.IsValueCreated)
4562 {
4563 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4564 List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
4565
4566 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4567 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
4568 for (int i = 0; i < blocks.Count; i++)
4569 packet.ObjectData[i] = blocks[i];
4570
4571 packet.Header.Zerocoded = true;
4572
4573 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4574 // of the object rather than the properties when the packet was created
4575 OutPacket(packet, ThrottleOutPacketType.Task, true,
4576 delegate(OutgoingPacket oPacket)
4577 {
4578 ResendPropertyUpdates(updates, oPacket);
4579 });
4580
4581 // pbcnt += blocks.Count;
4582 // ppcnt++;
4583 }
4584
4585 // Int32 fpcnt = 0;
4586 // Int32 fbcnt = 0;
4587
4588 if (objectFamilyBlocks.IsValueCreated)
4589 {
4590 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4591
4592 // one packet per object block... uggh...
4593 for (int i = 0; i < blocks.Count; i++)
4594 {
4595 ObjectPropertiesFamilyPacket packet =
4596 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4597
4598 packet.ObjectData = blocks[i];
4599 packet.Header.Zerocoded = true;
4600
4601 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4602 // of the object rather than the properties when the packet was created
4603 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4604 updates.Add(familyUpdates.Value[i]);
4605 OutPacket(packet, ThrottleOutPacketType.Task, true,
4606 delegate(OutgoingPacket oPacket)
4607 {
4608 ResendPropertyUpdates(updates, oPacket);
4609 });
4610
4611 // fpcnt++;
4612 // fbcnt++;
4613 }
4614
4615 }
4616
4617 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
4618 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt);
4619 }
4620
4621 private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags)
4622 {
4623 ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock();
4624
4625 block.RequestFlags = requestFlags;
4626 block.ObjectID = sop.UUID;
4627 if (sop.OwnerID == sop.GroupID)
4628 block.OwnerID = UUID.Zero;
4629 else
4630 block.OwnerID = sop.OwnerID;
4631 block.GroupID = sop.GroupID;
4632 block.BaseMask = sop.BaseMask;
4633 block.OwnerMask = sop.OwnerMask;
4634 block.GroupMask = sop.GroupMask;
4635 block.EveryoneMask = sop.EveryoneMask;
4636 block.NextOwnerMask = sop.NextOwnerMask;
4637
4638 // TODO: More properties are needed in SceneObjectPart!
4639 block.OwnershipCost = sop.OwnershipCost;
4640 block.SaleType = sop.ObjectSaleType;
4641 block.SalePrice = sop.SalePrice;
4642 block.Category = sop.Category;
4643 block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right?
4644 block.Name = Util.StringToBytes256(sop.Name);
4645 block.Description = Util.StringToBytes256(sop.Description);
4646
4647 return block;
4648 }
4649
4650 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop)
4651 {
4652 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4653 // TODO: don't create new blocks if recycling an old packet
4654
4655 ObjectPropertiesPacket.ObjectDataBlock block =
4656 new ObjectPropertiesPacket.ObjectDataBlock();
4657
4658 block.ObjectID = sop.UUID;
4659 block.Name = Util.StringToBytes256(sop.Name);
4660 block.Description = Util.StringToBytes256(sop.Description);
4661
4662 block.CreationDate = (ulong)sop.CreationDate * 1000000; // viewer wants date in microseconds
4663 block.CreatorID = sop.CreatorID;
4664 block.GroupID = sop.GroupID;
4665 block.LastOwnerID = sop.LastOwnerID;
4666 if (sop.OwnerID == sop.GroupID)
4667 block.OwnerID = UUID.Zero;
4668 else
4669 block.OwnerID = sop.OwnerID;
4670
4671 block.ItemID = sop.FromUserInventoryItemID;
4672 block.FolderID = UUID.Zero; // sog.FromFolderID ??
4673 block.FromTaskID = UUID.Zero; // ???
4674 block.InventorySerial = (short)sop.InventorySerial;
4675
4676 SceneObjectPart root = sop.ParentGroup.RootPart;
4677
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
4705 block.TextureID = new byte[0]; // TextureID ???
4706 block.SitName = Util.StringToBytes256(root.SitName);
4707 block.OwnerMask = root.OwnerMask;
4708 block.NextOwnerMask = root.NextOwnerMask;
4709 block.GroupMask = root.GroupMask;
4710 block.EveryoneMask = root.EveryoneMask;
4711 block.BaseMask = root.BaseMask;
4712 block.SaleType = root.ObjectSaleType;
4713 block.SalePrice = root.SalePrice;
4714
4715 return block;
4716 }
4717
4718 #region Estate Data Sending Methods
4719
4720 private static bool convertParamStringToBool(byte[] field)
4721 {
4722 string s = Utils.BytesToString(field);
4723 if (s == "1" || s.ToLower() == "y" || s.ToLower() == "yes" || s.ToLower() == "t" || s.ToLower() == "true")
4724 {
4725 return true;
4726 }
4727 return false;
4728 }
4729
4730 public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID)
4731
4732 {
4733 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4734 packet.AgentData.TransactionID = UUID.Random();
4735 packet.AgentData.AgentID = AgentId;
4736 packet.AgentData.SessionID = SessionId;
4737 packet.MethodData.Invoice = invoice;
4738 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4739
4740 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + Data.Length];
4741
4742 for (int i = 0; i < (6 + Data.Length); i++)
4743 {
4744 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
4745 }
4746 int j = 0;
4747
4748 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4749 returnblock[j].Parameter = Utils.StringToBytes(code.ToString()); j++;
4750 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4751 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4752 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4753 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4754
4755 j = 2; // Agents
4756 if ((code & 2) != 0)
4757 j = 3; // Groups
4758 if ((code & 8) != 0)
4759 j = 5; // Managers
4760
4761 returnblock[j].Parameter = Utils.StringToBytes(Data.Length.ToString());
4762 j = 6;
4763
4764 for (int i = 0; i < Data.Length; i++)
4765 {
4766 returnblock[j].Parameter = Data[i].GetBytes(); j++;
4767 }
4768 packet.ParamList = returnblock;
4769 packet.Header.Reliable = true;
4770 OutPacket(packet, ThrottleOutPacketType.Task);
4771 }
4772
4773 public void SendBannedUserList(UUID invoice, EstateBan[] bl, uint estateID)
4774 {
4775 List<UUID> BannedUsers = new List<UUID>();
4776
4777 for (int i = 0; i < bl.Length; i++)
4778 {
4779 if (bl[i] == null)
4780 continue;
4781 if (bl[i].BannedUserID == UUID.Zero)
4782 continue;
4783 BannedUsers.Add(bl[i].BannedUserID);
4784
4785 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4786 {
4787 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4788 packet.AgentData.TransactionID = UUID.Random();
4789 packet.AgentData.AgentID = AgentId;
4790 packet.AgentData.SessionID = SessionId;
4791 packet.MethodData.Invoice = invoice;
4792 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4793
4794 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4795
4796 int j;
4797 for (j = 0; j < (6 + BannedUsers.Count); j++)
4798 {
4799 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4800 }
4801 j = 0;
4802
4803 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4804 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4805 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4806 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4807 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4808 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4809
4810 foreach (UUID banned in BannedUsers)
4811 {
4812 returnblock[j].Parameter = banned.GetBytes(); j++;
4813 }
4814 packet.ParamList = returnblock;
4815 packet.Header.Reliable = true;
4816 OutPacket(packet, ThrottleOutPacketType.Task);
4817
4818 BannedUsers.Clear();
4819 }
4820 }
4821
4822 }
4823
4824 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
4825 {
4826 RegionInfoPacket rinfopack = new RegionInfoPacket();
4827 RegionInfoPacket.RegionInfoBlock rinfoblk = new RegionInfoPacket.RegionInfoBlock();
4828 rinfopack.AgentData.AgentID = AgentId;
4829 rinfopack.AgentData.SessionID = SessionId;
4830 rinfoblk.BillableFactor = args.billableFactor;
4831 rinfoblk.EstateID = args.estateID;
4832 rinfoblk.MaxAgents = args.maxAgents;
4833 rinfoblk.ObjectBonusFactor = args.objectBonusFactor;
4834 rinfoblk.ParentEstateID = args.parentEstateID;
4835 rinfoblk.PricePerMeter = args.pricePerMeter;
4836 rinfoblk.RedirectGridX = args.redirectGridX;
4837 rinfoblk.RedirectGridY = args.redirectGridY;
4838 rinfoblk.RegionFlags = args.regionFlags;
4839 rinfoblk.SimAccess = args.simAccess;
4840 rinfoblk.SunHour = args.sunHour;
4841 rinfoblk.TerrainLowerLimit = args.terrainLowerLimit;
4842 rinfoblk.TerrainRaiseLimit = args.terrainRaiseLimit;
4843 rinfoblk.UseEstateSun = args.useEstateSun;
4844 rinfoblk.WaterHeight = args.waterHeight;
4845 rinfoblk.SimName = Utils.StringToBytes(args.simName);
4846
4847 rinfopack.RegionInfo2 = new RegionInfoPacket.RegionInfo2Block();
4848 rinfopack.RegionInfo2.HardMaxAgents = uint.MaxValue;
4849 rinfopack.RegionInfo2.HardMaxObjects = uint.MaxValue;
4850 rinfopack.RegionInfo2.MaxAgents32 = uint.MaxValue;
4851 rinfopack.RegionInfo2.ProductName = Util.StringToBytes256(args.regionType);
4852 rinfopack.RegionInfo2.ProductSKU = Utils.EmptyBytes;
4853
4854 rinfopack.HasVariableBlocks = true;
4855 rinfopack.RegionInfo = rinfoblk;
4856 rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock();
4857 rinfopack.AgentData.AgentID = AgentId;
4858 rinfopack.AgentData.SessionID = SessionId;
4859 rinfopack.RegionInfo3 = new RegionInfoPacket.RegionInfo3Block[0];
4860
4861 OutPacket(rinfopack, ThrottleOutPacketType.Task);
4862 }
4863
4864 public void SendEstateCovenantInformation(UUID covenant)
4865 {
4866// m_log.DebugFormat("[LLCLIENTVIEW]: Sending estate covenant asset id of {0} to {1}", covenant, Name);
4867
4868 EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket();
4869 EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock();
4870 edata.CovenantID = covenant;
4871 edata.CovenantTimestamp = (uint) m_scene.RegionInfo.RegionSettings.CovenantChangedDateTime;
4872 edata.EstateOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
4873 edata.EstateName = Utils.StringToBytes(m_scene.RegionInfo.EstateSettings.EstateName);
4874 einfopack.Data = edata;
4875 OutPacket(einfopack, ThrottleOutPacketType.Task);
4876 }
4877
4878 public void SendDetailedEstateData(
4879 UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition,
4880 UUID covenant, uint covenantChanged, string abuseEmail, UUID estateOwner)
4881 {
4882// m_log.DebugFormat(
4883// "[LLCLIENTVIEW]: Sending detailed estate data to {0} with covenant asset id {1}", Name, covenant);
4884
4885 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4886 packet.MethodData.Invoice = invoice;
4887 packet.AgentData.TransactionID = UUID.Random();
4888 packet.MethodData.Method = Utils.StringToBytes("estateupdateinfo");
4889 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[10];
4890
4891 for (int i = 0; i < 10; i++)
4892 {
4893 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
4894 }
4895
4896 //Sending Estate Settings
4897 returnblock[0].Parameter = Utils.StringToBytes(estateName);
4898 returnblock[1].Parameter = Utils.StringToBytes(estateOwner.ToString());
4899 returnblock[2].Parameter = Utils.StringToBytes(estateID.ToString());
4900
4901 returnblock[3].Parameter = Utils.StringToBytes(estateFlags.ToString());
4902 returnblock[4].Parameter = Utils.StringToBytes(sunPosition.ToString());
4903 returnblock[5].Parameter = Utils.StringToBytes(parentEstate.ToString());
4904 returnblock[6].Parameter = Utils.StringToBytes(covenant.ToString());
4905 returnblock[7].Parameter = Utils.StringToBytes(covenantChanged.ToString());
4906 returnblock[8].Parameter = Utils.StringToBytes("1"); // what is this?
4907 returnblock[9].Parameter = Utils.StringToBytes(abuseEmail);
4908
4909 packet.ParamList = returnblock;
4910 packet.Header.Reliable = false;
4911 //m_log.Debug("[ESTATE]: SIM--->" + packet.ToString());
4912 OutPacket(packet, ThrottleOutPacketType.Task);
4913 }
4914
4915 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
4916 {
4917 TelehubInfoPacket packet = (TelehubInfoPacket)PacketPool.Instance.GetPacket(PacketType.TelehubInfo);
4918 packet.TelehubBlock.ObjectID = ObjectID;
4919 packet.TelehubBlock.ObjectName = Utils.StringToBytes(ObjectName);
4920 packet.TelehubBlock.TelehubPos = ObjectPos;
4921 packet.TelehubBlock.TelehubRot = ObjectRot;
4922
4923 packet.SpawnPointBlock = new TelehubInfoPacket.SpawnPointBlockBlock[SpawnPoint.Count];
4924 for (int n = 0; n < SpawnPoint.Count; n++)
4925 {
4926 packet.SpawnPointBlock[n] = new TelehubInfoPacket.SpawnPointBlockBlock{SpawnPointPos = SpawnPoint[n]};
4927 }
4928
4929 OutPacket(packet, ThrottleOutPacketType.Task);
4930 }
4931
4932 #endregion
4933
4934 #region Land Data Sending Methods
4935
4936 public void SendLandParcelOverlay(byte[] data, int sequence_id)
4937 {
4938 ParcelOverlayPacket packet = (ParcelOverlayPacket)PacketPool.Instance.GetPacket(PacketType.ParcelOverlay);
4939 packet.ParcelData.Data = data;
4940 packet.ParcelData.SequenceID = sequence_id;
4941 packet.Header.Zerocoded = true;
4942 OutPacket(packet, ThrottleOutPacketType.Task);
4943 }
4944
4945 public void SendLandProperties(
4946 int sequence_id, bool snap_selection, int request_result, ILandObject lo,
4947 float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
4948 {
4949// m_log.DebugFormat("[LLCLIENTVIEW]: Sending land properties for {0} to {1}", lo.LandData.GlobalID, Name);
4950
4951 LandData landData = lo.LandData;
4952
4953 ParcelPropertiesMessage updateMessage = new ParcelPropertiesMessage();
4954
4955 updateMessage.AABBMax = landData.AABBMax;
4956 updateMessage.AABBMin = landData.AABBMin;
4957 updateMessage.Area = landData.Area;
4958 updateMessage.AuctionID = landData.AuctionID;
4959 updateMessage.AuthBuyerID = landData.AuthBuyerID;
4960 updateMessage.Bitmap = landData.Bitmap;
4961 updateMessage.Desc = landData.Description;
4962 updateMessage.Category = landData.Category;
4963 updateMessage.ClaimDate = Util.ToDateTime(landData.ClaimDate);
4964 updateMessage.ClaimPrice = landData.ClaimPrice;
4965 updateMessage.GroupID = landData.GroupID;
4966 updateMessage.IsGroupOwned = landData.IsGroupOwned;
4967 updateMessage.LandingType = (LandingType) landData.LandingType;
4968 updateMessage.LocalID = landData.LocalID;
4969
4970 if (landData.Area > 0)
4971 {
4972 updateMessage.MaxPrims = parcelObjectCapacity;
4973 }
4974 else
4975 {
4976 updateMessage.MaxPrims = 0;
4977 }
4978
4979 updateMessage.MediaAutoScale = Convert.ToBoolean(landData.MediaAutoScale);
4980 updateMessage.MediaID = landData.MediaID;
4981 updateMessage.MediaURL = landData.MediaURL;
4982 updateMessage.MusicURL = landData.MusicURL;
4983 updateMessage.Name = landData.Name;
4984 updateMessage.OtherCleanTime = landData.OtherCleanTime;
4985 updateMessage.OtherCount = 0; //TODO: Unimplemented
4986 updateMessage.OwnerID = landData.OwnerID;
4987 updateMessage.ParcelFlags = (ParcelFlags) landData.Flags;
4988 updateMessage.ParcelPrimBonus = simObjectBonusFactor;
4989 updateMessage.PassHours = landData.PassHours;
4990 updateMessage.PassPrice = landData.PassPrice;
4991 updateMessage.PublicCount = 0; //TODO: Unimplemented
4992
4993 updateMessage.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0;
4994 updateMessage.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0;
4995
4996 //updateMessage.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0;
4997 //updateMessage.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0;
4998
4999 updateMessage.RentPrice = 0;
5000 updateMessage.RequestResult = (ParcelResult) request_result;
5001 updateMessage.SalePrice = landData.SalePrice;
5002 updateMessage.SelfCount = 0; //TODO: Unimplemented
5003 updateMessage.SequenceID = sequence_id;
5004
5005 if (landData.SimwideArea > 0)
5006 {
5007 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
5008 updateMessage.SimWideMaxPrims = simulatorCapacity;
5009 }
5010 else
5011 {
5012 updateMessage.SimWideMaxPrims = 0;
5013 }
5014
5015 updateMessage.SnapSelection = snap_selection;
5016 updateMessage.SnapshotID = landData.SnapshotID;
5017 updateMessage.Status = (ParcelStatus) landData.Status;
5018 updateMessage.UserLocation = landData.UserLocation;
5019 updateMessage.UserLookAt = landData.UserLookAt;
5020
5021 updateMessage.MediaType = landData.MediaType;
5022 updateMessage.MediaDesc = landData.MediaDescription;
5023 updateMessage.MediaWidth = landData.MediaWidth;
5024 updateMessage.MediaHeight = landData.MediaHeight;
5025 updateMessage.MediaLoop = landData.MediaLoop;
5026 updateMessage.ObscureMusic = landData.ObscureMusic;
5027 updateMessage.ObscureMedia = landData.ObscureMedia;
5028
5029 IPrimCounts pc = lo.PrimCounts;
5030 updateMessage.OwnerPrims = pc.Owner;
5031 updateMessage.GroupPrims = pc.Group;
5032 updateMessage.OtherPrims = pc.Others;
5033 updateMessage.SelectedPrims = pc.Selected;
5034 updateMessage.TotalPrims = pc.Total;
5035 updateMessage.SimWideTotalPrims = pc.Simulator;
5036
5037 try
5038 {
5039 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
5040 if (eq != null)
5041 {
5042 eq.ParcelProperties(updateMessage, this.AgentId);
5043 }
5044 else
5045 {
5046 m_log.Warn("[LLCLIENTVIEW]: No EQ Interface when sending parcel data.");
5047 }
5048 }
5049 catch (Exception ex)
5050 {
5051 m_log.Error("[LLCLIENTVIEW]: Unable to send parcel data via eventqueue - exception: " + ex.ToString());
5052 }
5053 }
5054
5055 public void SendLandAccessListData(List<LandAccessEntry> accessList, uint accessFlag, int localLandID)
5056 {
5057 ParcelAccessListReplyPacket replyPacket = (ParcelAccessListReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
5058 replyPacket.Data.AgentID = AgentId;
5059 replyPacket.Data.Flags = accessFlag;
5060 replyPacket.Data.LocalID = localLandID;
5061 replyPacket.Data.SequenceID = 0;
5062
5063 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
5064 foreach (LandAccessEntry entry in accessList)
5065 {
5066 ParcelAccessListReplyPacket.ListBlock block = new ParcelAccessListReplyPacket.ListBlock();
5067 block.Flags = accessFlag;
5068 block.ID = entry.AgentID;
5069 block.Time = entry.Expires;
5070 list.Add(block);
5071 }
5072
5073 replyPacket.List = list.ToArray();
5074 replyPacket.Header.Zerocoded = true;
5075 OutPacket(replyPacket, ThrottleOutPacketType.Task);
5076 }
5077
5078 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
5079 {
5080// m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
5081
5082 bool firstCall = true;
5083 const int MAX_OBJECTS_PER_PACKET = 251;
5084 ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
5085 ForceObjectSelectPacket.DataBlock[] data;
5086 while (ObjectIDs.Count > 0)
5087 {
5088 if (firstCall)
5089 {
5090 pack._Header.ResetList = true;
5091 firstCall = false;
5092 }
5093 else
5094 {
5095 pack._Header.ResetList = false;
5096 }
5097
5098 if (ObjectIDs.Count > MAX_OBJECTS_PER_PACKET)
5099 {
5100 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
5101 }
5102 else
5103 {
5104 data = new ForceObjectSelectPacket.DataBlock[ObjectIDs.Count];
5105 }
5106
5107 int i;
5108 for (i = 0; i < MAX_OBJECTS_PER_PACKET && ObjectIDs.Count > 0; i++)
5109 {
5110 data[i] = new ForceObjectSelectPacket.DataBlock();
5111 data[i].LocalID = Convert.ToUInt32(ObjectIDs[0]);
5112 ObjectIDs.RemoveAt(0);
5113 }
5114 pack.Data = data;
5115 pack.Header.Zerocoded = true;
5116 OutPacket(pack, ThrottleOutPacketType.Task);
5117 }
5118 }
5119
5120 public void SendCameraConstraint(Vector4 ConstraintPlane)
5121 {
5122 CameraConstraintPacket cpack = (CameraConstraintPacket)PacketPool.Instance.GetPacket(PacketType.CameraConstraint);
5123 cpack.CameraCollidePlane = new CameraConstraintPacket.CameraCollidePlaneBlock();
5124 cpack.CameraCollidePlane.Plane = ConstraintPlane;
5125 //m_log.DebugFormat("[CLIENTVIEW]: Constraint {0}", ConstraintPlane);
5126 OutPacket(cpack, ThrottleOutPacketType.Task);
5127 }
5128
5129 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
5130 {
5131 int notifyCount = ownersAndCount.Count;
5132 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
5133
5134 if (notifyCount > 0)
5135 {
5136 if (notifyCount > 32)
5137 {
5138 m_log.InfoFormat(
5139 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
5140 + " - a developer might want to investigate whether this is a hard limit", 32);
5141
5142 notifyCount = 32;
5143 }
5144
5145 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
5146 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
5147
5148 int num = 0;
5149 foreach (UUID owner in ownersAndCount.Keys)
5150 {
5151 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
5152 dataBlock[num].Count = ownersAndCount[owner];
5153
5154 if (land.GroupID == owner || groups.Contains(owner))
5155 dataBlock[num].IsGroupOwned = true;
5156
5157 dataBlock[num].OnlineStatus = true; //TODO: fix me later
5158 dataBlock[num].OwnerID = owner;
5159
5160 num++;
5161
5162 if (num >= notifyCount)
5163 {
5164 break;
5165 }
5166 }
5167
5168 pack.Data = dataBlock;
5169 }
5170 else
5171 {
5172 pack.Data = new ParcelObjectOwnersReplyPacket.DataBlock[0];
5173 }
5174 pack.Header.Zerocoded = true;
5175 this.OutPacket(pack, ThrottleOutPacketType.Task);
5176 }
5177
5178 #endregion
5179
5180 #region Helper Methods
5181
5182 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
5183 {
5184 #region ScenePresence/SOP Handling
5185
5186 bool avatar = (entity is ScenePresence);
5187 uint localID = entity.LocalId;
5188 uint attachPoint;
5189 Vector4 collisionPlane;
5190 Vector3 position, velocity, acceleration, angularVelocity;
5191 Quaternion rotation;
5192 byte[] textureEntry;
5193
5194 if (entity is ScenePresence)
5195 {
5196 ScenePresence presence = (ScenePresence)entity;
5197
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;
5203 collisionPlane = presence.CollisionPlane;
5204 position = presence.OffsetPosition;
5205 velocity = presence.Velocity;
5206 acceleration = Vector3.Zero;
5207
5208 // Interestingly, sending this to non-zero will cause the client's avatar to start moving & accelerating
5209 // in that direction, even though we don't model this on the server. Implementing this in the future
5210 // may improve movement smoothness.
5211// acceleration = new Vector3(1, 0, 0);
5212
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.
5223 rotation = presence.Rotation;
5224
5225 if (!presence.IsSatOnObject)
5226 {
5227 rotation.X = 0;
5228 rotation.Y = 0;
5229 }
5230
5231 if (sendTexture)
5232 textureEntry = presence.Appearance.Texture.GetBytes();
5233 else
5234 textureEntry = null;
5235 }
5236 else
5237 {
5238 SceneObjectPart part = (SceneObjectPart)entity;
5239
5240 attachPoint = part.ParentGroup.AttachmentPoint;
5241 attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
5242// m_log.DebugFormat(
5243// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
5244// attachPoint, part.Name, part.LocalId, Name);
5245
5246 collisionPlane = Vector4.Zero;
5247 position = part.RelativePosition;
5248 velocity = part.Velocity;
5249 acceleration = part.Acceleration;
5250 angularVelocity = part.AngularVelocity;
5251 rotation = part.RotationOffset;
5252
5253 if (sendTexture)
5254 textureEntry = part.Shape.TextureEntry;
5255 else
5256 textureEntry = null;
5257 }
5258
5259 #endregion ScenePresence/SOP Handling
5260
5261 int pos = 0;
5262 byte[] data = new byte[(avatar ? 60 : 44)];
5263
5264 // LocalID
5265 Utils.UIntToBytes(localID, data, pos);
5266 pos += 4;
5267
5268 // Avatar/CollisionPlane
5269 data[pos++] = (byte) attachPoint;
5270 if (avatar)
5271 {
5272 data[pos++] = 1;
5273
5274 if (collisionPlane == Vector4.Zero)
5275 collisionPlane = Vector4.UnitW;
5276 //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane);
5277 collisionPlane.ToBytes(data, pos);
5278 pos += 16;
5279 }
5280 else
5281 {
5282 ++pos;
5283 }
5284
5285 // Position
5286 position.ToBytes(data, pos);
5287 pos += 12;
5288
5289 // Velocity
5290 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2;
5291 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2;
5292 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2;
5293
5294 // Acceleration
5295 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2;
5296 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2;
5297 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2;
5298
5299 // Rotation
5300 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.X, -1.0f, 1.0f), data, pos); pos += 2;
5301 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Y, -1.0f, 1.0f), data, pos); pos += 2;
5302 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Z, -1.0f, 1.0f), data, pos); pos += 2;
5303 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2;
5304
5305 // Angular Velocity
5306 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2;
5307 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
5308 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
5309
5310 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
5311 = PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
5312
5313 block.Data = data;
5314
5315 if (textureEntry != null && textureEntry.Length > 0)
5316 {
5317 byte[] teBytesFinal = new byte[textureEntry.Length + 4];
5318
5319 // Texture Length
5320 Utils.IntToBytes(textureEntry.Length, textureEntry, 0);
5321 // Texture
5322 Buffer.BlockCopy(textureEntry, 0, teBytesFinal, 4, textureEntry.Length);
5323
5324 block.TextureEntry = teBytesFinal;
5325 }
5326 else
5327 {
5328 block.TextureEntry = Utils.EmptyBytes;
5329 }
5330
5331 return block;
5332 }
5333
5334 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
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
5339 byte[] objectData = new byte[76];
5340
5341 data.CollisionPlane.ToBytes(objectData, 0);
5342 data.OffsetPosition.ToBytes(objectData, 16);
5343 data.Velocity.ToBytes(objectData, 28);
5344// data.Acceleration.ToBytes(objectData, 40);
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);
5363 //data.AngularVelocity.ToBytes(objectData, 64);
5364
5365 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
5366
5367 update.Data = Utils.EmptyBytes;
5368 update.ExtraParams = new byte[1];
5369 update.FullID = data.UUID;
5370 update.ID = data.LocalId;
5371 update.Material = (byte)Material.Flesh;
5372 update.MediaURL = Utils.EmptyBytes;
5373 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5374 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5375 update.ObjectData = objectData;
5376
5377 SceneObjectPart parentPart = data.ParentPart;
5378 if (parentPart != null)
5379 update.ParentID = parentPart.ParentGroup.LocalId;
5380 else
5381 update.ParentID = 0;
5382
5383 update.PathCurve = 16;
5384 update.PathScaleX = 100;
5385 update.PathScaleY = 100;
5386 update.PCode = (byte)PCode.Avatar;
5387 update.ProfileCurve = 1;
5388 update.PSBlock = Utils.EmptyBytes;
5389 update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
5390 update.Text = Utils.EmptyBytes;
5391 update.TextColor = new byte[4];
5392
5393 // Don't send texture anim for avatars - this has no meaning for them.
5394 update.TextureAnim = Utils.EmptyBytes;
5395
5396 // Don't send texture entry for avatars here - this is accomplished via the AvatarAppearance packet
5397 update.TextureEntry = Utils.EmptyBytes;
5398// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5399
5400 update.UpdateFlags = (uint)(
5401 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5402 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5403 PrimFlags.ObjectOwnerModify);
5404
5405 return update;
5406 }
5407
5408 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
5409 {
5410 byte[] objectData = new byte[60];
5411 data.RelativePosition.ToBytes(objectData, 0);
5412 data.Velocity.ToBytes(objectData, 12);
5413 data.Acceleration.ToBytes(objectData, 24);
5414 try
5415 {
5416 data.RotationOffset.ToBytes(objectData, 36);
5417 }
5418 catch (Exception e)
5419 {
5420 m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString());
5421 OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36);
5422 }
5423 data.AngularVelocity.ToBytes(objectData, 48);
5424
5425 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
5426 update.ClickAction = (byte)data.ClickAction;
5427 update.CRC = 0;
5428 update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes;
5429 update.FullID = data.UUID;
5430 update.ID = data.LocalId;
5431 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
5432 //update.JointPivot = Vector3.Zero;
5433 //update.JointType = 0;
5434 update.Material = data.Material;
5435 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
5436
5437 if (data.ParentGroup.IsAttachment)
5438 {
5439 update.NameValue
5440 = Util.StringToBytes256(
5441 string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID));
5442
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);
5452 }
5453 else
5454 {
5455 update.NameValue = Utils.EmptyBytes;
5456
5457 // The root part state is the canonical state for all parts of the object. The other part states in the
5458 // case for attachments may contain conflicting values that can end up crashing the viewer.
5459 update.State = data.ParentGroup.RootPart.Shape.State;
5460 }
5461
5462 update.ObjectData = objectData;
5463 update.ParentID = data.ParentID;
5464 update.PathBegin = data.Shape.PathBegin;
5465 update.PathCurve = data.Shape.PathCurve;
5466 update.PathEnd = data.Shape.PathEnd;
5467 update.PathRadiusOffset = data.Shape.PathRadiusOffset;
5468 update.PathRevolutions = data.Shape.PathRevolutions;
5469 update.PathScaleX = data.Shape.PathScaleX;
5470 update.PathScaleY = data.Shape.PathScaleY;
5471 update.PathShearX = data.Shape.PathShearX;
5472 update.PathShearY = data.Shape.PathShearY;
5473 update.PathSkew = data.Shape.PathSkew;
5474 update.PathTaperX = data.Shape.PathTaperX;
5475 update.PathTaperY = data.Shape.PathTaperY;
5476 update.PathTwist = data.Shape.PathTwist;
5477 update.PathTwistBegin = data.Shape.PathTwistBegin;
5478 update.PCode = data.Shape.PCode;
5479 update.ProfileBegin = data.Shape.ProfileBegin;
5480 update.ProfileCurve = data.Shape.ProfileCurve;
5481 update.ProfileEnd = data.Shape.ProfileEnd;
5482 update.ProfileHollow = data.Shape.ProfileHollow;
5483 update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes;
5484 update.TextColor = data.GetTextColor().GetBytes(false);
5485 update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes;
5486 update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
5487 update.Scale = data.Shape.Scale;
5488 update.Text = Util.StringToBytes256(data.Text);
5489 update.MediaURL = Util.StringToBytes256(data.MediaUrl);
5490
5491 #region PrimFlags
5492
5493 PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID);
5494
5495 // Don't send the CreateSelected flag to everyone
5496 flags &= ~PrimFlags.CreateSelected;
5497
5498 if (recipientID == data.OwnerID)
5499 {
5500 if (data.CreateSelected)
5501 {
5502 // Only send this flag once, then unset it
5503 flags |= PrimFlags.CreateSelected;
5504 data.CreateSelected = false;
5505 }
5506 }
5507
5508// m_log.DebugFormat(
5509// "[LLCLIENTVIEW]: Constructing client update for part {0} {1} with flags {2}, localId {3}",
5510// data.Name, update.FullID, flags, update.ID);
5511
5512 update.UpdateFlags = (uint)flags;
5513
5514 #endregion PrimFlags
5515
5516 if (data.Sound != UUID.Zero)
5517 {
5518 update.Sound = data.Sound;
5519 update.OwnerID = data.OwnerID;
5520 update.Gain = (float)data.SoundGain;
5521 update.Radius = (float)data.SoundRadius;
5522 update.Flags = data.SoundFlags;
5523 }
5524
5525 switch ((PCode)data.Shape.PCode)
5526 {
5527 case PCode.Grass:
5528 case PCode.Tree:
5529 case PCode.NewTree:
5530 update.Data = new byte[] { data.Shape.State };
5531 break;
5532 default:
5533 update.Data = Utils.EmptyBytes;
5534 break;
5535 }
5536
5537 return update;
5538 }
5539
5540 protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags)
5541 {
5542 // TODO: Implement this
5543 return null;
5544 }
5545
5546 public void SendNameReply(UUID profileId, string firstname, string lastname)
5547 {
5548 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
5549 // TODO: don't create new blocks if recycling an old packet
5550 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1];
5551 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock();
5552 packet.UUIDNameBlock[0].ID = profileId;
5553 packet.UUIDNameBlock[0].FirstName = Util.StringToBytes256(firstname);
5554 packet.UUIDNameBlock[0].LastName = Util.StringToBytes256(lastname);
5555
5556 OutPacket(packet, ThrottleOutPacketType.Task);
5557 }
5558
5559 public ulong GetGroupPowers(UUID groupID)
5560 {
5561 if (groupID == ActiveGroupId)
5562 return ActiveGroupPowers;
5563
5564 if (m_groupPowers.ContainsKey(groupID))
5565 return m_groupPowers[groupID];
5566
5567 return 0;
5568 }
5569
5570 #endregion
5571
5572 /// <summary>
5573 /// This is a different way of processing packets then ProcessInPacket
5574 /// </summary>
5575 protected virtual void RegisterLocalPacketHandlers()
5576 {
5577 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
5578
5579 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5580 // for each AgentUpdate packet.
5581 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5582
5583 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5584 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5585 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5586 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
5587 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
5588 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
5589 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
5590 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true);
5591 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true);
5592 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
5593 AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true);
5594 AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
5595 AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
5596 AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
5597 AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
5598 AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
5599 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
5600 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
5601 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
5602 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
5603 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
5604 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
5605 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
5606 AddLocalPacketHandler(PacketType.RezSingleAttachmentFromInv, HandlerRezSingleAttachmentFromInv);
5607 AddLocalPacketHandler(PacketType.RezMultipleAttachmentsFromInv, HandleRezMultipleAttachmentsFromInv);
5608 AddLocalPacketHandler(PacketType.DetachAttachmentIntoInv, HandleDetachAttachmentIntoInv);
5609 AddLocalPacketHandler(PacketType.ObjectAttach, HandleObjectAttach);
5610 AddLocalPacketHandler(PacketType.ObjectDetach, HandleObjectDetach);
5611 AddLocalPacketHandler(PacketType.ObjectDrop, HandleObjectDrop);
5612 AddLocalPacketHandler(PacketType.SetAlwaysRun, HandleSetAlwaysRun, false);
5613 AddLocalPacketHandler(PacketType.CompleteAgentMovement, HandleCompleteAgentMovement);
5614 AddLocalPacketHandler(PacketType.AgentAnimation, HandleAgentAnimation, false);
5615 AddLocalPacketHandler(PacketType.AgentRequestSit, HandleAgentRequestSit);
5616 AddLocalPacketHandler(PacketType.AgentSit, HandleAgentSit);
5617 AddLocalPacketHandler(PacketType.SoundTrigger, HandleSoundTrigger);
5618 AddLocalPacketHandler(PacketType.AvatarPickerRequest, HandleAvatarPickerRequest);
5619 AddLocalPacketHandler(PacketType.AgentDataUpdateRequest, HandleAgentDataUpdateRequest);
5620 AddLocalPacketHandler(PacketType.UserInfoRequest, HandleUserInfoRequest);
5621 AddLocalPacketHandler(PacketType.UpdateUserInfo, HandleUpdateUserInfo);
5622 AddLocalPacketHandler(PacketType.SetStartLocationRequest, HandleSetStartLocationRequest);
5623 AddLocalPacketHandler(PacketType.AgentThrottle, HandleAgentThrottle, false);
5624 AddLocalPacketHandler(PacketType.AgentPause, HandleAgentPause, false);
5625 AddLocalPacketHandler(PacketType.AgentResume, HandleAgentResume, false);
5626 AddLocalPacketHandler(PacketType.ForceScriptControlRelease, HandleForceScriptControlRelease);
5627 AddLocalPacketHandler(PacketType.ObjectLink, HandleObjectLink);
5628 AddLocalPacketHandler(PacketType.ObjectDelink, HandleObjectDelink);
5629 AddLocalPacketHandler(PacketType.ObjectAdd, HandleObjectAdd);
5630 AddLocalPacketHandler(PacketType.ObjectShape, HandleObjectShape);
5631 AddLocalPacketHandler(PacketType.ObjectExtraParams, HandleObjectExtraParams);
5632 AddLocalPacketHandler(PacketType.ObjectDuplicate, HandleObjectDuplicate);
5633 AddLocalPacketHandler(PacketType.RequestMultipleObjects, HandleRequestMultipleObjects);
5634 AddLocalPacketHandler(PacketType.ObjectSelect, HandleObjectSelect);
5635 AddLocalPacketHandler(PacketType.ObjectDeselect, HandleObjectDeselect);
5636 AddLocalPacketHandler(PacketType.ObjectPosition, HandleObjectPosition);
5637 AddLocalPacketHandler(PacketType.ObjectScale, HandleObjectScale);
5638 AddLocalPacketHandler(PacketType.ObjectRotation, HandleObjectRotation);
5639 AddLocalPacketHandler(PacketType.ObjectFlagUpdate, HandleObjectFlagUpdate);
5640
5641 // Handle ObjectImage (TextureEntry) updates synchronously, since when updating multiple prim faces at once,
5642 // some clients will send out a separate ObjectImage packet for each face
5643 AddLocalPacketHandler(PacketType.ObjectImage, HandleObjectImage, false);
5644
5645 AddLocalPacketHandler(PacketType.ObjectGrab, HandleObjectGrab, false);
5646 AddLocalPacketHandler(PacketType.ObjectGrabUpdate, HandleObjectGrabUpdate, false);
5647 AddLocalPacketHandler(PacketType.ObjectDeGrab, HandleObjectDeGrab);
5648 AddLocalPacketHandler(PacketType.ObjectSpinStart, HandleObjectSpinStart, false);
5649 AddLocalPacketHandler(PacketType.ObjectSpinUpdate, HandleObjectSpinUpdate, false);
5650 AddLocalPacketHandler(PacketType.ObjectSpinStop, HandleObjectSpinStop, false);
5651 AddLocalPacketHandler(PacketType.ObjectDescription, HandleObjectDescription, false);
5652 AddLocalPacketHandler(PacketType.ObjectName, HandleObjectName, false);
5653 AddLocalPacketHandler(PacketType.ObjectPermissions, HandleObjectPermissions, false);
5654 AddLocalPacketHandler(PacketType.Undo, HandleUndo, false);
5655 AddLocalPacketHandler(PacketType.UndoLand, HandleLandUndo, false);
5656 AddLocalPacketHandler(PacketType.Redo, HandleRedo, false);
5657 AddLocalPacketHandler(PacketType.ObjectDuplicateOnRay, HandleObjectDuplicateOnRay);
5658 AddLocalPacketHandler(PacketType.RequestObjectPropertiesFamily, HandleRequestObjectPropertiesFamily, false);
5659 AddLocalPacketHandler(PacketType.ObjectIncludeInSearch, HandleObjectIncludeInSearch);
5660 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
5661 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
5662 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
5663 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
5664 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
5665 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
5666 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
5667 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
5668 AddLocalPacketHandler(PacketType.ConfirmXferPacket, HandleConfirmXferPacket);
5669 AddLocalPacketHandler(PacketType.AbortXfer, HandleAbortXfer);
5670 AddLocalPacketHandler(PacketType.CreateInventoryFolder, HandleCreateInventoryFolder);
5671 AddLocalPacketHandler(PacketType.UpdateInventoryFolder, HandleUpdateInventoryFolder);
5672 AddLocalPacketHandler(PacketType.MoveInventoryFolder, HandleMoveInventoryFolder);
5673 AddLocalPacketHandler(PacketType.CreateInventoryItem, HandleCreateInventoryItem);
5674 AddLocalPacketHandler(PacketType.LinkInventoryItem, HandleLinkInventoryItem);
5675 AddLocalPacketHandler(PacketType.FetchInventory, HandleFetchInventory);
5676 AddLocalPacketHandler(PacketType.FetchInventoryDescendents, HandleFetchInventoryDescendents);
5677 AddLocalPacketHandler(PacketType.PurgeInventoryDescendents, HandlePurgeInventoryDescendents);
5678 AddLocalPacketHandler(PacketType.UpdateInventoryItem, HandleUpdateInventoryItem);
5679 AddLocalPacketHandler(PacketType.CopyInventoryItem, HandleCopyInventoryItem);
5680 AddLocalPacketHandler(PacketType.MoveInventoryItem, HandleMoveInventoryItem);
5681 AddLocalPacketHandler(PacketType.RemoveInventoryItem, HandleRemoveInventoryItem);
5682 AddLocalPacketHandler(PacketType.RemoveInventoryFolder, HandleRemoveInventoryFolder);
5683 AddLocalPacketHandler(PacketType.RemoveInventoryObjects, HandleRemoveInventoryObjects);
5684 AddLocalPacketHandler(PacketType.RequestTaskInventory, HandleRequestTaskInventory);
5685 AddLocalPacketHandler(PacketType.UpdateTaskInventory, HandleUpdateTaskInventory);
5686 AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory);
5687 AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory);
5688 AddLocalPacketHandler(PacketType.RezScript, HandleRezScript);
5689 AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest);
5690 AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest);
5691 AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest);
5692 AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest);
5693 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5694 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
5695 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
5696 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
5697 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
5698 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
5699 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
5700 AddLocalPacketHandler(PacketType.ParcelPropertiesRequest, HandleParcelPropertiesRequest, false);
5701 AddLocalPacketHandler(PacketType.ParcelDivide, HandleParcelDivide);
5702 AddLocalPacketHandler(PacketType.ParcelJoin, HandleParcelJoin);
5703 AddLocalPacketHandler(PacketType.ParcelPropertiesUpdate, HandleParcelPropertiesUpdate);
5704 AddLocalPacketHandler(PacketType.ParcelSelectObjects, HandleParcelSelectObjects);
5705 AddLocalPacketHandler(PacketType.ParcelObjectOwnersRequest, HandleParcelObjectOwnersRequest);
5706 AddLocalPacketHandler(PacketType.ParcelGodForceOwner, HandleParcelGodForceOwner);
5707 AddLocalPacketHandler(PacketType.ParcelRelease, HandleParcelRelease);
5708 AddLocalPacketHandler(PacketType.ParcelReclaim, HandleParcelReclaim);
5709 AddLocalPacketHandler(PacketType.ParcelReturnObjects, HandleParcelReturnObjects);
5710 AddLocalPacketHandler(PacketType.ParcelSetOtherCleanTime, HandleParcelSetOtherCleanTime);
5711 AddLocalPacketHandler(PacketType.LandStatRequest, HandleLandStatRequest);
5712 AddLocalPacketHandler(PacketType.ParcelDwellRequest, HandleParcelDwellRequest);
5713 AddLocalPacketHandler(PacketType.EstateOwnerMessage, HandleEstateOwnerMessage);
5714 AddLocalPacketHandler(PacketType.RequestRegionInfo, HandleRequestRegionInfo, false);
5715 AddLocalPacketHandler(PacketType.EstateCovenantRequest, HandleEstateCovenantRequest);
5716 AddLocalPacketHandler(PacketType.RequestGodlikePowers, HandleRequestGodlikePowers);
5717 AddLocalPacketHandler(PacketType.GodKickUser, HandleGodKickUser);
5718 AddLocalPacketHandler(PacketType.MoneyBalanceRequest, HandleMoneyBalanceRequest);
5719 AddLocalPacketHandler(PacketType.EconomyDataRequest, HandleEconomyDataRequest);
5720 AddLocalPacketHandler(PacketType.RequestPayPrice, HandleRequestPayPrice);
5721 AddLocalPacketHandler(PacketType.ObjectSaleInfo, HandleObjectSaleInfo);
5722 AddLocalPacketHandler(PacketType.ObjectBuy, HandleObjectBuy);
5723 AddLocalPacketHandler(PacketType.GetScriptRunning, HandleGetScriptRunning);
5724 AddLocalPacketHandler(PacketType.SetScriptRunning, HandleSetScriptRunning);
5725 AddLocalPacketHandler(PacketType.ScriptReset, HandleScriptReset);
5726 AddLocalPacketHandler(PacketType.ActivateGestures, HandleActivateGestures);
5727 AddLocalPacketHandler(PacketType.DeactivateGestures, HandleDeactivateGestures);
5728 AddLocalPacketHandler(PacketType.ObjectOwner, HandleObjectOwner);
5729 AddLocalPacketHandler(PacketType.AgentFOV, HandleAgentFOV, false);
5730 AddLocalPacketHandler(PacketType.ViewerStats, HandleViewerStats);
5731 AddLocalPacketHandler(PacketType.MapItemRequest, HandleMapItemRequest, false);
5732 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5733 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5734 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5735 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5736 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5737 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
5738 AddLocalPacketHandler(PacketType.DirFindQuery, HandleDirFindQuery);
5739 AddLocalPacketHandler(PacketType.DirLandQuery, HandleDirLandQuery);
5740 AddLocalPacketHandler(PacketType.DirPopularQuery, HandleDirPopularQuery);
5741 AddLocalPacketHandler(PacketType.DirClassifiedQuery, HandleDirClassifiedQuery);
5742 AddLocalPacketHandler(PacketType.EventInfoRequest, HandleEventInfoRequest);
5743 AddLocalPacketHandler(PacketType.OfferCallingCard, HandleOfferCallingCard);
5744 AddLocalPacketHandler(PacketType.AcceptCallingCard, HandleAcceptCallingCard);
5745 AddLocalPacketHandler(PacketType.DeclineCallingCard, HandleDeclineCallingCard);
5746 AddLocalPacketHandler(PacketType.ActivateGroup, HandleActivateGroup);
5747 AddLocalPacketHandler(PacketType.GroupTitlesRequest, HandleGroupTitlesRequest);
5748 AddLocalPacketHandler(PacketType.GroupProfileRequest, HandleGroupProfileRequest);
5749 AddLocalPacketHandler(PacketType.GroupMembersRequest, HandleGroupMembersRequest);
5750 AddLocalPacketHandler(PacketType.GroupRoleDataRequest, HandleGroupRoleDataRequest);
5751 AddLocalPacketHandler(PacketType.GroupRoleMembersRequest, HandleGroupRoleMembersRequest);
5752 AddLocalPacketHandler(PacketType.CreateGroupRequest, HandleCreateGroupRequest);
5753 AddLocalPacketHandler(PacketType.UpdateGroupInfo, HandleUpdateGroupInfo);
5754 AddLocalPacketHandler(PacketType.SetGroupAcceptNotices, HandleSetGroupAcceptNotices);
5755 AddLocalPacketHandler(PacketType.GroupTitleUpdate, HandleGroupTitleUpdate);
5756 AddLocalPacketHandler(PacketType.ParcelDeedToGroup, HandleParcelDeedToGroup);
5757 AddLocalPacketHandler(PacketType.GroupNoticesListRequest, HandleGroupNoticesListRequest);
5758 AddLocalPacketHandler(PacketType.GroupNoticeRequest, HandleGroupNoticeRequest);
5759 AddLocalPacketHandler(PacketType.GroupRoleUpdate, HandleGroupRoleUpdate);
5760 AddLocalPacketHandler(PacketType.GroupRoleChanges, HandleGroupRoleChanges);
5761 AddLocalPacketHandler(PacketType.JoinGroupRequest, HandleJoinGroupRequest);
5762 AddLocalPacketHandler(PacketType.LeaveGroupRequest, HandleLeaveGroupRequest);
5763 AddLocalPacketHandler(PacketType.EjectGroupMemberRequest, HandleEjectGroupMemberRequest);
5764 AddLocalPacketHandler(PacketType.InviteGroupRequest, HandleInviteGroupRequest);
5765 AddLocalPacketHandler(PacketType.StartLure, HandleStartLure);
5766 AddLocalPacketHandler(PacketType.TeleportLureRequest, HandleTeleportLureRequest);
5767 AddLocalPacketHandler(PacketType.ClassifiedInfoRequest, HandleClassifiedInfoRequest);
5768 AddLocalPacketHandler(PacketType.ClassifiedInfoUpdate, HandleClassifiedInfoUpdate);
5769 AddLocalPacketHandler(PacketType.ClassifiedDelete, HandleClassifiedDelete);
5770 AddLocalPacketHandler(PacketType.ClassifiedGodDelete, HandleClassifiedGodDelete);
5771 AddLocalPacketHandler(PacketType.EventGodDelete, HandleEventGodDelete);
5772 AddLocalPacketHandler(PacketType.EventNotificationAddRequest, HandleEventNotificationAddRequest);
5773 AddLocalPacketHandler(PacketType.EventNotificationRemoveRequest, HandleEventNotificationRemoveRequest);
5774 AddLocalPacketHandler(PacketType.RetrieveInstantMessages, HandleRetrieveInstantMessages);
5775 AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete);
5776 AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete);
5777 AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate);
5778 AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true);
5779 AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true);
5780 AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights);
5781 AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery);
5782 AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry);
5783 AddLocalPacketHandler(PacketType.RemoveMuteListEntry, HandleRemoveMuteListEntry);
5784 AddLocalPacketHandler(PacketType.UserReport, HandleUserReport);
5785 AddLocalPacketHandler(PacketType.FindAgent, HandleFindAgent);
5786 AddLocalPacketHandler(PacketType.TrackAgent, HandleTrackAgent);
5787 AddLocalPacketHandler(PacketType.GodUpdateRegionInfo, HandleGodUpdateRegionInfoUpdate);
5788 AddLocalPacketHandler(PacketType.GodlikeMessage, HandleGodlikeMessage);
5789 AddLocalPacketHandler(PacketType.StateSave, HandleSaveStatePacket);
5790 AddLocalPacketHandler(PacketType.GroupAccountDetailsRequest, HandleGroupAccountDetailsRequest);
5791 AddLocalPacketHandler(PacketType.GroupAccountSummaryRequest, HandleGroupAccountSummaryRequest);
5792 AddLocalPacketHandler(PacketType.GroupAccountTransactionsRequest, HandleGroupTransactionsDetailsRequest);
5793 AddLocalPacketHandler(PacketType.FreezeUser, HandleFreezeUser);
5794 AddLocalPacketHandler(PacketType.EjectUser, HandleEjectUser);
5795 AddLocalPacketHandler(PacketType.ParcelBuyPass, HandleParcelBuyPass);
5796 AddLocalPacketHandler(PacketType.ParcelGodMarkAsContent, HandleParcelGodMarkAsContent);
5797 AddLocalPacketHandler(PacketType.GroupActiveProposalsRequest, HandleGroupActiveProposalsRequest);
5798 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5799 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5800 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5801
5802 AddGenericPacketHandler("autopilot", HandleAutopilot);
5803 }
5804
5805 #region Packet Handlers
5806
5807 public int TotalAgentUpdates { get; set; }
5808
5809 #region Scene/Avatar
5810
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)
5823 {
5824 return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
5825 }
5826
5827 /// <summary>
5828 /// This checks the movement/state update significance against the last update made.
5829 /// </summary>
5830 /// <remarks>Can only be called by one thread at a time</remarks>
5831 /// <returns></returns>
5832 /// <param name='x'></param>
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 }
5857
5858 /// <summary>
5859 /// This checks the camera update significance against the last update made.
5860 /// </summary>
5861 /// <remarks>Can only be called by one thread at a time</remarks>
5862 /// <returns></returns>
5863 /// <param name='x'></param>
5864 private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5865 {
5866 float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
5867 float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
5868 float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
5869 float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
5870
5871 bool cameraSignificant =
5872 (vdelta1 > VDELTA) ||
5873 (vdelta2 > VDELTA) ||
5874 (vdelta3 > VDELTA) ||
5875 (vdelta4 > VDELTA)
5876 ;
5877
5878 //if (cameraSignificant)
5879 //{
5880 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
5881 // x.CameraAtAxis, x.CameraCenter);
5882 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
5883 // x.CameraLeftAxis, x.CameraUpAxis);
5884 //}
5885
5886 return cameraSignificant;
5887 }
5888
5889 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5890 {
5891 // We got here, which means that something in agent update was significant
5892
5893 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5894 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5895
5896 if (x.AgentID != AgentId || x.SessionID != SessionId)
5897 return false;
5898
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;
5938
5939 PacketPool.Instance.ReturnPacket(packet);
5940
5941 return true;
5942 }
5943
5944 private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack)
5945 {
5946 MoneyTransferRequestPacket money = (MoneyTransferRequestPacket)Pack;
5947 // validate the agent owns the agentID and sessionID
5948 if (money.MoneyData.SourceID == sender.AgentId && money.AgentData.AgentID == sender.AgentId &&
5949 money.AgentData.SessionID == sender.SessionId)
5950 {
5951 MoneyTransferRequest handlerMoneyTransferRequest = OnMoneyTransferRequest;
5952 if (handlerMoneyTransferRequest != null)
5953 {
5954 handlerMoneyTransferRequest(money.MoneyData.SourceID, money.MoneyData.DestID,
5955 money.MoneyData.Amount, money.MoneyData.TransactionType,
5956 Util.FieldToString(money.MoneyData.Description));
5957 }
5958
5959 return true;
5960 }
5961
5962 return false;
5963 }
5964
5965 private bool HandleParcelGodMarkAsContent(IClientAPI client, Packet Packet)
5966 {
5967 ParcelGodMarkAsContentPacket ParcelGodMarkAsContent =
5968 (ParcelGodMarkAsContentPacket)Packet;
5969
5970 ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark;
5971 if (ParcelGodMarkAsContentHandler != null)
5972 {
5973 ParcelGodMarkAsContentHandler(this,
5974 ParcelGodMarkAsContent.AgentData.AgentID,
5975 ParcelGodMarkAsContent.ParcelData.LocalID);
5976 return true;
5977 }
5978 return false;
5979 }
5980
5981 private bool HandleFreezeUser(IClientAPI client, Packet Packet)
5982 {
5983 FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet;
5984
5985 FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser;
5986 if (FreezeUserHandler != null)
5987 {
5988 FreezeUserHandler(this,
5989 FreezeUser.AgentData.AgentID,
5990 FreezeUser.Data.Flags,
5991 FreezeUser.Data.TargetID);
5992 return true;
5993 }
5994 return false;
5995 }
5996
5997 private bool HandleEjectUser(IClientAPI client, Packet Packet)
5998 {
5999 EjectUserPacket EjectUser =
6000 (EjectUserPacket)Packet;
6001
6002 EjectUserUpdate EjectUserHandler = OnParcelEjectUser;
6003 if (EjectUserHandler != null)
6004 {
6005 EjectUserHandler(this,
6006 EjectUser.AgentData.AgentID,
6007 EjectUser.Data.Flags,
6008 EjectUser.Data.TargetID);
6009 return true;
6010 }
6011 return false;
6012 }
6013
6014 private bool HandleParcelBuyPass(IClientAPI client, Packet Packet)
6015 {
6016 ParcelBuyPassPacket ParcelBuyPass =
6017 (ParcelBuyPassPacket)Packet;
6018
6019 ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass;
6020 if (ParcelBuyPassHandler != null)
6021 {
6022 ParcelBuyPassHandler(this,
6023 ParcelBuyPass.AgentData.AgentID,
6024 ParcelBuyPass.ParcelData.LocalID);
6025 return true;
6026 }
6027 return false;
6028 }
6029
6030 private bool HandleParcelBuyRequest(IClientAPI sender, Packet Pack)
6031 {
6032 ParcelBuyPacket parcel = (ParcelBuyPacket)Pack;
6033 if (parcel.AgentData.AgentID == AgentId && parcel.AgentData.SessionID == SessionId)
6034 {
6035 ParcelBuy handlerParcelBuy = OnParcelBuy;
6036 if (handlerParcelBuy != null)
6037 {
6038 handlerParcelBuy(parcel.AgentData.AgentID, parcel.Data.GroupID, parcel.Data.Final,
6039 parcel.Data.IsGroupOwned,
6040 parcel.Data.RemoveContribution, parcel.Data.LocalID, parcel.ParcelData.Area,
6041 parcel.ParcelData.Price,
6042 false);
6043 }
6044 return true;
6045 }
6046 return false;
6047 }
6048
6049 private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack)
6050 {
6051 UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack;
6052
6053
6054 for (int i = 0; i < upack.UUIDNameBlock.Length; i++)
6055 {
6056 UUIDNameRequest handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest;
6057 if (handlerUUIDGroupNameRequest != null)
6058 {
6059 handlerUUIDGroupNameRequest(upack.UUIDNameBlock[i].ID, this);
6060 }
6061 }
6062
6063 return true;
6064 }
6065
6066 public bool HandleGenericMessage(IClientAPI sender, Packet pack)
6067 {
6068 GenericMessagePacket gmpack = (GenericMessagePacket)pack;
6069 if (m_genericPacketHandlers.Count == 0) return false;
6070 if (gmpack.AgentData.SessionID != SessionId) return false;
6071
6072 GenericMessage handlerGenericMessage = null;
6073
6074 string method = Util.FieldToString(gmpack.MethodData.Method).ToLower().Trim();
6075
6076 if (m_genericPacketHandlers.TryGetValue(method, out handlerGenericMessage))
6077 {
6078 List<string> msg = new List<string>();
6079 List<byte[]> msgBytes = new List<byte[]>();
6080
6081 if (handlerGenericMessage != null)
6082 {
6083 foreach (GenericMessagePacket.ParamListBlock block in gmpack.ParamList)
6084 {
6085 msg.Add(Util.FieldToString(block.Parameter));
6086 msgBytes.Add(block.Parameter);
6087 }
6088 try
6089 {
6090 if (OnBinaryGenericMessage != null)
6091 {
6092 OnBinaryGenericMessage(this, method, msgBytes.ToArray());
6093 }
6094 handlerGenericMessage(sender, method, msg);
6095 return true;
6096 }
6097 catch (Exception e)
6098 {
6099 m_log.ErrorFormat(
6100 "[LLCLIENTVIEW]: Exeception when handling generic message {0}{1}", e.Message, e.StackTrace);
6101 }
6102 }
6103 }
6104
6105 //m_log.Debug("[LLCLIENTVIEW]: Not handling GenericMessage with method-type of: " + method);
6106 return false;
6107 }
6108
6109 public bool HandleObjectGroupRequest(IClientAPI sender, Packet Pack)
6110 {
6111 ObjectGroupPacket ogpack = (ObjectGroupPacket)Pack;
6112 if (ogpack.AgentData.SessionID != SessionId) return false;
6113
6114 RequestObjectPropertiesFamily handlerObjectGroupRequest = OnObjectGroupRequest;
6115 if (handlerObjectGroupRequest != null)
6116 {
6117 for (int i = 0; i < ogpack.ObjectData.Length; i++)
6118 {
6119 handlerObjectGroupRequest(this, ogpack.AgentData.GroupID, ogpack.ObjectData[i].ObjectLocalID, UUID.Zero);
6120 }
6121 }
6122 return true;
6123 }
6124
6125 private bool HandleViewerEffect(IClientAPI sender, Packet Pack)
6126 {
6127 ViewerEffectPacket viewer = (ViewerEffectPacket)Pack;
6128 if (viewer.AgentData.SessionID != SessionId) return false;
6129 ViewerEffectEventHandler handlerViewerEffect = OnViewerEffect;
6130 if (handlerViewerEffect != null)
6131 {
6132 int length = viewer.Effect.Length;
6133 List<ViewerEffectEventHandlerArg> args = new List<ViewerEffectEventHandlerArg>(length);
6134 for (int i = 0; i < length; i++)
6135 {
6136 //copy the effects block arguments into the event handler arg.
6137 ViewerEffectEventHandlerArg argument = new ViewerEffectEventHandlerArg();
6138 argument.AgentID = viewer.Effect[i].AgentID;
6139 argument.Color = viewer.Effect[i].Color;
6140 argument.Duration = viewer.Effect[i].Duration;
6141 argument.ID = viewer.Effect[i].ID;
6142 argument.Type = viewer.Effect[i].Type;
6143 argument.TypeData = viewer.Effect[i].TypeData;
6144 args.Add(argument);
6145 }
6146
6147 handlerViewerEffect(sender, args);
6148 }
6149
6150 return true;
6151 }
6152
6153 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
6154 {
6155 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
6156
6157 #region Packet Session and User Check
6158 if (m_checkPackets)
6159 {
6160 if (avatarProperties.AgentData.SessionID != SessionId ||
6161 avatarProperties.AgentData.AgentID != AgentId)
6162 return true;
6163 }
6164 #endregion
6165
6166 RequestAvatarProperties handlerRequestAvatarProperties = OnRequestAvatarProperties;
6167 if (handlerRequestAvatarProperties != null)
6168 {
6169 handlerRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID);
6170 }
6171 return true;
6172 }
6173
6174 private bool HandleChatFromViewer(IClientAPI sender, Packet Pack)
6175 {
6176 ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
6177
6178 #region Packet Session and User Check
6179 if (m_checkPackets)
6180 {
6181 if (inchatpack.AgentData.SessionID != SessionId ||
6182 inchatpack.AgentData.AgentID != AgentId)
6183 return true;
6184 }
6185 #endregion
6186
6187 string fromName = String.Empty; //ClientAvatar.firstname + " " + ClientAvatar.lastname;
6188 byte[] message = inchatpack.ChatData.Message;
6189 byte type = inchatpack.ChatData.Type;
6190 Vector3 fromPos = new Vector3(); // ClientAvatar.Pos;
6191 // UUID fromAgentID = AgentId;
6192
6193 int channel = inchatpack.ChatData.Channel;
6194
6195 if (OnChatFromClient != null)
6196 {
6197 OSChatMessage args = new OSChatMessage();
6198 args.Channel = channel;
6199 args.From = fromName;
6200 args.Message = Utils.BytesToString(message);
6201 args.Type = (ChatTypeEnum)type;
6202 args.Position = fromPos;
6203
6204 args.Scene = Scene;
6205 args.Sender = this;
6206 args.SenderUUID = this.AgentId;
6207
6208 ChatMessage handlerChatFromClient = OnChatFromClient;
6209 if (handlerChatFromClient != null)
6210 handlerChatFromClient(this, args);
6211 }
6212 return true;
6213 }
6214
6215 private bool HandlerAvatarPropertiesUpdate(IClientAPI sender, Packet Pack)
6216 {
6217 AvatarPropertiesUpdatePacket avatarProps = (AvatarPropertiesUpdatePacket)Pack;
6218
6219 #region Packet Session and User Check
6220 if (m_checkPackets)
6221 {
6222 if (avatarProps.AgentData.SessionID != SessionId ||
6223 avatarProps.AgentData.AgentID != AgentId)
6224 return true;
6225 }
6226 #endregion
6227
6228 UpdateAvatarProperties handlerUpdateAvatarProperties = OnUpdateAvatarProperties;
6229 if (handlerUpdateAvatarProperties != null)
6230 {
6231 AvatarPropertiesUpdatePacket.PropertiesDataBlock Properties = avatarProps.PropertiesData;
6232 UserProfileData UserProfile = new UserProfileData();
6233 UserProfile.ID = AgentId;
6234 UserProfile.AboutText = Utils.BytesToString(Properties.AboutText);
6235 UserProfile.FirstLifeAboutText = Utils.BytesToString(Properties.FLAboutText);
6236 UserProfile.FirstLifeImage = Properties.FLImageID;
6237 UserProfile.Image = Properties.ImageID;
6238 UserProfile.ProfileUrl = Utils.BytesToString(Properties.ProfileURL);
6239 UserProfile.UserFlags &= ~3;
6240 UserProfile.UserFlags |= Properties.AllowPublish ? 1 : 0;
6241 UserProfile.UserFlags |= Properties.MaturePublish ? 2 : 0;
6242
6243 handlerUpdateAvatarProperties(this, UserProfile);
6244 }
6245 return true;
6246 }
6247
6248 private bool HandlerScriptDialogReply(IClientAPI sender, Packet Pack)
6249 {
6250 ScriptDialogReplyPacket rdialog = (ScriptDialogReplyPacket)Pack;
6251
6252 //m_log.DebugFormat("[CLIENT]: Received ScriptDialogReply from {0}", rdialog.Data.ObjectID);
6253
6254 #region Packet Session and User Check
6255 if (m_checkPackets)
6256 {
6257 if (rdialog.AgentData.SessionID != SessionId ||
6258 rdialog.AgentData.AgentID != AgentId)
6259 return true;
6260 }
6261 #endregion
6262
6263 int ch = rdialog.Data.ChatChannel;
6264 byte[] msg = rdialog.Data.ButtonLabel;
6265 if (OnChatFromClient != null)
6266 {
6267 OSChatMessage args = new OSChatMessage();
6268 args.Channel = ch;
6269 args.From = String.Empty;
6270 args.Message = Utils.BytesToString(msg);
6271 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
6272 args.Position = new Vector3();
6273 args.Scene = Scene;
6274 args.Sender = this;
6275 ChatMessage handlerChatFromClient2 = OnChatFromClient;
6276 if (handlerChatFromClient2 != null)
6277 handlerChatFromClient2(this, args);
6278 }
6279
6280 return true;
6281 }
6282
6283 private bool HandlerImprovedInstantMessage(IClientAPI sender, Packet Pack)
6284 {
6285 ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket)Pack;
6286
6287 #region Packet Session and User Check
6288 if (m_checkPackets)
6289 {
6290 if (msgpack.AgentData.SessionID != SessionId ||
6291 msgpack.AgentData.AgentID != AgentId)
6292 return true;
6293 }
6294 #endregion
6295
6296 string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName);
6297 string IMmessage = Utils.BytesToString(msgpack.MessageBlock.Message);
6298 ImprovedInstantMessage handlerInstantMessage = OnInstantMessage;
6299
6300 if (handlerInstantMessage != null)
6301 {
6302 GridInstantMessage im = new GridInstantMessage(Scene,
6303 msgpack.AgentData.AgentID,
6304 IMfromName,
6305 msgpack.MessageBlock.ToAgentID,
6306 msgpack.MessageBlock.Dialog,
6307 msgpack.MessageBlock.FromGroup,
6308 IMmessage,
6309 msgpack.MessageBlock.ID,
6310 msgpack.MessageBlock.Offline != 0 ? true : false,
6311 msgpack.MessageBlock.Position,
6312 msgpack.MessageBlock.BinaryBucket,
6313 true);
6314
6315 handlerInstantMessage(this, im);
6316 }
6317 return true;
6318
6319 }
6320
6321 private bool HandlerAcceptFriendship(IClientAPI sender, Packet Pack)
6322 {
6323 AcceptFriendshipPacket afriendpack = (AcceptFriendshipPacket)Pack;
6324
6325 #region Packet Session and User Check
6326 if (m_checkPackets)
6327 {
6328 if (afriendpack.AgentData.SessionID != SessionId ||
6329 afriendpack.AgentData.AgentID != AgentId)
6330 return true;
6331 }
6332 #endregion
6333
6334 // My guess is this is the folder to stick the calling card into
6335 List<UUID> callingCardFolders = new List<UUID>();
6336
6337 UUID transactionID = afriendpack.TransactionBlock.TransactionID;
6338
6339 for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
6340 {
6341 callingCardFolders.Add(afriendpack.FolderData[fi].FolderID);
6342 }
6343
6344 FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
6345 if (handlerApproveFriendRequest != null)
6346 {
6347 handlerApproveFriendRequest(this, transactionID, callingCardFolders);
6348 }
6349
6350 return true;
6351 }
6352
6353 private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
6354 {
6355 DeclineFriendshipPacket dfriendpack = (DeclineFriendshipPacket)Pack;
6356
6357 #region Packet Session and User Check
6358 if (m_checkPackets)
6359 {
6360 if (dfriendpack.AgentData.SessionID != SessionId ||
6361 dfriendpack.AgentData.AgentID != AgentId)
6362 return true;
6363 }
6364 #endregion
6365
6366 if (OnDenyFriendRequest != null)
6367 {
6368 OnDenyFriendRequest(this,
6369 dfriendpack.TransactionBlock.TransactionID,
6370 null);
6371 }
6372 return true;
6373 }
6374
6375 private bool HandlerTerminateFriendship(IClientAPI sender, Packet Pack)
6376 {
6377 TerminateFriendshipPacket tfriendpack = (TerminateFriendshipPacket)Pack;
6378
6379 #region Packet Session and User Check
6380 if (m_checkPackets)
6381 {
6382 if (tfriendpack.AgentData.SessionID != SessionId ||
6383 tfriendpack.AgentData.AgentID != AgentId)
6384 return true;
6385 }
6386 #endregion
6387
6388 UUID exFriendID = tfriendpack.ExBlock.OtherID;
6389 FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
6390 if (TerminateFriendshipHandler != null)
6391 {
6392 TerminateFriendshipHandler(this, exFriendID);
6393 return true;
6394 }
6395
6396 return false;
6397 }
6398
6399 private bool HandleFindAgent(IClientAPI client, Packet Packet)
6400 {
6401 FindAgentPacket FindAgent =
6402 (FindAgentPacket)Packet;
6403
6404 FindAgentUpdate FindAgentHandler = OnFindAgent;
6405 if (FindAgentHandler != null)
6406 {
6407 FindAgentHandler(this,FindAgent.AgentBlock.Hunter,FindAgent.AgentBlock.Prey);
6408 return true;
6409 }
6410 return false;
6411 }
6412
6413 private bool HandleTrackAgent(IClientAPI client, Packet Packet)
6414 {
6415 TrackAgentPacket TrackAgent =
6416 (TrackAgentPacket)Packet;
6417
6418 TrackAgentUpdate TrackAgentHandler = OnTrackAgent;
6419 if (TrackAgentHandler != null)
6420 {
6421 TrackAgentHandler(this,
6422 TrackAgent.AgentData.AgentID,
6423 TrackAgent.TargetData.PreyID);
6424 return true;
6425 }
6426 return false;
6427 }
6428
6429 private bool HandlerRezObject(IClientAPI sender, Packet Pack)
6430 {
6431 RezObjectPacket rezPacket = (RezObjectPacket)Pack;
6432
6433 #region Packet Session and User Check
6434 if (m_checkPackets)
6435 {
6436 if (rezPacket.AgentData.SessionID != SessionId ||
6437 rezPacket.AgentData.AgentID != AgentId)
6438 return true;
6439 }
6440 #endregion
6441
6442 RezObject handlerRezObject = OnRezObject;
6443 if (handlerRezObject != null)
6444 {
6445 handlerRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd,
6446 rezPacket.RezData.RayStart, rezPacket.RezData.RayTargetID,
6447 rezPacket.RezData.BypassRaycast, rezPacket.RezData.RayEndIsIntersection,
6448 rezPacket.RezData.RezSelected, rezPacket.RezData.RemoveItem,
6449 rezPacket.RezData.FromTaskID);
6450 }
6451 return true;
6452 }
6453
6454 private bool HandlerDeRezObject(IClientAPI sender, Packet Pack)
6455 {
6456 DeRezObjectPacket DeRezPacket = (DeRezObjectPacket)Pack;
6457
6458 #region Packet Session and User Check
6459 if (m_checkPackets)
6460 {
6461 if (DeRezPacket.AgentData.SessionID != SessionId ||
6462 DeRezPacket.AgentData.AgentID != AgentId)
6463 return true;
6464 }
6465 #endregion
6466
6467 DeRezObject handlerDeRezObject = OnDeRezObject;
6468 if (handlerDeRezObject != null)
6469 {
6470 List<uint> deRezIDs = new List<uint>();
6471
6472 foreach (DeRezObjectPacket.ObjectDataBlock data in
6473 DeRezPacket.ObjectData)
6474 {
6475 deRezIDs.Add(data.ObjectLocalID);
6476 }
6477 // It just so happens that the values on the DeRezAction enumerator match the Destination
6478 // values given by a Second Life client
6479 handlerDeRezObject(this, deRezIDs,
6480 DeRezPacket.AgentBlock.GroupID,
6481 (DeRezAction)DeRezPacket.AgentBlock.Destination,
6482 DeRezPacket.AgentBlock.DestinationID);
6483
6484 }
6485 return true;
6486 }
6487
6488 private bool HandlerModifyLand(IClientAPI sender, Packet Pack)
6489 {
6490 ModifyLandPacket modify = (ModifyLandPacket)Pack;
6491
6492 #region Packet Session and User Check
6493 if (m_checkPackets)
6494 {
6495 if (modify.AgentData.SessionID != SessionId ||
6496 modify.AgentData.AgentID != AgentId)
6497 return true;
6498 }
6499
6500 #endregion
6501 //m_log.Info("[LAND]: LAND:" + modify.ToString());
6502 if (modify.ParcelData.Length > 0)
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
6507 if (OnModifyTerrain != null)
6508 {
6509 for (int i = 0; i < modify.ParcelData.Length; i++)
6510 {
6511 ModifyTerrain handlerModifyTerrain = OnModifyTerrain;
6512 if (handlerModifyTerrain != null)
6513 {
6514 handlerModifyTerrain(AgentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds,
6515 modify.ModifyBlock.BrushSize,
6516 modify.ModifyBlock.Action, modify.ParcelData[i].North,
6517 modify.ParcelData[i].West, modify.ParcelData[i].South,
6518 modify.ParcelData[i].East, AgentId);
6519 }
6520 }
6521 }
6522 m_justEditedTerrain = false; // Queue terrain packet (Land layer) if necessary, make it reliable again
6523 }
6524
6525 return true;
6526 }
6527
6528 private bool HandlerRegionHandshakeReply(IClientAPI sender, Packet Pack)
6529 {
6530 Action<IClientAPI> handlerRegionHandShakeReply = OnRegionHandShakeReply;
6531 if (handlerRegionHandShakeReply != null)
6532 {
6533 handlerRegionHandShakeReply(this);
6534 }
6535
6536 return true;
6537 }
6538
6539 private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack)
6540 {
6541 GenericCall1 handlerRequestWearables = OnRequestWearables;
6542
6543 if (handlerRequestWearables != null)
6544 {
6545 handlerRequestWearables(sender);
6546 }
6547
6548 Action<IClientAPI> handlerRequestAvatarsData = OnRequestAvatarsData;
6549
6550 if (handlerRequestAvatarsData != null)
6551 {
6552 handlerRequestAvatarsData(this);
6553 }
6554
6555 return true;
6556 }
6557
6558 private bool HandlerAgentSetAppearance(IClientAPI sender, Packet Pack)
6559 {
6560 AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack;
6561
6562 #region Packet Session and User Check
6563 if (m_checkPackets)
6564 {
6565 if (appear.AgentData.SessionID != SessionId ||
6566 appear.AgentData.AgentID != AgentId)
6567 return true;
6568 }
6569 #endregion
6570
6571 SetAppearance handlerSetAppearance = OnSetAppearance;
6572 if (handlerSetAppearance != null)
6573 {
6574 // Temporarily protect ourselves from the mantis #951 failure.
6575 // However, we could do this for several other handlers where a failure isn't terminal
6576 // for the client session anyway, in order to protect ourselves against bad code in plugins
6577 Vector3 avSize = appear.AgentData.Size;
6578 try
6579 {
6580 byte[] visualparams = new byte[appear.VisualParam.Length];
6581 for (int i = 0; i < appear.VisualParam.Length; i++)
6582 visualparams[i] = appear.VisualParam[i].ParamValue;
6583 //var b = appear.WearableData[0];
6584
6585 Primitive.TextureEntry te = null;
6586 if (appear.ObjectData.TextureEntry.Length > 1)
6587 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6588
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);
6596 }
6597 catch (Exception e)
6598 {
6599 m_log.ErrorFormat(
6600 "[CLIENT VIEW]: AgentSetApperance packet handler threw an exception, {0}",
6601 e);
6602 }
6603 }
6604
6605 return true;
6606 }
6607
6608 private bool HandlerAgentIsNowWearing(IClientAPI sender, Packet Pack)
6609 {
6610 if (OnAvatarNowWearing != null)
6611 {
6612 AgentIsNowWearingPacket nowWearing = (AgentIsNowWearingPacket)Pack;
6613
6614 #region Packet Session and User Check
6615 if (m_checkPackets)
6616 {
6617 if (nowWearing.AgentData.SessionID != SessionId ||
6618 nowWearing.AgentData.AgentID != AgentId)
6619 return true;
6620 }
6621 #endregion
6622
6623 AvatarWearingArgs wearingArgs = new AvatarWearingArgs();
6624 for (int i = 0; i < nowWearing.WearableData.Length; i++)
6625 {
6626 //m_log.DebugFormat("[XXX]: Wearable type {0} item {1}", nowWearing.WearableData[i].WearableType, nowWearing.WearableData[i].ItemID);
6627 AvatarWearingArgs.Wearable wearable =
6628 new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID,
6629 nowWearing.WearableData[i].WearableType);
6630 wearingArgs.NowWearing.Add(wearable);
6631 }
6632
6633 AvatarNowWearing handlerAvatarNowWearing = OnAvatarNowWearing;
6634 if (handlerAvatarNowWearing != null)
6635 {
6636 handlerAvatarNowWearing(this, wearingArgs);
6637 }
6638 }
6639 return true;
6640 }
6641
6642 private bool HandlerRezSingleAttachmentFromInv(IClientAPI sender, Packet Pack)
6643 {
6644 RezSingleAttachmentFromInv handlerRezSingleAttachment = OnRezSingleAttachmentFromInv;
6645 if (handlerRezSingleAttachment != null)
6646 {
6647 RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket)Pack;
6648
6649 #region Packet Session and User Check
6650 if (m_checkPackets)
6651 {
6652 if (rez.AgentData.SessionID != SessionId ||
6653 rez.AgentData.AgentID != AgentId)
6654 return true;
6655 }
6656 #endregion
6657
6658 handlerRezSingleAttachment(this, rez.ObjectData.ItemID,
6659 rez.ObjectData.AttachmentPt);
6660 }
6661
6662 return true;
6663 }
6664
6665 private bool HandleRezMultipleAttachmentsFromInv(IClientAPI sender, Packet Pack)
6666 {
6667 RezMultipleAttachmentsFromInv handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv;
6668 if (handlerRezMultipleAttachments != null)
6669 {
6670 List<KeyValuePair<UUID, uint>> rezlist = new List<KeyValuePair<UUID, uint>>();
6671 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in ((RezMultipleAttachmentsFromInvPacket)Pack).ObjectData)
6672 rezlist.Add(new KeyValuePair<UUID, uint>(obj.ItemID, obj.AttachmentPt));
6673 handlerRezMultipleAttachments(this, rezlist);
6674 }
6675
6676 return true;
6677 }
6678
6679 private bool HandleDetachAttachmentIntoInv(IClientAPI sender, Packet Pack)
6680 {
6681 UUIDNameRequest handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv;
6682 if (handlerDetachAttachmentIntoInv != null)
6683 {
6684 DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack;
6685
6686 #region Packet Session and User Check
6687 // UNSUPPORTED ON THIS PACKET
6688 #endregion
6689
6690 UUID itemID = detachtoInv.ObjectData.ItemID;
6691 // UUID ATTACH_agentID = detachtoInv.ObjectData.AgentID;
6692
6693 handlerDetachAttachmentIntoInv(itemID, this);
6694 }
6695 return true;
6696 }
6697
6698 private bool HandleObjectAttach(IClientAPI sender, Packet Pack)
6699 {
6700 if (OnObjectAttach != null)
6701 {
6702 ObjectAttachPacket att = (ObjectAttachPacket)Pack;
6703
6704 #region Packet Session and User Check
6705 if (m_checkPackets)
6706 {
6707 if (att.AgentData.SessionID != SessionId ||
6708 att.AgentData.AgentID != AgentId)
6709 return true;
6710 }
6711 #endregion
6712
6713 ObjectAttach handlerObjectAttach = OnObjectAttach;
6714
6715 if (handlerObjectAttach != null)
6716 {
6717 if (att.ObjectData.Length > 0)
6718 {
6719 handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, false);
6720 }
6721 }
6722 }
6723 return true;
6724 }
6725
6726 private bool HandleObjectDetach(IClientAPI sender, Packet Pack)
6727 {
6728 ObjectDetachPacket dett = (ObjectDetachPacket)Pack;
6729
6730 #region Packet Session and User Check
6731 if (m_checkPackets)
6732 {
6733 if (dett.AgentData.SessionID != SessionId ||
6734 dett.AgentData.AgentID != AgentId)
6735 return true;
6736 }
6737 #endregion
6738
6739 for (int j = 0; j < dett.ObjectData.Length; j++)
6740 {
6741 uint obj = dett.ObjectData[j].ObjectLocalID;
6742 ObjectDeselect handlerObjectDetach = OnObjectDetach;
6743 if (handlerObjectDetach != null)
6744 {
6745 handlerObjectDetach(obj, this);
6746 }
6747
6748 }
6749 return true;
6750 }
6751
6752 private bool HandleObjectDrop(IClientAPI sender, Packet Pack)
6753 {
6754 ObjectDropPacket dropp = (ObjectDropPacket)Pack;
6755
6756 #region Packet Session and User Check
6757 if (m_checkPackets)
6758 {
6759 if (dropp.AgentData.SessionID != SessionId ||
6760 dropp.AgentData.AgentID != AgentId)
6761 return true;
6762 }
6763 #endregion
6764
6765 for (int j = 0; j < dropp.ObjectData.Length; j++)
6766 {
6767 uint obj = dropp.ObjectData[j].ObjectLocalID;
6768 ObjectDrop handlerObjectDrop = OnObjectDrop;
6769 if (handlerObjectDrop != null)
6770 {
6771 handlerObjectDrop(obj, this);
6772 }
6773 }
6774 return true;
6775 }
6776
6777 private bool HandleSetAlwaysRun(IClientAPI sender, Packet Pack)
6778 {
6779 SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;
6780
6781 #region Packet Session and User Check
6782 if (m_checkPackets)
6783 {
6784 if (run.AgentData.SessionID != SessionId ||
6785 run.AgentData.AgentID != AgentId)
6786 return true;
6787 }
6788 #endregion
6789
6790 SetAlwaysRun handlerSetAlwaysRun = OnSetAlwaysRun;
6791 if (handlerSetAlwaysRun != null)
6792 handlerSetAlwaysRun(this, run.AgentData.AlwaysRun);
6793
6794 return true;
6795 }
6796
6797 private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack)
6798 {
6799 Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion;
6800 if (handlerCompleteMovementToRegion != null)
6801 {
6802 handlerCompleteMovementToRegion(sender, true);
6803 }
6804 handlerCompleteMovementToRegion = null;
6805
6806 return true;
6807 }
6808
6809 private bool HandleAgentAnimation(IClientAPI sender, Packet Pack)
6810 {
6811 AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack;
6812
6813 #region Packet Session and User Check
6814 if (m_checkPackets)
6815 {
6816 if (AgentAni.AgentData.SessionID != SessionId ||
6817 AgentAni.AgentData.AgentID != AgentId)
6818 return true;
6819 }
6820 #endregion
6821
6822 StartAnim handlerStartAnim = null;
6823 StopAnim handlerStopAnim = null;
6824
6825 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6826 {
6827 if (AgentAni.AnimationList[i].StartAnim)
6828 {
6829 handlerStartAnim = OnStartAnim;
6830 if (handlerStartAnim != null)
6831 {
6832 handlerStartAnim(this, AgentAni.AnimationList[i].AnimID);
6833 }
6834 }
6835 else
6836 {
6837 handlerStopAnim = OnStopAnim;
6838 if (handlerStopAnim != null)
6839 {
6840 handlerStopAnim(this, AgentAni.AnimationList[i].AnimID);
6841 }
6842 }
6843 }
6844 return true;
6845 }
6846
6847 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
6848 {
6849 if (OnAgentRequestSit != null)
6850 {
6851 AgentRequestSitPacket agentRequestSit = (AgentRequestSitPacket)Pack;
6852
6853 #region Packet Session and User Check
6854 if (m_checkPackets)
6855 {
6856 if (agentRequestSit.AgentData.SessionID != SessionId ||
6857 agentRequestSit.AgentData.AgentID != AgentId)
6858 return true;
6859 }
6860 #endregion
6861
6862 if (SceneAgent.IsChildAgent)
6863 {
6864 SendCantSitBecauseChildAgentResponse();
6865 return true;
6866 }
6867
6868 AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit;
6869
6870 if (handlerAgentRequestSit != null)
6871 handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID,
6872 agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
6873 }
6874 return true;
6875 }
6876
6877 private bool HandleAgentSit(IClientAPI sender, Packet Pack)
6878 {
6879 if (OnAgentSit != null)
6880 {
6881 AgentSitPacket agentSit = (AgentSitPacket)Pack;
6882
6883 #region Packet Session and User Check
6884 if (m_checkPackets)
6885 {
6886 if (agentSit.AgentData.SessionID != SessionId ||
6887 agentSit.AgentData.AgentID != AgentId)
6888 return true;
6889 }
6890 #endregion
6891
6892 if (SceneAgent.IsChildAgent)
6893 {
6894 SendCantSitBecauseChildAgentResponse();
6895 return true;
6896 }
6897
6898 AgentSit handlerAgentSit = OnAgentSit;
6899 if (handlerAgentSit != null)
6900 {
6901 OnAgentSit(this, agentSit.AgentData.AgentID);
6902 }
6903 }
6904 return true;
6905 }
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
6915 private bool HandleSoundTrigger(IClientAPI sender, Packet Pack)
6916 {
6917 SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack;
6918
6919 #region Packet Session and User Check
6920 if (m_checkPackets)
6921 {
6922 // UNSUPPORTED ON THIS PACKET
6923 }
6924 #endregion
6925
6926 SoundTrigger handlerSoundTrigger = OnSoundTrigger;
6927 if (handlerSoundTrigger != null)
6928 {
6929 // UUIDS are sent as zeroes by the client, substitute agent's id
6930 handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, AgentId,
6931 AgentId, AgentId,
6932 soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position,
6933 soundTriggerPacket.SoundData.Handle, 0);
6934
6935 }
6936 return true;
6937 }
6938
6939 private bool HandleAvatarPickerRequest(IClientAPI sender, Packet Pack)
6940 {
6941 AvatarPickerRequestPacket avRequestQuery = (AvatarPickerRequestPacket)Pack;
6942
6943 #region Packet Session and User Check
6944 if (m_checkPackets)
6945 {
6946 if (avRequestQuery.AgentData.SessionID != SessionId ||
6947 avRequestQuery.AgentData.AgentID != AgentId)
6948 return true;
6949 }
6950 #endregion
6951
6952 AvatarPickerRequestPacket.AgentDataBlock Requestdata = avRequestQuery.AgentData;
6953 AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data;
6954 //m_log.Debug("Agent Sends:" + Utils.BytesToString(querydata.Name));
6955
6956 AvatarPickerRequest handlerAvatarPickerRequest = OnAvatarPickerRequest;
6957 if (handlerAvatarPickerRequest != null)
6958 {
6959 handlerAvatarPickerRequest(this, Requestdata.AgentID, Requestdata.QueryID,
6960 Utils.BytesToString(querydata.Name));
6961 }
6962 return true;
6963 }
6964
6965 private bool HandleAgentDataUpdateRequest(IClientAPI sender, Packet Pack)
6966 {
6967 AgentDataUpdateRequestPacket avRequestDataUpdatePacket = (AgentDataUpdateRequestPacket)Pack;
6968
6969 #region Packet Session and User Check
6970 if (m_checkPackets)
6971 {
6972 if (avRequestDataUpdatePacket.AgentData.SessionID != SessionId ||
6973 avRequestDataUpdatePacket.AgentData.AgentID != AgentId)
6974 return true;
6975 }
6976 #endregion
6977
6978 FetchInventory handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest;
6979
6980 if (handlerAgentDataUpdateRequest != null)
6981 {
6982 handlerAgentDataUpdateRequest(this, avRequestDataUpdatePacket.AgentData.AgentID, avRequestDataUpdatePacket.AgentData.SessionID);
6983 }
6984
6985 return true;
6986 }
6987
6988 private bool HandleUserInfoRequest(IClientAPI sender, Packet Pack)
6989 {
6990 UserInfoRequest handlerUserInfoRequest = OnUserInfoRequest;
6991 if (handlerUserInfoRequest != null)
6992 {
6993 handlerUserInfoRequest(this);
6994 }
6995 else
6996 {
6997 SendUserInfoReply(false, true, "");
6998 }
6999 return true;
7000
7001 }
7002
7003 private bool HandleUpdateUserInfo(IClientAPI sender, Packet Pack)
7004 {
7005 UpdateUserInfoPacket updateUserInfo = (UpdateUserInfoPacket)Pack;
7006
7007 #region Packet Session and User Check
7008 if (m_checkPackets)
7009 {
7010 if (updateUserInfo.AgentData.SessionID != SessionId ||
7011 updateUserInfo.AgentData.AgentID != AgentId)
7012 return true;
7013 }
7014 #endregion
7015
7016 UpdateUserInfo handlerUpdateUserInfo = OnUpdateUserInfo;
7017 if (handlerUpdateUserInfo != null)
7018 {
7019 bool visible = true;
7020 string DirectoryVisibility =
7021 Utils.BytesToString(updateUserInfo.UserData.DirectoryVisibility);
7022 if (DirectoryVisibility == "hidden")
7023 visible = false;
7024
7025 handlerUpdateUserInfo(
7026 updateUserInfo.UserData.IMViaEMail,
7027 visible, this);
7028 }
7029 return true;
7030 }
7031
7032 private bool HandleSetStartLocationRequest(IClientAPI sender, Packet Pack)
7033 {
7034 SetStartLocationRequestPacket avSetStartLocationRequestPacket = (SetStartLocationRequestPacket)Pack;
7035
7036 #region Packet Session and User Check
7037 if (m_checkPackets)
7038 {
7039 if (avSetStartLocationRequestPacket.AgentData.SessionID != SessionId ||
7040 avSetStartLocationRequestPacket.AgentData.AgentID != AgentId)
7041 return true;
7042 }
7043 #endregion
7044
7045 if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId)
7046 {
7047 // Linden Client limitation..
7048 if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.X == 255.5f
7049 || avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y == 255.5f)
7050 {
7051 ScenePresence avatar = null;
7052 if (((Scene)m_scene).TryGetScenePresence(AgentId, out avatar))
7053 {
7054 if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.X == 255.5f)
7055 {
7056 avSetStartLocationRequestPacket.StartLocationData.LocationPos.X = avatar.AbsolutePosition.X;
7057 }
7058 if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y == 255.5f)
7059 {
7060 avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y = avatar.AbsolutePosition.Y;
7061 }
7062 }
7063
7064 }
7065 TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest;
7066 if (handlerSetStartLocationRequest != null)
7067 {
7068 handlerSetStartLocationRequest(this, 0, avSetStartLocationRequestPacket.StartLocationData.LocationPos,
7069 avSetStartLocationRequestPacket.StartLocationData.LocationLookAt,
7070 avSetStartLocationRequestPacket.StartLocationData.LocationID);
7071 }
7072 }
7073 return true;
7074 }
7075
7076 private bool HandleAgentThrottle(IClientAPI sender, Packet Pack)
7077 {
7078 AgentThrottlePacket atpack = (AgentThrottlePacket)Pack;
7079
7080 #region Packet Session and User Check
7081 if (m_checkPackets)
7082 {
7083 if (atpack.AgentData.SessionID != SessionId ||
7084 atpack.AgentData.AgentID != AgentId)
7085 return true;
7086 }
7087 #endregion
7088
7089 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
7090 return true;
7091 }
7092
7093 private bool HandleAgentPause(IClientAPI sender, Packet Pack)
7094 {
7095 m_udpClient.IsPaused = true;
7096 return true;
7097 }
7098
7099 private bool HandleAgentResume(IClientAPI sender, Packet Pack)
7100 {
7101 m_udpClient.IsPaused = false;
7102 SendStartPingCheck(m_udpClient.CurrentPingSequence++);
7103 return true;
7104 }
7105
7106 private bool HandleForceScriptControlRelease(IClientAPI sender, Packet Pack)
7107 {
7108 ForceReleaseControls handlerForceReleaseControls = OnForceReleaseControls;
7109 if (handlerForceReleaseControls != null)
7110 {
7111 handlerForceReleaseControls(this, AgentId);
7112 }
7113 return true;
7114 }
7115
7116 #endregion Scene/Avatar
7117
7118 #region Objects/m_sceneObjects
7119
7120 private bool HandleObjectLink(IClientAPI sender, Packet Pack)
7121 {
7122 ObjectLinkPacket link = (ObjectLinkPacket)Pack;
7123
7124 #region Packet Session and User Check
7125 if (m_checkPackets)
7126 {
7127 if (link.AgentData.SessionID != SessionId ||
7128 link.AgentData.AgentID != AgentId)
7129 return true;
7130 }
7131 #endregion
7132
7133 uint parentprimid = 0;
7134 List<uint> childrenprims = new List<uint>();
7135 if (link.ObjectData.Length > 1)
7136 {
7137 parentprimid = link.ObjectData[0].ObjectLocalID;
7138
7139 for (int i = 1; i < link.ObjectData.Length; i++)
7140 {
7141 childrenprims.Add(link.ObjectData[i].ObjectLocalID);
7142 }
7143 }
7144 LinkObjects handlerLinkObjects = OnLinkObjects;
7145 if (handlerLinkObjects != null)
7146 {
7147 handlerLinkObjects(this, parentprimid, childrenprims);
7148 }
7149 return true;
7150 }
7151
7152 private bool HandleObjectDelink(IClientAPI sender, Packet Pack)
7153 {
7154 ObjectDelinkPacket delink = (ObjectDelinkPacket)Pack;
7155
7156 #region Packet Session and User Check
7157 if (m_checkPackets)
7158 {
7159 if (delink.AgentData.SessionID != SessionId ||
7160 delink.AgentData.AgentID != AgentId)
7161 return true;
7162 }
7163 #endregion
7164
7165 // It appears the prim at index 0 is not always the root prim (for
7166 // instance, when one prim of a link set has been edited independently
7167 // of the others). Therefore, we'll pass all the ids onto the delink
7168 // method for it to decide which is the root.
7169 List<uint> prims = new List<uint>();
7170 for (int i = 0; i < delink.ObjectData.Length; i++)
7171 {
7172 prims.Add(delink.ObjectData[i].ObjectLocalID);
7173 }
7174 DelinkObjects handlerDelinkObjects = OnDelinkObjects;
7175 if (handlerDelinkObjects != null)
7176 {
7177 handlerDelinkObjects(prims, this);
7178 }
7179
7180 return true;
7181 }
7182
7183 private bool HandleObjectAdd(IClientAPI sender, Packet Pack)
7184 {
7185 if (OnAddPrim != null)
7186 {
7187 ObjectAddPacket addPacket = (ObjectAddPacket)Pack;
7188
7189 #region Packet Session and User Check
7190 if (m_checkPackets)
7191 {
7192 if (addPacket.AgentData.SessionID != SessionId ||
7193 addPacket.AgentData.AgentID != AgentId)
7194 return true;
7195 }
7196 #endregion
7197
7198 PrimitiveBaseShape shape = GetShapeFromAddPacket(addPacket);
7199 // m_log.Info("[REZData]: " + addPacket.ToString());
7200 //BypassRaycast: 1
7201 //RayStart: <69.79469, 158.2652, 98.40343>
7202 //RayEnd: <61.97724, 141.995, 92.58341>
7203 //RayTargetID: 00000000-0000-0000-0000-000000000000
7204
7205 //Check to see if adding the prim is allowed; useful for any module wanting to restrict the
7206 //object from rezing initially
7207
7208 AddNewPrim handlerAddPrim = OnAddPrim;
7209 if (handlerAddPrim != null)
7210 handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection);
7211 }
7212 return true;
7213 }
7214
7215 private bool HandleObjectShape(IClientAPI sender, Packet Pack)
7216 {
7217 ObjectShapePacket shapePacket = (ObjectShapePacket)Pack;
7218
7219 #region Packet Session and User Check
7220 if (m_checkPackets)
7221 {
7222 if (shapePacket.AgentData.SessionID != SessionId ||
7223 shapePacket.AgentData.AgentID != AgentId)
7224 return true;
7225 }
7226 #endregion
7227
7228 UpdateShape handlerUpdatePrimShape = null;
7229 for (int i = 0; i < shapePacket.ObjectData.Length; i++)
7230 {
7231 handlerUpdatePrimShape = OnUpdatePrimShape;
7232 if (handlerUpdatePrimShape != null)
7233 {
7234 UpdateShapeArgs shapeData = new UpdateShapeArgs();
7235 shapeData.ObjectLocalID = shapePacket.ObjectData[i].ObjectLocalID;
7236 shapeData.PathBegin = shapePacket.ObjectData[i].PathBegin;
7237 shapeData.PathCurve = shapePacket.ObjectData[i].PathCurve;
7238 shapeData.PathEnd = shapePacket.ObjectData[i].PathEnd;
7239 shapeData.PathRadiusOffset = shapePacket.ObjectData[i].PathRadiusOffset;
7240 shapeData.PathRevolutions = shapePacket.ObjectData[i].PathRevolutions;
7241 shapeData.PathScaleX = shapePacket.ObjectData[i].PathScaleX;
7242 shapeData.PathScaleY = shapePacket.ObjectData[i].PathScaleY;
7243 shapeData.PathShearX = shapePacket.ObjectData[i].PathShearX;
7244 shapeData.PathShearY = shapePacket.ObjectData[i].PathShearY;
7245 shapeData.PathSkew = shapePacket.ObjectData[i].PathSkew;
7246 shapeData.PathTaperX = shapePacket.ObjectData[i].PathTaperX;
7247 shapeData.PathTaperY = shapePacket.ObjectData[i].PathTaperY;
7248 shapeData.PathTwist = shapePacket.ObjectData[i].PathTwist;
7249 shapeData.PathTwistBegin = shapePacket.ObjectData[i].PathTwistBegin;
7250 shapeData.ProfileBegin = shapePacket.ObjectData[i].ProfileBegin;
7251 shapeData.ProfileCurve = shapePacket.ObjectData[i].ProfileCurve;
7252 shapeData.ProfileEnd = shapePacket.ObjectData[i].ProfileEnd;
7253 shapeData.ProfileHollow = shapePacket.ObjectData[i].ProfileHollow;
7254
7255 handlerUpdatePrimShape(m_agentId, shapePacket.ObjectData[i].ObjectLocalID,
7256 shapeData);
7257 }
7258 }
7259 return true;
7260 }
7261
7262 private bool HandleObjectExtraParams(IClientAPI sender, Packet Pack)
7263 {
7264 ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket)Pack;
7265
7266 #region Packet Session and User Check
7267 if (m_checkPackets)
7268 {
7269 if (extraPar.AgentData.SessionID != SessionId ||
7270 extraPar.AgentData.AgentID != AgentId)
7271 return true;
7272 }
7273 #endregion
7274
7275 ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams;
7276 if (handlerUpdateExtraParams != null)
7277 {
7278 for (int i = 0; i < extraPar.ObjectData.Length; i++)
7279 {
7280 handlerUpdateExtraParams(m_agentId, extraPar.ObjectData[i].ObjectLocalID,
7281 extraPar.ObjectData[i].ParamType,
7282 extraPar.ObjectData[i].ParamInUse, extraPar.ObjectData[i].ParamData);
7283 }
7284 }
7285 return true;
7286 }
7287
7288 private bool HandleObjectDuplicate(IClientAPI sender, Packet Pack)
7289 {
7290 ObjectDuplicatePacket dupe = (ObjectDuplicatePacket)Pack;
7291
7292 #region Packet Session and User Check
7293 if (m_checkPackets)
7294 {
7295 if (dupe.AgentData.SessionID != SessionId ||
7296 dupe.AgentData.AgentID != AgentId)
7297 return true;
7298 }
7299 #endregion
7300
7301// ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData;
7302
7303 ObjectDuplicate handlerObjectDuplicate = null;
7304
7305 for (int i = 0; i < dupe.ObjectData.Length; i++)
7306 {
7307 handlerObjectDuplicate = OnObjectDuplicate;
7308 if (handlerObjectDuplicate != null)
7309 {
7310 handlerObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset,
7311 dupe.SharedData.DuplicateFlags, AgentId,
7312 ActiveGroupId);
7313 }
7314 }
7315
7316 return true;
7317 }
7318
7319 private bool HandleRequestMultipleObjects(IClientAPI sender, Packet Pack)
7320 {
7321 RequestMultipleObjectsPacket incomingRequest = (RequestMultipleObjectsPacket)Pack;
7322
7323 #region Packet Session and User Check
7324 if (m_checkPackets)
7325 {
7326 if (incomingRequest.AgentData.SessionID != SessionId ||
7327 incomingRequest.AgentData.AgentID != AgentId)
7328 return true;
7329 }
7330 #endregion
7331
7332 ObjectRequest handlerObjectRequest = null;
7333
7334 for (int i = 0; i < incomingRequest.ObjectData.Length; i++)
7335 {
7336 handlerObjectRequest = OnObjectRequest;
7337 if (handlerObjectRequest != null)
7338 {
7339 handlerObjectRequest(incomingRequest.ObjectData[i].ID, this);
7340 }
7341 }
7342 return true;
7343 }
7344
7345 private bool HandleObjectSelect(IClientAPI sender, Packet Pack)
7346 {
7347 ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack;
7348
7349 #region Packet Session and User Check
7350 if (m_checkPackets)
7351 {
7352 if (incomingselect.AgentData.SessionID != SessionId ||
7353 incomingselect.AgentData.AgentID != AgentId)
7354 return true;
7355 }
7356 #endregion
7357
7358 ObjectSelect handlerObjectSelect = null;
7359
7360 for (int i = 0; i < incomingselect.ObjectData.Length; i++)
7361 {
7362 handlerObjectSelect = OnObjectSelect;
7363 if (handlerObjectSelect != null)
7364 {
7365 handlerObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this);
7366 }
7367 }
7368 return true;
7369 }
7370
7371 private bool HandleObjectDeselect(IClientAPI sender, Packet Pack)
7372 {
7373 ObjectDeselectPacket incomingdeselect = (ObjectDeselectPacket)Pack;
7374
7375 #region Packet Session and User Check
7376 if (m_checkPackets)
7377 {
7378 if (incomingdeselect.AgentData.SessionID != SessionId ||
7379 incomingdeselect.AgentData.AgentID != AgentId)
7380 return true;
7381 }
7382 #endregion
7383
7384 ObjectDeselect handlerObjectDeselect = null;
7385
7386 for (int i = 0; i < incomingdeselect.ObjectData.Length; i++)
7387 {
7388 handlerObjectDeselect = OnObjectDeselect;
7389 if (handlerObjectDeselect != null)
7390 {
7391 OnObjectDeselect(incomingdeselect.ObjectData[i].ObjectLocalID, this);
7392 }
7393 }
7394 return true;
7395 }
7396
7397 private bool HandleObjectPosition(IClientAPI sender, Packet Pack)
7398 {
7399 // DEPRECATED: but till libsecondlife removes it, people will use it
7400 ObjectPositionPacket position = (ObjectPositionPacket)Pack;
7401
7402 #region Packet Session and User Check
7403 if (m_checkPackets)
7404 {
7405 if (position.AgentData.SessionID != SessionId ||
7406 position.AgentData.AgentID != AgentId)
7407 return true;
7408 }
7409 #endregion
7410
7411
7412 for (int i = 0; i < position.ObjectData.Length; i++)
7413 {
7414 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition;
7415 if (handlerUpdateVector != null)
7416 handlerUpdateVector(position.ObjectData[i].ObjectLocalID, position.ObjectData[i].Position, this);
7417 }
7418
7419 return true;
7420 }
7421
7422 private bool HandleObjectScale(IClientAPI sender, Packet Pack)
7423 {
7424 // DEPRECATED: but till libsecondlife removes it, people will use it
7425 ObjectScalePacket scale = (ObjectScalePacket)Pack;
7426
7427 #region Packet Session and User Check
7428 if (m_checkPackets)
7429 {
7430 if (scale.AgentData.SessionID != SessionId ||
7431 scale.AgentData.AgentID != AgentId)
7432 return true;
7433 }
7434 #endregion
7435
7436 for (int i = 0; i < scale.ObjectData.Length; i++)
7437 {
7438 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale;
7439 if (handlerUpdatePrimGroupScale != null)
7440 handlerUpdatePrimGroupScale(scale.ObjectData[i].ObjectLocalID, scale.ObjectData[i].Scale, this);
7441 }
7442
7443 return true;
7444 }
7445
7446 private bool HandleObjectRotation(IClientAPI sender, Packet Pack)
7447 {
7448 // DEPRECATED: but till libsecondlife removes it, people will use it
7449 ObjectRotationPacket rotation = (ObjectRotationPacket)Pack;
7450
7451 #region Packet Session and User Check
7452 if (m_checkPackets)
7453 {
7454 if (rotation.AgentData.SessionID != SessionId ||
7455 rotation.AgentData.AgentID != AgentId)
7456 return true;
7457 }
7458 #endregion
7459
7460 for (int i = 0; i < rotation.ObjectData.Length; i++)
7461 {
7462 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation;
7463 if (handlerUpdatePrimRotation != null)
7464 handlerUpdatePrimRotation(rotation.ObjectData[i].ObjectLocalID, rotation.ObjectData[i].Rotation, this);
7465 }
7466
7467 return true;
7468 }
7469
7470 private bool HandleObjectFlagUpdate(IClientAPI sender, Packet Pack)
7471 {
7472 ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack;
7473
7474 #region Packet Session and User Check
7475 if (m_checkPackets)
7476 {
7477 if (flags.AgentData.SessionID != SessionId ||
7478 flags.AgentData.AgentID != AgentId)
7479 return true;
7480 }
7481 #endregion
7482
7483 UpdatePrimFlags handlerUpdatePrimFlags = OnUpdatePrimFlags;
7484
7485 if (handlerUpdatePrimFlags != null)
7486 {
7487// byte[] data = Pack.ToBytes();
7488 // 46,47,48 are special positions within the packet
7489 // This may change so perhaps we need a better way
7490 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7491 /*
7492 bool UsePhysics = (data[46] != 0) ? true : false;
7493 bool IsTemporary = (data[47] != 0) ? true : false;
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);
7518 }
7519 return true;
7520 }
7521
7522 private bool HandleObjectImage(IClientAPI sender, Packet Pack)
7523 {
7524 ObjectImagePacket imagePack = (ObjectImagePacket)Pack;
7525
7526 UpdatePrimTexture handlerUpdatePrimTexture = null;
7527 for (int i = 0; i < imagePack.ObjectData.Length; i++)
7528 {
7529 handlerUpdatePrimTexture = OnUpdatePrimTexture;
7530 if (handlerUpdatePrimTexture != null)
7531 {
7532 handlerUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID,
7533 imagePack.ObjectData[i].TextureEntry, this);
7534 }
7535 }
7536 return true;
7537 }
7538
7539 private bool HandleObjectGrab(IClientAPI sender, Packet Pack)
7540 {
7541 ObjectGrabPacket grab = (ObjectGrabPacket)Pack;
7542
7543 #region Packet Session and User Check
7544 if (m_checkPackets)
7545 {
7546 if (grab.AgentData.SessionID != SessionId ||
7547 grab.AgentData.AgentID != AgentId)
7548 return true;
7549 }
7550 #endregion
7551
7552 GrabObject handlerGrabObject = OnGrabObject;
7553
7554 if (handlerGrabObject != null)
7555 {
7556 List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
7557 if ((grab.SurfaceInfo != null) && (grab.SurfaceInfo.Length > 0))
7558 {
7559 foreach (ObjectGrabPacket.SurfaceInfoBlock surfaceInfo in grab.SurfaceInfo)
7560 {
7561 SurfaceTouchEventArgs arg = new SurfaceTouchEventArgs();
7562 arg.Binormal = surfaceInfo.Binormal;
7563 arg.FaceIndex = surfaceInfo.FaceIndex;
7564 arg.Normal = surfaceInfo.Normal;
7565 arg.Position = surfaceInfo.Position;
7566 arg.STCoord = surfaceInfo.STCoord;
7567 arg.UVCoord = surfaceInfo.UVCoord;
7568 touchArgs.Add(arg);
7569 }
7570 }
7571 handlerGrabObject(grab.ObjectData.LocalID, grab.ObjectData.GrabOffset, this, touchArgs);
7572 }
7573 return true;
7574 }
7575
7576 private bool HandleObjectGrabUpdate(IClientAPI sender, Packet Pack)
7577 {
7578 ObjectGrabUpdatePacket grabUpdate = (ObjectGrabUpdatePacket)Pack;
7579
7580 #region Packet Session and User Check
7581 if (m_checkPackets)
7582 {
7583 if (grabUpdate.AgentData.SessionID != SessionId ||
7584 grabUpdate.AgentData.AgentID != AgentId)
7585 return true;
7586 }
7587 #endregion
7588
7589 MoveObject handlerGrabUpdate = OnGrabUpdate;
7590
7591 if (handlerGrabUpdate != null)
7592 {
7593 List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
7594 if ((grabUpdate.SurfaceInfo != null) && (grabUpdate.SurfaceInfo.Length > 0))
7595 {
7596 foreach (ObjectGrabUpdatePacket.SurfaceInfoBlock surfaceInfo in grabUpdate.SurfaceInfo)
7597 {
7598 SurfaceTouchEventArgs arg = new SurfaceTouchEventArgs();
7599 arg.Binormal = surfaceInfo.Binormal;
7600 arg.FaceIndex = surfaceInfo.FaceIndex;
7601 arg.Normal = surfaceInfo.Normal;
7602 arg.Position = surfaceInfo.Position;
7603 arg.STCoord = surfaceInfo.STCoord;
7604 arg.UVCoord = surfaceInfo.UVCoord;
7605 touchArgs.Add(arg);
7606 }
7607 }
7608 handlerGrabUpdate(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial,
7609 grabUpdate.ObjectData.GrabPosition, this, touchArgs);
7610 }
7611 return true;
7612 }
7613
7614 private bool HandleObjectDeGrab(IClientAPI sender, Packet Pack)
7615 {
7616 ObjectDeGrabPacket deGrab = (ObjectDeGrabPacket)Pack;
7617
7618 #region Packet Session and User Check
7619 if (m_checkPackets)
7620 {
7621 if (deGrab.AgentData.SessionID != SessionId ||
7622 deGrab.AgentData.AgentID != AgentId)
7623 return true;
7624 }
7625 #endregion
7626
7627 DeGrabObject handlerDeGrabObject = OnDeGrabObject;
7628 if (handlerDeGrabObject != null)
7629 {
7630 List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
7631 if ((deGrab.SurfaceInfo != null) && (deGrab.SurfaceInfo.Length > 0))
7632 {
7633 foreach (ObjectDeGrabPacket.SurfaceInfoBlock surfaceInfo in deGrab.SurfaceInfo)
7634 {
7635 SurfaceTouchEventArgs arg = new SurfaceTouchEventArgs();
7636 arg.Binormal = surfaceInfo.Binormal;
7637 arg.FaceIndex = surfaceInfo.FaceIndex;
7638 arg.Normal = surfaceInfo.Normal;
7639 arg.Position = surfaceInfo.Position;
7640 arg.STCoord = surfaceInfo.STCoord;
7641 arg.UVCoord = surfaceInfo.UVCoord;
7642 touchArgs.Add(arg);
7643 }
7644 }
7645 handlerDeGrabObject(deGrab.ObjectData.LocalID, this, touchArgs);
7646 }
7647 return true;
7648 }
7649
7650 private bool HandleObjectSpinStart(IClientAPI sender, Packet Pack)
7651 {
7652 //m_log.Warn("[CLIENT]: unhandled ObjectSpinStart packet");
7653 ObjectSpinStartPacket spinStart = (ObjectSpinStartPacket)Pack;
7654
7655 #region Packet Session and User Check
7656 if (m_checkPackets)
7657 {
7658 if (spinStart.AgentData.SessionID != SessionId ||
7659 spinStart.AgentData.AgentID != AgentId)
7660 return true;
7661 }
7662 #endregion
7663
7664 SpinStart handlerSpinStart = OnSpinStart;
7665 if (handlerSpinStart != null)
7666 {
7667 handlerSpinStart(spinStart.ObjectData.ObjectID, this);
7668 }
7669 return true;
7670 }
7671
7672 private bool HandleObjectSpinUpdate(IClientAPI sender, Packet Pack)
7673 {
7674 //m_log.Warn("[CLIENT]: unhandled ObjectSpinUpdate packet");
7675 ObjectSpinUpdatePacket spinUpdate = (ObjectSpinUpdatePacket)Pack;
7676
7677 #region Packet Session and User Check
7678 if (m_checkPackets)
7679 {
7680 if (spinUpdate.AgentData.SessionID != SessionId ||
7681 spinUpdate.AgentData.AgentID != AgentId)
7682 return true;
7683 }
7684 #endregion
7685
7686 Vector3 axis;
7687 float angle;
7688 spinUpdate.ObjectData.Rotation.GetAxisAngle(out axis, out angle);
7689 //m_log.Warn("[CLIENT]: ObjectSpinUpdate packet rot axis:" + axis + " angle:" + angle);
7690
7691 SpinObject handlerSpinUpdate = OnSpinUpdate;
7692 if (handlerSpinUpdate != null)
7693 {
7694 handlerSpinUpdate(spinUpdate.ObjectData.ObjectID, spinUpdate.ObjectData.Rotation, this);
7695 }
7696 return true;
7697 }
7698
7699 private bool HandleObjectSpinStop(IClientAPI sender, Packet Pack)
7700 {
7701 //m_log.Warn("[CLIENT]: unhandled ObjectSpinStop packet");
7702 ObjectSpinStopPacket spinStop = (ObjectSpinStopPacket)Pack;
7703
7704 #region Packet Session and User Check
7705 if (m_checkPackets)
7706 {
7707 if (spinStop.AgentData.SessionID != SessionId ||
7708 spinStop.AgentData.AgentID != AgentId)
7709 return true;
7710 }
7711 #endregion
7712
7713 SpinStop handlerSpinStop = OnSpinStop;
7714 if (handlerSpinStop != null)
7715 {
7716 handlerSpinStop(spinStop.ObjectData.ObjectID, this);
7717 }
7718 return true;
7719 }
7720
7721 private bool HandleObjectDescription(IClientAPI sender, Packet Pack)
7722 {
7723 ObjectDescriptionPacket objDes = (ObjectDescriptionPacket)Pack;
7724
7725 #region Packet Session and User Check
7726 if (m_checkPackets)
7727 {
7728 if (objDes.AgentData.SessionID != SessionId ||
7729 objDes.AgentData.AgentID != AgentId)
7730 return true;
7731 }
7732 #endregion
7733
7734 GenericCall7 handlerObjectDescription = null;
7735
7736 for (int i = 0; i < objDes.ObjectData.Length; i++)
7737 {
7738 handlerObjectDescription = OnObjectDescription;
7739 if (handlerObjectDescription != null)
7740 {
7741 handlerObjectDescription(this, objDes.ObjectData[i].LocalID,
7742 Util.FieldToString(objDes.ObjectData[i].Description));
7743 }
7744 }
7745 return true;
7746 }
7747
7748 private bool HandleObjectName(IClientAPI sender, Packet Pack)
7749 {
7750 ObjectNamePacket objName = (ObjectNamePacket)Pack;
7751
7752 #region Packet Session and User Check
7753 if (m_checkPackets)
7754 {
7755 if (objName.AgentData.SessionID != SessionId ||
7756 objName.AgentData.AgentID != AgentId)
7757 return true;
7758 }
7759 #endregion
7760
7761 GenericCall7 handlerObjectName = null;
7762 for (int i = 0; i < objName.ObjectData.Length; i++)
7763 {
7764 handlerObjectName = OnObjectName;
7765 if (handlerObjectName != null)
7766 {
7767 handlerObjectName(this, objName.ObjectData[i].LocalID,
7768 Util.FieldToString(objName.ObjectData[i].Name));
7769 }
7770 }
7771 return true;
7772 }
7773
7774 private bool HandleObjectPermissions(IClientAPI sender, Packet Pack)
7775 {
7776 if (OnObjectPermissions != null)
7777 {
7778 ObjectPermissionsPacket newobjPerms = (ObjectPermissionsPacket)Pack;
7779
7780 #region Packet Session and User Check
7781 if (m_checkPackets)
7782 {
7783 if (newobjPerms.AgentData.SessionID != SessionId ||
7784 newobjPerms.AgentData.AgentID != AgentId)
7785 return true;
7786 }
7787 #endregion
7788
7789 UUID AgentID = newobjPerms.AgentData.AgentID;
7790 UUID SessionID = newobjPerms.AgentData.SessionID;
7791
7792 ObjectPermissions handlerObjectPermissions = null;
7793
7794 for (int i = 0; i < newobjPerms.ObjectData.Length; i++)
7795 {
7796 ObjectPermissionsPacket.ObjectDataBlock permChanges = newobjPerms.ObjectData[i];
7797
7798 byte field = permChanges.Field;
7799 uint localID = permChanges.ObjectLocalID;
7800 uint mask = permChanges.Mask;
7801 byte set = permChanges.Set;
7802
7803 handlerObjectPermissions = OnObjectPermissions;
7804
7805 if (handlerObjectPermissions != null)
7806 handlerObjectPermissions(this, AgentID, SessionID, field, localID, mask, set);
7807 }
7808 }
7809
7810 // Here's our data,
7811 // PermField contains the field the info goes into
7812 // PermField determines which mask we're changing
7813 //
7814 // chmask is the mask of the change
7815 // setTF is whether we're adding it or taking it away
7816 //
7817 // objLocalID is the localID of the object.
7818
7819 // Unfortunately, we have to pass the event the packet because objData is an array
7820 // That means multiple object perms may be updated in a single packet.
7821
7822 return true;
7823 }
7824
7825 private bool HandleUndo(IClientAPI sender, Packet Pack)
7826 {
7827 UndoPacket undoitem = (UndoPacket)Pack;
7828
7829 #region Packet Session and User Check
7830 if (m_checkPackets)
7831 {
7832 if (undoitem.AgentData.SessionID != SessionId ||
7833 undoitem.AgentData.AgentID != AgentId)
7834 return true;
7835 }
7836 #endregion
7837
7838 if (undoitem.ObjectData.Length > 0)
7839 {
7840 for (int i = 0; i < undoitem.ObjectData.Length; i++)
7841 {
7842 UUID objiD = undoitem.ObjectData[i].ObjectID;
7843 AgentSit handlerOnUndo = OnUndo;
7844 if (handlerOnUndo != null)
7845 {
7846 handlerOnUndo(this, objiD);
7847 }
7848
7849 }
7850 }
7851 return true;
7852 }
7853
7854 private bool HandleLandUndo(IClientAPI sender, Packet Pack)
7855 {
7856 UndoLandPacket undolanditem = (UndoLandPacket)Pack;
7857
7858 #region Packet Session and User Check
7859 if (m_checkPackets)
7860 {
7861 if (undolanditem.AgentData.SessionID != SessionId ||
7862 undolanditem.AgentData.AgentID != AgentId)
7863 return true;
7864 }
7865 #endregion
7866
7867 LandUndo handlerOnUndo = OnLandUndo;
7868 if (handlerOnUndo != null)
7869 {
7870 handlerOnUndo(this);
7871 }
7872 return true;
7873 }
7874
7875 private bool HandleRedo(IClientAPI sender, Packet Pack)
7876 {
7877 RedoPacket redoitem = (RedoPacket)Pack;
7878
7879 #region Packet Session and User Check
7880 if (m_checkPackets)
7881 {
7882 if (redoitem.AgentData.SessionID != SessionId ||
7883 redoitem.AgentData.AgentID != AgentId)
7884 return true;
7885 }
7886 #endregion
7887
7888 if (redoitem.ObjectData.Length > 0)
7889 {
7890 for (int i = 0; i < redoitem.ObjectData.Length; i++)
7891 {
7892 UUID objiD = redoitem.ObjectData[i].ObjectID;
7893 AgentSit handlerOnRedo = OnRedo;
7894 if (handlerOnRedo != null)
7895 {
7896 handlerOnRedo(this, objiD);
7897 }
7898
7899 }
7900 }
7901 return true;
7902 }
7903
7904 private bool HandleObjectDuplicateOnRay(IClientAPI sender, Packet Pack)
7905 {
7906 ObjectDuplicateOnRayPacket dupeOnRay = (ObjectDuplicateOnRayPacket)Pack;
7907
7908 #region Packet Session and User Check
7909 if (m_checkPackets)
7910 {
7911 if (dupeOnRay.AgentData.SessionID != SessionId ||
7912 dupeOnRay.AgentData.AgentID != AgentId)
7913 return true;
7914 }
7915 #endregion
7916
7917 ObjectDuplicateOnRay handlerObjectDuplicateOnRay = null;
7918
7919 for (int i = 0; i < dupeOnRay.ObjectData.Length; i++)
7920 {
7921 handlerObjectDuplicateOnRay = OnObjectDuplicateOnRay;
7922 if (handlerObjectDuplicateOnRay != null)
7923 {
7924 handlerObjectDuplicateOnRay(dupeOnRay.ObjectData[i].ObjectLocalID, dupeOnRay.AgentData.DuplicateFlags,
7925 AgentId, ActiveGroupId, dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd,
7926 dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast, dupeOnRay.AgentData.RayEndIsIntersection,
7927 dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates);
7928 }
7929 }
7930
7931 return true;
7932 }
7933
7934 private bool HandleRequestObjectPropertiesFamily(IClientAPI sender, Packet Pack)
7935 {
7936 //This powers the little tooltip that appears when you move your mouse over an object
7937 RequestObjectPropertiesFamilyPacket packToolTip = (RequestObjectPropertiesFamilyPacket)Pack;
7938
7939 #region Packet Session and User Check
7940 if (m_checkPackets)
7941 {
7942 if (packToolTip.AgentData.SessionID != SessionId ||
7943 packToolTip.AgentData.AgentID != AgentId)
7944 return true;
7945 }
7946 #endregion
7947
7948 RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData;
7949
7950 RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily;
7951
7952 if (handlerRequestObjectPropertiesFamily != null)
7953 {
7954 handlerRequestObjectPropertiesFamily(this, m_agentId, packObjBlock.RequestFlags,
7955 packObjBlock.ObjectID);
7956 }
7957
7958 return true;
7959 }
7960
7961 private bool HandleObjectIncludeInSearch(IClientAPI sender, Packet Pack)
7962 {
7963 //This lets us set objects to appear in search (stuff like DataSnapshot, etc)
7964 ObjectIncludeInSearchPacket packInSearch = (ObjectIncludeInSearchPacket)Pack;
7965 ObjectIncludeInSearch handlerObjectIncludeInSearch = null;
7966
7967 #region Packet Session and User Check
7968 if (m_checkPackets)
7969 {
7970 if (packInSearch.AgentData.SessionID != SessionId ||
7971 packInSearch.AgentData.AgentID != AgentId)
7972 return true;
7973 }
7974 #endregion
7975
7976 foreach (ObjectIncludeInSearchPacket.ObjectDataBlock objData in packInSearch.ObjectData)
7977 {
7978 bool inSearch = objData.IncludeInSearch;
7979 uint localID = objData.ObjectLocalID;
7980
7981 handlerObjectIncludeInSearch = OnObjectIncludeInSearch;
7982
7983 if (handlerObjectIncludeInSearch != null)
7984 {
7985 handlerObjectIncludeInSearch(this, inSearch, localID);
7986 }
7987 }
7988 return true;
7989 }
7990
7991 private bool HandleScriptAnswerYes(IClientAPI sender, Packet Pack)
7992 {
7993 ScriptAnswerYesPacket scriptAnswer = (ScriptAnswerYesPacket)Pack;
7994
7995 #region Packet Session and User Check
7996 if (m_checkPackets)
7997 {
7998 if (scriptAnswer.AgentData.SessionID != SessionId ||
7999 scriptAnswer.AgentData.AgentID != AgentId)
8000 return true;
8001 }
8002 #endregion
8003
8004 ScriptAnswer handlerScriptAnswer = OnScriptAnswer;
8005 if (handlerScriptAnswer != null)
8006 {
8007 handlerScriptAnswer(this, scriptAnswer.Data.TaskID, scriptAnswer.Data.ItemID, scriptAnswer.Data.Questions);
8008 }
8009 return true;
8010 }
8011
8012 private bool HandleObjectClickAction(IClientAPI sender, Packet Pack)
8013 {
8014 ObjectClickActionPacket ocpacket = (ObjectClickActionPacket)Pack;
8015
8016 #region Packet Session and User Check
8017 if (m_checkPackets)
8018 {
8019 if (ocpacket.AgentData.SessionID != SessionId ||
8020 ocpacket.AgentData.AgentID != AgentId)
8021 return true;
8022 }
8023 #endregion
8024
8025 GenericCall7 handlerObjectClickAction = OnObjectClickAction;
8026 if (handlerObjectClickAction != null)
8027 {
8028 foreach (ObjectClickActionPacket.ObjectDataBlock odata in ocpacket.ObjectData)
8029 {
8030 byte action = odata.ClickAction;
8031 uint localID = odata.ObjectLocalID;
8032 handlerObjectClickAction(this, localID, action.ToString());
8033 }
8034 }
8035 return true;
8036 }
8037
8038 private bool HandleObjectMaterial(IClientAPI sender, Packet Pack)
8039 {
8040 ObjectMaterialPacket ompacket = (ObjectMaterialPacket)Pack;
8041
8042 #region Packet Session and User Check
8043 if (m_checkPackets)
8044 {
8045 if (ompacket.AgentData.SessionID != SessionId ||
8046 ompacket.AgentData.AgentID != AgentId)
8047 return true;
8048 }
8049 #endregion
8050
8051 GenericCall7 handlerObjectMaterial = OnObjectMaterial;
8052 if (handlerObjectMaterial != null)
8053 {
8054 foreach (ObjectMaterialPacket.ObjectDataBlock odata in ompacket.ObjectData)
8055 {
8056 byte material = odata.Material;
8057 uint localID = odata.ObjectLocalID;
8058 handlerObjectMaterial(this, localID, material.ToString());
8059 }
8060 }
8061 return true;
8062 }
8063
8064 #endregion Objects/m_sceneObjects
8065
8066 #region Inventory/Asset/Other related packets
8067
8068 private bool HandleRequestImage(IClientAPI sender, Packet Pack)
8069 {
8070 RequestImagePacket imageRequest = (RequestImagePacket)Pack;
8071 //m_log.Debug("image request: " + Pack.ToString());
8072
8073 #region Packet Session and User Check
8074 if (m_checkPackets)
8075 {
8076 if (imageRequest.AgentData.SessionID != SessionId ||
8077 imageRequest.AgentData.AgentID != AgentId)
8078 return true;
8079 }
8080 #endregion
8081
8082 //handlerTextureRequest = null;
8083 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
8084 {
8085 TextureRequestArgs args = new TextureRequestArgs();
8086
8087 RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i];
8088
8089 args.RequestedAssetID = block.Image;
8090 args.DiscardLevel = block.DiscardLevel;
8091 args.PacketNumber = block.Packet;
8092 args.Priority = block.DownloadPriority;
8093 args.requestSequence = imageRequest.Header.Sequence;
8094
8095 // NOTE: This is not a built in part of the LLUDP protocol, but we double the
8096 // priority of avatar textures to get avatars rezzing in faster than the
8097 // surrounding scene
8098 if ((ImageType)block.Type == ImageType.Baked)
8099 args.Priority *= 2.0f;
8100
8101 ImageManager.EnqueueReq(args);
8102 }
8103
8104 return true;
8105 }
8106
8107 /// <summary>
8108 /// This is the entry point for the UDP route by which the client can retrieve asset data. If the request
8109 /// is successful then a TransferInfo packet will be sent back, followed by one or more TransferPackets
8110 /// </summary>
8111 /// <param name="sender"></param>
8112 /// <param name="Pack"></param>
8113 /// <returns>This parameter may be ignored since we appear to return true whatever happens</returns>
8114 private bool HandleTransferRequest(IClientAPI sender, Packet Pack)
8115 {
8116 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
8117
8118 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
8119 UUID taskID = UUID.Zero;
8120 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
8121 {
8122 if (!(((Scene)m_scene).Permissions.BypassPermissions()))
8123 {
8124 // We're spawning a thread because the permissions check can block this thread
8125 Util.FireAndForget(delegate
8126 {
8127 // This requests the asset if needed
8128 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
8129 }, null, "LLClientView.HandleTransferRequest");
8130
8131 return true;
8132 }
8133 }
8134 else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
8135 {
8136 //TransferRequestPacket does not include covenant uuid?
8137 //get scene covenant uuid
8138 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
8139 }
8140
8141 // This is non-blocking
8142 MakeAssetRequest(transfer, taskID);
8143
8144 return true;
8145 }
8146
8147 private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
8148 {
8149 UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
8150 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
8151 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
8152
8153 //m_log.DebugFormat(
8154 // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
8155 // requestID, itemID, taskID, Name);
8156
8157 //m_log.Debug("Transfer Request: " + transfer.ToString());
8158 // Validate inventory transfers
8159 // Has to be done here, because AssetCache can't do it
8160 //
8161 if (taskID != UUID.Zero) // Prim
8162 {
8163 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
8164
8165 if (part == null)
8166 {
8167 m_log.WarnFormat(
8168 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
8169 Name, requestID, itemID, taskID);
8170 return;
8171 }
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;
8202 }
8203
8204 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
8205 {
8206 m_log.WarnFormat(
8207 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
8208 Name, requestID, itemID, taskID);
8209 return;
8210 }
8211
8212 if (tii.OwnerID != AgentId)
8213 {
8214 m_log.WarnFormat(
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;
8236 }
8237 }
8238 }
8239 else // Agent
8240 {
8241 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
8242 if (invAccess != null)
8243 {
8244 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
8245 return;
8246 }
8247 else
8248 {
8249 return;
8250 }
8251 }
8252
8253 // Permissions out of the way, let's request the asset
8254 MakeAssetRequest(transfer, taskID);
8255
8256 }
8257
8258
8259 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
8260 {
8261 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
8262
8263 // m_log.Debug("upload request " + request.ToString());
8264 // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString());
8265 UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId);
8266
8267 UDPAssetUploadRequest handlerAssetUploadRequest = OnAssetUploadRequest;
8268
8269 if (handlerAssetUploadRequest != null)
8270 {
8271 handlerAssetUploadRequest(this, temp,
8272 request.AssetBlock.TransactionID, request.AssetBlock.Type,
8273 request.AssetBlock.AssetData, request.AssetBlock.StoreLocal,
8274 request.AssetBlock.Tempfile);
8275 }
8276 return true;
8277 }
8278
8279 private bool HandleRequestXfer(IClientAPI sender, Packet Pack)
8280 {
8281 RequestXferPacket xferReq = (RequestXferPacket)Pack;
8282
8283 RequestXfer handlerRequestXfer = OnRequestXfer;
8284
8285 if (handlerRequestXfer != null)
8286 {
8287 handlerRequestXfer(this, xferReq.XferID.ID, Util.FieldToString(xferReq.XferID.Filename));
8288 }
8289 return true;
8290 }
8291
8292 private bool HandleSendXferPacket(IClientAPI sender, Packet Pack)
8293 {
8294 SendXferPacketPacket xferRec = (SendXferPacketPacket)Pack;
8295
8296 XferReceive handlerXferReceive = OnXferReceive;
8297 if (handlerXferReceive != null)
8298 {
8299 handlerXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data);
8300 }
8301 return true;
8302 }
8303
8304 private bool HandleConfirmXferPacket(IClientAPI sender, Packet Pack)
8305 {
8306 ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack;
8307
8308 ConfirmXfer handlerConfirmXfer = OnConfirmXfer;
8309 if (handlerConfirmXfer != null)
8310 {
8311 handlerConfirmXfer(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet);
8312 }
8313 return true;
8314 }
8315
8316 private bool HandleAbortXfer(IClientAPI sender, Packet Pack)
8317 {
8318 AbortXferPacket abortXfer = (AbortXferPacket)Pack;
8319 AbortXfer handlerAbortXfer = OnAbortXfer;
8320 if (handlerAbortXfer != null)
8321 {
8322 handlerAbortXfer(this, abortXfer.XferID.ID);
8323 }
8324
8325 return true;
8326 }
8327
8328 private bool HandleCreateInventoryFolder(IClientAPI sender, Packet Pack)
8329 {
8330 CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack;
8331
8332 #region Packet Session and User Check
8333 if (m_checkPackets)
8334 {
8335 if (invFolder.AgentData.SessionID != SessionId ||
8336 invFolder.AgentData.AgentID != AgentId)
8337 return true;
8338 }
8339 #endregion
8340
8341 CreateInventoryFolder handlerCreateInventoryFolder = OnCreateNewInventoryFolder;
8342 if (handlerCreateInventoryFolder != null)
8343 {
8344 handlerCreateInventoryFolder(this, invFolder.FolderData.FolderID,
8345 (ushort)invFolder.FolderData.Type,
8346 Util.FieldToString(invFolder.FolderData.Name),
8347 invFolder.FolderData.ParentID);
8348 }
8349 return true;
8350 }
8351
8352 private bool HandleUpdateInventoryFolder(IClientAPI sender, Packet Pack)
8353 {
8354 if (OnUpdateInventoryFolder != null)
8355 {
8356 UpdateInventoryFolderPacket invFolderx = (UpdateInventoryFolderPacket)Pack;
8357
8358 #region Packet Session and User Check
8359 if (m_checkPackets)
8360 {
8361 if (invFolderx.AgentData.SessionID != SessionId ||
8362 invFolderx.AgentData.AgentID != AgentId)
8363 return true;
8364 }
8365 #endregion
8366
8367 UpdateInventoryFolder handlerUpdateInventoryFolder = null;
8368
8369 for (int i = 0; i < invFolderx.FolderData.Length; i++)
8370 {
8371 handlerUpdateInventoryFolder = OnUpdateInventoryFolder;
8372 if (handlerUpdateInventoryFolder != null)
8373 {
8374 OnUpdateInventoryFolder(this, invFolderx.FolderData[i].FolderID,
8375 (ushort)invFolderx.FolderData[i].Type,
8376 Util.FieldToString(invFolderx.FolderData[i].Name),
8377 invFolderx.FolderData[i].ParentID);
8378 }
8379 }
8380 }
8381 return true;
8382 }
8383
8384 private bool HandleMoveInventoryFolder(IClientAPI sender, Packet Pack)
8385 {
8386 if (OnMoveInventoryFolder != null)
8387 {
8388 MoveInventoryFolderPacket invFoldery = (MoveInventoryFolderPacket)Pack;
8389
8390 #region Packet Session and User Check
8391 if (m_checkPackets)
8392 {
8393 if (invFoldery.AgentData.SessionID != SessionId ||
8394 invFoldery.AgentData.AgentID != AgentId)
8395 return true;
8396 }
8397 #endregion
8398
8399 MoveInventoryFolder handlerMoveInventoryFolder = null;
8400
8401 for (int i = 0; i < invFoldery.InventoryData.Length; i++)
8402 {
8403 handlerMoveInventoryFolder = OnMoveInventoryFolder;
8404 if (handlerMoveInventoryFolder != null)
8405 {
8406 OnMoveInventoryFolder(this, invFoldery.InventoryData[i].FolderID,
8407 invFoldery.InventoryData[i].ParentID);
8408 }
8409 }
8410 }
8411 return true;
8412 }
8413
8414 private bool HandleCreateInventoryItem(IClientAPI sender, Packet Pack)
8415 {
8416 CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack;
8417
8418 #region Packet Session and User Check
8419 if (m_checkPackets)
8420 {
8421 if (createItem.AgentData.SessionID != SessionId ||
8422 createItem.AgentData.AgentID != AgentId)
8423 return true;
8424 }
8425 #endregion
8426
8427 CreateNewInventoryItem handlerCreateNewInventoryItem = OnCreateNewInventoryItem;
8428 if (handlerCreateNewInventoryItem != null)
8429 {
8430 handlerCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID,
8431 createItem.InventoryBlock.FolderID,
8432 createItem.InventoryBlock.CallbackID,
8433 Util.FieldToString(createItem.InventoryBlock.Description),
8434 Util.FieldToString(createItem.InventoryBlock.Name),
8435 createItem.InventoryBlock.InvType,
8436 createItem.InventoryBlock.Type,
8437 createItem.InventoryBlock.WearableType,
8438 createItem.InventoryBlock.NextOwnerMask,
8439 Util.UnixTimeSinceEpoch());
8440 }
8441 return true;
8442 }
8443
8444 private bool HandleLinkInventoryItem(IClientAPI sender, Packet Pack)
8445 {
8446 LinkInventoryItemPacket createLink = (LinkInventoryItemPacket)Pack;
8447
8448 #region Packet Session and User Check
8449 if (m_checkPackets)
8450 {
8451 if (createLink.AgentData.SessionID != SessionId ||
8452 createLink.AgentData.AgentID != AgentId)
8453 return true;
8454 }
8455 #endregion
8456
8457 LinkInventoryItem linkInventoryItem = OnLinkInventoryItem;
8458
8459 if (linkInventoryItem != null)
8460 {
8461 linkInventoryItem(
8462 this,
8463 createLink.InventoryBlock.TransactionID,
8464 createLink.InventoryBlock.FolderID,
8465 createLink.InventoryBlock.CallbackID,
8466 Util.FieldToString(createLink.InventoryBlock.Description),
8467 Util.FieldToString(createLink.InventoryBlock.Name),
8468 createLink.InventoryBlock.InvType,
8469 createLink.InventoryBlock.Type,
8470 createLink.InventoryBlock.OldItemID);
8471 }
8472
8473 return true;
8474 }
8475
8476 private bool HandleFetchInventory(IClientAPI sender, Packet Pack)
8477 {
8478 if (OnFetchInventory != null)
8479 {
8480 FetchInventoryPacket FetchInventoryx = (FetchInventoryPacket)Pack;
8481
8482 #region Packet Session and User Check
8483 if (m_checkPackets)
8484 {
8485 if (FetchInventoryx.AgentData.SessionID != SessionId ||
8486 FetchInventoryx.AgentData.AgentID != AgentId)
8487 return true;
8488 }
8489 #endregion
8490
8491 FetchInventory handlerFetchInventory = null;
8492
8493 for (int i = 0; i < FetchInventoryx.InventoryData.Length; i++)
8494 {
8495 handlerFetchInventory = OnFetchInventory;
8496
8497 if (handlerFetchInventory != null)
8498 {
8499 OnFetchInventory(this, FetchInventoryx.InventoryData[i].ItemID,
8500 FetchInventoryx.InventoryData[i].OwnerID);
8501 }
8502 }
8503 }
8504 return true;
8505 }
8506
8507 private bool HandleFetchInventoryDescendents(IClientAPI sender, Packet Pack)
8508 {
8509 FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack;
8510
8511 #region Packet Session and User Check
8512 if (m_checkPackets)
8513 {
8514 if (Fetch.AgentData.SessionID != SessionId ||
8515 Fetch.AgentData.AgentID != AgentId)
8516 return true;
8517 }
8518 #endregion
8519
8520 FetchInventoryDescendents handlerFetchInventoryDescendents = OnFetchInventoryDescendents;
8521 if (handlerFetchInventoryDescendents != null)
8522 {
8523 handlerFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID,
8524 Fetch.InventoryData.FetchFolders, Fetch.InventoryData.FetchItems,
8525 Fetch.InventoryData.SortOrder);
8526 }
8527 return true;
8528 }
8529
8530 private bool HandlePurgeInventoryDescendents(IClientAPI sender, Packet Pack)
8531 {
8532 PurgeInventoryDescendentsPacket Purge = (PurgeInventoryDescendentsPacket)Pack;
8533
8534 #region Packet Session and User Check
8535 if (m_checkPackets)
8536 {
8537 if (Purge.AgentData.SessionID != SessionId ||
8538 Purge.AgentData.AgentID != AgentId)
8539 return true;
8540 }
8541 #endregion
8542
8543 PurgeInventoryDescendents handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents;
8544 if (handlerPurgeInventoryDescendents != null)
8545 {
8546 handlerPurgeInventoryDescendents(this, Purge.InventoryData.FolderID);
8547 }
8548 return true;
8549 }
8550
8551 private bool HandleUpdateInventoryItem(IClientAPI sender, Packet Pack)
8552 {
8553 UpdateInventoryItemPacket inventoryItemUpdate = (UpdateInventoryItemPacket)Pack;
8554
8555 #region Packet Session and User Check
8556 if (m_checkPackets)
8557 {
8558 if (inventoryItemUpdate.AgentData.SessionID != SessionId ||
8559 inventoryItemUpdate.AgentData.AgentID != AgentId)
8560 return true;
8561 }
8562 #endregion
8563
8564 if (OnUpdateInventoryItem != null)
8565 {
8566 UpdateInventoryItem handlerUpdateInventoryItem = null;
8567 for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++)
8568 {
8569 handlerUpdateInventoryItem = OnUpdateInventoryItem;
8570
8571 if (handlerUpdateInventoryItem != null)
8572 {
8573 InventoryItemBase itemUpd = new InventoryItemBase();
8574 itemUpd.ID = inventoryItemUpdate.InventoryData[i].ItemID;
8575 itemUpd.Name = Util.FieldToString(inventoryItemUpdate.InventoryData[i].Name);
8576 itemUpd.Description = Util.FieldToString(inventoryItemUpdate.InventoryData[i].Description);
8577 itemUpd.GroupID = inventoryItemUpdate.InventoryData[i].GroupID;
8578 itemUpd.GroupOwned = inventoryItemUpdate.InventoryData[i].GroupOwned;
8579 itemUpd.GroupPermissions = inventoryItemUpdate.InventoryData[i].GroupMask;
8580 itemUpd.NextPermissions = inventoryItemUpdate.InventoryData[i].NextOwnerMask;
8581 itemUpd.EveryOnePermissions = inventoryItemUpdate.InventoryData[i].EveryoneMask;
8582 itemUpd.CreationDate = inventoryItemUpdate.InventoryData[i].CreationDate;
8583 itemUpd.Folder = inventoryItemUpdate.InventoryData[i].FolderID;
8584 itemUpd.InvType = inventoryItemUpdate.InventoryData[i].InvType;
8585 itemUpd.SalePrice = inventoryItemUpdate.InventoryData[i].SalePrice;
8586 itemUpd.SaleType = inventoryItemUpdate.InventoryData[i].SaleType;
8587 itemUpd.Flags = inventoryItemUpdate.InventoryData[i].Flags;
8588
8589 OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID,
8590 inventoryItemUpdate.InventoryData[i].ItemID,
8591 itemUpd);
8592 }
8593 }
8594 }
8595 return true;
8596 }
8597
8598 private bool HandleCopyInventoryItem(IClientAPI sender, Packet Pack)
8599 {
8600 CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket)Pack;
8601
8602 #region Packet Session and User Check
8603 if (m_checkPackets)
8604 {
8605 if (copyitem.AgentData.SessionID != SessionId ||
8606 copyitem.AgentData.AgentID != AgentId)
8607 return true;
8608 }
8609 #endregion
8610
8611 CopyInventoryItem handlerCopyInventoryItem = null;
8612 if (OnCopyInventoryItem != null)
8613 {
8614 foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData)
8615 {
8616 handlerCopyInventoryItem = OnCopyInventoryItem;
8617 if (handlerCopyInventoryItem != null)
8618 {
8619 handlerCopyInventoryItem(this, datablock.CallbackID, datablock.OldAgentID,
8620 datablock.OldItemID, datablock.NewFolderID,
8621 Util.FieldToString(datablock.NewName));
8622 }
8623 }
8624 }
8625 return true;
8626 }
8627
8628 private bool HandleMoveInventoryItem(IClientAPI sender, Packet Pack)
8629 {
8630 MoveInventoryItemPacket moveitem = (MoveInventoryItemPacket)Pack;
8631
8632 #region Packet Session and User Check
8633 if (m_checkPackets)
8634 {
8635 if (moveitem.AgentData.SessionID != SessionId ||
8636 moveitem.AgentData.AgentID != AgentId)
8637 return true;
8638 }
8639 #endregion
8640
8641 if (OnMoveInventoryItem != null)
8642 {
8643 MoveInventoryItem handlerMoveInventoryItem = null;
8644 InventoryItemBase itm = null;
8645 List<InventoryItemBase> items = new List<InventoryItemBase>();
8646 foreach (MoveInventoryItemPacket.InventoryDataBlock datablock in moveitem.InventoryData)
8647 {
8648 itm = new InventoryItemBase(datablock.ItemID, AgentId);
8649 itm.Folder = datablock.FolderID;
8650 itm.Name = Util.FieldToString(datablock.NewName);
8651 // weird, comes out as empty string
8652 //m_log.DebugFormat("[XXX] new name: {0}", itm.Name);
8653 items.Add(itm);
8654 }
8655 handlerMoveInventoryItem = OnMoveInventoryItem;
8656 if (handlerMoveInventoryItem != null)
8657 {
8658 handlerMoveInventoryItem(this, items);
8659 }
8660 }
8661 return true;
8662 }
8663
8664 private bool HandleRemoveInventoryItem(IClientAPI sender, Packet Pack)
8665 {
8666 RemoveInventoryItemPacket removeItem = (RemoveInventoryItemPacket)Pack;
8667
8668 #region Packet Session and User Check
8669 if (m_checkPackets)
8670 {
8671 if (removeItem.AgentData.SessionID != SessionId ||
8672 removeItem.AgentData.AgentID != AgentId)
8673 return true;
8674 }
8675 #endregion
8676
8677 if (OnRemoveInventoryItem != null)
8678 {
8679 RemoveInventoryItem handlerRemoveInventoryItem = null;
8680 List<UUID> uuids = new List<UUID>();
8681 foreach (RemoveInventoryItemPacket.InventoryDataBlock datablock in removeItem.InventoryData)
8682 {
8683 uuids.Add(datablock.ItemID);
8684 }
8685 handlerRemoveInventoryItem = OnRemoveInventoryItem;
8686 if (handlerRemoveInventoryItem != null)
8687 {
8688 handlerRemoveInventoryItem(this, uuids);
8689 }
8690
8691 }
8692 return true;
8693 }
8694
8695 private bool HandleRemoveInventoryFolder(IClientAPI sender, Packet Pack)
8696 {
8697 RemoveInventoryFolderPacket removeFolder = (RemoveInventoryFolderPacket)Pack;
8698
8699 #region Packet Session and User Check
8700 if (m_checkPackets)
8701 {
8702 if (removeFolder.AgentData.SessionID != SessionId ||
8703 removeFolder.AgentData.AgentID != AgentId)
8704 return true;
8705 }
8706 #endregion
8707
8708 if (OnRemoveInventoryFolder != null)
8709 {
8710 RemoveInventoryFolder handlerRemoveInventoryFolder = null;
8711 List<UUID> uuids = new List<UUID>();
8712 foreach (RemoveInventoryFolderPacket.FolderDataBlock datablock in removeFolder.FolderData)
8713 {
8714 uuids.Add(datablock.FolderID);
8715 }
8716 handlerRemoveInventoryFolder = OnRemoveInventoryFolder;
8717 if (handlerRemoveInventoryFolder != null)
8718 {
8719 handlerRemoveInventoryFolder(this, uuids);
8720 }
8721 }
8722 return true;
8723 }
8724
8725 private bool HandleRemoveInventoryObjects(IClientAPI sender, Packet Pack)
8726 {
8727 RemoveInventoryObjectsPacket removeObject = (RemoveInventoryObjectsPacket)Pack;
8728 #region Packet Session and User Check
8729 if (m_checkPackets)
8730 {
8731 if (removeObject.AgentData.SessionID != SessionId ||
8732 removeObject.AgentData.AgentID != AgentId)
8733 return true;
8734 }
8735 #endregion
8736 if (OnRemoveInventoryFolder != null)
8737 {
8738 RemoveInventoryFolder handlerRemoveInventoryFolder = null;
8739 List<UUID> uuids = new List<UUID>();
8740 foreach (RemoveInventoryObjectsPacket.FolderDataBlock datablock in removeObject.FolderData)
8741 {
8742 uuids.Add(datablock.FolderID);
8743 }
8744 handlerRemoveInventoryFolder = OnRemoveInventoryFolder;
8745 if (handlerRemoveInventoryFolder != null)
8746 {
8747 handlerRemoveInventoryFolder(this, uuids);
8748 }
8749 }
8750
8751 if (OnRemoveInventoryItem != null)
8752 {
8753 RemoveInventoryItem handlerRemoveInventoryItem = null;
8754 List<UUID> uuids = new List<UUID>();
8755 foreach (RemoveInventoryObjectsPacket.ItemDataBlock datablock in removeObject.ItemData)
8756 {
8757 uuids.Add(datablock.ItemID);
8758 }
8759 handlerRemoveInventoryItem = OnRemoveInventoryItem;
8760 if (handlerRemoveInventoryItem != null)
8761 {
8762 handlerRemoveInventoryItem(this, uuids);
8763 }
8764 }
8765 return true;
8766 }
8767
8768 private bool HandleRequestTaskInventory(IClientAPI sender, Packet Pack)
8769 {
8770 RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack;
8771
8772 #region Packet Session and User Check
8773 if (m_checkPackets)
8774 {
8775 if (requesttask.AgentData.SessionID != SessionId ||
8776 requesttask.AgentData.AgentID != AgentId)
8777 return true;
8778 }
8779 #endregion
8780
8781 RequestTaskInventory handlerRequestTaskInventory = OnRequestTaskInventory;
8782 if (handlerRequestTaskInventory != null)
8783 {
8784 handlerRequestTaskInventory(this, requesttask.InventoryData.LocalID);
8785 }
8786 return true;
8787 }
8788
8789 private bool HandleUpdateTaskInventory(IClientAPI sender, Packet Pack)
8790 {
8791 UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack;
8792
8793 #region Packet Session and User Check
8794 if (m_checkPackets)
8795 {
8796 if (updatetask.AgentData.SessionID != SessionId ||
8797 updatetask.AgentData.AgentID != AgentId)
8798 return true;
8799 }
8800 #endregion
8801
8802 if (OnUpdateTaskInventory != null)
8803 {
8804 if (updatetask.UpdateData.Key == 0)
8805 {
8806 UpdateTaskInventory handlerUpdateTaskInventory = OnUpdateTaskInventory;
8807 if (handlerUpdateTaskInventory != null)
8808 {
8809 TaskInventoryItem newTaskItem = new TaskInventoryItem();
8810 newTaskItem.ItemID = updatetask.InventoryData.ItemID;
8811 newTaskItem.ParentID = updatetask.InventoryData.FolderID;
8812 newTaskItem.CreatorID = updatetask.InventoryData.CreatorID;
8813 newTaskItem.OwnerID = updatetask.InventoryData.OwnerID;
8814 newTaskItem.GroupID = updatetask.InventoryData.GroupID;
8815 newTaskItem.BasePermissions = updatetask.InventoryData.BaseMask;
8816 newTaskItem.CurrentPermissions = updatetask.InventoryData.OwnerMask;
8817 newTaskItem.GroupPermissions = updatetask.InventoryData.GroupMask;
8818 newTaskItem.EveryonePermissions = updatetask.InventoryData.EveryoneMask;
8819 newTaskItem.NextPermissions = updatetask.InventoryData.NextOwnerMask;
8820
8821 // Unused? Clicking share with group sets GroupPermissions instead, so perhaps this is something
8822 // different
8823 //newTaskItem.GroupOwned=updatetask.InventoryData.GroupOwned;
8824 newTaskItem.Type = updatetask.InventoryData.Type;
8825 newTaskItem.InvType = updatetask.InventoryData.InvType;
8826 newTaskItem.Flags = updatetask.InventoryData.Flags;
8827 //newTaskItem.SaleType=updatetask.InventoryData.SaleType;
8828 //newTaskItem.SalePrice=updatetask.InventoryData.SalePrice;
8829 newTaskItem.Name = Util.FieldToString(updatetask.InventoryData.Name);
8830 newTaskItem.Description = Util.FieldToString(updatetask.InventoryData.Description);
8831 newTaskItem.CreationDate = (uint)updatetask.InventoryData.CreationDate;
8832 handlerUpdateTaskInventory(this, updatetask.InventoryData.TransactionID,
8833 newTaskItem, updatetask.UpdateData.LocalID);
8834 }
8835 }
8836 }
8837
8838 return true;
8839 }
8840
8841 private bool HandleRemoveTaskInventory(IClientAPI sender, Packet Pack)
8842 {
8843 RemoveTaskInventoryPacket removeTask = (RemoveTaskInventoryPacket)Pack;
8844
8845 #region Packet Session and User Check
8846 if (m_checkPackets)
8847 {
8848 if (removeTask.AgentData.SessionID != SessionId ||
8849 removeTask.AgentData.AgentID != AgentId)
8850 return true;
8851 }
8852 #endregion
8853
8854 RemoveTaskInventory handlerRemoveTaskItem = OnRemoveTaskItem;
8855
8856 if (handlerRemoveTaskItem != null)
8857 {
8858 handlerRemoveTaskItem(this, removeTask.InventoryData.ItemID, removeTask.InventoryData.LocalID);
8859 }
8860
8861 return true;
8862 }
8863
8864 private bool HandleMoveTaskInventory(IClientAPI sender, Packet Pack)
8865 {
8866 MoveTaskInventoryPacket moveTaskInventoryPacket = (MoveTaskInventoryPacket)Pack;
8867
8868 #region Packet Session and User Check
8869 if (m_checkPackets)
8870 {
8871 if (moveTaskInventoryPacket.AgentData.SessionID != SessionId ||
8872 moveTaskInventoryPacket.AgentData.AgentID != AgentId)
8873 return true;
8874 }
8875 #endregion
8876
8877 MoveTaskInventory handlerMoveTaskItem = OnMoveTaskItem;
8878
8879 if (handlerMoveTaskItem != null)
8880 {
8881 handlerMoveTaskItem(
8882 this, moveTaskInventoryPacket.AgentData.FolderID,
8883 moveTaskInventoryPacket.InventoryData.LocalID,
8884 moveTaskInventoryPacket.InventoryData.ItemID);
8885 }
8886
8887 return true;
8888 }
8889
8890 private bool HandleRezScript(IClientAPI sender, Packet Pack)
8891 {
8892 //m_log.Debug(Pack.ToString());
8893 RezScriptPacket rezScriptx = (RezScriptPacket)Pack;
8894
8895 #region Packet Session and User Check
8896 if (m_checkPackets)
8897 {
8898 if (rezScriptx.AgentData.SessionID != SessionId ||
8899 rezScriptx.AgentData.AgentID != AgentId)
8900 return true;
8901 }
8902 #endregion
8903
8904 RezScript handlerRezScript = OnRezScript;
8905 InventoryItemBase item = new InventoryItemBase();
8906 item.ID = rezScriptx.InventoryBlock.ItemID;
8907 item.Folder = rezScriptx.InventoryBlock.FolderID;
8908 item.CreatorId = rezScriptx.InventoryBlock.CreatorID.ToString();
8909 item.Owner = rezScriptx.InventoryBlock.OwnerID;
8910 item.BasePermissions = rezScriptx.InventoryBlock.BaseMask;
8911 item.CurrentPermissions = rezScriptx.InventoryBlock.OwnerMask;
8912 item.EveryOnePermissions = rezScriptx.InventoryBlock.EveryoneMask;
8913 item.NextPermissions = rezScriptx.InventoryBlock.NextOwnerMask;
8914 item.GroupPermissions = rezScriptx.InventoryBlock.GroupMask;
8915 item.GroupOwned = rezScriptx.InventoryBlock.GroupOwned;
8916 item.GroupID = rezScriptx.InventoryBlock.GroupID;
8917 item.AssetType = rezScriptx.InventoryBlock.Type;
8918 item.InvType = rezScriptx.InventoryBlock.InvType;
8919 item.Flags = rezScriptx.InventoryBlock.Flags;
8920 item.SaleType = rezScriptx.InventoryBlock.SaleType;
8921 item.SalePrice = rezScriptx.InventoryBlock.SalePrice;
8922 item.Name = Util.FieldToString(rezScriptx.InventoryBlock.Name);
8923 item.Description = Util.FieldToString(rezScriptx.InventoryBlock.Description);
8924 item.CreationDate = rezScriptx.InventoryBlock.CreationDate;
8925
8926 if (handlerRezScript != null)
8927 {
8928 handlerRezScript(this, item, rezScriptx.InventoryBlock.TransactionID, rezScriptx.UpdateBlock.ObjectLocalID);
8929 }
8930 return true;
8931 }
8932
8933 private bool HandleMapLayerRequest(IClientAPI sender, Packet Pack)
8934 {
8935 RequestMapLayer();
8936 return true;
8937 }
8938
8939 private bool HandleMapBlockRequest(IClientAPI sender, Packet Pack)
8940 {
8941 MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack;
8942
8943 #region Packet Session and User Check
8944 if (m_checkPackets)
8945 {
8946 if (MapRequest.AgentData.SessionID != SessionId ||
8947 MapRequest.AgentData.AgentID != AgentId)
8948 return true;
8949 }
8950 #endregion
8951
8952 RequestMapBlocks handlerRequestMapBlocks = OnRequestMapBlocks;
8953 if (handlerRequestMapBlocks != null)
8954 {
8955 handlerRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY,
8956 MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY, MapRequest.AgentData.Flags);
8957 }
8958 return true;
8959 }
8960
8961 private bool HandleMapNameRequest(IClientAPI sender, Packet Pack)
8962 {
8963 MapNameRequestPacket map = (MapNameRequestPacket)Pack;
8964
8965 #region Packet Session and User Check
8966 if (m_checkPackets)
8967 {
8968 if (map.AgentData.SessionID != SessionId ||
8969 map.AgentData.AgentID != AgentId)
8970 return true;
8971 }
8972 #endregion
8973 string mapName = Util.UTF8.GetString(map.NameData.Name, 0,
8974 map.NameData.Name.Length - 1);
8975 RequestMapName handlerMapNameRequest = OnMapNameRequest;
8976 if (handlerMapNameRequest != null)
8977 {
8978 handlerMapNameRequest(this, mapName, map.AgentData.Flags);
8979 }
8980 return true;
8981 }
8982
8983 private bool HandleTeleportLandmarkRequest(IClientAPI sender, Packet Pack)
8984 {
8985 TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack;
8986
8987 #region Packet Session and User Check
8988 if (m_checkPackets)
8989 {
8990 if (tpReq.Info.SessionID != SessionId ||
8991 tpReq.Info.AgentID != AgentId)
8992 return true;
8993 }
8994 #endregion
8995
8996 UUID lmid = tpReq.Info.LandmarkID;
8997 AssetLandmark lm;
8998 if (lmid != UUID.Zero)
8999 {
9000
9001 //AssetBase lma = m_assetCache.GetAsset(lmid, false);
9002 AssetBase lma = m_assetService.Get(lmid.ToString());
9003
9004 if (lma == null)
9005 {
9006 // Failed to find landmark
9007
9008 // Let's try to search in the user's home asset server
9009 lma = FindAssetInUserAssetServer(lmid.ToString());
9010
9011 if (lma == null)
9012 {
9013 // Really doesn't exist
9014 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
9015 tpCancel.Info.SessionID = tpReq.Info.SessionID;
9016 tpCancel.Info.AgentID = tpReq.Info.AgentID;
9017 OutPacket(tpCancel, ThrottleOutPacketType.Task);
9018 }
9019 }
9020
9021 try
9022 {
9023 lm = new AssetLandmark(lma);
9024 }
9025 catch (NullReferenceException)
9026 {
9027 // asset not found generates null ref inside the assetlandmark constructor.
9028 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
9029 tpCancel.Info.SessionID = tpReq.Info.SessionID;
9030 tpCancel.Info.AgentID = tpReq.Info.AgentID;
9031 OutPacket(tpCancel, ThrottleOutPacketType.Task);
9032 return true;
9033 }
9034 }
9035 else
9036 {
9037 // Teleport home request
9038 UUIDNameRequest handlerTeleportHomeRequest = OnTeleportHomeRequest;
9039 if (handlerTeleportHomeRequest != null)
9040 {
9041 handlerTeleportHomeRequest(AgentId, this);
9042 }
9043 return true;
9044 }
9045
9046 TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
9047 if (handlerTeleportLandmarkRequest != null)
9048 {
9049 handlerTeleportLandmarkRequest(this, lm);
9050 }
9051 else
9052 {
9053 //no event handler so cancel request
9054 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
9055 tpCancel.Info.AgentID = tpReq.Info.AgentID;
9056 tpCancel.Info.SessionID = tpReq.Info.SessionID;
9057 OutPacket(tpCancel, ThrottleOutPacketType.Task);
9058
9059 }
9060 return true;
9061 }
9062
9063 private bool HandleTeleportCancel(IClientAPI sender, Packet Pack)
9064 {
9065 TeleportCancel handlerTeleportCancel = OnTeleportCancel;
9066 if (handlerTeleportCancel != null)
9067 {
9068 handlerTeleportCancel(this);
9069 }
9070 return true;
9071 }
9072
9073 private AssetBase FindAssetInUserAssetServer(string id)
9074 {
9075 AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
9076 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
9077 {
9078 string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
9079 if (!string.IsNullOrEmpty(assetServer))
9080 return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
9081 }
9082
9083 return null;
9084 }
9085
9086 private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
9087 {
9088 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
9089 // m_log.Debug(tpLocReq.ToString());
9090
9091 #region Packet Session and User Check
9092 if (m_checkPackets)
9093 {
9094 if (tpLocReq.AgentData.SessionID != SessionId ||
9095 tpLocReq.AgentData.AgentID != AgentId)
9096 return true;
9097 }
9098 #endregion
9099
9100 TeleportLocationRequest handlerTeleportLocationRequest = OnTeleportLocationRequest;
9101 if (handlerTeleportLocationRequest != null)
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
9116 handlerTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position,
9117 tpLocReq.Info.LookAt, 16);
9118 }
9119 else
9120 {
9121 //no event handler so cancel request
9122 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
9123 tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID;
9124 tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID;
9125 OutPacket(tpCancel, ThrottleOutPacketType.Task);
9126 }
9127 return true;
9128 }
9129
9130 #endregion Inventory/Asset/Other related packets
9131
9132 private bool HandleUUIDNameRequest(IClientAPI sender, Packet Pack)
9133 {
9134 UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack;
9135
9136 foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock)
9137 {
9138 UUIDNameRequest handlerNameRequest = OnNameFromUUIDRequest;
9139 if (handlerNameRequest != null)
9140 {
9141 handlerNameRequest(UUIDBlock.ID, this);
9142 }
9143 }
9144 return true;
9145 }
9146
9147 #region Parcel related packets
9148
9149 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
9150 {
9151 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
9152
9153 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
9154 if (handlerRegionHandleRequest != null)
9155 {
9156 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID);
9157 }
9158 return true;
9159 }
9160
9161 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
9162 {
9163 ParcelInfoRequestPacket pirPack = (ParcelInfoRequestPacket)Pack;
9164
9165 #region Packet Session and User Check
9166 if (m_checkPackets)
9167 {
9168 if (pirPack.AgentData.SessionID != SessionId ||
9169 pirPack.AgentData.AgentID != AgentId)
9170 return true;
9171 }
9172 #endregion
9173
9174 ParcelInfoRequest handlerParcelInfoRequest = OnParcelInfoRequest;
9175 if (handlerParcelInfoRequest != null)
9176 {
9177 handlerParcelInfoRequest(this, pirPack.Data.ParcelID);
9178 }
9179 return true;
9180 }
9181
9182 private bool HandleParcelAccessListRequest(IClientAPI sender, Packet Pack)
9183 {
9184 ParcelAccessListRequestPacket requestPacket = (ParcelAccessListRequestPacket)Pack;
9185
9186 #region Packet Session and User Check
9187 if (m_checkPackets)
9188 {
9189 if (requestPacket.AgentData.SessionID != SessionId ||
9190 requestPacket.AgentData.AgentID != AgentId)
9191 return true;
9192 }
9193 #endregion
9194
9195 ParcelAccessListRequest handlerParcelAccessListRequest = OnParcelAccessListRequest;
9196
9197 if (handlerParcelAccessListRequest != null)
9198 {
9199 handlerParcelAccessListRequest(requestPacket.AgentData.AgentID, requestPacket.AgentData.SessionID,
9200 requestPacket.Data.Flags, requestPacket.Data.SequenceID,
9201 requestPacket.Data.LocalID, this);
9202 }
9203 return true;
9204 }
9205
9206 private bool HandleParcelAccessListUpdate(IClientAPI sender, Packet Pack)
9207 {
9208 ParcelAccessListUpdatePacket updatePacket = (ParcelAccessListUpdatePacket)Pack;
9209
9210 #region Packet Session and User Check
9211 if (m_checkPackets)
9212 {
9213 if (updatePacket.AgentData.SessionID != SessionId ||
9214 updatePacket.AgentData.AgentID != AgentId)
9215 return true;
9216 }
9217 #endregion
9218
9219 List<LandAccessEntry> entries = new List<LandAccessEntry>();
9220 foreach (ParcelAccessListUpdatePacket.ListBlock block in updatePacket.List)
9221 {
9222 LandAccessEntry entry = new LandAccessEntry();
9223 entry.AgentID = block.ID;
9224 entry.Flags = (AccessList)block.Flags;
9225 entry.Expires = block.Time;
9226 entries.Add(entry);
9227 }
9228
9229 ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest;
9230 if (handlerParcelAccessListUpdateRequest != null)
9231 {
9232 handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID,
9233 updatePacket.Data.Flags,
9234 updatePacket.Data.LocalID,
9235 updatePacket.Data.TransactionID,
9236 updatePacket.Data.SequenceID,
9237 updatePacket.Data.Sections,
9238 entries, this);
9239 }
9240 return true;
9241 }
9242
9243 private bool HandleParcelPropertiesRequest(IClientAPI sender, Packet Pack)
9244 {
9245 ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket)Pack;
9246
9247 #region Packet Session and User Check
9248 if (m_checkPackets)
9249 {
9250 if (propertiesRequest.AgentData.SessionID != SessionId ||
9251 propertiesRequest.AgentData.AgentID != AgentId)
9252 return true;
9253 }
9254 #endregion
9255
9256 ParcelPropertiesRequest handlerParcelPropertiesRequest = OnParcelPropertiesRequest;
9257 if (handlerParcelPropertiesRequest != null)
9258 {
9259 handlerParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West),
9260 (int)Math.Round(propertiesRequest.ParcelData.South),
9261 (int)Math.Round(propertiesRequest.ParcelData.East),
9262 (int)Math.Round(propertiesRequest.ParcelData.North),
9263 propertiesRequest.ParcelData.SequenceID,
9264 propertiesRequest.ParcelData.SnapSelection, this);
9265 }
9266 return true;
9267 }
9268
9269 private bool HandleParcelDivide(IClientAPI sender, Packet Pack)
9270 {
9271 ParcelDividePacket landDivide = (ParcelDividePacket)Pack;
9272
9273 #region Packet Session and User Check
9274 if (m_checkPackets)
9275 {
9276 if (landDivide.AgentData.SessionID != SessionId ||
9277 landDivide.AgentData.AgentID != AgentId)
9278 return true;
9279 }
9280 #endregion
9281
9282 ParcelDivideRequest handlerParcelDivideRequest = OnParcelDivideRequest;
9283 if (handlerParcelDivideRequest != null)
9284 {
9285 handlerParcelDivideRequest((int)Math.Round(landDivide.ParcelData.West),
9286 (int)Math.Round(landDivide.ParcelData.South),
9287 (int)Math.Round(landDivide.ParcelData.East),
9288 (int)Math.Round(landDivide.ParcelData.North), this);
9289 }
9290 return true;
9291 }
9292
9293 private bool HandleParcelJoin(IClientAPI sender, Packet Pack)
9294 {
9295 ParcelJoinPacket landJoin = (ParcelJoinPacket)Pack;
9296
9297 #region Packet Session and User Check
9298 if (m_checkPackets)
9299 {
9300 if (landJoin.AgentData.SessionID != SessionId ||
9301 landJoin.AgentData.AgentID != AgentId)
9302 return true;
9303 }
9304 #endregion
9305
9306 ParcelJoinRequest handlerParcelJoinRequest = OnParcelJoinRequest;
9307
9308 if (handlerParcelJoinRequest != null)
9309 {
9310 handlerParcelJoinRequest((int)Math.Round(landJoin.ParcelData.West),
9311 (int)Math.Round(landJoin.ParcelData.South),
9312 (int)Math.Round(landJoin.ParcelData.East),
9313 (int)Math.Round(landJoin.ParcelData.North), this);
9314 }
9315 return true;
9316 }
9317
9318 private bool HandleParcelPropertiesUpdate(IClientAPI sender, Packet Pack)
9319 {
9320 ParcelPropertiesUpdatePacket parcelPropertiesPacket = (ParcelPropertiesUpdatePacket)Pack;
9321
9322 #region Packet Session and User Check
9323 if (m_checkPackets)
9324 {
9325 if (parcelPropertiesPacket.AgentData.SessionID != SessionId ||
9326 parcelPropertiesPacket.AgentData.AgentID != AgentId)
9327 return true;
9328 }
9329 #endregion
9330
9331 ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest;
9332
9333 if (handlerParcelPropertiesUpdateRequest != null)
9334 {
9335 LandUpdateArgs args = new LandUpdateArgs();
9336
9337 args.AuthBuyerID = parcelPropertiesPacket.ParcelData.AuthBuyerID;
9338 args.Category = (ParcelCategory)parcelPropertiesPacket.ParcelData.Category;
9339 args.Desc = Utils.BytesToString(parcelPropertiesPacket.ParcelData.Desc);
9340 args.GroupID = parcelPropertiesPacket.ParcelData.GroupID;
9341 args.LandingType = parcelPropertiesPacket.ParcelData.LandingType;
9342 args.MediaAutoScale = parcelPropertiesPacket.ParcelData.MediaAutoScale;
9343 args.MediaID = parcelPropertiesPacket.ParcelData.MediaID;
9344 args.MediaURL = Utils.BytesToString(parcelPropertiesPacket.ParcelData.MediaURL);
9345 args.MusicURL = Utils.BytesToString(parcelPropertiesPacket.ParcelData.MusicURL);
9346 args.Name = Utils.BytesToString(parcelPropertiesPacket.ParcelData.Name);
9347 args.ParcelFlags = parcelPropertiesPacket.ParcelData.ParcelFlags;
9348 args.PassHours = parcelPropertiesPacket.ParcelData.PassHours;
9349 args.PassPrice = parcelPropertiesPacket.ParcelData.PassPrice;
9350 args.SalePrice = parcelPropertiesPacket.ParcelData.SalePrice;
9351 args.SnapshotID = parcelPropertiesPacket.ParcelData.SnapshotID;
9352 args.UserLocation = parcelPropertiesPacket.ParcelData.UserLocation;
9353 args.UserLookAt = parcelPropertiesPacket.ParcelData.UserLookAt;
9354 handlerParcelPropertiesUpdateRequest(args, parcelPropertiesPacket.ParcelData.LocalID, this);
9355 }
9356 return true;
9357 }
9358
9359 private bool HandleParcelSelectObjects(IClientAPI sender, Packet Pack)
9360 {
9361 ParcelSelectObjectsPacket selectPacket = (ParcelSelectObjectsPacket)Pack;
9362
9363 #region Packet Session and User Check
9364 if (m_checkPackets)
9365 {
9366 if (selectPacket.AgentData.SessionID != SessionId ||
9367 selectPacket.AgentData.AgentID != AgentId)
9368 return true;
9369 }
9370 #endregion
9371
9372 List<UUID> returnIDs = new List<UUID>();
9373
9374 foreach (ParcelSelectObjectsPacket.ReturnIDsBlock rb in
9375 selectPacket.ReturnIDs)
9376 {
9377 returnIDs.Add(rb.ReturnID);
9378 }
9379
9380 ParcelSelectObjects handlerParcelSelectObjects = OnParcelSelectObjects;
9381
9382 if (handlerParcelSelectObjects != null)
9383 {
9384 handlerParcelSelectObjects(selectPacket.ParcelData.LocalID,
9385 Convert.ToInt32(selectPacket.ParcelData.ReturnType), returnIDs, this);
9386 }
9387 return true;
9388 }
9389
9390 private bool HandleParcelObjectOwnersRequest(IClientAPI sender, Packet Pack)
9391 {
9392 ParcelObjectOwnersRequestPacket reqPacket = (ParcelObjectOwnersRequestPacket)Pack;
9393
9394 #region Packet Session and User Check
9395 if (m_checkPackets)
9396 {
9397 if (reqPacket.AgentData.SessionID != SessionId ||
9398 reqPacket.AgentData.AgentID != AgentId)
9399 return true;
9400 }
9401 #endregion
9402
9403 ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest;
9404
9405 if (handlerParcelObjectOwnerRequest != null)
9406 {
9407 handlerParcelObjectOwnerRequest(reqPacket.ParcelData.LocalID, this);
9408 }
9409 return true;
9410
9411 }
9412
9413 private bool HandleParcelGodForceOwner(IClientAPI sender, Packet Pack)
9414 {
9415 ParcelGodForceOwnerPacket godForceOwnerPacket = (ParcelGodForceOwnerPacket)Pack;
9416
9417 #region Packet Session and User Check
9418 if (m_checkPackets)
9419 {
9420 if (godForceOwnerPacket.AgentData.SessionID != SessionId ||
9421 godForceOwnerPacket.AgentData.AgentID != AgentId)
9422 return true;
9423 }
9424 #endregion
9425
9426 ParcelGodForceOwner handlerParcelGodForceOwner = OnParcelGodForceOwner;
9427 if (handlerParcelGodForceOwner != null)
9428 {
9429 handlerParcelGodForceOwner(godForceOwnerPacket.Data.LocalID, godForceOwnerPacket.Data.OwnerID, this);
9430 }
9431 return true;
9432 }
9433
9434 private bool HandleParcelRelease(IClientAPI sender, Packet Pack)
9435 {
9436 ParcelReleasePacket releasePacket = (ParcelReleasePacket)Pack;
9437
9438 #region Packet Session and User Check
9439 if (m_checkPackets)
9440 {
9441 if (releasePacket.AgentData.SessionID != SessionId ||
9442 releasePacket.AgentData.AgentID != AgentId)
9443 return true;
9444 }
9445 #endregion
9446
9447 ParcelAbandonRequest handlerParcelAbandonRequest = OnParcelAbandonRequest;
9448 if (handlerParcelAbandonRequest != null)
9449 {
9450 handlerParcelAbandonRequest(releasePacket.Data.LocalID, this);
9451 }
9452 return true;
9453 }
9454
9455 private bool HandleParcelReclaim(IClientAPI sender, Packet Pack)
9456 {
9457 ParcelReclaimPacket reclaimPacket = (ParcelReclaimPacket)Pack;
9458
9459 #region Packet Session and User Check
9460 if (m_checkPackets)
9461 {
9462 if (reclaimPacket.AgentData.SessionID != SessionId ||
9463 reclaimPacket.AgentData.AgentID != AgentId)
9464 return true;
9465 }
9466 #endregion
9467
9468 ParcelReclaim handlerParcelReclaim = OnParcelReclaim;
9469 if (handlerParcelReclaim != null)
9470 {
9471 handlerParcelReclaim(reclaimPacket.Data.LocalID, this);
9472 }
9473 return true;
9474 }
9475
9476 private bool HandleParcelReturnObjects(IClientAPI sender, Packet Pack)
9477 {
9478 ParcelReturnObjectsPacket parcelReturnObjects = (ParcelReturnObjectsPacket)Pack;
9479
9480 #region Packet Session and User Check
9481 if (m_checkPackets)
9482 {
9483 if (parcelReturnObjects.AgentData.SessionID != SessionId ||
9484 parcelReturnObjects.AgentData.AgentID != AgentId)
9485 return true;
9486 }
9487 #endregion
9488
9489 UUID[] puserselectedOwnerIDs = new UUID[parcelReturnObjects.OwnerIDs.Length];
9490 for (int parceliterator = 0; parceliterator < parcelReturnObjects.OwnerIDs.Length; parceliterator++)
9491 puserselectedOwnerIDs[parceliterator] = parcelReturnObjects.OwnerIDs[parceliterator].OwnerID;
9492
9493 UUID[] puserselectedTaskIDs = new UUID[parcelReturnObjects.TaskIDs.Length];
9494
9495 for (int parceliterator = 0; parceliterator < parcelReturnObjects.TaskIDs.Length; parceliterator++)
9496 puserselectedTaskIDs[parceliterator] = parcelReturnObjects.TaskIDs[parceliterator].TaskID;
9497
9498 ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest;
9499 if (handlerParcelReturnObjectsRequest != null)
9500 {
9501 handlerParcelReturnObjectsRequest(parcelReturnObjects.ParcelData.LocalID, parcelReturnObjects.ParcelData.ReturnType, puserselectedOwnerIDs, puserselectedTaskIDs, this);
9502
9503 }
9504 return true;
9505 }
9506
9507 private bool HandleParcelSetOtherCleanTime(IClientAPI sender, Packet Pack)
9508 {
9509 ParcelSetOtherCleanTimePacket parcelSetOtherCleanTimePacket = (ParcelSetOtherCleanTimePacket)Pack;
9510
9511 #region Packet Session and User Check
9512 if (m_checkPackets)
9513 {
9514 if (parcelSetOtherCleanTimePacket.AgentData.SessionID != SessionId ||
9515 parcelSetOtherCleanTimePacket.AgentData.AgentID != AgentId)
9516 return true;
9517 }
9518 #endregion
9519
9520 ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime;
9521 if (handlerParcelSetOtherCleanTime != null)
9522 {
9523 handlerParcelSetOtherCleanTime(this,
9524 parcelSetOtherCleanTimePacket.ParcelData.LocalID,
9525 parcelSetOtherCleanTimePacket.ParcelData.OtherCleanTime);
9526 }
9527 return true;
9528 }
9529
9530 private bool HandleLandStatRequest(IClientAPI sender, Packet Pack)
9531 {
9532 LandStatRequestPacket lsrp = (LandStatRequestPacket)Pack;
9533
9534 #region Packet Session and User Check
9535 if (m_checkPackets)
9536 {
9537 if (lsrp.AgentData.SessionID != SessionId ||
9538 lsrp.AgentData.AgentID != AgentId)
9539 return true;
9540 }
9541 #endregion
9542
9543 GodLandStatRequest handlerLandStatRequest = OnLandStatRequest;
9544 if (handlerLandStatRequest != null)
9545 {
9546 handlerLandStatRequest(lsrp.RequestData.ParcelLocalID, lsrp.RequestData.ReportType, lsrp.RequestData.RequestFlags, Utils.BytesToString(lsrp.RequestData.Filter), this);
9547 }
9548 return true;
9549 }
9550
9551 private bool HandleParcelDwellRequest(IClientAPI sender, Packet Pack)
9552 {
9553 ParcelDwellRequestPacket dwellrq =
9554 (ParcelDwellRequestPacket)Pack;
9555
9556 #region Packet Session and User Check
9557 if (m_checkPackets)
9558 {
9559 if (dwellrq.AgentData.SessionID != SessionId ||
9560 dwellrq.AgentData.AgentID != AgentId)
9561 return true;
9562 }
9563 #endregion
9564
9565 ParcelDwellRequest handlerParcelDwellRequest = OnParcelDwellRequest;
9566 if (handlerParcelDwellRequest != null)
9567 {
9568 handlerParcelDwellRequest(dwellrq.Data.LocalID, this);
9569 }
9570 return true;
9571 }
9572
9573 #endregion Parcel related packets
9574
9575 #region Estate Packets
9576
9577 private bool HandleEstateOwnerMessage(IClientAPI sender, Packet Pack)
9578 {
9579 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack;
9580 // m_log.InfoFormat("[LLCLIENTVIEW]: Packet: {0}", Utils.BytesToString(messagePacket.MethodData.Method));
9581 GodLandStatRequest handlerLandStatRequest;
9582
9583 #region Packet Session and User Check
9584 if (m_checkPackets)
9585 {
9586 if (messagePacket.AgentData.SessionID != SessionId ||
9587 messagePacket.AgentData.AgentID != AgentId)
9588 return true;
9589 }
9590 #endregion
9591
9592 string method = Utils.BytesToString(messagePacket.MethodData.Method);
9593
9594 switch (method)
9595 {
9596 case "getinfo":
9597 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9598 {
9599 OnDetailedEstateDataRequest(this, messagePacket.MethodData.Invoice);
9600 }
9601 return true;
9602 case "setregioninfo":
9603 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9604 {
9605 OnSetEstateFlagsRequest(convertParamStringToBool(messagePacket.ParamList[0].Parameter), convertParamStringToBool(messagePacket.ParamList[1].Parameter),
9606 convertParamStringToBool(messagePacket.ParamList[2].Parameter), !convertParamStringToBool(messagePacket.ParamList[3].Parameter),
9607 Convert.ToInt16(Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[4].Parameter), Culture.NumberFormatInfo)),
9608 (float)Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[5].Parameter), Culture.NumberFormatInfo),
9609 Convert.ToInt16(Utils.BytesToString(messagePacket.ParamList[6].Parameter)),
9610 convertParamStringToBool(messagePacket.ParamList[7].Parameter), convertParamStringToBool(messagePacket.ParamList[8].Parameter));
9611 }
9612 return true;
9613 // case "texturebase":
9614 // if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9615 // {
9616 // foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
9617 // {
9618 // string s = Utils.BytesToString(block.Parameter);
9619 // string[] splitField = s.Split(' ');
9620 // if (splitField.Length == 2)
9621 // {
9622 // UUID tempUUID = new UUID(splitField[1]);
9623 // OnSetEstateTerrainBaseTexture(this, Convert.ToInt16(splitField[0]), tempUUID);
9624 // }
9625 // }
9626 // }
9627 // break;
9628 case "texturedetail":
9629 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9630 {
9631 foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
9632 {
9633 string s = Utils.BytesToString(block.Parameter);
9634 string[] splitField = s.Split(' ');
9635 if (splitField.Length == 2)
9636 {
9637 Int16 corner = Convert.ToInt16(splitField[0]);
9638 UUID textureUUID = new UUID(splitField[1]);
9639
9640 OnSetEstateTerrainDetailTexture(this, corner, textureUUID);
9641 }
9642 }
9643 }
9644
9645 return true;
9646 case "textureheights":
9647 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9648 {
9649 foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
9650 {
9651 string s = Utils.BytesToString(block.Parameter);
9652 string[] splitField = s.Split(' ');
9653 if (splitField.Length == 3)
9654 {
9655 Int16 corner = Convert.ToInt16(splitField[0]);
9656 float lowValue = (float)Convert.ToDecimal(splitField[1], Culture.NumberFormatInfo);
9657 float highValue = (float)Convert.ToDecimal(splitField[2], Culture.NumberFormatInfo);
9658
9659 OnSetEstateTerrainTextureHeights(this, corner, lowValue, highValue);
9660 }
9661 }
9662 }
9663 return true;
9664 case "texturecommit":
9665 OnCommitEstateTerrainTextureRequest(this);
9666 return true;
9667 case "setregionterrain":
9668 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9669 {
9670 if (messagePacket.ParamList.Length != 9)
9671 {
9672 m_log.Error("EstateOwnerMessage: SetRegionTerrain method has a ParamList of invalid length");
9673 }
9674 else
9675 {
9676 try
9677 {
9678 string tmp = Utils.BytesToString(messagePacket.ParamList[0].Parameter);
9679 if (!tmp.Contains(".")) tmp += ".00";
9680 float WaterHeight = (float)Convert.ToDecimal(tmp, Culture.NumberFormatInfo);
9681 tmp = Utils.BytesToString(messagePacket.ParamList[1].Parameter);
9682 if (!tmp.Contains(".")) tmp += ".00";
9683 float TerrainRaiseLimit = (float)Convert.ToDecimal(tmp, Culture.NumberFormatInfo);
9684 tmp = Utils.BytesToString(messagePacket.ParamList[2].Parameter);
9685 if (!tmp.Contains(".")) tmp += ".00";
9686 float TerrainLowerLimit = (float)Convert.ToDecimal(tmp, Culture.NumberFormatInfo);
9687 bool UseEstateSun = convertParamStringToBool(messagePacket.ParamList[3].Parameter);
9688 bool UseFixedSun = convertParamStringToBool(messagePacket.ParamList[4].Parameter);
9689 float SunHour = (float)Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[5].Parameter), Culture.NumberFormatInfo);
9690 bool UseGlobal = convertParamStringToBool(messagePacket.ParamList[6].Parameter);
9691 bool EstateFixedSun = convertParamStringToBool(messagePacket.ParamList[7].Parameter);
9692 float EstateSunHour = (float)Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[8].Parameter), Culture.NumberFormatInfo);
9693
9694 OnSetRegionTerrainSettings(WaterHeight, TerrainRaiseLimit, TerrainLowerLimit, UseEstateSun, UseFixedSun, SunHour, UseGlobal, EstateFixedSun, EstateSunHour);
9695
9696 }
9697 catch (Exception ex)
9698 {
9699 m_log.Error("EstateOwnerMessage: Exception while setting terrain settings: \n" + messagePacket + "\n" + ex);
9700 }
9701 }
9702 }
9703
9704 return true;
9705 case "restart":
9706 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9707 {
9708 // There's only 1 block in the estateResetSim.. and that's the number of seconds till restart.
9709 foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
9710 {
9711 float timeSeconds;
9712 Utils.TryParseSingle(Utils.BytesToString(block.Parameter), out timeSeconds);
9713 timeSeconds = (int)timeSeconds;
9714 OnEstateRestartSimRequest(this, (int)timeSeconds);
9715
9716 }
9717 }
9718 return true;
9719 case "estatechangecovenantid":
9720 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9721 {
9722 foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
9723 {
9724 UUID newCovenantID = new UUID(Utils.BytesToString(block.Parameter));
9725 OnEstateChangeCovenantRequest(this, newCovenantID);
9726 }
9727 }
9728 return true;
9729 case "estateaccessdelta": // Estate access delta manages the banlist and allow list too.
9730 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9731 {
9732 int estateAccessType = Convert.ToInt16(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9733 OnUpdateEstateAccessDeltaRequest(this, messagePacket.MethodData.Invoice, estateAccessType, new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter)));
9734
9735 }
9736 return true;
9737 case "simulatormessage":
9738 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9739 {
9740 UUID invoice = messagePacket.MethodData.Invoice;
9741 UUID SenderID = new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter));
9742 string SenderName = Utils.BytesToString(messagePacket.ParamList[3].Parameter);
9743 string Message = Utils.BytesToString(messagePacket.ParamList[4].Parameter);
9744 UUID sessionID = messagePacket.AgentData.SessionID;
9745 OnSimulatorBlueBoxMessageRequest(this, invoice, SenderID, sessionID, SenderName, Message);
9746 }
9747 return true;
9748 case "instantmessage":
9749 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9750 {
9751 if (messagePacket.ParamList.Length < 2)
9752 return true;
9753
9754 UUID invoice = messagePacket.MethodData.Invoice;
9755 UUID sessionID = messagePacket.AgentData.SessionID;
9756
9757 UUID SenderID;
9758 string SenderName;
9759 string Message;
9760
9761 if (messagePacket.ParamList.Length < 5)
9762 {
9763 SenderID = AgentId;
9764 SenderName = Utils.BytesToString(messagePacket.ParamList[0].Parameter);
9765 Message = Utils.BytesToString(messagePacket.ParamList[1].Parameter);
9766 }
9767 else
9768 {
9769 SenderID = new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter));
9770 SenderName = Utils.BytesToString(messagePacket.ParamList[3].Parameter);
9771 Message = Utils.BytesToString(messagePacket.ParamList[4].Parameter);
9772 }
9773
9774 OnEstateBlueBoxMessageRequest(this, invoice, SenderID, sessionID, SenderName, Message);
9775 }
9776 return true;
9777 case "setregiondebug":
9778 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9779 {
9780 UUID invoice = messagePacket.MethodData.Invoice;
9781 UUID SenderID = messagePacket.AgentData.AgentID;
9782 bool scripted = convertParamStringToBool(messagePacket.ParamList[0].Parameter);
9783 bool collisionEvents = convertParamStringToBool(messagePacket.ParamList[1].Parameter);
9784 bool physics = convertParamStringToBool(messagePacket.ParamList[2].Parameter);
9785
9786 OnEstateDebugRegionRequest(this, invoice, SenderID, scripted, collisionEvents, physics);
9787 }
9788 return true;
9789 case "teleporthomeuser":
9790 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9791 {
9792 UUID invoice = messagePacket.MethodData.Invoice;
9793 UUID SenderID = messagePacket.AgentData.AgentID;
9794 UUID Prey;
9795
9796 UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[1].Parameter), out Prey);
9797
9798 OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey);
9799 }
9800 return true;
9801 case "teleporthomeallusers":
9802 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9803 {
9804 UUID invoice = messagePacket.MethodData.Invoice;
9805 UUID SenderID = messagePacket.AgentData.AgentID;
9806 OnEstateTeleportAllUsersHomeRequest(this, invoice, SenderID);
9807 }
9808 return true;
9809 case "colliders":
9810 handlerLandStatRequest = OnLandStatRequest;
9811 if (handlerLandStatRequest != null)
9812 {
9813 handlerLandStatRequest(0, 1, 0, "", this);
9814 }
9815 return true;
9816 case "scripts":
9817 handlerLandStatRequest = OnLandStatRequest;
9818 if (handlerLandStatRequest != null)
9819 {
9820 handlerLandStatRequest(0, 0, 0, "", this);
9821 }
9822 return true;
9823 case "terrain":
9824 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9825 {
9826 if (messagePacket.ParamList.Length > 0)
9827 {
9828 if (Utils.BytesToString(messagePacket.ParamList[0].Parameter) == "bake")
9829 {
9830 BakeTerrain handlerBakeTerrain = OnBakeTerrain;
9831 if (handlerBakeTerrain != null)
9832 {
9833 handlerBakeTerrain(this);
9834 }
9835 }
9836 if (Utils.BytesToString(messagePacket.ParamList[0].Parameter) == "download filename")
9837 {
9838 if (messagePacket.ParamList.Length > 1)
9839 {
9840 RequestTerrain handlerRequestTerrain = OnRequestTerrain;
9841 if (handlerRequestTerrain != null)
9842 {
9843 handlerRequestTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9844 }
9845 }
9846 }
9847 if (Utils.BytesToString(messagePacket.ParamList[0].Parameter) == "upload filename")
9848 {
9849 if (messagePacket.ParamList.Length > 1)
9850 {
9851 RequestTerrain handlerUploadTerrain = OnUploadTerrain;
9852 if (handlerUploadTerrain != null)
9853 {
9854 handlerUploadTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9855 }
9856 }
9857 }
9858
9859 }
9860
9861
9862 }
9863 return true;
9864
9865 case "estatechangeinfo":
9866 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9867 {
9868 UUID invoice = messagePacket.MethodData.Invoice;
9869 UUID SenderID = messagePacket.AgentData.AgentID;
9870 UInt32 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9871 UInt32 param2 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[2].Parameter));
9872
9873 EstateChangeInfo handlerEstateChangeInfo = OnEstateChangeInfo;
9874 if (handlerEstateChangeInfo != null)
9875 {
9876 handlerEstateChangeInfo(this, invoice, SenderID, param1, param2);
9877 }
9878 }
9879 return true;
9880
9881 case "telehub":
9882 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9883 {
9884 UUID invoice = messagePacket.MethodData.Invoice;
9885 UUID SenderID = messagePacket.AgentData.AgentID;
9886 UInt32 param1 = 0u;
9887
9888 string command = (string)Utils.BytesToString(messagePacket.ParamList[0].Parameter);
9889
9890 if (command != "info ui")
9891 {
9892 try
9893 {
9894 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9895 }
9896 catch
9897 {
9898 }
9899 }
9900
9901 EstateManageTelehub handlerEstateManageTelehub = OnEstateManageTelehub;
9902 if (handlerEstateManageTelehub != null)
9903 {
9904 handlerEstateManageTelehub(this, invoice, SenderID, command, param1);
9905 }
9906 }
9907 return true;
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
9923 default:
9924 m_log.WarnFormat(
9925 "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
9926 method, Name, Scene.Name);
9927
9928 for (int i = 0; i < messagePacket.ParamList.Length; i++)
9929 {
9930 EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
9931 string data = (string)Utils.BytesToString(block.Parameter);
9932 m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
9933 }
9934
9935 return true;
9936 }
9937
9938 //int parcelID, uint reportType, uint requestflags, string filter
9939
9940 //lsrp.RequestData.ParcelLocalID;
9941 //lsrp.RequestData.ReportType; // 1 = colliders, 0 = scripts
9942 //lsrp.RequestData.RequestFlags;
9943 //lsrp.RequestData.Filter;
9944 }
9945
9946 private bool HandleRequestRegionInfo(IClientAPI sender, Packet Pack)
9947 {
9948 RequestRegionInfoPacket.AgentDataBlock mPacket = ((RequestRegionInfoPacket)Pack).AgentData;
9949
9950 #region Packet Session and User Check
9951 if (m_checkPackets)
9952 {
9953 if (mPacket.SessionID != SessionId ||
9954 mPacket.AgentID != AgentId)
9955 return true;
9956 }
9957 #endregion
9958
9959 RegionInfoRequest handlerRegionInfoRequest = OnRegionInfoRequest;
9960 if (handlerRegionInfoRequest != null)
9961 {
9962 handlerRegionInfoRequest(this);
9963 }
9964 return true;
9965 }
9966
9967 private bool HandleEstateCovenantRequest(IClientAPI sender, Packet Pack)
9968 {
9969
9970 //EstateCovenantRequestPacket.AgentDataBlock epack =
9971 // ((EstateCovenantRequestPacket)Pack).AgentData;
9972
9973 EstateCovenantRequest handlerEstateCovenantRequest = OnEstateCovenantRequest;
9974 if (handlerEstateCovenantRequest != null)
9975 {
9976 handlerEstateCovenantRequest(this);
9977 }
9978 return true;
9979
9980 }
9981
9982 #endregion Estate Packets
9983
9984 #region GodPackets
9985
9986 private bool HandleRequestGodlikePowers(IClientAPI sender, Packet Pack)
9987 {
9988 RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack;
9989 RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock;
9990 UUID token = rblock.Token;
9991
9992 RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData;
9993
9994 RequestGodlikePowers handlerReqGodlikePowers = OnRequestGodlikePowers;
9995
9996 if (handlerReqGodlikePowers != null)
9997 {
9998 handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike, this);
9999 }
10000
10001 return true;
10002 }
10003
10004 private bool HandleGodUpdateRegionInfoUpdate(IClientAPI client, Packet Packet)
10005 {
10006 GodUpdateRegionInfoPacket GodUpdateRegionInfo =
10007 (GodUpdateRegionInfoPacket)Packet;
10008
10009 GodUpdateRegionInfoUpdate handlerGodUpdateRegionInfo = OnGodUpdateRegionInfoUpdate;
10010 if (handlerGodUpdateRegionInfo != null)
10011 {
10012 handlerGodUpdateRegionInfo(this,
10013 GodUpdateRegionInfo.RegionInfo.BillableFactor,
10014 GodUpdateRegionInfo.RegionInfo.EstateID,
10015 GodUpdateRegionInfo.RegionInfo.RegionFlags,
10016 GodUpdateRegionInfo.RegionInfo.SimName,
10017 GodUpdateRegionInfo.RegionInfo.RedirectGridX,
10018 GodUpdateRegionInfo.RegionInfo.RedirectGridY);
10019 return true;
10020 }
10021 return false;
10022 }
10023
10024 private bool HandleSimWideDeletes(IClientAPI client, Packet Packet)
10025 {
10026 SimWideDeletesPacket SimWideDeletesRequest =
10027 (SimWideDeletesPacket)Packet;
10028 SimWideDeletesDelegate handlerSimWideDeletesRequest = OnSimWideDeletes;
10029 if (handlerSimWideDeletesRequest != null)
10030 {
10031 handlerSimWideDeletesRequest(this, SimWideDeletesRequest.AgentData.AgentID,(int)SimWideDeletesRequest.DataBlock.Flags,SimWideDeletesRequest.DataBlock.TargetID);
10032 return true;
10033 }
10034 return false;
10035 }
10036
10037 private bool HandleGodlikeMessage(IClientAPI client, Packet Packet)
10038 {
10039 GodlikeMessagePacket GodlikeMessage =
10040 (GodlikeMessagePacket)Packet;
10041
10042 GodlikeMessage handlerGodlikeMessage = onGodlikeMessage;
10043 if (handlerGodlikeMessage != null)
10044 {
10045 handlerGodlikeMessage(this,
10046 GodlikeMessage.MethodData.Invoice,
10047 GodlikeMessage.MethodData.Method,
10048 GodlikeMessage.ParamList[0].Parameter);
10049 return true;
10050 }
10051 return false;
10052 }
10053
10054 private bool HandleSaveStatePacket(IClientAPI client, Packet Packet)
10055 {
10056 StateSavePacket SaveStateMessage =
10057 (StateSavePacket)Packet;
10058 SaveStateHandler handlerSaveStatePacket = OnSaveState;
10059 if (handlerSaveStatePacket != null)
10060 {
10061 handlerSaveStatePacket(this,SaveStateMessage.AgentData.AgentID);
10062 return true;
10063 }
10064 return false;
10065 }
10066
10067 private bool HandleGodKickUser(IClientAPI sender, Packet Pack)
10068 {
10069 GodKickUserPacket gkupack = (GodKickUserPacket)Pack;
10070
10071 if (gkupack.UserInfo.GodSessionID == SessionId && AgentId == gkupack.UserInfo.GodID)
10072 {
10073 GodKickUser handlerGodKickUser = OnGodKickUser;
10074 if (handlerGodKickUser != null)
10075 {
10076 handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID,
10077 gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason);
10078 }
10079 }
10080 else
10081 {
10082 SendAgentAlertMessage("Kick request denied", false);
10083 }
10084 //KickUserPacket kupack = new KickUserPacket();
10085 //KickUserPacket.UserInfoBlock kupackib = kupack.UserInfo;
10086
10087 //kupack.UserInfo.AgentID = gkupack.UserInfo.AgentID;
10088 //kupack.UserInfo.SessionID = gkupack.UserInfo.GodSessionID;
10089
10090 //kupack.TargetBlock.TargetIP = (uint)0;
10091 //kupack.TargetBlock.TargetPort = (ushort)0;
10092 //kupack.UserInfo.Reason = gkupack.UserInfo.Reason;
10093
10094 //OutPacket(kupack, ThrottleOutPacketType.Task);
10095 return true;
10096 }
10097 #endregion GodPackets
10098
10099 #region Economy/Transaction Packets
10100
10101 private bool HandleMoneyBalanceRequest(IClientAPI sender, Packet Pack)
10102 {
10103 MoneyBalanceRequestPacket moneybalancerequestpacket = (MoneyBalanceRequestPacket)Pack;
10104
10105 #region Packet Session and User Check
10106 if (m_checkPackets)
10107 {
10108 if (moneybalancerequestpacket.AgentData.SessionID != SessionId ||
10109 moneybalancerequestpacket.AgentData.AgentID != AgentId)
10110 return true;
10111 }
10112 #endregion
10113
10114 MoneyBalanceRequest handlerMoneyBalanceRequest = OnMoneyBalanceRequest;
10115
10116 if (handlerMoneyBalanceRequest != null)
10117 {
10118 handlerMoneyBalanceRequest(this, moneybalancerequestpacket.AgentData.AgentID, moneybalancerequestpacket.AgentData.SessionID, moneybalancerequestpacket.MoneyData.TransactionID);
10119 }
10120
10121 return true;
10122 }
10123 private bool HandleEconomyDataRequest(IClientAPI sender, Packet Pack)
10124 {
10125 EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest;
10126 if (handlerEconomoyDataRequest != null)
10127 {
10128 handlerEconomoyDataRequest(this);
10129 }
10130 return true;
10131 }
10132 private bool HandleRequestPayPrice(IClientAPI sender, Packet Pack)
10133 {
10134 RequestPayPricePacket requestPayPricePacket = (RequestPayPricePacket)Pack;
10135
10136 RequestPayPrice handlerRequestPayPrice = OnRequestPayPrice;
10137 if (handlerRequestPayPrice != null)
10138 {
10139 handlerRequestPayPrice(this, requestPayPricePacket.ObjectData.ObjectID);
10140 }
10141 return true;
10142 }
10143 private bool HandleObjectSaleInfo(IClientAPI sender, Packet Pack)
10144 {
10145 ObjectSaleInfoPacket objectSaleInfoPacket = (ObjectSaleInfoPacket)Pack;
10146
10147 #region Packet Session and User Check
10148 if (m_checkPackets)
10149 {
10150 if (objectSaleInfoPacket.AgentData.SessionID != SessionId ||
10151 objectSaleInfoPacket.AgentData.AgentID != AgentId)
10152 return true;
10153 }
10154 #endregion
10155
10156 ObjectSaleInfo handlerObjectSaleInfo = OnObjectSaleInfo;
10157 if (handlerObjectSaleInfo != null)
10158 {
10159 foreach (ObjectSaleInfoPacket.ObjectDataBlock d
10160 in objectSaleInfoPacket.ObjectData)
10161 {
10162 handlerObjectSaleInfo(this,
10163 objectSaleInfoPacket.AgentData.AgentID,
10164 objectSaleInfoPacket.AgentData.SessionID,
10165 d.LocalID,
10166 d.SaleType,
10167 d.SalePrice);
10168 }
10169 }
10170 return true;
10171 }
10172 private bool HandleObjectBuy(IClientAPI sender, Packet Pack)
10173 {
10174 ObjectBuyPacket objectBuyPacket = (ObjectBuyPacket)Pack;
10175
10176 #region Packet Session and User Check
10177 if (m_checkPackets)
10178 {
10179 if (objectBuyPacket.AgentData.SessionID != SessionId ||
10180 objectBuyPacket.AgentData.AgentID != AgentId)
10181 return true;
10182 }
10183 #endregion
10184
10185 ObjectBuy handlerObjectBuy = OnObjectBuy;
10186
10187 if (handlerObjectBuy != null)
10188 {
10189 foreach (ObjectBuyPacket.ObjectDataBlock d
10190 in objectBuyPacket.ObjectData)
10191 {
10192 handlerObjectBuy(this,
10193 objectBuyPacket.AgentData.AgentID,
10194 objectBuyPacket.AgentData.SessionID,
10195 objectBuyPacket.AgentData.GroupID,
10196 objectBuyPacket.AgentData.CategoryID,
10197 d.ObjectLocalID,
10198 d.SaleType,
10199 d.SalePrice);
10200 }
10201 }
10202 return true;
10203 }
10204
10205 #endregion Economy/Transaction Packets
10206
10207 #region Script Packets
10208 private bool HandleGetScriptRunning(IClientAPI sender, Packet Pack)
10209 {
10210 GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack;
10211
10212 GetScriptRunning handlerGetScriptRunning = OnGetScriptRunning;
10213 if (handlerGetScriptRunning != null)
10214 {
10215 handlerGetScriptRunning(this, scriptRunning.Script.ObjectID, scriptRunning.Script.ItemID);
10216 }
10217 return true;
10218 }
10219 private bool HandleSetScriptRunning(IClientAPI sender, Packet Pack)
10220 {
10221 SetScriptRunningPacket setScriptRunning = (SetScriptRunningPacket)Pack;
10222
10223 #region Packet Session and User Check
10224 if (m_checkPackets)
10225 {
10226 if (setScriptRunning.AgentData.SessionID != SessionId ||
10227 setScriptRunning.AgentData.AgentID != AgentId)
10228 return true;
10229 }
10230 #endregion
10231
10232 SetScriptRunning handlerSetScriptRunning = OnSetScriptRunning;
10233 if (handlerSetScriptRunning != null)
10234 {
10235 handlerSetScriptRunning(this, setScriptRunning.Script.ObjectID, setScriptRunning.Script.ItemID, setScriptRunning.Script.Running);
10236 }
10237 return true;
10238 }
10239
10240 private bool HandleScriptReset(IClientAPI sender, Packet Pack)
10241 {
10242 ScriptResetPacket scriptResetPacket = (ScriptResetPacket)Pack;
10243
10244 #region Packet Session and User Check
10245 if (m_checkPackets)
10246 {
10247 if (scriptResetPacket.AgentData.SessionID != SessionId ||
10248 scriptResetPacket.AgentData.AgentID != AgentId)
10249 return true;
10250 }
10251 #endregion
10252
10253 ScriptReset handlerScriptReset = OnScriptReset;
10254 if (handlerScriptReset != null)
10255 {
10256 handlerScriptReset(this, scriptResetPacket.Script.ObjectID, scriptResetPacket.Script.ItemID);
10257 }
10258 return true;
10259 }
10260
10261 #endregion Script Packets
10262
10263 #region Gesture Managment
10264
10265 private bool HandleActivateGestures(IClientAPI sender, Packet Pack)
10266 {
10267 ActivateGesturesPacket activateGesturePacket = (ActivateGesturesPacket)Pack;
10268
10269 #region Packet Session and User Check
10270 if (m_checkPackets)
10271 {
10272 if (activateGesturePacket.AgentData.SessionID != SessionId ||
10273 activateGesturePacket.AgentData.AgentID != AgentId)
10274 return true;
10275 }
10276 #endregion
10277
10278 ActivateGesture handlerActivateGesture = OnActivateGesture;
10279 if (handlerActivateGesture != null)
10280 {
10281 handlerActivateGesture(this,
10282 activateGesturePacket.Data[0].AssetID,
10283 activateGesturePacket.Data[0].ItemID);
10284 }
10285 else m_log.Error("Null pointer for activateGesture");
10286
10287 return true;
10288 }
10289 private bool HandleDeactivateGestures(IClientAPI sender, Packet Pack)
10290 {
10291 DeactivateGesturesPacket deactivateGesturePacket = (DeactivateGesturesPacket)Pack;
10292
10293 #region Packet Session and User Check
10294 if (m_checkPackets)
10295 {
10296 if (deactivateGesturePacket.AgentData.SessionID != SessionId ||
10297 deactivateGesturePacket.AgentData.AgentID != AgentId)
10298 return true;
10299 }
10300 #endregion
10301
10302 DeactivateGesture handlerDeactivateGesture = OnDeactivateGesture;
10303 if (handlerDeactivateGesture != null)
10304 {
10305 handlerDeactivateGesture(this, deactivateGesturePacket.Data[0].ItemID);
10306 }
10307 return true;
10308 }
10309 private bool HandleObjectOwner(IClientAPI sender, Packet Pack)
10310 {
10311 ObjectOwnerPacket objectOwnerPacket = (ObjectOwnerPacket)Pack;
10312
10313 #region Packet Session and User Check
10314 if (m_checkPackets)
10315 {
10316 if (objectOwnerPacket.AgentData.SessionID != SessionId ||
10317 objectOwnerPacket.AgentData.AgentID != AgentId)
10318 return true;
10319 }
10320 #endregion
10321
10322 List<uint> localIDs = new List<uint>();
10323
10324 foreach (ObjectOwnerPacket.ObjectDataBlock d in objectOwnerPacket.ObjectData)
10325 localIDs.Add(d.ObjectLocalID);
10326
10327 ObjectOwner handlerObjectOwner = OnObjectOwner;
10328 if (handlerObjectOwner != null)
10329 {
10330 handlerObjectOwner(this, objectOwnerPacket.HeaderData.OwnerID, objectOwnerPacket.HeaderData.GroupID, localIDs);
10331 }
10332 return true;
10333 }
10334
10335 #endregion Gesture Managment
10336
10337 private bool HandleAgentFOV(IClientAPI sender, Packet Pack)
10338 {
10339 AgentFOVPacket fovPacket = (AgentFOVPacket)Pack;
10340
10341 if (fovPacket.FOVBlock.GenCounter > m_agentFOVCounter)
10342 {
10343 m_agentFOVCounter = fovPacket.FOVBlock.GenCounter;
10344 AgentFOV handlerAgentFOV = OnAgentFOV;
10345 if (handlerAgentFOV != null)
10346 {
10347 handlerAgentFOV(this, fovPacket.FOVBlock.VerticalAngle);
10348 }
10349 }
10350 return true;
10351 }
10352
10353 #region unimplemented handlers
10354
10355 private bool HandleViewerStats(IClientAPI sender, Packet Pack)
10356 {
10357 // TODO: handle this packet
10358 //m_log.Warn("[CLIENT]: unhandled ViewerStats packet");
10359 return true;
10360 }
10361
10362 private bool HandleMapItemRequest(IClientAPI sender, Packet Pack)
10363 {
10364 MapItemRequestPacket mirpk = (MapItemRequestPacket)Pack;
10365
10366 #region Packet Session and User Check
10367 if (m_checkPackets)
10368 {
10369 if (mirpk.AgentData.SessionID != SessionId ||
10370 mirpk.AgentData.AgentID != AgentId)
10371 return true;
10372 }
10373 #endregion
10374
10375 //m_log.Debug(mirpk.ToString());
10376 MapItemRequest handlerMapItemRequest = OnMapItemRequest;
10377 if (handlerMapItemRequest != null)
10378 {
10379 handlerMapItemRequest(this, mirpk.AgentData.Flags, mirpk.AgentData.EstateID,
10380 mirpk.AgentData.Godlike, mirpk.RequestData.ItemType,
10381 mirpk.RequestData.RegionHandle);
10382
10383 }
10384 return true;
10385 }
10386
10387 private bool HandleTransferAbort(IClientAPI sender, Packet Pack)
10388 {
10389 return true;
10390 }
10391
10392 private bool HandleMuteListRequest(IClientAPI sender, Packet Pack)
10393 {
10394 MuteListRequestPacket muteListRequest =
10395 (MuteListRequestPacket)Pack;
10396
10397 #region Packet Session and User Check
10398 if (m_checkPackets)
10399 {
10400 if (muteListRequest.AgentData.SessionID != SessionId ||
10401 muteListRequest.AgentData.AgentID != AgentId)
10402 return true;
10403 }
10404 #endregion
10405
10406 MuteListRequest handlerMuteListRequest = OnMuteListRequest;
10407 if (handlerMuteListRequest != null)
10408 {
10409 handlerMuteListRequest(this, muteListRequest.MuteData.MuteCRC);
10410 }
10411 else
10412 {
10413 SendUseCachedMuteList();
10414 }
10415 return true;
10416 }
10417
10418 private bool HandleUpdateMuteListEntry(IClientAPI client, Packet Packet)
10419 {
10420 UpdateMuteListEntryPacket UpdateMuteListEntry =
10421 (UpdateMuteListEntryPacket)Packet;
10422 MuteListEntryUpdate handlerUpdateMuteListEntry = OnUpdateMuteListEntry;
10423 if (handlerUpdateMuteListEntry != null)
10424 {
10425 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10426 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10427 UpdateMuteListEntry.MuteData.MuteType,
10428 UpdateMuteListEntry.AgentData.AgentID);
10429 return true;
10430 }
10431 return false;
10432 }
10433
10434 private bool HandleRemoveMuteListEntry(IClientAPI client, Packet Packet)
10435 {
10436 RemoveMuteListEntryPacket RemoveMuteListEntry =
10437 (RemoveMuteListEntryPacket)Packet;
10438 MuteListEntryRemove handlerRemoveMuteListEntry = OnRemoveMuteListEntry;
10439 if (handlerRemoveMuteListEntry != null)
10440 {
10441 handlerRemoveMuteListEntry(this,
10442 RemoveMuteListEntry.MuteData.MuteID,
10443 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName),
10444 RemoveMuteListEntry.AgentData.AgentID);
10445 return true;
10446 }
10447 return false;
10448 }
10449
10450 private bool HandleUserReport(IClientAPI client, Packet Packet)
10451 {
10452 UserReportPacket UserReport =
10453 (UserReportPacket)Packet;
10454
10455 NewUserReport handlerUserReport = OnUserReport;
10456 if (handlerUserReport != null)
10457 {
10458 handlerUserReport(this,
10459 Utils.BytesToString(UserReport.ReportData.AbuseRegionName),
10460 UserReport.ReportData.AbuserID,
10461 UserReport.ReportData.Category,
10462 UserReport.ReportData.CheckFlags,
10463 Utils.BytesToString(UserReport.ReportData.Details),
10464 UserReport.ReportData.ObjectID,
10465 UserReport.ReportData.Position,
10466 UserReport.ReportData.ReportType,
10467 UserReport.ReportData.ScreenshotID,
10468 Utils.BytesToString(UserReport.ReportData.Summary),
10469 UserReport.AgentData.AgentID);
10470 return true;
10471 }
10472 return false;
10473 }
10474
10475 private bool HandleSendPostcard(IClientAPI client, Packet packet)
10476 {
10477// SendPostcardPacket SendPostcard =
10478// (SendPostcardPacket)packet;
10479 SendPostcard handlerSendPostcard = OnSendPostcard;
10480 if (handlerSendPostcard != null)
10481 {
10482 handlerSendPostcard(this);
10483 return true;
10484 }
10485 return false;
10486 }
10487
10488 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10489 {
10490 return true;
10491 }
10492
10493 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10494 {
10495 return true;
10496 }
10497
10498 private bool HandleInventoryDescendents(IClientAPI sender, Packet Pack)
10499 {
10500 return true;
10501 }
10502
10503 #endregion unimplemented handlers
10504
10505 #region Dir handlers
10506
10507 private bool HandleDirPlacesQuery(IClientAPI sender, Packet Pack)
10508 {
10509 DirPlacesQueryPacket dirPlacesQueryPacket = (DirPlacesQueryPacket)Pack;
10510 //m_log.Debug(dirPlacesQueryPacket.ToString());
10511
10512 #region Packet Session and User Check
10513 if (m_checkPackets)
10514 {
10515 if (dirPlacesQueryPacket.AgentData.SessionID != SessionId ||
10516 dirPlacesQueryPacket.AgentData.AgentID != AgentId)
10517 return true;
10518 }
10519 #endregion
10520
10521 DirPlacesQuery handlerDirPlacesQuery = OnDirPlacesQuery;
10522 if (handlerDirPlacesQuery != null)
10523 {
10524 handlerDirPlacesQuery(this,
10525 dirPlacesQueryPacket.QueryData.QueryID,
10526 Utils.BytesToString(
10527 dirPlacesQueryPacket.QueryData.QueryText),
10528 (int)dirPlacesQueryPacket.QueryData.QueryFlags,
10529 (int)dirPlacesQueryPacket.QueryData.Category,
10530 Utils.BytesToString(
10531 dirPlacesQueryPacket.QueryData.SimName),
10532 dirPlacesQueryPacket.QueryData.QueryStart);
10533 }
10534 return true;
10535 }
10536
10537 private bool HandleDirFindQuery(IClientAPI sender, Packet Pack)
10538 {
10539 DirFindQueryPacket dirFindQueryPacket = (DirFindQueryPacket)Pack;
10540
10541 #region Packet Session and User Check
10542 if (m_checkPackets)
10543 {
10544 if (dirFindQueryPacket.AgentData.SessionID != SessionId ||
10545 dirFindQueryPacket.AgentData.AgentID != AgentId)
10546 return true;
10547 }
10548 #endregion
10549
10550 DirFindQuery handlerDirFindQuery = OnDirFindQuery;
10551 if (handlerDirFindQuery != null)
10552 {
10553 handlerDirFindQuery(this,
10554 dirFindQueryPacket.QueryData.QueryID,
10555 Utils.BytesToString(
10556 dirFindQueryPacket.QueryData.QueryText).Trim(),
10557 dirFindQueryPacket.QueryData.QueryFlags,
10558 dirFindQueryPacket.QueryData.QueryStart);
10559 }
10560 return true;
10561 }
10562
10563 private bool HandleDirLandQuery(IClientAPI sender, Packet Pack)
10564 {
10565 DirLandQueryPacket dirLandQueryPacket = (DirLandQueryPacket)Pack;
10566
10567 #region Packet Session and User Check
10568 if (m_checkPackets)
10569 {
10570 if (dirLandQueryPacket.AgentData.SessionID != SessionId ||
10571 dirLandQueryPacket.AgentData.AgentID != AgentId)
10572 return true;
10573 }
10574 #endregion
10575
10576 DirLandQuery handlerDirLandQuery = OnDirLandQuery;
10577 if (handlerDirLandQuery != null)
10578 {
10579 handlerDirLandQuery(this,
10580 dirLandQueryPacket.QueryData.QueryID,
10581 dirLandQueryPacket.QueryData.QueryFlags,
10582 dirLandQueryPacket.QueryData.SearchType,
10583 dirLandQueryPacket.QueryData.Price,
10584 dirLandQueryPacket.QueryData.Area,
10585 dirLandQueryPacket.QueryData.QueryStart);
10586 }
10587 return true;
10588 }
10589
10590 private bool HandleDirPopularQuery(IClientAPI sender, Packet Pack)
10591 {
10592 DirPopularQueryPacket dirPopularQueryPacket = (DirPopularQueryPacket)Pack;
10593
10594 #region Packet Session and User Check
10595 if (m_checkPackets)
10596 {
10597 if (dirPopularQueryPacket.AgentData.SessionID != SessionId ||
10598 dirPopularQueryPacket.AgentData.AgentID != AgentId)
10599 return true;
10600 }
10601 #endregion
10602
10603 DirPopularQuery handlerDirPopularQuery = OnDirPopularQuery;
10604 if (handlerDirPopularQuery != null)
10605 {
10606 handlerDirPopularQuery(this,
10607 dirPopularQueryPacket.QueryData.QueryID,
10608 dirPopularQueryPacket.QueryData.QueryFlags);
10609 }
10610 return true;
10611 }
10612
10613 private bool HandleDirClassifiedQuery(IClientAPI sender, Packet Pack)
10614 {
10615 DirClassifiedQueryPacket dirClassifiedQueryPacket = (DirClassifiedQueryPacket)Pack;
10616
10617 #region Packet Session and User Check
10618 if (m_checkPackets)
10619 {
10620 if (dirClassifiedQueryPacket.AgentData.SessionID != SessionId ||
10621 dirClassifiedQueryPacket.AgentData.AgentID != AgentId)
10622 return true;
10623 }
10624 #endregion
10625
10626 DirClassifiedQuery handlerDirClassifiedQuery = OnDirClassifiedQuery;
10627 if (handlerDirClassifiedQuery != null)
10628 {
10629 handlerDirClassifiedQuery(this,
10630 dirClassifiedQueryPacket.QueryData.QueryID,
10631 Utils.BytesToString(
10632 dirClassifiedQueryPacket.QueryData.QueryText),
10633 dirClassifiedQueryPacket.QueryData.QueryFlags,
10634 dirClassifiedQueryPacket.QueryData.Category,
10635 dirClassifiedQueryPacket.QueryData.QueryStart);
10636 }
10637 return true;
10638 }
10639
10640 private bool HandleEventInfoRequest(IClientAPI sender, Packet Pack)
10641 {
10642 EventInfoRequestPacket eventInfoRequestPacket = (EventInfoRequestPacket)Pack;
10643
10644 #region Packet Session and User Check
10645 if (m_checkPackets)
10646 {
10647 if (eventInfoRequestPacket.AgentData.SessionID != SessionId ||
10648 eventInfoRequestPacket.AgentData.AgentID != AgentId)
10649 return true;
10650 }
10651 #endregion
10652
10653 if (OnEventInfoRequest != null)
10654 {
10655 OnEventInfoRequest(this, eventInfoRequestPacket.EventData.EventID);
10656 }
10657 return true;
10658 }
10659
10660 #endregion
10661
10662 #region Calling Card
10663
10664 private bool HandleOfferCallingCard(IClientAPI sender, Packet Pack)
10665 {
10666 OfferCallingCardPacket offerCallingCardPacket = (OfferCallingCardPacket)Pack;
10667
10668 #region Packet Session and User Check
10669 if (m_checkPackets)
10670 {
10671 if (offerCallingCardPacket.AgentData.SessionID != SessionId ||
10672 offerCallingCardPacket.AgentData.AgentID != AgentId)
10673 return true;
10674 }
10675 #endregion
10676
10677 if (OnOfferCallingCard != null)
10678 {
10679 OnOfferCallingCard(this,
10680 offerCallingCardPacket.AgentBlock.DestID,
10681 offerCallingCardPacket.AgentBlock.TransactionID);
10682 }
10683 return true;
10684 }
10685
10686 private bool HandleAcceptCallingCard(IClientAPI sender, Packet Pack)
10687 {
10688 AcceptCallingCardPacket acceptCallingCardPacket = (AcceptCallingCardPacket)Pack;
10689
10690 #region Packet Session and User Check
10691 if (m_checkPackets)
10692 {
10693 if (acceptCallingCardPacket.AgentData.SessionID != SessionId ||
10694 acceptCallingCardPacket.AgentData.AgentID != AgentId)
10695 return true;
10696 }
10697 #endregion
10698
10699 // according to http://wiki.secondlife.com/wiki/AcceptCallingCard FolderData should
10700 // contain exactly one entry
10701 if (OnAcceptCallingCard != null && acceptCallingCardPacket.FolderData.Length > 0)
10702 {
10703 OnAcceptCallingCard(this,
10704 acceptCallingCardPacket.TransactionBlock.TransactionID,
10705 acceptCallingCardPacket.FolderData[0].FolderID);
10706 }
10707 return true;
10708 }
10709
10710 private bool HandleDeclineCallingCard(IClientAPI sender, Packet Pack)
10711 {
10712 DeclineCallingCardPacket declineCallingCardPacket = (DeclineCallingCardPacket)Pack;
10713
10714 #region Packet Session and User Check
10715 if (m_checkPackets)
10716 {
10717 if (declineCallingCardPacket.AgentData.SessionID != SessionId ||
10718 declineCallingCardPacket.AgentData.AgentID != AgentId)
10719 return true;
10720 }
10721 #endregion
10722
10723 if (OnDeclineCallingCard != null)
10724 {
10725 OnDeclineCallingCard(this,
10726 declineCallingCardPacket.TransactionBlock.TransactionID);
10727 }
10728 return true;
10729 }
10730
10731 #endregion Calling Card
10732
10733 #region Groups
10734
10735 private bool HandleActivateGroup(IClientAPI sender, Packet Pack)
10736 {
10737 ActivateGroupPacket activateGroupPacket = (ActivateGroupPacket)Pack;
10738
10739 #region Packet Session and User Check
10740 if (m_checkPackets)
10741 {
10742 if (activateGroupPacket.AgentData.SessionID != SessionId ||
10743 activateGroupPacket.AgentData.AgentID != AgentId)
10744 return true;
10745 }
10746 #endregion
10747
10748 if (m_GroupsModule != null)
10749 {
10750 m_GroupsModule.ActivateGroup(this, activateGroupPacket.AgentData.GroupID);
10751 m_GroupsModule.SendAgentGroupDataUpdate(this);
10752 }
10753 return true;
10754
10755 }
10756
10757 private bool HandleGroupVoteHistoryRequest(IClientAPI client, Packet Packet)
10758 {
10759 GroupVoteHistoryRequestPacket GroupVoteHistoryRequest =
10760 (GroupVoteHistoryRequestPacket)Packet;
10761 GroupVoteHistoryRequest handlerGroupVoteHistoryRequest = OnGroupVoteHistoryRequest;
10762 if (handlerGroupVoteHistoryRequest != null)
10763 {
10764 handlerGroupVoteHistoryRequest(this, GroupVoteHistoryRequest.AgentData.AgentID,GroupVoteHistoryRequest.AgentData.SessionID,GroupVoteHistoryRequest.GroupData.GroupID,GroupVoteHistoryRequest.TransactionData.TransactionID);
10765 return true;
10766 }
10767 return false;
10768 }
10769
10770 private bool HandleGroupActiveProposalsRequest(IClientAPI client, Packet Packet)
10771 {
10772 GroupActiveProposalsRequestPacket GroupActiveProposalsRequest =
10773 (GroupActiveProposalsRequestPacket)Packet;
10774 GroupActiveProposalsRequest handlerGroupActiveProposalsRequest = OnGroupActiveProposalsRequest;
10775 if (handlerGroupActiveProposalsRequest != null)
10776 {
10777 handlerGroupActiveProposalsRequest(this, GroupActiveProposalsRequest.AgentData.AgentID,GroupActiveProposalsRequest.AgentData.SessionID,GroupActiveProposalsRequest.GroupData.GroupID,GroupActiveProposalsRequest.TransactionData.TransactionID);
10778 return true;
10779 }
10780 return false;
10781 }
10782
10783 private bool HandleGroupAccountDetailsRequest(IClientAPI client, Packet Packet)
10784 {
10785 GroupAccountDetailsRequestPacket GroupAccountDetailsRequest =
10786 (GroupAccountDetailsRequestPacket)Packet;
10787 GroupAccountDetailsRequest handlerGroupAccountDetailsRequest = OnGroupAccountDetailsRequest;
10788 if (handlerGroupAccountDetailsRequest != null)
10789 {
10790 handlerGroupAccountDetailsRequest(this, GroupAccountDetailsRequest.AgentData.AgentID,GroupAccountDetailsRequest.AgentData.GroupID,GroupAccountDetailsRequest.MoneyData.RequestID,GroupAccountDetailsRequest.AgentData.SessionID);
10791 return true;
10792 }
10793 return false;
10794 }
10795
10796 private bool HandleGroupAccountSummaryRequest(IClientAPI client, Packet Packet)
10797 {
10798 GroupAccountSummaryRequestPacket GroupAccountSummaryRequest =
10799 (GroupAccountSummaryRequestPacket)Packet;
10800 GroupAccountSummaryRequest handlerGroupAccountSummaryRequest = OnGroupAccountSummaryRequest;
10801 if (handlerGroupAccountSummaryRequest != null)
10802 {
10803 handlerGroupAccountSummaryRequest(this, GroupAccountSummaryRequest.AgentData.AgentID,GroupAccountSummaryRequest.AgentData.GroupID);
10804 return true;
10805 }
10806 return false;
10807 }
10808
10809 private bool HandleGroupTransactionsDetailsRequest(IClientAPI client, Packet Packet)
10810 {
10811 GroupAccountTransactionsRequestPacket GroupAccountTransactionsRequest =
10812 (GroupAccountTransactionsRequestPacket)Packet;
10813 GroupAccountTransactionsRequest handlerGroupAccountTransactionsRequest = OnGroupAccountTransactionsRequest;
10814 if (handlerGroupAccountTransactionsRequest != null)
10815 {
10816 handlerGroupAccountTransactionsRequest(this, GroupAccountTransactionsRequest.AgentData.AgentID,GroupAccountTransactionsRequest.AgentData.GroupID,GroupAccountTransactionsRequest.MoneyData.RequestID,GroupAccountTransactionsRequest.AgentData.SessionID);
10817 return true;
10818 }
10819 return false;
10820 }
10821
10822 private bool HandleGroupTitlesRequest(IClientAPI sender, Packet Pack)
10823 {
10824 GroupTitlesRequestPacket groupTitlesRequest =
10825 (GroupTitlesRequestPacket)Pack;
10826
10827 #region Packet Session and User Check
10828 if (m_checkPackets)
10829 {
10830 if (groupTitlesRequest.AgentData.SessionID != SessionId ||
10831 groupTitlesRequest.AgentData.AgentID != AgentId)
10832 return true;
10833 }
10834 #endregion
10835
10836 if (m_GroupsModule != null)
10837 {
10838 GroupTitlesReplyPacket groupTitlesReply = (GroupTitlesReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupTitlesReply);
10839
10840 groupTitlesReply.AgentData =
10841 new GroupTitlesReplyPacket.AgentDataBlock();
10842
10843 groupTitlesReply.AgentData.AgentID = AgentId;
10844 groupTitlesReply.AgentData.GroupID =
10845 groupTitlesRequest.AgentData.GroupID;
10846
10847 groupTitlesReply.AgentData.RequestID =
10848 groupTitlesRequest.AgentData.RequestID;
10849
10850 List<GroupTitlesData> titles =
10851 m_GroupsModule.GroupTitlesRequest(this,
10852 groupTitlesRequest.AgentData.GroupID);
10853
10854 groupTitlesReply.GroupData =
10855 new GroupTitlesReplyPacket.GroupDataBlock[titles.Count];
10856
10857 int i = 0;
10858 foreach (GroupTitlesData d in titles)
10859 {
10860 groupTitlesReply.GroupData[i] =
10861 new GroupTitlesReplyPacket.GroupDataBlock();
10862
10863 groupTitlesReply.GroupData[i].Title =
10864 Util.StringToBytes256(d.Name);
10865 groupTitlesReply.GroupData[i].RoleID =
10866 d.UUID;
10867 groupTitlesReply.GroupData[i].Selected =
10868 d.Selected;
10869 i++;
10870 }
10871
10872 OutPacket(groupTitlesReply, ThrottleOutPacketType.Task);
10873 }
10874 return true;
10875 }
10876 private bool HandleGroupProfileRequest(IClientAPI sender, Packet Pack)
10877 {
10878 GroupProfileRequestPacket groupProfileRequest =
10879 (GroupProfileRequestPacket)Pack;
10880
10881 #region Packet Session and User Check
10882 if (m_checkPackets)
10883 {
10884 if (groupProfileRequest.AgentData.SessionID != SessionId ||
10885 groupProfileRequest.AgentData.AgentID != AgentId)
10886 return true;
10887 }
10888 #endregion
10889
10890 if (m_GroupsModule != null)
10891 {
10892 GroupProfileReplyPacket groupProfileReply = (GroupProfileReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupProfileReply);
10893
10894 groupProfileReply.AgentData = new GroupProfileReplyPacket.AgentDataBlock();
10895 groupProfileReply.GroupData = new GroupProfileReplyPacket.GroupDataBlock();
10896 groupProfileReply.AgentData.AgentID = AgentId;
10897
10898 GroupProfileData d = m_GroupsModule.GroupProfileRequest(this,
10899 groupProfileRequest.GroupData.GroupID);
10900
10901 groupProfileReply.GroupData.GroupID = d.GroupID;
10902 groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name);
10903 groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter);
10904 groupProfileReply.GroupData.ShowInList = d.ShowInList;
10905 groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle);
10906 groupProfileReply.GroupData.PowersMask = d.PowersMask;
10907 groupProfileReply.GroupData.InsigniaID = d.InsigniaID;
10908 groupProfileReply.GroupData.FounderID = d.FounderID;
10909 groupProfileReply.GroupData.MembershipFee = d.MembershipFee;
10910 groupProfileReply.GroupData.OpenEnrollment = d.OpenEnrollment;
10911 groupProfileReply.GroupData.Money = d.Money;
10912 groupProfileReply.GroupData.GroupMembershipCount = d.GroupMembershipCount;
10913 groupProfileReply.GroupData.GroupRolesCount = d.GroupRolesCount;
10914 groupProfileReply.GroupData.AllowPublish = d.AllowPublish;
10915 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10916 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10917
10918 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10919 }
10920 return true;
10921 }
10922 private bool HandleGroupMembersRequest(IClientAPI sender, Packet Pack)
10923 {
10924 GroupMembersRequestPacket groupMembersRequestPacket =
10925 (GroupMembersRequestPacket)Pack;
10926
10927 #region Packet Session and User Check
10928 if (m_checkPackets)
10929 {
10930 if (groupMembersRequestPacket.AgentData.SessionID != SessionId ||
10931 groupMembersRequestPacket.AgentData.AgentID != AgentId)
10932 return true;
10933 }
10934 #endregion
10935
10936 if (m_GroupsModule != null)
10937 {
10938 List<GroupMembersData> members =
10939 m_GroupsModule.GroupMembersRequest(this, groupMembersRequestPacket.GroupData.GroupID);
10940
10941 int memberCount = members.Count;
10942
10943 while (true)
10944 {
10945 int blockCount = members.Count;
10946 if (blockCount > 40)
10947 blockCount = 40;
10948
10949 GroupMembersReplyPacket groupMembersReply = (GroupMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupMembersReply);
10950
10951 groupMembersReply.AgentData =
10952 new GroupMembersReplyPacket.AgentDataBlock();
10953 groupMembersReply.GroupData =
10954 new GroupMembersReplyPacket.GroupDataBlock();
10955 groupMembersReply.MemberData =
10956 new GroupMembersReplyPacket.MemberDataBlock[
10957 blockCount];
10958
10959 groupMembersReply.AgentData.AgentID = AgentId;
10960 groupMembersReply.GroupData.GroupID =
10961 groupMembersRequestPacket.GroupData.GroupID;
10962 groupMembersReply.GroupData.RequestID =
10963 groupMembersRequestPacket.GroupData.RequestID;
10964 groupMembersReply.GroupData.MemberCount = memberCount;
10965
10966 for (int i = 0; i < blockCount; i++)
10967 {
10968 GroupMembersData m = members[0];
10969 members.RemoveAt(0);
10970
10971 groupMembersReply.MemberData[i] =
10972 new GroupMembersReplyPacket.MemberDataBlock();
10973 groupMembersReply.MemberData[i].AgentID =
10974 m.AgentID;
10975 groupMembersReply.MemberData[i].Contribution =
10976 m.Contribution;
10977 groupMembersReply.MemberData[i].OnlineStatus =
10978 Util.StringToBytes256(m.OnlineStatus);
10979 groupMembersReply.MemberData[i].AgentPowers =
10980 m.AgentPowers;
10981 groupMembersReply.MemberData[i].Title =
10982 Util.StringToBytes256(m.Title);
10983 groupMembersReply.MemberData[i].IsOwner =
10984 m.IsOwner;
10985 }
10986 OutPacket(groupMembersReply, ThrottleOutPacketType.Task);
10987 if (members.Count == 0)
10988 return true;
10989 }
10990 }
10991 return true;
10992 }
10993 private bool HandleGroupRoleDataRequest(IClientAPI sender, Packet Pack)
10994 {
10995 GroupRoleDataRequestPacket groupRolesRequest =
10996 (GroupRoleDataRequestPacket)Pack;
10997
10998 #region Packet Session and User Check
10999 if (m_checkPackets)
11000 {
11001 if (groupRolesRequest.AgentData.SessionID != SessionId ||
11002 groupRolesRequest.AgentData.AgentID != AgentId)
11003 return true;
11004 }
11005 #endregion
11006
11007 if (m_GroupsModule != null)
11008 {
11009 GroupRoleDataReplyPacket groupRolesReply = (GroupRoleDataReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupRoleDataReply);
11010
11011 groupRolesReply.AgentData =
11012 new GroupRoleDataReplyPacket.AgentDataBlock();
11013
11014 groupRolesReply.AgentData.AgentID = AgentId;
11015
11016 groupRolesReply.GroupData =
11017 new GroupRoleDataReplyPacket.GroupDataBlock();
11018
11019 groupRolesReply.GroupData.GroupID =
11020 groupRolesRequest.GroupData.GroupID;
11021
11022 groupRolesReply.GroupData.RequestID =
11023 groupRolesRequest.GroupData.RequestID;
11024
11025 List<GroupRolesData> titles =
11026 m_GroupsModule.GroupRoleDataRequest(this,
11027 groupRolesRequest.GroupData.GroupID);
11028
11029 groupRolesReply.GroupData.RoleCount =
11030 titles.Count;
11031
11032 groupRolesReply.RoleData =
11033 new GroupRoleDataReplyPacket.RoleDataBlock[titles.Count];
11034
11035 int i = 0;
11036 foreach (GroupRolesData d in titles)
11037 {
11038 groupRolesReply.RoleData[i] =
11039 new GroupRoleDataReplyPacket.RoleDataBlock();
11040
11041 groupRolesReply.RoleData[i].RoleID =
11042 d.RoleID;
11043 groupRolesReply.RoleData[i].Name =
11044 Util.StringToBytes256(d.Name);
11045 groupRolesReply.RoleData[i].Title =
11046 Util.StringToBytes256(d.Title);
11047 groupRolesReply.RoleData[i].Description =
11048 Util.StringToBytes1024(d.Description);
11049 groupRolesReply.RoleData[i].Powers =
11050 d.Powers;
11051 groupRolesReply.RoleData[i].Members =
11052 (uint)d.Members;
11053
11054 i++;
11055 }
11056
11057 OutPacket(groupRolesReply, ThrottleOutPacketType.Task);
11058 }
11059 return true;
11060 }
11061
11062 private bool HandleGroupRoleMembersRequest(IClientAPI sender, Packet Pack)
11063 {
11064 GroupRoleMembersRequestPacket groupRoleMembersRequest =
11065 (GroupRoleMembersRequestPacket)Pack;
11066
11067 #region Packet Session and User Check
11068 if (m_checkPackets)
11069 {
11070 if (groupRoleMembersRequest.AgentData.SessionID != SessionId ||
11071 groupRoleMembersRequest.AgentData.AgentID != AgentId)
11072 return true;
11073 }
11074 #endregion
11075
11076 if (m_GroupsModule != null)
11077 {
11078 List<GroupRoleMembersData> mappings =
11079 m_GroupsModule.GroupRoleMembersRequest(this,
11080 groupRoleMembersRequest.GroupData.GroupID);
11081
11082 int mappingsCount = mappings.Count;
11083
11084 while (mappings.Count > 0)
11085 {
11086 int pairs = mappings.Count;
11087 if (pairs > 32)
11088 pairs = 32;
11089
11090 GroupRoleMembersReplyPacket groupRoleMembersReply = (GroupRoleMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupRoleMembersReply);
11091 groupRoleMembersReply.AgentData =
11092 new GroupRoleMembersReplyPacket.AgentDataBlock();
11093 groupRoleMembersReply.AgentData.AgentID =
11094 AgentId;
11095 groupRoleMembersReply.AgentData.GroupID =
11096 groupRoleMembersRequest.GroupData.GroupID;
11097 groupRoleMembersReply.AgentData.RequestID =
11098 groupRoleMembersRequest.GroupData.RequestID;
11099
11100 groupRoleMembersReply.AgentData.TotalPairs =
11101 (uint)mappingsCount;
11102
11103 groupRoleMembersReply.MemberData =
11104 new GroupRoleMembersReplyPacket.MemberDataBlock[pairs];
11105
11106 for (int i = 0; i < pairs; i++)
11107 {
11108 GroupRoleMembersData d = mappings[0];
11109 mappings.RemoveAt(0);
11110
11111 groupRoleMembersReply.MemberData[i] =
11112 new GroupRoleMembersReplyPacket.MemberDataBlock();
11113
11114 groupRoleMembersReply.MemberData[i].RoleID =
11115 d.RoleID;
11116 groupRoleMembersReply.MemberData[i].MemberID =
11117 d.MemberID;
11118 }
11119
11120 OutPacket(groupRoleMembersReply, ThrottleOutPacketType.Task);
11121 }
11122 }
11123 return true;
11124 }
11125 private bool HandleCreateGroupRequest(IClientAPI sender, Packet Pack)
11126 {
11127 CreateGroupRequestPacket createGroupRequest =
11128 (CreateGroupRequestPacket)Pack;
11129
11130 #region Packet Session and User Check
11131 if (m_checkPackets)
11132 {
11133 if (createGroupRequest.AgentData.SessionID != SessionId ||
11134 createGroupRequest.AgentData.AgentID != AgentId)
11135 return true;
11136 }
11137 #endregion
11138
11139 if (m_GroupsModule != null)
11140 {
11141 m_GroupsModule.CreateGroup(this,
11142 Utils.BytesToString(createGroupRequest.GroupData.Name),
11143 Utils.BytesToString(createGroupRequest.GroupData.Charter),
11144 createGroupRequest.GroupData.ShowInList,
11145 createGroupRequest.GroupData.InsigniaID,
11146 createGroupRequest.GroupData.MembershipFee,
11147 createGroupRequest.GroupData.OpenEnrollment,
11148 createGroupRequest.GroupData.AllowPublish,
11149 createGroupRequest.GroupData.MaturePublish);
11150 }
11151 return true;
11152 }
11153 private bool HandleUpdateGroupInfo(IClientAPI sender, Packet Pack)
11154 {
11155 UpdateGroupInfoPacket updateGroupInfo =
11156 (UpdateGroupInfoPacket)Pack;
11157
11158 #region Packet Session and User Check
11159 if (m_checkPackets)
11160 {
11161 if (updateGroupInfo.AgentData.SessionID != SessionId ||
11162 updateGroupInfo.AgentData.AgentID != AgentId)
11163 return true;
11164 }
11165 #endregion
11166
11167 if (m_GroupsModule != null)
11168 {
11169 m_GroupsModule.UpdateGroupInfo(this,
11170 updateGroupInfo.GroupData.GroupID,
11171 Utils.BytesToString(updateGroupInfo.GroupData.Charter),
11172 updateGroupInfo.GroupData.ShowInList,
11173 updateGroupInfo.GroupData.InsigniaID,
11174 updateGroupInfo.GroupData.MembershipFee,
11175 updateGroupInfo.GroupData.OpenEnrollment,
11176 updateGroupInfo.GroupData.AllowPublish,
11177 updateGroupInfo.GroupData.MaturePublish);
11178 }
11179
11180 return true;
11181 }
11182 private bool HandleSetGroupAcceptNotices(IClientAPI sender, Packet Pack)
11183 {
11184 SetGroupAcceptNoticesPacket setGroupAcceptNotices =
11185 (SetGroupAcceptNoticesPacket)Pack;
11186
11187 #region Packet Session and User Check
11188 if (m_checkPackets)
11189 {
11190 if (setGroupAcceptNotices.AgentData.SessionID != SessionId ||
11191 setGroupAcceptNotices.AgentData.AgentID != AgentId)
11192 return true;
11193 }
11194 #endregion
11195
11196 if (m_GroupsModule != null)
11197 {
11198 m_GroupsModule.SetGroupAcceptNotices(this,
11199 setGroupAcceptNotices.Data.GroupID,
11200 setGroupAcceptNotices.Data.AcceptNotices,
11201 setGroupAcceptNotices.NewData.ListInProfile);
11202 }
11203
11204 return true;
11205 }
11206 private bool HandleGroupTitleUpdate(IClientAPI sender, Packet Pack)
11207 {
11208 GroupTitleUpdatePacket groupTitleUpdate =
11209 (GroupTitleUpdatePacket)Pack;
11210
11211 #region Packet Session and User Check
11212 if (m_checkPackets)
11213 {
11214 if (groupTitleUpdate.AgentData.SessionID != SessionId ||
11215 groupTitleUpdate.AgentData.AgentID != AgentId)
11216 return true;
11217 }
11218 #endregion
11219
11220 if (m_GroupsModule != null)
11221 {
11222 m_GroupsModule.GroupTitleUpdate(this,
11223 groupTitleUpdate.AgentData.GroupID,
11224 groupTitleUpdate.AgentData.TitleRoleID);
11225 }
11226
11227 return true;
11228 }
11229 private bool HandleParcelDeedToGroup(IClientAPI sender, Packet Pack)
11230 {
11231 ParcelDeedToGroupPacket parcelDeedToGroup = (ParcelDeedToGroupPacket)Pack;
11232 if (m_GroupsModule != null)
11233 {
11234 ParcelDeedToGroup handlerParcelDeedToGroup = OnParcelDeedToGroup;
11235 if (handlerParcelDeedToGroup != null)
11236 {
11237 handlerParcelDeedToGroup(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID, this);
11238
11239 }
11240 }
11241
11242 return true;
11243 }
11244 private bool HandleGroupNoticesListRequest(IClientAPI sender, Packet Pack)
11245 {
11246 GroupNoticesListRequestPacket groupNoticesListRequest =
11247 (GroupNoticesListRequestPacket)Pack;
11248
11249 #region Packet Session and User Check
11250 if (m_checkPackets)
11251 {
11252 if (groupNoticesListRequest.AgentData.SessionID != SessionId ||
11253 groupNoticesListRequest.AgentData.AgentID != AgentId)
11254 return true;
11255 }
11256 #endregion
11257
11258 if (m_GroupsModule != null)
11259 {
11260 GroupNoticeData[] gn =
11261 m_GroupsModule.GroupNoticesListRequest(this,
11262 groupNoticesListRequest.Data.GroupID);
11263
11264 GroupNoticesListReplyPacket groupNoticesListReply = (GroupNoticesListReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupNoticesListReply);
11265 groupNoticesListReply.AgentData =
11266 new GroupNoticesListReplyPacket.AgentDataBlock();
11267 groupNoticesListReply.AgentData.AgentID = AgentId;
11268 groupNoticesListReply.AgentData.GroupID = groupNoticesListRequest.Data.GroupID;
11269
11270 groupNoticesListReply.Data = new GroupNoticesListReplyPacket.DataBlock[gn.Length];
11271
11272 int i = 0;
11273 foreach (GroupNoticeData g in gn)
11274 {
11275 groupNoticesListReply.Data[i] = new GroupNoticesListReplyPacket.DataBlock();
11276 groupNoticesListReply.Data[i].NoticeID =
11277 g.NoticeID;
11278 groupNoticesListReply.Data[i].Timestamp =
11279 g.Timestamp;
11280 groupNoticesListReply.Data[i].FromName =
11281 Util.StringToBytes256(g.FromName);
11282 groupNoticesListReply.Data[i].Subject =
11283 Util.StringToBytes256(g.Subject);
11284 groupNoticesListReply.Data[i].HasAttachment =
11285 g.HasAttachment;
11286 groupNoticesListReply.Data[i].AssetType =
11287 g.AssetType;
11288 i++;
11289 }
11290
11291 OutPacket(groupNoticesListReply, ThrottleOutPacketType.Task);
11292 }
11293
11294 return true;
11295 }
11296 private bool HandleGroupNoticeRequest(IClientAPI sender, Packet Pack)
11297 {
11298 GroupNoticeRequestPacket groupNoticeRequest =
11299 (GroupNoticeRequestPacket)Pack;
11300
11301 #region Packet Session and User Check
11302 if (m_checkPackets)
11303 {
11304 if (groupNoticeRequest.AgentData.SessionID != SessionId ||
11305 groupNoticeRequest.AgentData.AgentID != AgentId)
11306 return true;
11307 }
11308 #endregion
11309
11310 if (m_GroupsModule != null)
11311 {
11312 m_GroupsModule.GroupNoticeRequest(this,
11313 groupNoticeRequest.Data.GroupNoticeID);
11314 }
11315 return true;
11316 }
11317 private bool HandleGroupRoleUpdate(IClientAPI sender, Packet Pack)
11318 {
11319 GroupRoleUpdatePacket groupRoleUpdate =
11320 (GroupRoleUpdatePacket)Pack;
11321
11322 #region Packet Session and User Check
11323 if (m_checkPackets)
11324 {
11325 if (groupRoleUpdate.AgentData.SessionID != SessionId ||
11326 groupRoleUpdate.AgentData.AgentID != AgentId)
11327 return true;
11328 }
11329 #endregion
11330
11331 if (m_GroupsModule != null)
11332 {
11333 foreach (GroupRoleUpdatePacket.RoleDataBlock d in
11334 groupRoleUpdate.RoleData)
11335 {
11336 m_GroupsModule.GroupRoleUpdate(this,
11337 groupRoleUpdate.AgentData.GroupID,
11338 d.RoleID,
11339 Utils.BytesToString(d.Name),
11340 Utils.BytesToString(d.Description),
11341 Utils.BytesToString(d.Title),
11342 d.Powers,
11343 d.UpdateType);
11344 }
11345 m_GroupsModule.NotifyChange(groupRoleUpdate.AgentData.GroupID);
11346 }
11347 return true;
11348 }
11349 private bool HandleGroupRoleChanges(IClientAPI sender, Packet Pack)
11350 {
11351 GroupRoleChangesPacket groupRoleChanges =
11352 (GroupRoleChangesPacket)Pack;
11353
11354 #region Packet Session and User Check
11355 if (m_checkPackets)
11356 {
11357 if (groupRoleChanges.AgentData.SessionID != SessionId ||
11358 groupRoleChanges.AgentData.AgentID != AgentId)
11359 return true;
11360 }
11361 #endregion
11362
11363 if (m_GroupsModule != null)
11364 {
11365 foreach (GroupRoleChangesPacket.RoleChangeBlock d in
11366 groupRoleChanges.RoleChange)
11367 {
11368 m_GroupsModule.GroupRoleChanges(this,
11369 groupRoleChanges.AgentData.GroupID,
11370 d.RoleID,
11371 d.MemberID,
11372 d.Change);
11373 }
11374 m_GroupsModule.NotifyChange(groupRoleChanges.AgentData.GroupID);
11375 }
11376 return true;
11377 }
11378 private bool HandleJoinGroupRequest(IClientAPI sender, Packet Pack)
11379 {
11380 JoinGroupRequestPacket joinGroupRequest =
11381 (JoinGroupRequestPacket)Pack;
11382
11383 #region Packet Session and User Check
11384 if (m_checkPackets)
11385 {
11386 if (joinGroupRequest.AgentData.SessionID != SessionId ||
11387 joinGroupRequest.AgentData.AgentID != AgentId)
11388 return true;
11389 }
11390 #endregion
11391
11392 if (m_GroupsModule != null)
11393 {
11394 m_GroupsModule.JoinGroupRequest(this,
11395 joinGroupRequest.GroupData.GroupID);
11396 }
11397 return true;
11398 }
11399 private bool HandleLeaveGroupRequest(IClientAPI sender, Packet Pack)
11400 {
11401 LeaveGroupRequestPacket leaveGroupRequest =
11402 (LeaveGroupRequestPacket)Pack;
11403
11404 #region Packet Session and User Check
11405 if (m_checkPackets)
11406 {
11407 if (leaveGroupRequest.AgentData.SessionID != SessionId ||
11408 leaveGroupRequest.AgentData.AgentID != AgentId)
11409 return true;
11410 }
11411 #endregion
11412
11413 if (m_GroupsModule != null)
11414 {
11415 m_GroupsModule.LeaveGroupRequest(this,
11416 leaveGroupRequest.GroupData.GroupID);
11417 }
11418 return true;
11419 }
11420 private bool HandleEjectGroupMemberRequest(IClientAPI sender, Packet Pack)
11421 {
11422 EjectGroupMemberRequestPacket ejectGroupMemberRequest =
11423 (EjectGroupMemberRequestPacket)Pack;
11424
11425 #region Packet Session and User Check
11426 if (m_checkPackets)
11427 {
11428 if (ejectGroupMemberRequest.AgentData.SessionID != SessionId ||
11429 ejectGroupMemberRequest.AgentData.AgentID != AgentId)
11430 return true;
11431 }
11432 #endregion
11433
11434 if (m_GroupsModule != null)
11435 {
11436 foreach (EjectGroupMemberRequestPacket.EjectDataBlock e
11437 in ejectGroupMemberRequest.EjectData)
11438 {
11439 m_GroupsModule.EjectGroupMemberRequest(this,
11440 ejectGroupMemberRequest.GroupData.GroupID,
11441 e.EjecteeID);
11442 }
11443 }
11444 return true;
11445 }
11446 private bool HandleInviteGroupRequest(IClientAPI sender, Packet Pack)
11447 {
11448 InviteGroupRequestPacket inviteGroupRequest =
11449 (InviteGroupRequestPacket)Pack;
11450
11451 #region Packet Session and User Check
11452 if (m_checkPackets)
11453 {
11454 if (inviteGroupRequest.AgentData.SessionID != SessionId ||
11455 inviteGroupRequest.AgentData.AgentID != AgentId)
11456 return true;
11457 }
11458 #endregion
11459
11460 if (m_GroupsModule != null)
11461 {
11462 foreach (InviteGroupRequestPacket.InviteDataBlock b in
11463 inviteGroupRequest.InviteData)
11464 {
11465 m_GroupsModule.InviteGroupRequest(this,
11466 inviteGroupRequest.GroupData.GroupID,
11467 b.InviteeID,
11468 b.RoleID);
11469 }
11470 }
11471 return true;
11472 }
11473
11474 #endregion Groups
11475
11476 private bool HandleStartLure(IClientAPI sender, Packet Pack)
11477 {
11478 StartLurePacket startLureRequest = (StartLurePacket)Pack;
11479
11480 #region Packet Session and User Check
11481 if (m_checkPackets)
11482 {
11483 if (startLureRequest.AgentData.SessionID != SessionId ||
11484 startLureRequest.AgentData.AgentID != AgentId)
11485 return true;
11486 }
11487 #endregion
11488
11489 StartLure handlerStartLure = OnStartLure;
11490 if (handlerStartLure != null)
11491 handlerStartLure(startLureRequest.Info.LureType,
11492 Utils.BytesToString(
11493 startLureRequest.Info.Message),
11494 startLureRequest.TargetData[0].TargetID,
11495 this);
11496 return true;
11497 }
11498 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
11499 {
11500 TeleportLureRequestPacket teleportLureRequest =
11501 (TeleportLureRequestPacket)Pack;
11502
11503 #region Packet Session and User Check
11504 if (m_checkPackets)
11505 {
11506 if (teleportLureRequest.Info.SessionID != SessionId ||
11507 teleportLureRequest.Info.AgentID != AgentId)
11508 return true;
11509 }
11510 #endregion
11511
11512 TeleportLureRequest handlerTeleportLureRequest = OnTeleportLureRequest;
11513 if (handlerTeleportLureRequest != null)
11514 handlerTeleportLureRequest(
11515 teleportLureRequest.Info.LureID,
11516 teleportLureRequest.Info.TeleportFlags,
11517 this);
11518 return true;
11519 }
11520 private bool HandleClassifiedInfoRequest(IClientAPI sender, Packet Pack)
11521 {
11522 ClassifiedInfoRequestPacket classifiedInfoRequest =
11523 (ClassifiedInfoRequestPacket)Pack;
11524
11525 #region Packet Session and User Check
11526 if (m_checkPackets)
11527 {
11528 if (classifiedInfoRequest.AgentData.SessionID != SessionId ||
11529 classifiedInfoRequest.AgentData.AgentID != AgentId)
11530 return true;
11531 }
11532 #endregion
11533
11534 ClassifiedInfoRequest handlerClassifiedInfoRequest = OnClassifiedInfoRequest;
11535 if (handlerClassifiedInfoRequest != null)
11536 handlerClassifiedInfoRequest(
11537 classifiedInfoRequest.Data.ClassifiedID,
11538 this);
11539 return true;
11540 }
11541 private bool HandleClassifiedInfoUpdate(IClientAPI sender, Packet Pack)
11542 {
11543 ClassifiedInfoUpdatePacket classifiedInfoUpdate =
11544 (ClassifiedInfoUpdatePacket)Pack;
11545
11546 #region Packet Session and User Check
11547 if (m_checkPackets)
11548 {
11549 if (classifiedInfoUpdate.AgentData.SessionID != SessionId ||
11550 classifiedInfoUpdate.AgentData.AgentID != AgentId)
11551 return true;
11552 }
11553 #endregion
11554
11555 ClassifiedInfoUpdate handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate;
11556 if (handlerClassifiedInfoUpdate != null)
11557 handlerClassifiedInfoUpdate(
11558 classifiedInfoUpdate.Data.ClassifiedID,
11559 classifiedInfoUpdate.Data.Category,
11560 Utils.BytesToString(
11561 classifiedInfoUpdate.Data.Name),
11562 Utils.BytesToString(
11563 classifiedInfoUpdate.Data.Desc),
11564 classifiedInfoUpdate.Data.ParcelID,
11565 classifiedInfoUpdate.Data.ParentEstate,
11566 classifiedInfoUpdate.Data.SnapshotID,
11567 new Vector3(
11568 classifiedInfoUpdate.Data.PosGlobal),
11569 classifiedInfoUpdate.Data.ClassifiedFlags,
11570 classifiedInfoUpdate.Data.PriceForListing,
11571 this);
11572 return true;
11573 }
11574 private bool HandleClassifiedDelete(IClientAPI sender, Packet Pack)
11575 {
11576 ClassifiedDeletePacket classifiedDelete =
11577 (ClassifiedDeletePacket)Pack;
11578
11579 #region Packet Session and User Check
11580 if (m_checkPackets)
11581 {
11582 if (classifiedDelete.AgentData.SessionID != SessionId ||
11583 classifiedDelete.AgentData.AgentID != AgentId)
11584 return true;
11585 }
11586 #endregion
11587
11588 ClassifiedDelete handlerClassifiedDelete = OnClassifiedDelete;
11589 if (handlerClassifiedDelete != null)
11590 handlerClassifiedDelete(
11591 classifiedDelete.Data.ClassifiedID,
11592 this);
11593 return true;
11594 }
11595 private bool HandleClassifiedGodDelete(IClientAPI sender, Packet Pack)
11596 {
11597 ClassifiedGodDeletePacket classifiedGodDelete =
11598 (ClassifiedGodDeletePacket)Pack;
11599
11600 #region Packet Session and User Check
11601 if (m_checkPackets)
11602 {
11603 if (classifiedGodDelete.AgentData.SessionID != SessionId ||
11604 classifiedGodDelete.AgentData.AgentID != AgentId)
11605 return true;
11606 }
11607 #endregion
11608
11609 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11610 if (handlerClassifiedGodDelete != null)
11611 handlerClassifiedGodDelete(
11612 classifiedGodDelete.Data.ClassifiedID,
11613 this);
11614 return true;
11615 }
11616 private bool HandleEventGodDelete(IClientAPI sender, Packet Pack)
11617 {
11618 EventGodDeletePacket eventGodDelete =
11619 (EventGodDeletePacket)Pack;
11620
11621 #region Packet Session and User Check
11622 if (m_checkPackets)
11623 {
11624 if (eventGodDelete.AgentData.SessionID != SessionId ||
11625 eventGodDelete.AgentData.AgentID != AgentId)
11626 return true;
11627 }
11628 #endregion
11629
11630 EventGodDelete handlerEventGodDelete = OnEventGodDelete;
11631 if (handlerEventGodDelete != null)
11632 handlerEventGodDelete(
11633 eventGodDelete.EventData.EventID,
11634 eventGodDelete.QueryData.QueryID,
11635 Utils.BytesToString(
11636 eventGodDelete.QueryData.QueryText),
11637 eventGodDelete.QueryData.QueryFlags,
11638 eventGodDelete.QueryData.QueryStart,
11639 this);
11640 return true;
11641 }
11642 private bool HandleEventNotificationAddRequest(IClientAPI sender, Packet Pack)
11643 {
11644 EventNotificationAddRequestPacket eventNotificationAdd =
11645 (EventNotificationAddRequestPacket)Pack;
11646
11647 #region Packet Session and User Check
11648 if (m_checkPackets)
11649 {
11650 if (eventNotificationAdd.AgentData.SessionID != SessionId ||
11651 eventNotificationAdd.AgentData.AgentID != AgentId)
11652 return true;
11653 }
11654 #endregion
11655
11656 EventNotificationAddRequest handlerEventNotificationAddRequest = OnEventNotificationAddRequest;
11657 if (handlerEventNotificationAddRequest != null)
11658 handlerEventNotificationAddRequest(
11659 eventNotificationAdd.EventData.EventID, this);
11660 return true;
11661 }
11662 private bool HandleEventNotificationRemoveRequest(IClientAPI sender, Packet Pack)
11663 {
11664 EventNotificationRemoveRequestPacket eventNotificationRemove =
11665 (EventNotificationRemoveRequestPacket)Pack;
11666
11667 #region Packet Session and User Check
11668 if (m_checkPackets)
11669 {
11670 if (eventNotificationRemove.AgentData.SessionID != SessionId ||
11671 eventNotificationRemove.AgentData.AgentID != AgentId)
11672 return true;
11673 }
11674 #endregion
11675
11676 EventNotificationRemoveRequest handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest;
11677 if (handlerEventNotificationRemoveRequest != null)
11678 handlerEventNotificationRemoveRequest(
11679 eventNotificationRemove.EventData.EventID, this);
11680 return true;
11681 }
11682 private bool HandleRetrieveInstantMessages(IClientAPI sender, Packet Pack)
11683 {
11684 RetrieveInstantMessagesPacket rimpInstantMessagePack = (RetrieveInstantMessagesPacket)Pack;
11685
11686 #region Packet Session and User Check
11687 if (m_checkPackets)
11688 {
11689 if (rimpInstantMessagePack.AgentData.SessionID != SessionId ||
11690 rimpInstantMessagePack.AgentData.AgentID != AgentId)
11691 return true;
11692 }
11693 #endregion
11694
11695 RetrieveInstantMessages handlerRetrieveInstantMessages = OnRetrieveInstantMessages;
11696 if (handlerRetrieveInstantMessages != null)
11697 handlerRetrieveInstantMessages(this);
11698 return true;
11699 }
11700 private bool HandlePickDelete(IClientAPI sender, Packet Pack)
11701 {
11702 PickDeletePacket pickDelete =
11703 (PickDeletePacket)Pack;
11704
11705 #region Packet Session and User Check
11706 if (m_checkPackets)
11707 {
11708 if (pickDelete.AgentData.SessionID != SessionId ||
11709 pickDelete.AgentData.AgentID != AgentId)
11710 return true;
11711 }
11712 #endregion
11713
11714 PickDelete handlerPickDelete = OnPickDelete;
11715 if (handlerPickDelete != null)
11716 handlerPickDelete(this, pickDelete.Data.PickID);
11717 return true;
11718 }
11719 private bool HandlePickGodDelete(IClientAPI sender, Packet Pack)
11720 {
11721 PickGodDeletePacket pickGodDelete =
11722 (PickGodDeletePacket)Pack;
11723
11724 #region Packet Session and User Check
11725 if (m_checkPackets)
11726 {
11727 if (pickGodDelete.AgentData.SessionID != SessionId ||
11728 pickGodDelete.AgentData.AgentID != AgentId)
11729 return true;
11730 }
11731 #endregion
11732
11733 PickGodDelete handlerPickGodDelete = OnPickGodDelete;
11734 if (handlerPickGodDelete != null)
11735 handlerPickGodDelete(this,
11736 pickGodDelete.AgentData.AgentID,
11737 pickGodDelete.Data.PickID,
11738 pickGodDelete.Data.QueryID);
11739 return true;
11740 }
11741 private bool HandlePickInfoUpdate(IClientAPI sender, Packet Pack)
11742 {
11743 PickInfoUpdatePacket pickInfoUpdate =
11744 (PickInfoUpdatePacket)Pack;
11745
11746 #region Packet Session and User Check
11747 if (m_checkPackets)
11748 {
11749 if (pickInfoUpdate.AgentData.SessionID != SessionId ||
11750 pickInfoUpdate.AgentData.AgentID != AgentId)
11751 return true;
11752 }
11753 #endregion
11754
11755 PickInfoUpdate handlerPickInfoUpdate = OnPickInfoUpdate;
11756 if (handlerPickInfoUpdate != null)
11757 handlerPickInfoUpdate(this,
11758 pickInfoUpdate.Data.PickID,
11759 pickInfoUpdate.Data.CreatorID,
11760 pickInfoUpdate.Data.TopPick,
11761 Utils.BytesToString(pickInfoUpdate.Data.Name),
11762 Utils.BytesToString(pickInfoUpdate.Data.Desc),
11763 pickInfoUpdate.Data.SnapshotID,
11764 pickInfoUpdate.Data.SortOrder,
11765 pickInfoUpdate.Data.Enabled);
11766 return true;
11767 }
11768 private bool HandleAvatarNotesUpdate(IClientAPI sender, Packet Pack)
11769 {
11770 AvatarNotesUpdatePacket avatarNotesUpdate =
11771 (AvatarNotesUpdatePacket)Pack;
11772
11773 #region Packet Session and User Check
11774 if (m_checkPackets)
11775 {
11776 if (avatarNotesUpdate.AgentData.SessionID != SessionId ||
11777 avatarNotesUpdate.AgentData.AgentID != AgentId)
11778 return true;
11779 }
11780 #endregion
11781
11782 AvatarNotesUpdate handlerAvatarNotesUpdate = OnAvatarNotesUpdate;
11783 if (handlerAvatarNotesUpdate != null)
11784 handlerAvatarNotesUpdate(this,
11785 avatarNotesUpdate.Data.TargetID,
11786 Utils.BytesToString(avatarNotesUpdate.Data.Notes));
11787 return true;
11788 }
11789 private bool HandleAvatarInterestsUpdate(IClientAPI sender, Packet Pack)
11790 {
11791 AvatarInterestsUpdatePacket avatarInterestUpdate =
11792 (AvatarInterestsUpdatePacket)Pack;
11793
11794 #region Packet Session and User Check
11795 if (m_checkPackets)
11796 {
11797 if (avatarInterestUpdate.AgentData.SessionID != SessionId ||
11798 avatarInterestUpdate.AgentData.AgentID != AgentId)
11799 return true;
11800 }
11801 #endregion
11802
11803 AvatarInterestUpdate handlerAvatarInterestUpdate = OnAvatarInterestUpdate;
11804 if (handlerAvatarInterestUpdate != null)
11805 handlerAvatarInterestUpdate(this,
11806 avatarInterestUpdate.PropertiesData.WantToMask,
11807 Utils.BytesToString(avatarInterestUpdate.PropertiesData.WantToText),
11808 avatarInterestUpdate.PropertiesData.SkillsMask,
11809 Utils.BytesToString(avatarInterestUpdate.PropertiesData.SkillsText),
11810 Utils.BytesToString(avatarInterestUpdate.PropertiesData.LanguagesText));
11811 return true;
11812 }
11813
11814 private bool HandleGrantUserRights(IClientAPI sender, Packet Pack)
11815 {
11816 GrantUserRightsPacket GrantUserRights =
11817 (GrantUserRightsPacket)Pack;
11818 #region Packet Session and User Check
11819 if (m_checkPackets)
11820 {
11821 if (GrantUserRights.AgentData.SessionID != SessionId ||
11822 GrantUserRights.AgentData.AgentID != AgentId)
11823 return true;
11824 }
11825 #endregion
11826
11827 GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
11828 if (GrantUserRightsHandler != null)
11829 GrantUserRightsHandler(this,
11830 GrantUserRights.Rights[0].AgentRelated,
11831 GrantUserRights.Rights[0].RelatedRights);
11832
11833 return true;
11834 }
11835
11836 private bool HandlePlacesQuery(IClientAPI sender, Packet Pack)
11837 {
11838 PlacesQueryPacket placesQueryPacket =
11839 (PlacesQueryPacket)Pack;
11840
11841 PlacesQuery handlerPlacesQuery = OnPlacesQuery;
11842
11843 if (handlerPlacesQuery != null)
11844 handlerPlacesQuery(placesQueryPacket.AgentData.QueryID,
11845 placesQueryPacket.TransactionData.TransactionID,
11846 Utils.BytesToString(
11847 placesQueryPacket.QueryData.QueryText),
11848 placesQueryPacket.QueryData.QueryFlags,
11849 (byte)placesQueryPacket.QueryData.Category,
11850 Utils.BytesToString(
11851 placesQueryPacket.QueryData.SimName),
11852 this);
11853 return true;
11854 }
11855
11856 #endregion Packet Handlers
11857
11858 public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question)
11859 {
11860 ScriptQuestionPacket scriptQuestion = (ScriptQuestionPacket)PacketPool.Instance.GetPacket(PacketType.ScriptQuestion);
11861 scriptQuestion.Data = new ScriptQuestionPacket.DataBlock();
11862 // TODO: don't create new blocks if recycling an old packet
11863 scriptQuestion.Data.TaskID = taskID;
11864 scriptQuestion.Data.ItemID = itemID;
11865 scriptQuestion.Data.Questions = question;
11866 scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
11867 scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
11868
11869 OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
11870 }
11871
11872 /// <summary>
11873 /// Handler called when we receive a logout packet.
11874 /// </summary>
11875 /// <param name="client"></param>
11876 /// <param name="packet"></param>
11877 /// <returns></returns>
11878 protected virtual bool HandleLogout(IClientAPI client, Packet packet)
11879 {
11880 if (packet.Type == PacketType.LogoutRequest)
11881 {
11882 if (((LogoutRequestPacket)packet).AgentData.SessionID != SessionId) return false;
11883 }
11884
11885 return Logout(client);
11886 }
11887
11888 /// <summary>
11889 ///
11890 /// </summary>
11891 /// <param name="client"></param>
11892 /// <returns></returns>
11893 protected virtual bool Logout(IClientAPI client)
11894 {
11895 m_log.InfoFormat("[CLIENT]: Got a logout request for {0} in {1}", Name, Scene.RegionInfo.RegionName);
11896
11897 Action<IClientAPI> handlerLogout = OnLogout;
11898
11899 if (handlerLogout != null)
11900 {
11901 handlerLogout(client);
11902 }
11903
11904 return true;
11905 }
11906
11907 /// <summary>
11908 /// </summary>
11909 /// <remarks>
11910 /// At the moment, we always reply that there is no cached texture.
11911 /// </remarks>
11912 /// <param name="simclient"></param>
11913 /// <param name="packet"></param>
11914 /// <returns></returns>
11915 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11916 {
11917 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11918 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
11919
11920 if (cachedtex.AgentData.SessionID != SessionId)
11921 return false;
11922
11923
11924 // TODO: don't create new blocks if recycling an old packet
11925 cachedresp.AgentData.AgentID = AgentId;
11926 cachedresp.AgentData.SessionID = m_sessionId;
11927 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
11928 m_cachedTextureSerial++;
11929 cachedresp.WearableData =
11930 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11931
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)
11944 {
11945 ScenePresence p = m_scene.GetScenePresence(AgentId);
11946 if (p.Appearance != null)
11947 {
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 }
11967 }
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
12014 cachedresp.Header.Zerocoded = true;
12015 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12016
12017 return true;
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 }
12053
12054 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
12055 {
12056 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
12057
12058 if (multipleupdate.AgentData.SessionID != SessionId)
12059 return false;
12060
12061// m_log.DebugFormat(
12062// "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length);
12063
12064 Scene tScene = (Scene)m_scene;
12065
12066 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
12067 {
12068 MultipleObjectUpdatePacket.ObjectDataBlock block = multipleupdate.ObjectData[i];
12069
12070 // Can't act on Null Data
12071 if (block.Data != null)
12072 {
12073 uint localId = block.ObjectLocalID;
12074 SceneObjectPart part = tScene.GetSceneObjectPart(localId);
12075
12076 if (part == null)
12077 {
12078 // It's a ghost! tell the client to delete it from view.
12079 simClient.SendKillObject(new List<uint> { localId });
12080 }
12081 else
12082 {
12083// m_log.DebugFormat(
12084// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
12085// i, block.Type, part.Name, part.LocalId);
12086
12087// // Do this once since fetch parts creates a new array.
12088// SceneObjectPart[] parts = part.ParentGroup.Parts;
12089// for (int j = 0; j < parts.Length; j++)
12090// {
12091// part.StoreUndoState();
12092// parts[j].IgnoreUndoUpdate = true;
12093// }
12094
12095 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation;
12096
12097 switch (block.Type)
12098 {
12099 case 1:
12100 Vector3 pos1 = new Vector3(block.Data, 0);
12101
12102 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
12103 if (handlerUpdatePrimSinglePosition != null)
12104 {
12105 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
12106 handlerUpdatePrimSinglePosition(localId, pos1, this);
12107 }
12108 break;
12109
12110 case 2:
12111 Quaternion rot1 = new Quaternion(block.Data, 0, true);
12112
12113 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation;
12114 if (handlerUpdatePrimSingleRotation != null)
12115 {
12116 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
12117 handlerUpdatePrimSingleRotation(localId, rot1, this);
12118 }
12119 break;
12120
12121 case 3:
12122 Vector3 rotPos = new Vector3(block.Data, 0);
12123 Quaternion rot2 = new Quaternion(block.Data, 12, true);
12124
12125 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition;
12126 if (handlerUpdatePrimSingleRotationPosition != null)
12127 {
12128 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
12129 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
12130 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
12131 }
12132 break;
12133
12134 case 4:
12135 case 20:
12136 Vector3 scale4 = new Vector3(block.Data, 0);
12137
12138 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale;
12139 if (handlerUpdatePrimScale != null)
12140 {
12141 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
12142 handlerUpdatePrimScale(localId, scale4, this);
12143 }
12144 break;
12145
12146 case 5:
12147 Vector3 scale1 = new Vector3(block.Data, 12);
12148 Vector3 pos11 = new Vector3(block.Data, 0);
12149
12150 handlerUpdatePrimScale = OnUpdatePrimScale;
12151 if (handlerUpdatePrimScale != null)
12152 {
12153 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
12154 handlerUpdatePrimScale(localId, scale1, this);
12155
12156 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
12157 if (handlerUpdatePrimSinglePosition != null)
12158 {
12159 handlerUpdatePrimSinglePosition(localId, pos11, this);
12160 }
12161 }
12162 break;
12163
12164 case 9:
12165 Vector3 pos2 = new Vector3(block.Data, 0);
12166
12167 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition;
12168
12169 if (handlerUpdateVector != null)
12170 {
12171 handlerUpdateVector(localId, pos2, this);
12172 }
12173 break;
12174
12175 case 10:
12176 Quaternion rot3 = new Quaternion(block.Data, 0, true);
12177
12178 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation;
12179 if (handlerUpdatePrimRotation != null)
12180 {
12181 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
12182 handlerUpdatePrimRotation(localId, rot3, this);
12183 }
12184 break;
12185
12186 case 11:
12187 Vector3 pos3 = new Vector3(block.Data, 0);
12188 Quaternion rot4 = new Quaternion(block.Data, 12, true);
12189
12190 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation;
12191 if (handlerUpdatePrimGroupRotation != null)
12192 {
12193 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
12194 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
12195 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
12196 }
12197 break;
12198 case 12:
12199 case 28:
12200 Vector3 scale7 = new Vector3(block.Data, 0);
12201
12202 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale;
12203 if (handlerUpdatePrimGroupScale != null)
12204 {
12205 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
12206 handlerUpdatePrimGroupScale(localId, scale7, this);
12207 }
12208 break;
12209
12210 case 13:
12211 Vector3 scale2 = new Vector3(block.Data, 12);
12212 Vector3 pos4 = new Vector3(block.Data, 0);
12213
12214 handlerUpdatePrimScale = OnUpdatePrimScale;
12215 if (handlerUpdatePrimScale != null)
12216 {
12217 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
12218 handlerUpdatePrimScale(localId, scale2, this);
12219
12220 // Change the position based on scale (for bug number 246)
12221 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
12222 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
12223 if (handlerUpdatePrimSinglePosition != null)
12224 {
12225 handlerUpdatePrimSinglePosition(localId, pos4, this);
12226 }
12227 }
12228 break;
12229
12230 case 29:
12231 Vector3 scale5 = new Vector3(block.Data, 12);
12232 Vector3 pos5 = new Vector3(block.Data, 0);
12233
12234 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale;
12235 if (handlerUpdatePrimGroupScale != null)
12236 {
12237 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
12238 part.StoreUndoState(true);
12239 part.IgnoreUndoUpdate = true;
12240 handlerUpdatePrimGroupScale(localId, scale5, this);
12241 handlerUpdateVector = OnUpdatePrimGroupPosition;
12242
12243 if (handlerUpdateVector != null)
12244 {
12245 handlerUpdateVector(localId, pos5, this);
12246 }
12247
12248 part.IgnoreUndoUpdate = false;
12249 }
12250
12251 break;
12252
12253 case 21:
12254 Vector3 scale6 = new Vector3(block.Data, 12);
12255 Vector3 pos6 = new Vector3(block.Data, 0);
12256
12257 handlerUpdatePrimScale = OnUpdatePrimScale;
12258 if (handlerUpdatePrimScale != null)
12259 {
12260 part.StoreUndoState(false);
12261 part.IgnoreUndoUpdate = true;
12262
12263 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
12264 handlerUpdatePrimScale(localId, scale6, this);
12265 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
12266 if (handlerUpdatePrimSinglePosition != null)
12267 {
12268 handlerUpdatePrimSinglePosition(localId, pos6, this);
12269 }
12270
12271 part.IgnoreUndoUpdate = false;
12272 }
12273 break;
12274
12275 default:
12276 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12277 break;
12278 }
12279
12280// for (int j = 0; j < parts.Length; j++)
12281// parts[j].IgnoreUndoUpdate = false;
12282 }
12283 }
12284 }
12285
12286 return true;
12287 }
12288
12289 public void RequestMapLayer()
12290 {
12291 //should be getting the map layer from the grid server
12292 //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
12293 MapLayerReplyPacket mapReply = (MapLayerReplyPacket)PacketPool.Instance.GetPacket(PacketType.MapLayerReply);
12294 // TODO: don't create new blocks if recycling an old packet
12295 mapReply.AgentData.AgentID = AgentId;
12296 mapReply.AgentData.Flags = 0;
12297 mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
12298 mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
12299 mapReply.LayerData[0].Bottom = 0;
12300 mapReply.LayerData[0].Left = 0;
12301 mapReply.LayerData[0].Top = 30000;
12302 mapReply.LayerData[0].Right = 30000;
12303 mapReply.LayerData[0].ImageID = new UUID("00000000-0000-1111-9999-000000000006");
12304 mapReply.Header.Zerocoded = true;
12305 OutPacket(mapReply, ThrottleOutPacketType.Land);
12306 }
12307
12308 public void RequestMapBlocksX(int minX, int minY, int maxX, int maxY)
12309 {
12310 /*
12311 IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY);
12312 MapBlockReplyPacket mbReply = new MapBlockReplyPacket();
12313 mbReply.AgentData.AgentId = AgentId;
12314 int len;
12315 if (simMapProfiles == null)
12316 len = 0;
12317 else
12318 len = simMapProfiles.Count;
12319
12320 mbReply.Data = new MapBlockReplyPacket.DataBlock[len];
12321 int iii;
12322 for (iii = 0; iii < len; iii++)
12323 {
12324 Hashtable mp = (Hashtable)simMapProfiles[iii];
12325 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
12326 mbReply.Data[iii].Name = Util.UTF8.GetBytes((string)mp["name"]);
12327 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
12328 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
12329 mbReply.Data[iii].MapImageID = new UUID((string)mp["map-image-id"]);
12330 mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]);
12331 mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]);
12332 mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]);
12333 mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]);
12334 }
12335 this.OutPacket(mbReply, ThrottleOutPacketType.Land);
12336 */
12337 }
12338
12339 /// <summary>
12340 /// Sets the throttles from values supplied by the client
12341 /// </summary>
12342 /// <param name="throttles"></param>
12343 public void SetChildAgentThrottle(byte[] throttles)
12344 {
12345 m_udpClient.SetThrottles(throttles);
12346 }
12347
12348 /// <summary>
12349 /// Get the current throttles for this client as a packed byte array
12350 /// </summary>
12351 /// <param name="multiplier">Unused</param>
12352 /// <returns></returns>
12353 public byte[] GetThrottlesPacked(float multiplier)
12354 {
12355 return m_udpClient.GetThrottlesPacked(multiplier);
12356 }
12357
12358 /// <summary>
12359 /// Cruft?
12360 /// </summary>
12361 public virtual void InPacket(object NewPack)
12362 {
12363 throw new NotImplementedException();
12364 }
12365
12366 /// <summary>
12367 /// This is the starting point for sending a simulator packet out to the client
12368 /// </summary>
12369 /// <param name="packet">Packet to send</param>
12370 /// <param name="throttlePacketType">Throttling category for the packet</param>
12371 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType)
12372 {
12373 #region BinaryStats
12374 LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length);
12375 #endregion BinaryStats
12376
12377 OutPacket(packet, throttlePacketType, true);
12378 }
12379
12380 /// <summary>
12381 /// This is the starting point for sending a simulator packet out to the client
12382 /// </summary>
12383 /// <param name="packet">Packet to send</param>
12384 /// <param name="throttlePacketType">Throttling category for the packet</param>
12385 /// <param name="doAutomaticSplitting">True to automatically split oversized
12386 /// packets (the default), or false to disable splitting if the calling code
12387 /// handles splitting manually</param>
12388 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
12389 {
12390 OutPacket(packet, throttlePacketType, doAutomaticSplitting, null);
12391 }
12392
12393 /// <summary>
12394 /// This is the starting point for sending a simulator packet out to the client
12395 /// </summary>
12396 /// <param name="packet">Packet to send</param>
12397 /// <param name="throttlePacketType">Throttling category for the packet</param>
12398 /// <param name="doAutomaticSplitting">True to automatically split oversized
12399 /// packets (the default), or false to disable splitting if the calling code
12400 /// handles splitting manually</param>
12401 /// <param name="method">The method to be called in the event this packet is reliable
12402 /// and unacknowledged. The server will provide normal resend capability if you do not
12403 /// provide your own method.</param>
12404 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
12405 {
12406 if (m_outPacketsToDrop != null)
12407 if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
12408 return;
12409
12410 if (DebugPacketLevel > 0)
12411 {
12412 bool logPacket = true;
12413
12414 if (DebugPacketLevel <= 255
12415 && (packet.Type == PacketType.SimStats || packet.Type == PacketType.SimulatorViewerTimeMessage))
12416 logPacket = false;
12417
12418 if (DebugPacketLevel <= 200
12419 && (packet.Type == PacketType.ImagePacket
12420 || packet.Type == PacketType.ImageData
12421 || packet.Type == PacketType.LayerData
12422 || packet.Type == PacketType.CoarseLocationUpdate))
12423 logPacket = false;
12424
12425 if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
12426 logPacket = false;
12427
12428 if (DebugPacketLevel <= 50
12429 && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
12430 logPacket = false;
12431
12432 if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
12433 logPacket = false;
12434
12435 if (logPacket)
12436 m_log.DebugFormat(
12437 "[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}",
12438 Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
12439 }
12440
12441 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
12442 }
12443
12444 protected void HandleAutopilot(Object sender, string method, List<String> args)
12445 {
12446 float locx = 0;
12447 float locy = 0;
12448 float locz = 0;
12449 uint regionX = 0;
12450 uint regionY = 0;
12451
12452 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY);
12453 locx = Convert.ToSingle(args[0]) - (float)regionX;
12454 locy = Convert.ToSingle(args[1]) - (float)regionY;
12455 locz = Convert.ToSingle(args[2]);
12456
12457 Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo;
12458 if (handlerAutoPilotGo != null)
12459 handlerAutoPilotGo(new Vector3(locx, locy, locz), false, false);
12460 }
12461
12462 /// <summary>
12463 /// Entryway from the client to the simulator. All UDP packets from the client will end up here
12464 /// </summary>
12465 /// <param name="Pack">OpenMetaverse.packet</param>
12466 public void ProcessInPacket(Packet packet)
12467 {
12468 if (m_inPacketsToDrop != null)
12469 if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
12470 return;
12471
12472 if (DebugPacketLevel > 0)
12473 {
12474 bool logPacket = true;
12475
12476 if (DebugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
12477 logPacket = false;
12478
12479 if (DebugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
12480 logPacket = false;
12481
12482 if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
12483 logPacket = false;
12484
12485 if (DebugPacketLevel <= 25 && packet.Type == PacketType.RequestObjectPropertiesFamily)
12486 logPacket = false;
12487
12488 if (logPacket)
12489 m_log.DebugFormat(
12490 "[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}",
12491 Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name, packet.Type);
12492 }
12493
12494 if (!ProcessPacketMethod(packet))
12495 m_log.WarnFormat(
12496 "[CLIENT]: Unhandled packet {0} from {1} ({2}) in {3}. Ignoring.",
12497 packet.Type, Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name);
12498 }
12499
12500 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
12501 {
12502 PrimitiveBaseShape shape = new PrimitiveBaseShape();
12503
12504 shape.PCode = addPacket.ObjectData.PCode;
12505 shape.State = addPacket.ObjectData.State;
12506 shape.LastAttachPoint = addPacket.ObjectData.State;
12507 shape.PathBegin = addPacket.ObjectData.PathBegin;
12508 shape.PathEnd = addPacket.ObjectData.PathEnd;
12509 shape.PathScaleX = addPacket.ObjectData.PathScaleX;
12510 shape.PathScaleY = addPacket.ObjectData.PathScaleY;
12511 shape.PathShearX = addPacket.ObjectData.PathShearX;
12512 shape.PathShearY = addPacket.ObjectData.PathShearY;
12513 shape.PathSkew = addPacket.ObjectData.PathSkew;
12514 shape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
12515 shape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
12516 shape.Scale = addPacket.ObjectData.Scale;
12517 shape.PathCurve = addPacket.ObjectData.PathCurve;
12518 shape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
12519 shape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
12520 shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
12521 shape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
12522 shape.PathTaperX = addPacket.ObjectData.PathTaperX;
12523 shape.PathTaperY = addPacket.ObjectData.PathTaperY;
12524 shape.PathTwist = addPacket.ObjectData.PathTwist;
12525 shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
12526 Primitive.TextureEntry ntex = new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f"));
12527 shape.TextureEntry = ntex.GetBytes();
12528 //shape.Textures = ntex;
12529 return shape;
12530 }
12531
12532 public ClientInfo GetClientInfo()
12533 {
12534 ClientInfo info = m_udpClient.GetClientInfo();
12535
12536 info.proxyEP = null;
12537 if (info.agentcircuit == null)
12538 info.agentcircuit = RequestClientInfo();
12539
12540 return info;
12541 }
12542
12543 public void SetClientInfo(ClientInfo info)
12544 {
12545 m_udpClient.SetClientInfo(info);
12546 }
12547
12548 #region Media Parcel Members
12549
12550 public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
12551 {
12552 ParcelMediaCommandMessagePacket commandMessagePacket = new ParcelMediaCommandMessagePacket();
12553 commandMessagePacket.CommandBlock.Flags = flags;
12554 commandMessagePacket.CommandBlock.Command = (uint)command;
12555 commandMessagePacket.CommandBlock.Time = time;
12556
12557 OutPacket(commandMessagePacket, ThrottleOutPacketType.Task);
12558 }
12559
12560 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID,
12561 byte autoScale, string mediaType, string mediaDesc, int mediaWidth, int mediaHeight,
12562 byte mediaLoop)
12563 {
12564 ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket();
12565 updatePacket.DataBlock.MediaURL = Util.StringToBytes256(mediaUrl);
12566 updatePacket.DataBlock.MediaID = mediaTextureID;
12567 updatePacket.DataBlock.MediaAutoScale = autoScale;
12568
12569 updatePacket.DataBlockExtended.MediaType = Util.StringToBytes256(mediaType);
12570 updatePacket.DataBlockExtended.MediaDesc = Util.StringToBytes256(mediaDesc);
12571 updatePacket.DataBlockExtended.MediaWidth = mediaWidth;
12572 updatePacket.DataBlockExtended.MediaHeight = mediaHeight;
12573 updatePacket.DataBlockExtended.MediaLoop = mediaLoop;
12574
12575 OutPacket(updatePacket, ThrottleOutPacketType.Task);
12576 }
12577
12578 #endregion
12579
12580 #region Camera
12581
12582 public void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters)
12583 {
12584 SetFollowCamPropertiesPacket packet = (SetFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.SetFollowCamProperties);
12585 packet.ObjectData.ObjectID = objectID;
12586 SetFollowCamPropertiesPacket.CameraPropertyBlock[] camPropBlock = new SetFollowCamPropertiesPacket.CameraPropertyBlock[parameters.Count];
12587 uint idx = 0;
12588 foreach (KeyValuePair<int, float> pair in parameters)
12589 {
12590 SetFollowCamPropertiesPacket.CameraPropertyBlock block = new SetFollowCamPropertiesPacket.CameraPropertyBlock();
12591 block.Type = pair.Key;
12592 block.Value = pair.Value;
12593
12594 camPropBlock[idx++] = block;
12595 }
12596 packet.CameraProperty = camPropBlock;
12597 OutPacket(packet, ThrottleOutPacketType.Task);
12598 }
12599
12600 public void SendClearFollowCamProperties(UUID objectID)
12601 {
12602 ClearFollowCamPropertiesPacket packet = (ClearFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ClearFollowCamProperties);
12603 packet.ObjectData.ObjectID = objectID;
12604 OutPacket(packet, ThrottleOutPacketType.Task);
12605 }
12606
12607 #endregion
12608
12609 public void SetClientOption(string option, string value)
12610 {
12611 switch (option)
12612 {
12613 default:
12614 break;
12615 }
12616 }
12617
12618 public string GetClientOption(string option)
12619 {
12620 switch (option)
12621 {
12622 default:
12623 break;
12624 }
12625 return string.Empty;
12626 }
12627
12628 #region IClientCore
12629
12630 private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
12631
12632 /// <summary>
12633 /// Register an interface on this client, should only be called in the constructor.
12634 /// </summary>
12635 /// <typeparam name="T"></typeparam>
12636 /// <param name="iface"></param>
12637 protected void RegisterInterface<T>(T iface)
12638 {
12639 lock (m_clientInterfaces)
12640 {
12641 if (!m_clientInterfaces.ContainsKey(typeof(T)))
12642 {
12643 m_clientInterfaces.Add(typeof(T), iface);
12644 }
12645 }
12646 }
12647
12648 public bool TryGet<T>(out T iface)
12649 {
12650 if (m_clientInterfaces.ContainsKey(typeof(T)))
12651 {
12652 iface = (T)m_clientInterfaces[typeof(T)];
12653 return true;
12654 }
12655 iface = default(T);
12656 return false;
12657 }
12658
12659 public T Get<T>()
12660 {
12661 return (T)m_clientInterfaces[typeof(T)];
12662 }
12663
12664 public void Disconnect(string reason)
12665 {
12666 Kick(reason);
12667 Thread.Sleep(1000);
12668 Disconnect();
12669 }
12670
12671 public void Disconnect()
12672 {
12673 Close();
12674 }
12675
12676 #endregion
12677
12678 public void RefreshGroupMembership()
12679 {
12680 if (m_GroupsModule != null)
12681 {
12682 GroupMembershipData[] GroupMembership =
12683 m_GroupsModule.GetMembershipData(AgentId);
12684
12685 m_groupPowers.Clear();
12686
12687 if (GroupMembership != null)
12688 {
12689 for (int i = 0; i < GroupMembership.Length; i++)
12690 {
12691 m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers;
12692 }
12693 }
12694 }
12695 }
12696
12697 public string Report()
12698 {
12699 return m_udpClient.GetStats();
12700 }
12701
12702 public string XReport(string uptime, string version)
12703 {
12704 return String.Empty;
12705 }
12706
12707 public OSDMap OReport(string uptime, string version)
12708 {
12709 return new OSDMap();
12710 }
12711
12712 /// <summary>
12713 /// Make an asset request to the asset service in response to a client request.
12714 /// </summary>
12715 /// <param name="transferRequest"></param>
12716 /// <param name="taskID"></param>
12717 protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
12718 {
12719 UUID requestID = UUID.Zero;
12720 int sourceType = transferRequest.TransferInfo.SourceType;
12721
12722 if (sourceType == (int)SourceType.Asset)
12723 {
12724 requestID = new UUID(transferRequest.TransferInfo.Params, 0);
12725 }
12726 else if (sourceType == (int)SourceType.SimInventoryItem)
12727 {
12728 requestID = new UUID(transferRequest.TransferInfo.Params, 80);
12729 }
12730 else if (sourceType == (int)SourceType.SimEstate)
12731 {
12732 requestID = taskID;
12733 }
12734
12735// m_log.DebugFormat(
12736// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12737// requestID, taskID, (SourceType)sourceType, Name);
12738
12739 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12740 }
12741
12742 /// <summary>
12743 /// When we get a reply back from the asset service in response to a client request, send back the data.
12744 /// </summary>
12745 /// <param name="id"></param>
12746 /// <param name="sender"></param>
12747 /// <param name="asset"></param>
12748 protected void AssetReceived(string id, Object sender, AssetBase asset)
12749 {
12750 TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
12751
12752 UUID requestID = UUID.Zero;
12753 byte source = (byte)SourceType.Asset;
12754
12755 AssetRequestToClient req = new AssetRequestToClient();
12756
12757 if (asset == null)
12758 {
12759 // Try the user's asset server
12760 IInventoryAccessModule inventoryAccessModule = Scene.RequestModuleInterface<IInventoryAccessModule>();
12761
12762 string assetServerURL = string.Empty;
12763 if (inventoryAccessModule.IsForeignUser(AgentId, out assetServerURL) && !string.IsNullOrEmpty(assetServerURL))
12764 {
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 }
12785
12786 }
12787
12788 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
12789 {
12790 requestID = new UUID(transferRequest.TransferInfo.Params, 0);
12791 }
12792 else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
12793 {
12794 requestID = new UUID(transferRequest.TransferInfo.Params, 80);
12795 source = (byte)SourceType.SimInventoryItem;
12796 //m_log.Debug("asset request " + requestID);
12797 }
12798
12799 // Scripts cannot be retrieved by direct request
12800 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset && asset.Type == 10)
12801 return;
12802
12803 // The asset is known to exist and is in our cache, so add it to the AssetRequests list
12804 req.AssetInf = asset;
12805 req.AssetRequestSource = source;
12806 req.IsTextureRequest = false;
12807 req.NumPackets = CalculateNumPackets(asset.Data);
12808 req.Params = transferRequest.TransferInfo.Params;
12809 req.RequestAssetID = requestID;
12810 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
12811
12812 SendAsset(req);
12813 }
12814
12815 /// <summary>
12816 /// Calculate the number of packets required to send the asset to the client.
12817 /// </summary>
12818 /// <param name="data"></param>
12819 /// <returns></returns>
12820 private static int CalculateNumPackets(byte[] data)
12821 {
12822 const uint m_maxPacketSize = 600;
12823 int numPackets = 1;
12824
12825 if (data == null)
12826 return 0;
12827
12828 if (data.LongLength > m_maxPacketSize)
12829 {
12830 // over max number of bytes so split up file
12831 long restData = data.LongLength - m_maxPacketSize;
12832 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
12833 numPackets += restPackets;
12834 }
12835
12836 return numPackets;
12837 }
12838
12839 public void SendRebakeAvatarTextures(UUID textureID)
12840 {
12841 RebakeAvatarTexturesPacket pack =
12842 (RebakeAvatarTexturesPacket)PacketPool.Instance.GetPacket(PacketType.RebakeAvatarTextures);
12843
12844 pack.TextureData = new RebakeAvatarTexturesPacket.TextureDataBlock();
12845 pack.TextureData.TextureID = textureID;
12846 OutPacket(pack, ThrottleOutPacketType.Task);
12847 }
12848
12849 public struct PacketProcessor
12850 {
12851 /// <summary>
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; }
12866 }
12867
12868 public class AsyncPacketProcess
12869 {
12870 public bool result = false;
12871 public readonly LLClientView ClientView = null;
12872 public readonly Packet Pack = null;
12873 public readonly PacketMethod Method = null;
12874 public AsyncPacketProcess(LLClientView pClientview, PacketMethod pMethod, Packet pPack)
12875 {
12876 ClientView = pClientview;
12877 Method = pMethod;
12878 Pack = pPack;
12879 }
12880 }
12881
12882 public static OSD BuildEvent(string eventName, OSD eventBody)
12883 {
12884 OSDMap osdEvent = new OSDMap(2);
12885 osdEvent.Add("message", new OSDString(eventName));
12886 osdEvent.Add("body", eventBody);
12887
12888 return osdEvent;
12889 }
12890
12891 public void SendAvatarInterestsReply(UUID avatarID, uint wantMask, string wantText, uint skillsMask, string skillsText, string languages)
12892 {
12893 AvatarInterestsReplyPacket packet = (AvatarInterestsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarInterestsReply);
12894
12895 packet.AgentData = new AvatarInterestsReplyPacket.AgentDataBlock();
12896 packet.AgentData.AgentID = AgentId;
12897 packet.AgentData.AvatarID = avatarID;
12898
12899 packet.PropertiesData = new AvatarInterestsReplyPacket.PropertiesDataBlock();
12900 packet.PropertiesData.WantToMask = wantMask;
12901 packet.PropertiesData.WantToText = Utils.StringToBytes(wantText);
12902 packet.PropertiesData.SkillsMask = skillsMask;
12903 packet.PropertiesData.SkillsText = Utils.StringToBytes(skillsText);
12904 packet.PropertiesData.LanguagesText = Utils.StringToBytes(languages);
12905 OutPacket(packet, ThrottleOutPacketType.Task);
12906 }
12907
12908 public void SendChangeUserRights(UUID agentID, UUID friendID, int rights)
12909 {
12910 ChangeUserRightsPacket packet = (ChangeUserRightsPacket)PacketPool.Instance.GetPacket(PacketType.ChangeUserRights);
12911
12912 packet.AgentData = new ChangeUserRightsPacket.AgentDataBlock();
12913 packet.AgentData.AgentID = agentID;
12914
12915 packet.Rights = new ChangeUserRightsPacket.RightsBlock[1];
12916 packet.Rights[0] = new ChangeUserRightsPacket.RightsBlock();
12917 packet.Rights[0].AgentRelated = friendID;
12918 packet.Rights[0].RelatedRights = rights;
12919
12920 OutPacket(packet, ThrottleOutPacketType.Task);
12921 }
12922
12923 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
12924 {
12925 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
12926 dialog.Data.ObjectID = objectId;
12927 dialog.Data.ChatChannel = chatChannel;
12928 dialog.Data.ImageID = UUID.Zero;
12929 dialog.Data.ObjectName = Util.StringToBytes256(objectname);
12930 // this is the username of the *owner*
12931 dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName);
12932 dialog.Data.LastName = Util.StringToBytes256(ownerLastName);
12933 dialog.Data.Message = Util.StringToBytes256(message);
12934
12935 ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[1];
12936 buttons[0] = new ScriptDialogPacket.ButtonsBlock();
12937 buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!");
12938 dialog.Buttons = buttons;
12939
12940 dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
12941 dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
12942 dialog.OwnerData[0].OwnerID = ownerID;
12943
12944 OutPacket(dialog, ThrottleOutPacketType.Task);
12945 }
12946
12947 public void SendAgentTerseUpdate(ISceneEntity p)
12948 {
12949 if (p is ScenePresence)
12950 {
12951// m_log.DebugFormat(
12952// "[LLCLIENTVIEW]: Immediately sending terse agent update for {0} to {1} in {2}",
12953// p.Name, Name, Scene.Name);
12954
12955 // It turns out to get the agent to stop flying, you have to feed it stop flying velocities
12956 // There's no explicit message to send the client to tell it to stop flying.. it relies on the
12957 // velocity, collision plane and avatar height
12958
12959 // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air
12960 // when the avatar stands up
12961
12962 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
12963 CreateImprovedTerseBlock(p, false);
12964
12965 const float TIME_DILATION = 1.0f;
12966 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
12967
12968 ImprovedTerseObjectUpdatePacket packet
12969 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
12970 PacketType.ImprovedTerseObjectUpdate);
12971
12972 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
12973 packet.RegionData.TimeDilation = timeDilation;
12974 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
12975
12976 packet.ObjectData[0] = block;
12977
12978 OutPacket(packet, ThrottleOutPacketType.Task, true);
12979 }
12980
12981 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
12982 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
12983 }
12984
12985 public void SendPlacesReply(UUID queryID, UUID transactionID,
12986 PlacesReplyData[] data)
12987 {
12988 PlacesReplyPacket reply = null;
12989 PlacesReplyPacket.QueryDataBlock[] dataBlocks =
12990 new PlacesReplyPacket.QueryDataBlock[0];
12991
12992 for (int i = 0 ; i < data.Length ; i++)
12993 {
12994 PlacesReplyPacket.QueryDataBlock block =
12995 new PlacesReplyPacket.QueryDataBlock();
12996
12997 block.OwnerID = data[i].OwnerID;
12998 block.Name = Util.StringToBytes256(data[i].Name);
12999 block.Desc = Util.StringToBytes1024(data[i].Desc);
13000 block.ActualArea = data[i].ActualArea;
13001 block.BillableArea = data[i].BillableArea;
13002 block.Flags = data[i].Flags;
13003 block.GlobalX = data[i].GlobalX;
13004 block.GlobalY = data[i].GlobalY;
13005 block.GlobalZ = data[i].GlobalZ;
13006 block.SimName = Util.StringToBytes256(data[i].SimName);
13007 block.SnapshotID = data[i].SnapshotID;
13008 block.Dwell = data[i].Dwell;
13009 block.Price = data[i].Price;
13010
13011 if (reply != null && reply.Length + block.Length > 1400)
13012 {
13013 OutPacket(reply, ThrottleOutPacketType.Task);
13014
13015 reply = null;
13016 dataBlocks = new PlacesReplyPacket.QueryDataBlock[0];
13017 }
13018
13019 if (reply == null)
13020 {
13021 reply = (PlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.PlacesReply);
13022 reply.AgentData = new PlacesReplyPacket.AgentDataBlock();
13023 reply.AgentData.AgentID = AgentId;
13024 reply.AgentData.QueryID = queryID;
13025
13026 reply.TransactionData = new PlacesReplyPacket.TransactionDataBlock();
13027 reply.TransactionData.TransactionID = transactionID;
13028
13029 reply.QueryData = dataBlocks;
13030 }
13031
13032 Array.Resize(ref dataBlocks, dataBlocks.Length + 1);
13033 dataBlocks[dataBlocks.Length - 1] = block;
13034 reply.QueryData = dataBlocks;
13035 }
13036 if (reply != null)
13037 OutPacket(reply, ThrottleOutPacketType.Task);
13038 }
13039
13040 public void SendRemoveInventoryItems(UUID[] items)
13041 {
13042 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
13043
13044 if (eq == null)
13045 {
13046 m_log.DebugFormat("[LLCLIENT]: Null event queue");
13047 return;
13048 }
13049
13050 OSDMap llsd = new OSDMap(3);
13051
13052 OSDMap AgentDataMap = new OSDMap(1);
13053 AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
13054 AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
13055
13056 OSDArray AgentData = new OSDArray(1);
13057 AgentData.Add(AgentDataMap);
13058
13059 llsd.Add("AgentData", AgentData);
13060
13061 OSDArray ItemData = new OSDArray();
13062
13063 foreach (UUID item in items)
13064 {
13065 OSDMap ItemDataMap = new OSDMap(2);
13066 ItemDataMap.Add("ItemID", OSD.FromUUID(item));
13067 ItemDataMap.Add("AgentID", OSD.FromUUID(AgentId));
13068
13069 ItemData.Add(ItemDataMap);
13070 }
13071
13072 llsd.Add("InventoryData", ItemData);
13073
13074 eq.Enqueue(BuildEvent("RemoveInventoryItem",
13075 llsd), AgentId);
13076 }
13077
13078 public void SendRemoveInventoryFolders(UUID[] folders)
13079 {
13080 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
13081
13082 if (eq == null)
13083 {
13084 m_log.DebugFormat("[LLCLIENT]: Null event queue");
13085 return;
13086 }
13087
13088 OSDMap llsd = new OSDMap(3);
13089
13090 OSDMap AgentDataMap = new OSDMap(1);
13091 AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
13092 AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
13093
13094 OSDArray AgentData = new OSDArray(1);
13095 AgentData.Add(AgentDataMap);
13096
13097 llsd.Add("AgentData", AgentData);
13098
13099 OSDArray FolderData = new OSDArray();
13100
13101 foreach (UUID folder in folders)
13102 {
13103 OSDMap FolderDataMap = new OSDMap(2);
13104 FolderDataMap.Add("FolderID", OSD.FromUUID(folder));
13105 FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
13106
13107 FolderData.Add(FolderDataMap);
13108 }
13109
13110 llsd.Add("FolderData", FolderData);
13111
13112 eq.Enqueue(BuildEvent("RemoveInventoryFolder",
13113 llsd), AgentId);
13114 }
13115
13116 private byte[] EncodeU32(uint val)
13117 {
13118 byte[] ret = BitConverter.GetBytes(val);
13119 if (BitConverter.IsLittleEndian)
13120 Array.Reverse(ret);
13121 return ret;
13122 }
13123
13124 public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
13125 {
13126 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
13127
13128 if (eq == null)
13129 {
13130 m_log.DebugFormat("[LLCLIENT]: Null event queue");
13131 return;
13132 }
13133
13134 OSDMap llsd = new OSDMap(3);
13135
13136 OSDMap AgentDataMap = new OSDMap(1);
13137 AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
13138 AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
13139 AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random()));
13140
13141 OSDArray AgentData = new OSDArray(1);
13142 AgentData.Add(AgentDataMap);
13143
13144 llsd.Add("AgentData", AgentData);
13145
13146 OSDArray FolderData = new OSDArray();
13147
13148 foreach (InventoryFolderBase folder in folders)
13149 {
13150 OSDMap FolderDataMap = new OSDMap(5);
13151 FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID));
13152 FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
13153 FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID));
13154 FolderDataMap.Add("Type", OSD.FromInteger(folder.Type));
13155 FolderDataMap.Add("Name", OSD.FromString(folder.Name));
13156
13157 FolderData.Add(FolderDataMap);
13158 }
13159
13160 llsd.Add("FolderData", FolderData);
13161
13162 OSDArray ItemData = new OSDArray();
13163
13164 foreach (InventoryItemBase item in items)
13165 {
13166 OSDMap ItemDataMap = new OSDMap();
13167
13168 ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID));
13169 ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder));
13170
13171 ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid));
13172 ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner));
13173 ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID));
13174 ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions)));
13175 ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions)));
13176 ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions)));
13177 ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions)));
13178 ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions)));
13179 ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned));
13180 ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID));
13181 ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType));
13182 ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType));
13183 ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags)));
13184 ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType));
13185 ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice));
13186 ItemDataMap.Add("Name", OSD.FromString(item.Name));
13187 ItemDataMap.Add("Description", OSD.FromString(item.Description));
13188 ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate));
13189
13190 ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32(
13191 Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
13192 (sbyte)item.AssetType, item.AssetID,
13193 item.GroupID, 100,
13194 item.Owner, item.CreatorIdAsUuid,
13195 item.ID, item.Folder,
13196 (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
13197 (uint)PermissionMask.All)
13198 )));
13199 ItemDataMap.Add("CallbackID", 0);
13200
13201 ItemData.Add(ItemDataMap);
13202 }
13203
13204 llsd.Add("ItemData", ItemData);
13205
13206 eq.Enqueue(BuildEvent("BulkUpdateInventory",
13207 llsd), AgentId);
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 }
13255 }
13256}