aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-04-14 18:43:23 +0000
committerJustin Clarke Casey2008-04-14 18:43:23 +0000
commitb7ae8701ce6881991fbacf28cdbb0d09f220f6ec (patch)
tree39247c37f31b9ad774a47e660eb9d314ef4c4582
parent* Fixed a few warnings. (diff)
downloadopensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.zip
opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.tar.gz
opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.tar.bz2
opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.tar.xz
* Working towards notifying the client if the inventory service has failed, rather than simply returning 0 items.
* This is very early support which would only be triggered in a rather unlikely case (if the user server correctly received an inventory skeleton, but later on failed to return the whole inventory in a timely manner. Also, this only applies to the 1.19.1.4 client onwards * Code cleanup and support for other failure cases (failure of inventory caching on region crossing, failure to actually add a folder/item, etc, should follow.
-rw-r--r--OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs6
-rw-r--r--OpenSim/Framework/Communications/Capabilities/Caps.cs35
-rw-r--r--OpenSim/Region/ClientStack/ClientView.cs9
-rw-r--r--OpenSim/Region/Environment/Scenes/InnerScene.cs33
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs2
5 files changed, 70 insertions, 15 deletions
diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
index 7995841..f746e8b 100644
--- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
+++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
@@ -340,7 +340,7 @@ namespace OpenSim.Framework.Communications.Cache
340 /// <param name="fetchFolders"></param> 340 /// <param name="fetchFolders"></param>
341 /// <param name="fetchItems"></param> 341 /// <param name="fetchItems"></param>
342 /// <param name="sortOrder"></param> 342 /// <param name="sortOrder"></param>
343 /// <returns></returns> 343 /// <returns>null if the inventory look up failed</returns>
344 public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, 344 public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID,
345 bool fetchFolders, bool fetchItems, int sortOrder) 345 bool fetchFolders, bool fetchItems, int sortOrder)
346 { 346 {
@@ -403,7 +403,7 @@ namespace OpenSim.Framework.Communications.Cache
403 { 403 {
404 m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID.ToString()); 404 m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID.ToString());
405 405
406 return new List<InventoryItemBase>(); ; 406 return null;
407 } 407 }
408 } 408 }
409 else 409 else
@@ -412,7 +412,7 @@ namespace OpenSim.Framework.Communications.Cache
412 "[USER CACHE]: HandleFetchInventoryDescendentsCAPS() Could not find user profile for {0}", 412 "[USER CACHE]: HandleFetchInventoryDescendentsCAPS() Could not find user profile for {0}",
413 agentID); 413 agentID);
414 414
415 return new List<InventoryItemBase>(); 415 return null;
416 } 416 }
417 417
418 // If we've reached this point then we couldn't find the folder, even though the client thinks 418 // If we've reached this point then we couldn't find the folder, even though the client thinks
diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs
index f164208..46f50ad 100644
--- a/OpenSim/Framework/Communications/Capabilities/Caps.cs
+++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs
@@ -56,6 +56,13 @@ namespace OpenSim.Region.Capabilities
56 56
57 public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, 57 public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID,
58 bool fetchFolders, bool fetchItems, int sortOrder); 58 bool fetchFolders, bool fetchItems, int sortOrder);
59
60 /// <summary>
61 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
62 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
63 /// to just pass the whole Scene into CAPS.
64 /// </summary>
65 public delegate IClientAPI GetClientDelegate(LLUUID agentID);
59 66
60 public class Caps 67 public class Caps
61 { 68 {
@@ -99,8 +106,8 @@ namespace OpenSim.Region.Capabilities
99 public NewInventoryItem AddNewInventoryItem = null; 106 public NewInventoryItem AddNewInventoryItem = null;
100 public ItemUpdatedCallback ItemUpdatedCall = null; 107 public ItemUpdatedCallback ItemUpdatedCall = null;
101 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; 108 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
102 //
103 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; 109 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
110 public GetClientDelegate GetClient = null;
104 111
105 public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath, 112 public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
106 LLUUID agent, bool dumpAssetsToFile) 113 LLUUID agent, bool dumpAssetsToFile)
@@ -240,7 +247,7 @@ namespace OpenSim.Region.Capabilities
240 247
241 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); 248 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
242 LLSDHelpers.DeserialiseLLSDMap(inventoryhash, llsdRequest); 249 LLSDHelpers.DeserialiseLLSDMap(inventoryhash, llsdRequest);
243 LLSDInventoryDescendents reply = FetchInventory(llsdRequest); 250 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
244 251
245 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); 252 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
246 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); 253 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
@@ -265,7 +272,7 @@ namespace OpenSim.Region.Capabilities
265 return response; 272 return response;
266 } 273 }
267 274
268 private LLSDInventoryDescendents FetchInventory(LLSDFetchInventoryDescendents invFetch) 275 private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
269 { 276 {
270 LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); 277 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
271 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); 278 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
@@ -289,6 +296,7 @@ namespace OpenSim.Region.Capabilities
289 { 296 {
290 itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order); 297 itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order);
291 } 298 }
299
292 if (itemList != null) 300 if (itemList != null)
293 { 301 {
294 foreach (InventoryItemBase invItem in itemList) 302 foreach (InventoryItemBase invItem in itemList)
@@ -296,6 +304,27 @@ namespace OpenSim.Region.Capabilities
296 contents.items.Array.Add(ConvertInventoryItem(invItem)); 304 contents.items.Array.Add(ConvertInventoryItem(invItem));
297 } 305 }
298 } 306 }
307 else
308 {
309 IClientAPI client = GetClient(m_agentID);
310
311 // We're going to both notify the client of inventory service failure and send back a 'no folder contents' response.
312 // If we don't send back the response,
313 // the client becomes unhappy (see Teravus' comment in FetchInventoryRequest())
314 if (client != null)
315 {
316 client.SendAgentAlertMessage(
317 "AGIN0001E: The inventory service has either failed or is not responding. Your inventory will not function properly for the rest of this session. Please clear your cache and relog.",
318 true);
319 }
320 else
321 {
322 m_log.ErrorFormat(
323 "[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure",
324 m_agentID);
325 }
326 }
327
299 contents.descendents = contents.items.Array.Count; 328 contents.descendents = contents.items.Array.Count;
300 return reply; 329 return reply;
301 } 330 }
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index 2599456..6ba40df 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -1576,7 +1576,8 @@ namespace OpenSim.Region.ClientStack
1576 } 1576 }
1577 1577
1578 /// <summary> 1578 /// <summary>
1579 /// 1579 /// Send an alert message to the client. On the Linden client (tested 1.19.1.4), this pops up a brief duration
1580 /// blue information box in the bottom right hand corner.
1580 /// </summary> 1581 /// </summary>
1581 /// <param name="message"></param> 1582 /// <param name="message"></param>
1582 public void SendAlertMessage(string message) 1583 public void SendAlertMessage(string message)
@@ -1587,10 +1588,12 @@ namespace OpenSim.Region.ClientStack
1587 } 1588 }
1588 1589
1589 /// <summary> 1590 /// <summary>
1590 /// 1591 /// Send an agent alert message to the client.
1591 /// </summary> 1592 /// </summary>
1592 /// <param name="message"></param> 1593 /// <param name="message"></param>
1593 /// <param name="modal"></param> 1594 /// <param name="modal">On the linden client, if this true then it displays a one button text box placed in the
1595 /// middle of the window. If false, the message is displayed in a brief duration blue information box (as for
1596 /// the AlertMessage packet).</param>
1594 public void SendAgentAlertMessage(string message, bool modal) 1597 public void SendAgentAlertMessage(string message, bool modal)
1595 { 1598 {
1596 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); 1599 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index ef98599..0838387 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -618,6 +618,28 @@ namespace OpenSim.Region.Environment.Scenes
618 618
619 return result; 619 return result;
620 } 620 }
621
622 /// <summary>
623 /// Get the controlling client for the given avatar, if there is one.
624 ///
625 /// FIXME: The only user of the method right now is Caps.cs, in order to resolve a client API since it can't
626 /// use the ScenePresence. This could be better solved in a number of ways - we could establish an
627 /// OpenSim.Framework.IScenePresence, or move the caps code into a region package (which might be the more
628 /// suitable solution).
629 /// </summary>
630 /// <param name="agentId"></param>
631 /// <returns>null if either the avatar wasn't in the scene, or they do not have a controlling client</returns>
632 public IClientAPI GetControllingClient(LLUUID agentId)
633 {
634 ScenePresence presence = GetScenePresence(agentId);
635
636 if (presence != null)
637 {
638 return presence.ControllingClient;
639 }
640
641 return null;
642 }
621 643
622 /// <summary> 644 /// <summary>
623 /// Request a filtered list of m_scenePresences in this World 645 /// Request a filtered list of m_scenePresences in this World
@@ -640,16 +662,17 @@ namespace OpenSim.Region.Environment.Scenes
640 } 662 }
641 663
642 /// <summary> 664 /// <summary>
643 /// Request a Avatar by UUID 665 /// Request a scene presence by UUID
644 /// </summary> 666 /// </summary>
645 /// <param name="avatarID"></param> 667 /// <param name="avatarID"></param>
646 /// <returns></returns> 668 /// <returns>null if the agent was not found</returns>
647 public ScenePresence GetScenePresence(LLUUID avatarID) 669 public ScenePresence GetScenePresence(LLUUID agentID)
648 { 670 {
649 if (ScenePresences.ContainsKey(avatarID)) 671 if (ScenePresences.ContainsKey(agentID))
650 { 672 {
651 return ScenePresences[avatarID]; 673 return ScenePresences[agentID];
652 } 674 }
675
653 return null; 676 return null;
654 } 677 }
655 678
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 410120f..b93367c 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -1884,7 +1884,7 @@ namespace OpenSim.Region.Environment.Scenes
1884 cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; 1884 cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset;
1885 cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset; 1885 cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset;
1886 cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS; 1886 cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS;
1887 1887 cap.GetClient = m_innerScene.GetControllingClient;
1888 m_capsHandlers[agentId] = cap; 1888 m_capsHandlers[agentId] = cap;
1889 } 1889 }
1890 1890