aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
diff options
context:
space:
mode:
authorDr Scofield2009-02-06 16:55:34 +0000
committerDr Scofield2009-02-06 16:55:34 +0000
commit9b66108081a8c8cf79faaa6c541554091c40850e (patch)
tree095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
parent* removed superfluous constants class (diff)
downloadopensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.zip
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx!
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs632
1 files changed, 632 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
new file mode 100644
index 0000000..039b81b
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -0,0 +1,632 @@
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 OpenSim 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.Collections.Generic;
29using System.Threading;
30using OpenMetaverse;
31using OpenMetaverse.Packets;
32using OpenSim.Framework;
33using OpenSim.Framework.Communications;
34using OpenSim.Framework.Communications.Cache;
35
36namespace OpenSim.Region.Framework.Scenes
37{
38 public partial class Scene
39 {
40 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
41 UUID fromID, bool fromAgent, bool broadcast)
42 {
43 OSChatMessage args = new OSChatMessage();
44
45 args.Message = Utils.BytesToString(message);
46 args.Channel = channel;
47 args.Type = type;
48 args.Position = fromPos;
49 args.SenderUUID = fromID;
50 args.Scene = this;
51
52 if (fromAgent)
53 {
54 ScenePresence user = GetScenePresence(fromID);
55 if (user != null)
56 args.Sender = user.ControllingClient;
57 }
58 else
59 {
60 SceneObjectPart obj = GetSceneObjectPart(fromID);
61 args.SenderObject = obj;
62 }
63
64 args.From = fromName;
65 //args.
66
67 if (broadcast)
68 EventManager.TriggerOnChatBroadcast(this, args);
69 else
70 EventManager.TriggerOnChatFromWorld(this, args);
71
72 }
73 /// <summary>
74 ///
75 /// </summary>
76 /// <param name="message"></param>
77 /// <param name="type"></param>
78 /// <param name="fromPos"></param>
79 /// <param name="fromName"></param>
80 /// <param name="fromAgentID"></param>
81 public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
82 UUID fromID, bool fromAgent)
83 {
84 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, false);
85 }
86
87 /// <summary>
88 ///
89 /// </summary>
90 /// <param name="message"></param>
91 /// <param name="type"></param>
92 /// <param name="fromPos"></param>
93 /// <param name="fromName"></param>
94 /// <param name="fromAgentID"></param>
95 public void SimChatBroadcast(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
96 UUID fromID, bool fromAgent)
97 {
98 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true);
99 }
100
101 /// <summary>
102 /// Invoked when the client selects a prim.
103 /// </summary>
104 /// <param name="primLocalID"></param>
105 /// <param name="remoteClient"></param>
106 public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
107 {
108 List<EntityBase> EntityList = GetEntities();
109
110 foreach (EntityBase ent in EntityList)
111 {
112 if (ent is SceneObjectGroup)
113 {
114 if (((SceneObjectGroup) ent).LocalId == primLocalID)
115 {
116 ((SceneObjectGroup) ent).GetProperties(remoteClient);
117 ((SceneObjectGroup) ent).IsSelected = true;
118 // A prim is only tainted if it's allowed to be edited by the person clicking it.
119 if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)
120 || Permissions.CanMoveObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId))
121 {
122 EventManager.TriggerParcelPrimCountTainted();
123 }
124 break;
125 }
126 else
127 {
128 // We also need to check the children of this prim as they
129 // can be selected as well and send property information
130 bool foundPrim = false;
131 foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children)
132 {
133 if (child.Value.LocalId == primLocalID)
134 {
135 child.Value.GetProperties(remoteClient);
136 foundPrim = true;
137 break;
138 }
139 }
140 if (foundPrim) break;
141 }
142 }
143 }
144 }
145
146 /// <summary>
147 /// Handle the deselection of a prim from the client.
148 /// </summary>
149 /// <param name="primLocalID"></param>
150 /// <param name="remoteClient"></param>
151 public void DeselectPrim(uint primLocalID, IClientAPI remoteClient)
152 {
153 SceneObjectPart part = GetSceneObjectPart(primLocalID);
154 if (part == null)
155 return;
156
157 // The prim is in the process of being deleted.
158 if (null == part.ParentGroup.RootPart)
159 return;
160
161 // A deselect packet contains all the local prims being deselected. However, since selection is still
162 // group based we only want the root prim to trigger a full update - otherwise on objects with many prims
163 // we end up sending many duplicate ObjectUpdates
164 if (part.ParentGroup.RootPart.LocalId != part.LocalId)
165 return;
166
167 bool isAttachment = false;
168
169 // This is wrong, wrong, wrong. Selection should not be
170 // handled by group, but by prim. Legacy cruft.
171 // TODO: Make selection flagging per prim!
172 //
173 part.ParentGroup.IsSelected = false;
174
175 if (part.ParentGroup.IsAttachment)
176 isAttachment = true;
177 else
178 part.ParentGroup.ScheduleGroupForFullUpdate();
179
180 // If it's not an attachment, and we are allowed to move it,
181 // then we might have done so. If we moved across a parcel
182 // boundary, we will need to recount prims on the parcels.
183 // For attachments, that makes no sense.
184 //
185 if (!isAttachment)
186 {
187 if (Permissions.CanEditObject(
188 part.UUID, remoteClient.AgentId)
189 || Permissions.CanMoveObject(
190 part.UUID, remoteClient.AgentId))
191 EventManager.TriggerParcelPrimCountTainted();
192 }
193 }
194
195 public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount,
196 int transactiontype, string description)
197 {
198 EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount,
199 transactiontype, description);
200
201 EventManager.TriggerMoneyTransfer(this, args);
202 }
203
204 public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned,
205 bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated)
206 {
207 EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned,
208 removeContribution, parcelLocalID, parcelArea,
209 parcelPrice, authenticated);
210
211 // First, allow all validators a stab at it
212 m_eventManager.TriggerValidateLandBuy(this, args);
213
214 // Then, check validation and transfer
215 m_eventManager.TriggerLandBuy(this, args);
216 }
217
218 public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
219 {
220 List<EntityBase> EntityList = GetEntities();
221
222 SurfaceTouchEventArgs surfaceArg = null;
223 if (surfaceArgs != null && surfaceArgs.Count > 0)
224 surfaceArg = surfaceArgs[0];
225
226 foreach (EntityBase ent in EntityList)
227 {
228 if (ent is SceneObjectGroup)
229 {
230 SceneObjectGroup obj = ent as SceneObjectGroup;
231 if (obj != null)
232 {
233 // Is this prim part of the group
234 if (obj.HasChildPrim(localID))
235 {
236 // Currently only grab/touch for the single prim
237 // the client handles rez correctly
238 obj.ObjectGrabHandler(localID, offsetPos, remoteClient);
239
240 SceneObjectPart part = obj.GetChildPart(localID);
241
242 // If the touched prim handles touches, deliver it
243 // If not, deliver to root prim
244 if ((part.ScriptEvents & scriptEvents.touch_start) != 0)
245 EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
246 else
247 EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
248
249 return;
250 }
251 }
252 }
253 }
254 }
255
256 public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient)
257 {
258 List<EntityBase> EntityList = GetEntities();
259
260 foreach (EntityBase ent in EntityList)
261 {
262 if (ent is SceneObjectGroup)
263 {
264 SceneObjectGroup obj = ent as SceneObjectGroup;
265
266 // Is this prim part of the group
267 if (obj.HasChildPrim(localID))
268 {
269 SceneObjectPart part=obj.GetChildPart(localID);
270 if (part != null)
271 {
272 // If the touched prim handles touches, deliver it
273 // If not, deliver to root prim
274 if ((part.ScriptEvents & scriptEvents.touch_end) != 0)
275 EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient);
276 else
277 EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient);
278
279 return;
280 }
281 return;
282 }
283 }
284 }
285 }
286
287 public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
288 {
289 //EventManager.TriggerAvatarPickerRequest();
290
291 List<AvatarPickerAvatar> AvatarResponses = new List<AvatarPickerAvatar>();
292 AvatarResponses = m_sceneGridService.GenerateAgentPickerRequestResponse(RequestID, query);
293
294 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
295 // TODO: don't create new blocks if recycling an old packet
296
297 AvatarPickerReplyPacket.DataBlock[] searchData =
298 new AvatarPickerReplyPacket.DataBlock[AvatarResponses.Count];
299 AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
300
301 agentData.AgentID = avatarID;
302 agentData.QueryID = RequestID;
303 replyPacket.AgentData = agentData;
304 //byte[] bytes = new byte[AvatarResponses.Count*32];
305
306 int i = 0;
307 foreach (AvatarPickerAvatar item in AvatarResponses)
308 {
309 UUID translatedIDtem = item.AvatarID;
310 searchData[i] = new AvatarPickerReplyPacket.DataBlock();
311 searchData[i].AvatarID = translatedIDtem;
312 searchData[i].FirstName = Utils.StringToBytes((string) item.firstName);
313 searchData[i].LastName = Utils.StringToBytes((string) item.lastName);
314 i++;
315 }
316 if (AvatarResponses.Count == 0)
317 {
318 searchData = new AvatarPickerReplyPacket.DataBlock[0];
319 }
320 replyPacket.Data = searchData;
321
322 AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
323 agent_data.AgentID = replyPacket.AgentData.AgentID;
324 agent_data.QueryID = replyPacket.AgentData.QueryID;
325
326 List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
327 for (i = 0; i < replyPacket.Data.Length; i++)
328 {
329 AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
330 data_arg.AvatarID = replyPacket.Data[i].AvatarID;
331 data_arg.FirstName = replyPacket.Data[i].FirstName;
332 data_arg.LastName = replyPacket.Data[i].LastName;
333 data_args.Add(data_arg);
334 }
335 client.SendAvatarPickerReply(agent_data, data_args);
336 }
337
338 public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
339 UUID itemID)
340 {
341 SceneObjectPart part=GetSceneObjectPart(objectID);
342 if (part == null)
343 return;
344
345 if (Permissions.CanResetScript(objectID, itemID, remoteClient.AgentId))
346 {
347 EventManager.TriggerScriptReset(part.LocalId, itemID);
348 }
349 }
350
351 /// <summary>
352 /// Handle a fetch inventory request from the client
353 /// </summary>
354 /// <param name="remoteClient"></param>
355 /// <param name="itemID"></param>
356 /// <param name="ownerID"></param>
357 public void HandleFetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID)
358 {
359 if (ownerID == CommsManager.UserProfileCacheService.LibraryRoot.Owner)
360 {
361 //Console.WriteLine("request info for library item");
362 return;
363 }
364
365 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
366
367 if (null == userProfile)
368 {
369 m_log.ErrorFormat(
370 "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
371 remoteClient.Name, remoteClient.AgentId);
372 return;
373 }
374
375 if (userProfile.HasReceivedInventory)
376 {
377 InventoryItemBase item = null;
378 if (userProfile.RootFolder == null)
379 m_log.ErrorFormat(
380 "[AGENT INVENTORY]: User {0} {1} does not have a root folder.",
381 remoteClient.Name, remoteClient.AgentId);
382 else
383 item = userProfile.RootFolder.FindItem(itemID);
384
385 if (item != null)
386 {
387 remoteClient.SendInventoryItemDetails(ownerID, item);
388 }
389 }
390 }
391
392 /// <summary>
393 /// Tell the client about the various child items and folders contained in the requested folder.
394 /// </summary>
395 /// <param name="remoteClient"></param>
396 /// <param name="folderID"></param>
397 /// <param name="ownerID"></param>
398 /// <param name="fetchFolders"></param>
399 /// <param name="fetchItems"></param>
400 /// <param name="sortOrder"></param>
401 public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID,
402 bool fetchFolders, bool fetchItems, int sortOrder)
403 {
404 // FIXME MAYBE: We're not handling sortOrder!
405
406 // TODO: This code for looking in the folder for the library should be folded back into the
407 // CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc.
408 // can be handled transparently).
409 InventoryFolderImpl fold = null;
410 if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null)
411 {
412 remoteClient.SendInventoryFolderDetails(
413 fold.Owner, folderID, fold.RequestListOfItems(),
414 fold.RequestListOfFolders(), fetchFolders, fetchItems);
415 return;
416 }
417
418 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
419
420 if (null == userProfile)
421 {
422 m_log.ErrorFormat(
423 "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
424 remoteClient.Name, remoteClient.AgentId);
425 return;
426 }
427
428 userProfile.SendInventoryDecendents(remoteClient, folderID, fetchFolders, fetchItems);
429 }
430
431 /// <summary>
432 /// Handle the caps inventory descendents fetch.
433 ///
434 /// Since the folder structure is sent to the client on login, I believe we only need to handle items.
435 /// </summary>
436 /// <param name="agentID"></param>
437 /// <param name="folderID"></param>
438 /// <param name="ownerID"></param>
439 /// <param name="fetchFolders"></param>
440 /// <param name="fetchItems"></param>
441 /// <param name="sortOrder"></param>
442 /// <returns>null if the inventory look up failed</returns>
443 public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
444 bool fetchFolders, bool fetchItems, int sortOrder)
445 {
446// m_log.DebugFormat(
447// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
448// fetchFolders, fetchItems, folderID, agentID);
449
450 // FIXME MAYBE: We're not handling sortOrder!
451
452 // TODO: This code for looking in the folder for the library should be folded back into the
453 // CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc.
454 // can be handled transparently).
455 InventoryFolderImpl fold;
456 if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null)
457 {
458 return fold.RequestListOfItems();
459 }
460
461 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(agentID);
462
463 if (null == userProfile)
464 {
465 m_log.ErrorFormat("[AGENT INVENTORY]: Could not find user profile for {0}", agentID);
466 return null;
467 }
468
469 // XXX: When a client crosses into a scene, their entire inventory is fetched
470 // asynchronously. If the client makes a request before the inventory is received, we need
471 // to give the inventory a chance to come in.
472 //
473 // This is a crude way of dealing with that by retrying the lookup. It's not quite as bad
474 // in CAPS as doing this with the udp request, since here it won't hold up other packets.
475 // In fact, here we'll be generous and try for longer.
476 if (!userProfile.HasReceivedInventory)
477 {
478 int attempts = 0;
479 while (attempts++ < 30)
480 {
481 m_log.DebugFormat(
482 "[INVENTORY CACHE]: Poll number {0} for inventory items in folder {1} for user {2}",
483 attempts, folderID, agentID);
484
485 Thread.Sleep(2000);
486
487 if (userProfile.HasReceivedInventory)
488 {
489 break;
490 }
491 }
492 }
493
494 if (userProfile.HasReceivedInventory)
495 {
496 if ((fold = userProfile.RootFolder.FindFolder(folderID)) != null)
497 {
498 return fold.RequestListOfItems();
499 }
500 else
501 {
502 m_log.WarnFormat(
503 "[AGENT INVENTORY]: Could not find folder {0} requested by user {1}",
504 folderID, agentID);
505 return null;
506 }
507 }
508 else
509 {
510 m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID);
511 return null;
512 }
513 }
514
515 /// <summary>
516 /// Handle an inventory folder creation request from the client.
517 /// </summary>
518 /// <param name="remoteClient"></param>
519 /// <param name="folderID"></param>
520 /// <param name="folderType"></param>
521 /// <param name="folderName"></param>
522 /// <param name="parentID"></param>
523 public void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType,
524 string folderName, UUID parentID)
525 {
526 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
527
528 if (null == userProfile)
529 {
530 m_log.ErrorFormat(
531 "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
532 remoteClient.Name, remoteClient.AgentId);
533 return;
534 }
535
536 if (!userProfile.CreateFolder(folderName, folderID, folderType, parentID))
537 {
538 m_log.ErrorFormat(
539 "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}",
540 remoteClient.Name, remoteClient.AgentId);
541 }
542 }
543
544 /// <summary>
545 /// Handle a client request to update the inventory folder
546 /// </summary>
547 ///
548 /// FIXME: We call add new inventory folder because in the data layer, we happen to use an SQL REPLACE
549 /// so this will work to rename an existing folder. Needless to say, to rely on this is very confusing,
550 /// and needs to be changed.
551 ///
552 /// <param name="remoteClient"></param>
553 /// <param name="folderID"></param>
554 /// <param name="type"></param>
555 /// <param name="name"></param>
556 /// <param name="parentID"></param>
557 public void HandleUpdateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort type, string name,
558 UUID parentID)
559 {
560// m_log.DebugFormat(
561// "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId);
562
563 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
564
565 if (null == userProfile)
566 {
567 m_log.ErrorFormat(
568 "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
569 remoteClient.Name, remoteClient.AgentId);
570 return;
571 }
572
573 if (!userProfile.UpdateFolder(name, folderID, type, parentID))
574 {
575 m_log.ErrorFormat(
576 "[AGENT INVENTORY]: Failed to update folder for user {0} {1}",
577 remoteClient.Name, remoteClient.AgentId);
578 }
579 }
580
581 /// <summary>
582 /// Handle an inventory folder move request from the client.
583 /// </summary>
584 /// <param name="remoteClient"></param>
585 /// <param name="folderID"></param>
586 /// <param name="parentID"></param>
587 public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID)
588 {
589 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
590
591 if (null == userProfile)
592 {
593 m_log.ErrorFormat(
594 "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
595 remoteClient.Name, remoteClient.AgentId);
596 return;
597 }
598
599 if (!userProfile.MoveFolder(folderID, parentID))
600 {
601 m_log.ErrorFormat(
602 "[AGENT INVENTORY]: Failed to move folder {0} to {1} for user {2}",
603 folderID, parentID, remoteClient.Name);
604 }
605 }
606
607 /// <summary>
608 /// This should delete all the items and folders in the given directory.
609 /// </summary>
610 /// <param name="remoteClient"></param>
611 /// <param name="folderID"></param>
612 public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID)
613 {
614 CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
615
616 if (null == userProfile)
617 {
618 m_log.ErrorFormat(
619 "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
620 remoteClient.Name, remoteClient.AgentId);
621 return;
622 }
623
624 if (!userProfile.PurgeFolder(folderID))
625 {
626 m_log.ErrorFormat(
627 "[AGENT INVENTORY]: Failed to purge folder for user {0} {1}",
628 remoteClient.Name, remoteClient.AgentId);
629 }
630 }
631 }
632}