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.
This commit is contained in:
parent
c40c551316
commit
c00a11a99d
4 changed files with 75 additions and 5 deletions
|
|
@ -47,6 +47,8 @@ ENV basic_Username='' \
|
||||||
datastore_ImChatHistoryLimit=50 \
|
datastore_ImChatHistoryLimit=50 \
|
||||||
datastore_PrefetchGroupMembers='true' \
|
datastore_PrefetchGroupMembers='true' \
|
||||||
datastore_PrefetchGroupRoles='false' \
|
datastore_PrefetchGroupRoles='false' \
|
||||||
|
datastore_PrefetchInventory='false' \
|
||||||
|
datastore_PrefetchInventoryDepth='2' \
|
||||||
datastore_PrefetchEstateBanlist='true' \
|
datastore_PrefetchEstateBanlist='true' \
|
||||||
datastore_AutoCleanKeyValueStore='true' \
|
datastore_AutoCleanKeyValueStore='true' \
|
||||||
datastore_CleanKeyValueStoreAfterMins=10 \
|
datastore_CleanKeyValueStoreAfterMins=10 \
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,21 @@ namespace SecondBotEvents.Config
|
||||||
settings.Add("PrefetchGroupRoles");
|
settings.Add("PrefetchGroupRoles");
|
||||||
settings.Add("PrefetchEstateBanlist");
|
settings.Add("PrefetchEstateBanlist");
|
||||||
settings.Add("PrefetchAvatarDisplaynames");
|
settings.Add("PrefetchAvatarDisplaynames");
|
||||||
|
settings.Add("PrefetchInventory");
|
||||||
|
settings.Add("PrefetchInventoryDepth");
|
||||||
settings.Add("AutoCleanKeyValueStore");
|
settings.Add("AutoCleanKeyValueStore");
|
||||||
settings.Add("CleanKeyValueStoreAfterMins");
|
settings.Add("CleanKeyValueStoreAfterMins");
|
||||||
settings.Add("CommandHistoryLimit");
|
settings.Add("CommandHistoryLimit");
|
||||||
settings.Add("HideStatusOutput");
|
settings.Add("HideStatusOutput");
|
||||||
}
|
}
|
||||||
|
public int GetPrefetchInventoryDepth()
|
||||||
|
{
|
||||||
|
return ReadSettingAsInt("PrefetchInventoryDepth", 2);
|
||||||
|
}
|
||||||
|
public bool GetPrefetchInventory()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("PrefetchInventory", false);
|
||||||
|
}
|
||||||
|
|
||||||
public bool GetPrefetchAvatarDisplaynames()
|
public bool GetPrefetchAvatarDisplaynames()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -436,14 +436,15 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public void CommandNotice(string command,string source, string args,bool accepted, string results)
|
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);
|
BotCommandNotice e = new(command, args, source, accepted, results);
|
||||||
EventHandler<BotCommandNotice> handler = BotclientCommandEventNotices;
|
EventHandler<BotCommandNotice> handler = BotclientCommandEventNotices;
|
||||||
handler?.Invoke(this, e);
|
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));
|
LogFormater.Info("Command log:" + JsonConvert.SerializeObject(e));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ using SecondBotEvents.Commands;
|
||||||
using OpenMetaverse.ImportExport.Collada14;
|
using OpenMetaverse.ImportExport.Collada14;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using OpenMetaverse.Messages.Linden;
|
using OpenMetaverse.Messages.Linden;
|
||||||
|
using Org.BouncyCastle.Asn1.BC;
|
||||||
|
using Swan;
|
||||||
|
|
||||||
namespace SecondBotEvents.Services
|
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 +
|
int sum = commandHistories.Count + KeyValueStoreLastUsed.Count + KeyValueStore.Count +
|
||||||
chatWindowsOwner.Count + chatWindowsIsGroup.Count + chatWindowsUnread.Count +
|
chatWindowsOwner.Count + chatWindowsIsGroup.Count + chatWindowsUnread.Count +
|
||||||
chatWindows.Count + localChatHistory.Count + groupRoles.Count +
|
chatWindows.Count + localChatHistory.Count + groupRoles.Count +
|
||||||
|
|
@ -999,7 +1012,51 @@ namespace SecondBotEvents.Services
|
||||||
GetClient().Avatars.AvatarPropertiesReply += AvatarDetailsReply;
|
GetClient().Avatars.AvatarPropertiesReply += AvatarDetailsReply;
|
||||||
GetClient().Groups.RequestCurrentGroups();
|
GetClient().Groups.RequestCurrentGroups();
|
||||||
_ = GetClient().Self.RetrieveInstantMessages();
|
_ = GetClient().Self.RetrieveInstantMessages();
|
||||||
|
if(myConfig.GetPrefetchInventory() == true)
|
||||||
|
{
|
||||||
|
preloadDone = false;
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
preloadFolder("root", GetClient().Inventory.Store.RootFolder.UUID, myConfig.GetPrefetchInventoryDepth(), 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<string> 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<InventoryBase> 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"];
|
readonly string[] hard_blocked_agents = ["secondlife", "second life"];
|
||||||
protected void ChatFromSim(object o, ChatEventArgs e)
|
protected void ChatFromSim(object o, ChatEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue