SecondBot/SecondBotEvents/Static/Inventory.cs
Madpeter 008cb44e24 Use UnsafeRelaxed JSON serialization globally
Replaces all usages of JsonSerializer.Serialize with the UnsafeRelaxed option via a new JsonOptions.UnsafeRelaxed static property. This ensures consistent relaxed escaping for all JSON output, improving compatibility with consumers expecting unescaped JSON. Refactors affected command, service, and static classes to use the new option.
2025-10-05 20:07:42 +01:00

256 lines
8.7 KiB
C#

using OpenMetaverse;
using OpenMetaverse.ImportExport.Collada14;
using SecondBotEvents.Services;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
namespace BetterSecondBot.Static
{
public class InventoryMapFolder
{
public string id;
public string name;
public List<InventoryMapFolder> subfolders = [];
}
public class InventoryMapItem
{
public string id;
public string name;
public string typename;
}
public static class HelperInventory
{
public static InventoryItem getItemByInventoryUUID(GridClient bot, UUID target)
{
return bot.Inventory.FetchItem(target, bot.Self.AgentID, TimeSpan.FromSeconds(15));
}
public static UUID GetAssetUUID(GridClient bot, UUID target)
{
InventoryItem A = getItemByInventoryUUID(bot, target);
if (A != null)
{
return A.AssetUUID;
}
return UUID.Zero;
}
public static InventoryFolder FindFolderByPath(GridClient bot, string path)
{
return DigFolderForPath(bot, path, 0, bot.Inventory.Store.RootFolder.UUID);
}
private static InventoryFolder DigFolderForPath(GridClient bot, string path, int level, UUID folder)
{
string[] bits = path.Split('/');
List<InventoryBase> T = bot.Inventory.Store.GetContents(folder);
InventoryFolder foundFolder = null;
bool found = false;
foreach (InventoryBase t in T)
{
if (t.GetType() == typeof(InventoryFolder))
{
if (t.Name == bits[level])
{
folder = t.UUID;
if (bits.Length > (level+1))
{
// need to go deeper
foundFolder = DigFolderForPath(bot, path, level + 1, folder);
if (foundFolder != null)
{
found = true;
}
}
else
{
// we are here
foundFolder = (InventoryFolder)t;
found = true;
break;
}
}
else
{
continue;
}
}
else
{
continue;
}
}
if(found == true)
{
return foundFolder;
}
else
{
return null;
}
}
public static InventoryBase FindFolder(GridClient bot, InventoryFolder current,UUID target)
{
List<InventoryBase> T = bot.Inventory.Store.GetContents(current);
InventoryBase Found = null;
foreach (InventoryBase R in T)
{
if(R.UUID == target)
{
Found = R;
break;
}
else
{
InventoryBase FoundSub = FindFolder(bot, (InventoryFolder)R, target);
if(FoundSub != null)
{
Found = FoundSub;
break;
}
}
}
return Found;
}
public static List<InventoryMapItem> getfolderinventory(GridClient bot, UUID folder)
{
List<InventoryMapItem> entrys = [];
InventoryNode node = bot.Inventory.Store.GetNodeFor(folder);
InventoryMapItem mapitem = new()
{
name = node.Data.Name,
id = node.Data.UUID.ToString(),
typename = "Folder"
};
entrys.Add(mapitem);
List<InventoryBase> contents = bot.Inventory.FolderContents(folder, bot.Self.AgentID, true, true, InventorySortOrder.ByDate, TimeSpan.FromSeconds(45), true);
if (contents != null)
{
if (contents.Count > 0)
{
foreach (InventoryBase item in contents)
{
mapitem = new InventoryMapItem
{
name = item.Name,
id = item.UUID.ToString(),
typename = item.GetType().Name
};
entrys.Add(mapitem);
}
}
}
return entrys;
}
public static string MapFolderInventoryJson(GridClient bot,UUID folder)
{
return JsonSerializer.Serialize(getfolderinventory(bot, folder), JsonOptions.UnsafeRelaxed);
}
public static KeyValuePair<string,string> MapFolderInventoryHumanReadable(GridClient bot, UUID folder)
{
StringBuilder output = new();
string foldername = "Unknown";
foreach(InventoryMapItem mitem in getfolderinventory(bot, folder))
{
if(mitem.typename == "Folder")
{
foldername = mitem.name;
}
output.Append("ID: ");
output.Append(mitem.id);
output.Append(" | ");
output.Append("Name: ");
output.Append(mitem.name);
output.Append(" | ");
output.Append("Type: ");
output.Append(mitem.typename);
output.Append("\n\r");
}
return new KeyValuePair<string,string>(foldername,output.ToString());
}
public static string MapFolderJson(GridClient bot,string targetFolder="root", bool subfolders = true)
{
if (bot.Inventory.Store != null)
{
if (bot.Inventory.Store.RootFolder != null)
{
InventoryFolder topLevel = null;
if (targetFolder == "root")
{
topLevel = bot.Inventory.Store.RootFolder;
}
else
{
if(UUID.TryParse(targetFolder, out UUID folderUUID) == true)
{
topLevel = new InventoryFolder(folderUUID);
}
}
if (topLevel != null)
{
return JsonSerializer.Serialize(DoMapFolderJson(bot, topLevel, subfolders), JsonOptions.UnsafeRelaxed);
}
}
}
return null;
}
public static InventoryMapFolder DoMapFolderJson(GridClient bot, InventoryFolder folder, bool subfolders=true)
{
InventoryMapFolder ReplyFolder = new()
{
id = folder.UUID.ToString(),
name = folder.Name
};
Dictionary<string, string> foldernode = [];
List<InventoryBase> T = bot.Inventory.Store.GetContents(folder);
foreach (InventoryBase R in T)
{
if (R.GetType() == typeof(InventoryFolder))
{
if (subfolders == true)
{
ReplyFolder.subfolders.Add(DoMapFolderJson(bot, (InventoryFolder)R, subfolders));
}
}
}
return ReplyFolder;
}
public static string MapFolderHumanReadable(GridClient bot)
{
StringBuilder B = new();
DoMapFolderHumanReadable(bot, 0, bot.Inventory.Store.RootFolder, B);
return B.ToString();
}
public static void DoMapFolderHumanReadable(GridClient bot,int level, InventoryFolder folder, StringBuilder reply)
{
List<InventoryBase> T = bot.Inventory.Store.GetContents(folder);
foreach (InventoryBase R in T)
{
if (R.GetType() == typeof(InventoryFolder))
{
reply.Append("" + Spaces(level) + "|- " + R.Name + " [" + R.UUID.ToString() + "]\n\r");
DoMapFolderHumanReadable(bot, level + 1, (InventoryFolder)R, reply);
}
}
}
public static string Spaces(int counter)
{
StringBuilder reply = new();
while (counter > 0)
{
reply.Append(" ");
counter--;
}
return reply.ToString();
}
}
}