node-metaverse icon indicating copy to clipboard operation
node-metaverse copied to clipboard

Inventory Commands fail to load folders unless cache explicitly ignored

Open KsaRedFx opened this issue 3 years ago • 9 comments

The Inventory Cache does not cache folders, at all

Currently the saveCache method saves;

        const json = {
            version: this.version,
            items: this.items
        };

While inversely, the loadCache method only looks at this.items

However, folders are under this.folders and when loading the inventory via

const inv = bot.clientCommands.inventory.getInventoryRoot();
inv = inv.populate();

You end up with a inv.folders of [] instead of the array of folders you'd expect, so you're basically forced to not use the cache at all if you want your inventory to be usable in any way

KsaRedFx avatar Sep 13 '22 19:09 KsaRedFx

inv.populate() returns a promise, are you awaiting that?

Lokomojo avatar Nov 07 '22 01:11 Lokomojo

Yes, absolutely.

I ended up just dealing with it myself / work around it by looping over the results of a different call, and await inv.populate()'ing each folder in a Promise.all() as for some reason, that caused it to finally build up a list.

The only issue is it rapidly gets stale and cannot be relied upon for many things you'd use inventory for.

KsaRedFx avatar Nov 07 '22 01:11 KsaRedFx

That's weird, because i'm using exactly that in some of my bots.

Can you provide a sample script demonstrating the failure?

Lokomojo avatar Nov 07 '22 01:11 Lokomojo

One of the really ideal scenarios for me was figuring out what items were "New" within the inventory.
I wanted to hold a copy of top-level inventory in memory, and when the bot received an item/folder I could filter down based on IDs when fetching the now-updated inventory, but always got the old (or empty) one back.

I'll have to re-write a script for this, since my code with the workaround has been done for months now

KsaRedFx avatar Nov 07 '22 01:11 KsaRedFx

Sorry to be a pain, but I really need it to be able to diagnose this issue, since I have code which depends on this feature. I need to figure out what's different.

Lokomojo avatar Nov 07 '22 01:11 Lokomojo

The initial use-case where it returns [] I can't get to happen anymore, I'm not 100% sure how I did it.... But I do still have a case where the data becomes EXTREMELY stale, fast.

All you have to do is echo out;

  const inv = bot.clientCommands.inventory.getInventoryRoot();
  await inv.populate(false);

  console.log('folders', inv.folders.map((folder) => folder.name));

Then do any operation on the inventory. Rename folders, delete folders... It does not matter. In my case, when I "receive" a folder inventory offer, I delete an older instance with the same name from the inventory

Run the above code again, and you'll get the same result as before, with the modified data not present and the old data still there

From my understanding, the false in inv.populate() is supposed to prevent that

KsaRedFx avatar Nov 07 '22 02:11 KsaRedFx

Actually I've replicated it, sorry it took me a minute; Just do this;

  const inv = bot.clientCommands.inventory.getInventoryRoot();
  await inv.populate();

  console.log('folders', inv.folders.map((folder) => folder.name));

If inv.populate() isn't false the response is folders []

KsaRedFx avatar Nov 07 '22 02:11 KsaRedFx


let login = {
  firstName: '',
  lastName: '',
  password: '',
  start: '',
  url: ''
};

const newBot = new Bot(login, BotOptionFlags.LiteObjectStore | BotOptionFlags.StoreMyAttachmentsOnly);
const init = async () => {
  try {
    const loginResp = await botCore.bot.login();
    await botCore.bot.connectToSim();
  } catch (e) {
    console.log('Failed Login', e)
  }

  botCore.bot.clientEvents.onInventoryOffered.subscribe(async (event) => {
    console.log(`Accepted inventory offer of "${event.message}" from: ${event.fromName}`);
    const inv = await botCore.bot.clientCommands.inventory.getInventoryRoot();
    await inv.populate();

    console.log('folders', inv.folders.map((folder) => folder.name));
    await botCore.bot.clientCommands.inventory.acceptInventoryOffer(event);
  });
}

export const botCore = {
  master: '',
  bot: newBot,
  connected: false,
  init,
}

botCore.init();

KsaRedFx avatar Nov 07 '22 02:11 KsaRedFx

folder.getChildFolders() works for me.

gwigz avatar Mar 19 '23 15:03 gwigz