From c00a11a99d8ae63dc3a910ea11e97f64b5c04e5c Mon Sep 17 00:00:00 2001 From: Madpeter <57852827+Madpeterz@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:22:19 +0100 Subject: [PATCH] Add inventory prefetching support Introduces configuration options and logic for prefetching inventory folders on startup, including depth control. Updates Dockerfile and DataStoreConfig to support new settings, and modifies DataStoreService to handle inventory preloading asynchronously. --- Dockerfile | 2 + SecondBotEvents/Config/DataStoreConfig.cs | 10 ++++ SecondBotEvents/Services/CommandsService.cs | 11 ++-- SecondBotEvents/Services/DataStoreService.cs | 57 ++++++++++++++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 15456fb..6025f1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,6 +47,8 @@ ENV basic_Username='' \ datastore_ImChatHistoryLimit=50 \ datastore_PrefetchGroupMembers='true' \ datastore_PrefetchGroupRoles='false' \ + datastore_PrefetchInventory='false' \ + datastore_PrefetchInventoryDepth='2' \ datastore_PrefetchEstateBanlist='true' \ datastore_AutoCleanKeyValueStore='true' \ datastore_CleanKeyValueStoreAfterMins=10 \ diff --git a/SecondBotEvents/Config/DataStoreConfig.cs b/SecondBotEvents/Config/DataStoreConfig.cs index b622b32..1637f2a 100644 --- a/SecondBotEvents/Config/DataStoreConfig.cs +++ b/SecondBotEvents/Config/DataStoreConfig.cs @@ -18,11 +18,21 @@ namespace SecondBotEvents.Config settings.Add("PrefetchGroupRoles"); settings.Add("PrefetchEstateBanlist"); settings.Add("PrefetchAvatarDisplaynames"); + settings.Add("PrefetchInventory"); + settings.Add("PrefetchInventoryDepth"); settings.Add("AutoCleanKeyValueStore"); settings.Add("CleanKeyValueStoreAfterMins"); settings.Add("CommandHistoryLimit"); settings.Add("HideStatusOutput"); } + public int GetPrefetchInventoryDepth() + { + return ReadSettingAsInt("PrefetchInventoryDepth", 2); + } + public bool GetPrefetchInventory() + { + return ReadSettingAsBool("PrefetchInventory", false); + } public bool GetPrefetchAvatarDisplaynames() { diff --git a/SecondBotEvents/Services/CommandsService.cs b/SecondBotEvents/Services/CommandsService.cs index 4e0e656..39d8db3 100644 --- a/SecondBotEvents/Services/CommandsService.cs +++ b/SecondBotEvents/Services/CommandsService.cs @@ -436,14 +436,15 @@ namespace SecondBotEvents.Services public void CommandNotice(string command,string source, string args,bool accepted, string results) { - if(myConfig.GetCommandHistoryLogResults() == false) - { - results = ""; - } + BotCommandNotice e = new(command, args, source, accepted, results); EventHandler handler = BotclientCommandEventNotices; handler?.Invoke(this, e); - if(master.BotClient.basicCfg.GetLogCommands() == true) + if (myConfig.GetCommandHistoryLogResults() == false) + { + return; + } + if (master.BotClient.basicCfg.GetLogCommands() == true) { LogFormater.Info("Command log:" + JsonConvert.SerializeObject(e)); } diff --git a/SecondBotEvents/Services/DataStoreService.cs b/SecondBotEvents/Services/DataStoreService.cs index bb8c505..8629caa 100644 --- a/SecondBotEvents/Services/DataStoreService.cs +++ b/SecondBotEvents/Services/DataStoreService.cs @@ -10,6 +10,8 @@ using SecondBotEvents.Commands; using OpenMetaverse.ImportExport.Collada14; using System.Threading.Tasks; using OpenMetaverse.Messages.Linden; +using Org.BouncyCastle.Asn1.BC; +using Swan; namespace SecondBotEvents.Services { @@ -208,6 +210,17 @@ namespace SecondBotEvents.Services } } } + if (myConfig.GetPrefetchInventory() == true) + { + if(preloadDone == false) + { + if(preloadingFolders.Count() == 0) + { + preloadDone = true; + } + return "Loading "+preloadingFolders.Count()+" inventory folders"; + } + } int sum = commandHistories.Count + KeyValueStoreLastUsed.Count + KeyValueStore.Count + chatWindowsOwner.Count + chatWindowsIsGroup.Count + chatWindowsUnread.Count + chatWindows.Count + localChatHistory.Count + groupRoles.Count + @@ -999,7 +1012,51 @@ namespace SecondBotEvents.Services GetClient().Avatars.AvatarPropertiesReply += AvatarDetailsReply; GetClient().Groups.RequestCurrentGroups(); _ = GetClient().Self.RetrieveInstantMessages(); + if(myConfig.GetPrefetchInventory() == true) + { + preloadDone = false; + Task.Run(() => + { + preloadFolder("root", GetClient().Inventory.Store.RootFolder.UUID, myConfig.GetPrefetchInventoryDepth(), 0); + }); + } } + + protected List preloadingFolders = []; + protected bool preloadDone = true; + + protected async void preloadFolder(string foldername,UUID folder, int maxDepth, int currentDepth) + { + await Task.Run(async () => + { + lock (preloadingFolders) + { + preloadingFolders.Add(folder.Guid.ToString()); + } + await Task.Delay(1000 * currentDepth); + List foldercontents = GetClient().Inventory.FolderContents( + GetClient().Inventory.Store.RootFolder.UUID, + GetClient().Self.AgentID, true, true, + InventorySortOrder.ByName, TimeSpan.FromSeconds(30), false); + foreach (InventoryBase item in foldercontents) + { + if (item is InventoryFolder == false) + { + continue; + } + if ((currentDepth + 1) > maxDepth) + { + continue; + } + preloadFolder(item.Name, item.UUID, maxDepth, currentDepth + 1); + } + lock (preloadingFolders) + { + preloadingFolders.Remove(folder.Guid.ToString()); + } + }); + } + readonly string[] hard_blocked_agents = ["secondlife", "second life"]; protected void ChatFromSim(object o, ChatEventArgs e) {