OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
Scene.PacketHandlers.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections.Generic;
30 using System.Threading;
31 using OpenMetaverse;
32 using OpenMetaverse.Packets;
33 using OpenSim.Framework;
34 using OpenSim.Services.Interfaces;
35 
36 namespace OpenSim.Region.Framework.Scenes
37 {
38  public partial class Scene
39  {
52  public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
53  UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
54  {
55  OSChatMessage args = new OSChatMessage();
56 
57  args.Message = Utils.BytesToString(message);
58  args.Channel = channel;
59  args.Type = type;
60  args.Position = fromPos;
61  args.SenderUUID = fromID;
62  args.Scene = this;
63  args.Destination = targetID;
64 
65  if (fromAgent)
66  {
67  ScenePresence user = GetScenePresence(fromID);
68  if (user != null)
69  args.Sender = user.ControllingClient;
70  }
71  else
72  {
73  SceneObjectPart obj = GetSceneObjectPart(fromID);
74  args.SenderObject = obj;
75  }
76 
77  args.From = fromName;
78  //args.
79 
80 // m_log.DebugFormat(
81 // "[SCENE]: Sending message {0} on channel {1}, type {2} from {3}, broadcast {4}",
82 // args.Message.Replace("\n", "\\n"), args.Channel, args.Type, fromName, broadcast);
83 
84  if (broadcast)
85  EventManager.TriggerOnChatBroadcast(this, args);
86  else
87  EventManager.TriggerOnChatFromWorld(this, args);
88  }
89 
90  protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
91  UUID fromID, bool fromAgent, bool broadcast)
92  {
93  SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast);
94  }
95 
104  public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
105  UUID fromID, bool fromAgent)
106  {
107  SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, false);
108  }
109 
110  public void SimChat(string message, ChatTypeEnum type, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
111  {
112  SimChat(Utils.StringToBytes(message), type, 0, fromPos, fromName, fromID, fromAgent);
113  }
114 
115  public void SimChat(string message, string fromName)
116  {
117  SimChat(message, ChatTypeEnum.Broadcast, Vector3.Zero, fromName, UUID.Zero, false);
118  }
119 
128  public void SimChatBroadcast(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
129  UUID fromID, bool fromAgent)
130  {
131  SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true);
132  }
133 
144  public void SimChatToAgent(UUID targetID, byte[] message, int channel, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
145  {
146  SimChat(message, ChatTypeEnum.Region, channel, fromPos, fromName, fromID, targetID, fromAgent, false);
147  }
148 
154  public void RequestPrim(uint primLocalID, IClientAPI remoteClient)
155  {
156  SceneObjectGroup sog = GetGroupByPrim(primLocalID);
157 
158  if (sog != null)
159  sog.SendFullUpdateToClient(remoteClient);
160  }
161 
167  public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
168  {
169  /*
170  SceneObjectPart part = GetSceneObjectPart(primLocalID);
171 
172  if (null == part)
173  return;
174 
175  if (part.IsRoot)
176  {
177  SceneObjectGroup sog = part.ParentGroup;
178  sog.SendPropertiesToClient(remoteClient);
179 
180  // A prim is only tainted if it's allowed to be edited by the person clicking it.
181  if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
182  || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
183  {
184  sog.IsSelected = true;
185  EventManager.TriggerParcelPrimCountTainted();
186  }
187  }
188  else
189  {
190  part.SendPropertiesToClient(remoteClient);
191  }
192  */
193  SceneObjectPart part = GetSceneObjectPart(primLocalID);
194 
195  if (null == part)
196  return;
197 
198  SceneObjectGroup sog = part.ParentGroup;
199  if (sog == null)
200  return;
201 
202  part.SendPropertiesToClient(remoteClient);
203 
204  // waste of time because properties do not send prim flags as they should
205  // if a friend got or lost edit rights after login, a full update is needed
206  if(sog.OwnerID != remoteClient.AgentId)
207  part.SendFullUpdate(remoteClient);
208 
209  // A prim is only tainted if it's allowed to be edited by the person clicking it.
210  if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
211  || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
212  {
213  part.IsSelected = true;
214  EventManager.TriggerParcelPrimCountTainted();
215  }
216  }
217 
225  private void HandleObjectGroupUpdate(
226  IClientAPI remoteClient, UUID groupID, uint objectLocalID, UUID Garbage)
227  {
228  if (m_groupsModule == null)
229  return;
230 
231  // XXX: Might be better to get rid of this special casing and have GetMembershipData return something
232  // reasonable for a UUID.Zero group.
233  if (groupID != UUID.Zero)
234  {
235  GroupMembershipData gmd = m_groupsModule.GetMembershipData(groupID, remoteClient.AgentId);
236 
237  if (gmd == null)
238  {
239 // m_log.WarnFormat(
240 // "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group",
241 // remoteClient.Name, GroupID, objectLocalID);
242 
243  return;
244  }
245  }
246 
247  SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID);
248  if (so != null)
249  {
250  if (so.OwnerID == remoteClient.AgentId)
251  {
252  so.SetGroup(groupID, remoteClient);
253  }
254  }
255  }
256 
262  public void DeselectPrim(uint primLocalID, IClientAPI remoteClient)
263  {
264  SceneObjectPart part = GetSceneObjectPart(primLocalID);
265  if (part == null)
266  return;
267  /*
268  // A deselect packet contains all the local prims being deselected. However, since selection is still
269  // group based we only want the root prim to trigger a full update - otherwise on objects with many prims
270  // we end up sending many duplicate ObjectUpdates
271  if (part.ParentGroup.RootPart.LocalId != part.LocalId)
272  return;
273 
274  // This is wrong, wrong, wrong. Selection should not be
275  // handled by group, but by prim. Legacy cruft.
276  // TODO: Make selection flagging per prim!
277  //
278  if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)
279  || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId))
280  part.ParentGroup.IsSelected = false;
281 
282  part.ParentGroup.ScheduleGroupForFullUpdate();
283 
284  // If it's not an attachment, and we are allowed to move it,
285  // then we might have done so. If we moved across a parcel
286  // boundary, we will need to recount prims on the parcels.
287  // For attachments, that makes no sense.
288  //
289  if (!part.ParentGroup.IsAttachment)
290  {
291  if (Permissions.CanEditObject(
292  part.UUID, remoteClient.AgentId)
293  || Permissions.CanMoveObject(
294  part.UUID, remoteClient.AgentId))
295  EventManager.TriggerParcelPrimCountTainted();
296  }
297  */
298 
299  bool oldgprSelect = part.ParentGroup.IsSelected;
300 
301  // This is wrong, wrong, wrong. Selection should not be
302  // handled by group, but by prim. Legacy cruft.
303  // TODO: Make selection flagging per prim!
304  //
305  if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)
306  || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId))
307  {
308  part.IsSelected = false;
309  if (!part.ParentGroup.IsAttachment && oldgprSelect != part.ParentGroup.IsSelected)
310  EventManager.TriggerParcelPrimCountTainted();
311 
312  // restore targetOmega
313  if (part.AngularVelocity != Vector3.Zero)
314  part.ScheduleTerseUpdate();
315  }
316  }
317 
318  public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount,
319  int transactiontype, string description)
320  {
321  EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount,
322  transactiontype, description);
323 
324  EventManager.TriggerMoneyTransfer(this, args);
325  }
326 
327  public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned,
328  bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated)
329  {
330  EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned,
331  removeContribution, parcelLocalID, parcelArea,
332  parcelPrice, authenticated);
333 
334  // First, allow all validators a stab at it
335  m_eventManager.TriggerValidateLandBuy(this, args);
336 
337  // Then, check validation and transfer
338  m_eventManager.TriggerLandBuy(this, args);
339  }
340 
341  public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
342  {
343  SceneObjectPart part = GetSceneObjectPart(localID);
344 
345  if (part == null)
346  return;
347 
348  SceneObjectGroup obj = part.ParentGroup;
349 
350  SurfaceTouchEventArgs surfaceArg = null;
351  if (surfaceArgs != null && surfaceArgs.Count > 0)
352  surfaceArg = surfaceArgs[0];
353 
354  // Currently only grab/touch for the single prim
355  // the client handles rez correctly
356  obj.ObjectGrabHandler(localID, offsetPos, remoteClient);
357 
358  // If the touched prim handles touches, deliver it
359  // If not, deliver to root prim
360  if ((part.ScriptEvents & scriptEvents.touch_start) != 0)
361  EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
362 
363  // Deliver to the root prim if the touched prim doesn't handle touches
364  // or if we're meant to pass on touches anyway. Don't send to root prim
365  // if prim touched is the root prim as we just did it
366  if (((part.ScriptEvents & scriptEvents.touch_start) == 0) ||
367  (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
368  {
369  EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
370  }
371  }
372 
373  public virtual void ProcessObjectGrabUpdate(
374  UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
375  {
376  SceneObjectPart part = GetSceneObjectPart(objectID);
377  if (part == null)
378  return;
379 
380  SceneObjectGroup obj = part.ParentGroup;
381 
382  SurfaceTouchEventArgs surfaceArg = null;
383  if (surfaceArgs != null && surfaceArgs.Count > 0)
384  surfaceArg = surfaceArgs[0];
385 
386  // If the touched prim handles touches, deliver it
387  // If not, deliver to root prim
388  if ((part.ScriptEvents & scriptEvents.touch) != 0)
389  EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
390  // Deliver to the root prim if the touched prim doesn't handle touches
391  // or if we're meant to pass on touches anyway. Don't send to root prim
392  // if prim touched is the root prim as we just did it
393  if (((part.ScriptEvents & scriptEvents.touch) == 0) ||
394  (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
395  {
396  EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
397  }
398  }
399 
400  public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
401  {
402  SceneObjectPart part = GetSceneObjectPart(localID);
403  if (part == null)
404  return;
405 
406  SceneObjectGroup obj = part.ParentGroup;
407 
408  SurfaceTouchEventArgs surfaceArg = null;
409  if (surfaceArgs != null && surfaceArgs.Count > 0)
410  surfaceArg = surfaceArgs[0];
411 
412  // If the touched prim handles touches, deliver it
413  // If not, deliver to root prim
414  if ((part.ScriptEvents & scriptEvents.touch_end) != 0)
415  EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient, surfaceArg);
416  else
417  EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg);
418  }
419 
420  public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
421  UUID itemID)
422  {
423  SceneObjectPart part=GetSceneObjectPart(objectID);
424  if (part == null)
425  return;
426 
427  if (Permissions.CanResetScript(objectID, itemID, remoteClient.AgentId))
428  {
429  EventManager.TriggerScriptReset(part.LocalId, itemID);
430  }
431  }
432 
433  void ProcessViewerEffect(IClientAPI remoteClient, List<ViewerEffectEventHandlerArg> args)
434  {
435  // TODO: don't create new blocks if recycling an old packet
436  bool discardableEffects = true;
437  ViewerEffectPacket.EffectBlock[] effectBlockArray = new ViewerEffectPacket.EffectBlock[args.Count];
438  for (int i = 0; i < args.Count; i++)
439  {
440  ViewerEffectPacket.EffectBlock effect = new ViewerEffectPacket.EffectBlock();
441  effect.AgentID = args[i].AgentID;
442  effect.Color = args[i].Color;
443  effect.Duration = args[i].Duration;
444  effect.ID = args[i].ID;
445  effect.Type = args[i].Type;
446  effect.TypeData = args[i].TypeData;
447  effectBlockArray[i] = effect;
448 
449  if ((EffectType)effect.Type != EffectType.LookAt && (EffectType)effect.Type != EffectType.Beam)
450  discardableEffects = false;
451 
452  //m_log.DebugFormat("[YYY]: VE {0} {1} {2}", effect.AgentID, effect.Duration, (EffectType)effect.Type);
453  }
454 
455  ForEachScenePresence(sp =>
456  {
457  if (sp.ControllingClient.AgentId != remoteClient.AgentId)
458  {
459  if (!discardableEffects ||
460  (discardableEffects && ShouldSendDiscardableEffect(remoteClient, sp)))
461  {
462  //m_log.DebugFormat("[YYY]: Sending to {0}", sp.UUID);
463  sp.ControllingClient.SendViewerEffect(effectBlockArray);
464  }
465  //else
466  // m_log.DebugFormat("[YYY]: Not sending to {0}", sp.UUID);
467  }
468  });
469  }
470 
471  private bool ShouldSendDiscardableEffect(IClientAPI thisClient, ScenePresence other)
472  {
473  return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10;
474  }
475 
476  private class DescendentsRequestData
477  {
478  public IClientAPI RemoteClient;
479  public UUID FolderID;
480  public UUID OwnerID;
481  public bool FetchFolders;
482  public bool FetchItems;
483  public int SortOrder;
484  }
485 
486  private Queue<DescendentsRequestData> m_descendentsRequestQueue = new Queue<DescendentsRequestData>();
487  private Object m_descendentsRequestLock = new Object();
488  private bool m_descendentsRequestProcessing = false;
489 
499  public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID,
500  bool fetchFolders, bool fetchItems, int sortOrder)
501  {
502 // m_log.DebugFormat(
503 // "[USER INVENTORY]: HandleFetchInventoryDescendents() for {0}, folder={1}, fetchFolders={2}, fetchItems={3}, sortOrder={4}",
504 // remoteClient.Name, folderID, fetchFolders, fetchItems, sortOrder);
505 
506  if (folderID == UUID.Zero)
507  return;
508 
509  // FIXME MAYBE: We're not handling sortOrder!
510 
511  // TODO: This code for looking in the folder for the library should be folded somewhere else
512  // so that this class doesn't have to know the details (and so that multiple libraries, etc.
513  // can be handled transparently).
514  InventoryFolderImpl fold = null;
515  if (LibraryService != null && LibraryService.LibraryRootFolder != null)
516  {
517  if ((fold = LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
518  {
519  remoteClient.SendInventoryFolderDetails(
520  fold.Owner, folderID, fold.RequestListOfItems(),
521  fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems);
522  return;
523  }
524  }
525 
526  lock (m_descendentsRequestLock)
527  {
528  if (!m_descendentsRequestProcessing)
529  {
530  m_descendentsRequestProcessing = true;
531 
532  // We're going to send the reply async, because there may be
533  // an enormous quantity of packets -- basically the entire inventory!
534  // We don't want to block the client thread while all that is happening.
535  SendInventoryDelegate d = SendInventoryAsync;
536  d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d);
537 
538  return;
539  }
540 
541  DescendentsRequestData req = new DescendentsRequestData();
542  req.RemoteClient = remoteClient;
543  req.FolderID = folderID;
544  req.OwnerID = ownerID;
545  req.FetchFolders = fetchFolders;
546  req.FetchItems = fetchItems;
547  req.SortOrder = sortOrder;
548 
549  m_descendentsRequestQueue.Enqueue(req);
550  }
551  }
552 
553  delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder);
554 
555  void SendInventoryAsync(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder)
556  {
557  try
558  {
559  SendInventoryUpdate(remoteClient, new InventoryFolderBase(folderID), fetchFolders, fetchItems);
560  }
561  catch (Exception e)
562  {
563  m_log.Error(
564  string.Format(
565  "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e));
566  }
567  Thread.Sleep(20);
568  }
569 
570  void SendInventoryComplete(IAsyncResult iar)
571  {
572  SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState;
573  d.EndInvoke(iar);
574 
575  lock (m_descendentsRequestLock)
576  {
577  if (m_descendentsRequestQueue.Count > 0)
578  {
579  DescendentsRequestData req = m_descendentsRequestQueue.Dequeue();
580 
581  d = SendInventoryAsync;
582  d.BeginInvoke(req.RemoteClient, req.FolderID, req.OwnerID, req.FetchFolders, req.FetchItems, req.SortOrder, SendInventoryComplete, d);
583 
584  return;
585  }
586 
587  m_descendentsRequestProcessing = false;
588  }
589  }
590 
599  public void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType,
600  string folderName, UUID parentID)
601  {
602  InventoryFolderBase folder = new InventoryFolderBase(folderID, folderName, remoteClient.AgentId, (short)folderType, parentID, 1);
603  if (!InventoryService.AddFolder(folder))
604  {
605  m_log.WarnFormat(
606  "[AGENT INVENTORY]: Failed to create folder for user {0} {1}",
607  remoteClient.Name, remoteClient.AgentId);
608  }
609  }
610 
624  public void HandleUpdateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort type, string name,
625  UUID parentID)
626  {
627 // m_log.DebugFormat(
628 // "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId);
629 
630  InventoryFolderBase folder = new InventoryFolderBase(folderID, remoteClient.AgentId);
631  folder = InventoryService.GetFolder(folder);
632  if (folder != null)
633  {
634  folder.Name = name;
635  folder.Type = (short)type;
636  folder.ParentID = parentID;
637  if (!InventoryService.UpdateFolder(folder))
638  {
639  m_log.ErrorFormat(
640  "[AGENT INVENTORY]: Failed to update folder for user {0} {1}",
641  remoteClient.Name, remoteClient.AgentId);
642  }
643  }
644  }
645 
646  public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID)
647  {
648  InventoryFolderBase folder = new InventoryFolderBase(folderID, remoteClient.AgentId);
649  folder = InventoryService.GetFolder(folder);
650  if (folder != null)
651  {
652  folder.ParentID = parentID;
653  if (!InventoryService.MoveFolder(folder))
654  m_log.WarnFormat("[AGENT INVENTORY]: could not move folder {0}", folderID);
655  else
656  m_log.DebugFormat("[AGENT INVENTORY]: folder {0} moved to parent {1}", folderID, parentID);
657  }
658  else
659  {
660  m_log.WarnFormat("[AGENT INVENTORY]: request to move folder {0} but folder not found", folderID);
661  }
662  }
663 
664  delegate void PurgeFolderDelegate(UUID userID, UUID folder);
665 
671  public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID)
672  {
673  PurgeFolderDelegate d = PurgeFolderAsync;
674  try
675  {
676  d.BeginInvoke(remoteClient.AgentId, folderID, PurgeFolderCompleted, d);
677  }
678  catch (Exception e)
679  {
680  m_log.WarnFormat("[AGENT INVENTORY]: Exception on purge folder for user {0}: {1}", remoteClient.AgentId, e.Message);
681  }
682  }
683 
684  private void PurgeFolderAsync(UUID userID, UUID folderID)
685  {
686  InventoryFolderBase folder = new InventoryFolderBase(folderID, userID);
687 
688  if (InventoryService.PurgeFolder(folder))
689  m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID);
690  else
691  m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID);
692  }
693 
694  private void PurgeFolderCompleted(IAsyncResult iar)
695  {
696  PurgeFolderDelegate d = (PurgeFolderDelegate)iar.AsyncState;
697  d.EndInvoke(iar);
698  }
699  }
700 }
virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned, bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated)
void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType, string folderName, UUID parentID)
Handle an inventory folder creation request from the client.
void SimChatBroadcast(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
void TriggerObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
void SimChat(string message, ChatTypeEnum type, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
OpenSim.Server.Handlers.Simulation.Utils Utils
void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID)
This should delete all the items and folders in the given directory.
List< InventoryFolderBase > RequestListOfFolders()
Return a copy of the list of child folders in this folder. The folders themselves are the originals...
InventoryFolderImpl FindFolder(UUID folderID)
Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth first.
virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List< SurfaceTouchEventArgs > surfaceArgs)
void SimChatToAgent(UUID targetID, byte[] message, int channel, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List< SurfaceTouchEventArgs > surfaceArgs)
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
Send chat to listeners.
void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID)
void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, UUID itemID)
void SimChat(string message, string fromName)
virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount, int transactiontype, string description)
ChatFromViewer Arguments
void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent, bool broadcast)
Vector3 AngularVelocity
Get or set angular velocity. Does not schedule update.
void SelectPrim(uint primLocalID, IClientAPI remoteClient)
Invoked when the client selects a prim.
void RequestPrim(uint primLocalID, IClientAPI remoteClient)
Invoked when the client requests a prim.
A class for triggering remote scene events.
Definition: EventManager.cs:44
void HandleUpdateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort type, string name, UUID parentID)
Handle a client request to update the inventory folder
void DeselectPrim(uint primLocalID, IClientAPI remoteClient)
Handle the deselection of a prim from the client.
virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List< SurfaceTouchEventArgs > surfaceArgs)
bool IsAttachment
Is this scene object acting as an attachment?
void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder)
Tell the client about the various child items and folders contained in the requested folder...