diff options
author | Justin Clarke Casey | 2008-12-10 19:12:59 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-12-10 19:12:59 +0000 |
commit | f38c35b60947fd926246fd95cfce5b9674967124 (patch) | |
tree | ad349b864b99f0b88d236abdb51993e41fbd6b74 /OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs | |
parent | * Establish OpenSim.Framework.Communications.Tests beachhead (diff) | |
download | opensim-SC-f38c35b60947fd926246fd95cfce5b9674967124.zip opensim-SC-f38c35b60947fd926246fd95cfce5b9674967124.tar.gz opensim-SC-f38c35b60947fd926246fd95cfce5b9674967124.tar.bz2 opensim-SC-f38c35b60947fd926246fd95cfce5b9674967124.tar.xz |
* refactor: Move inventory handlers out from UserProfileCacheService
* This means that UserProfileCacheService no longer needs to know about IClientAPI and can leave it to callers to do their own error logging
* This is also more consistent with the way that item inventory manipulation is handled
* I don't really think Scene.PacketHandlers.cs should be a permanent home for these handlers - this is just for convenience
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs | 286 |
1 files changed, 284 insertions, 2 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs index 8d12a94..3334e81 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs | |||
@@ -26,9 +26,12 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Threading; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using OpenMetaverse.Packets; | 31 | using OpenMetaverse.Packets; |
31 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Communications; | ||
34 | using OpenSim.Framework.Communications.Cache; | ||
32 | 35 | ||
33 | namespace OpenSim.Region.Environment.Scenes | 36 | namespace OpenSim.Region.Environment.Scenes |
34 | { | 37 | { |
@@ -214,7 +217,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
214 | 217 | ||
215 | public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) | 218 | public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) |
216 | { | 219 | { |
217 | |||
218 | List<EntityBase> EntityList = GetEntities(); | 220 | List<EntityBase> EntityList = GetEntities(); |
219 | 221 | ||
220 | SurfaceTouchEventArgs surfaceArg = null; | 222 | SurfaceTouchEventArgs surfaceArg = null; |
@@ -253,7 +255,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
253 | 255 | ||
254 | public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient) | 256 | public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient) |
255 | { | 257 | { |
256 | |||
257 | List<EntityBase> EntityList = GetEntities(); | 258 | List<EntityBase> EntityList = GetEntities(); |
258 | 259 | ||
259 | foreach (EntityBase ent in EntityList) | 260 | foreach (EntityBase ent in EntityList) |
@@ -346,5 +347,286 @@ namespace OpenSim.Region.Environment.Scenes | |||
346 | EventManager.TriggerScriptReset(part.LocalId, itemID); | 347 | EventManager.TriggerScriptReset(part.LocalId, itemID); |
347 | } | 348 | } |
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 | } | ||
349 | } | 631 | } |
350 | } | 632 | } |