recently i was in need of being able to send inventory items (well, a whole folder full of stuff) to the inventory of a logged-in avatar.
just copying the the inventory items to the avatar inventory (for example, using Scene.GiveInventoryItem() or Scene.GiveInventoryFolder()) will not cause your avatar to notice that there is additional junk in her inventory all of a sudden — once the avatar is logged out and logs in again, she will find the stuff in her inventory. kicking the avatar out every time you want to send some inventory her way is a tad bad on the user experience side1. clearly not something we want to do.
after trying a 101 ways of sending inventory to the avatar and none of them catching, i finally remembered that avatars can give inventory to one another, even whole folders!2 taking my favorite tool to the OpenSim source tree3 i found code in the InventoryTransferModule that seemed to take care of this process. the first attempt of just sending a GridInstantMessage via the usual means was not producing the right result: the avatar would get the pop-up that a folder was being given to her and would she like to keep it? looked good but checking the inventory revealed it to be a big blue lie.
here’s what i finally figured out. you need:
- a
ScenePresenceobject representing the avatar - the
UUIDof the sending “avatar” - the name of the sending “avatar”
- the
InventoryNodeBaseobject (actually you would pass in a subclass such asInventoryItemBaseorInventoryFolderBaseor similar)
here’s the “pseudo-code”:
// pseudo code: send inventory content to a logged in avatar's
// inventory
//
// avatar: ScenePresence object
// src: struct containing "UUID" and "Name" of the source "avatar"
// get the CachedUserInfo object for the target avatar
CachedUserInfo cuiAvatar =
m_commsManager.UserProfileCacheService.GetUserDetails(avatar,UUID);
if (!cuiAvatar.HasReceivedInventory) cuiAvatar.FetchInventory();
// target folder is the Clothing folder (type 5)
InventoryFolderImpl dstFolder = cuiAvatar.FindFolderForType(5);
// copy source folder from src avatar to dstFolder
copyFolder = scene.GiveInventoryFolder(avatar.UUID, src.UUID,
dstFolder.ID);
// content is in the target folder, ping target avatar and let her
// know about it: we do this through a GridInstantMessage
// GridInstantMessage: prepare bucket byte array first byte is asset
// type, remaining bytes are the UUID of the InventoryItem
byte[] idBytes = item.ID.GetBytes();
byte[] bucket = new byte[1 + idBytes.Length];
if (item is InventoryFolderBase)
bucket[0] = (byte)AssetType.Folder;
else if (item is InventoryItemBase)
bucket[0] = (byte)(item as e).AssetType;
Array.Copy(idBytes, 0, bucket, 1, idBytes.Length);
GridInstantMessage im =
new GridInstantMessage(scene, src.UUID, src.Name, avatar.UUID,
(byte)InstantMessageDialog.InventoryOffered,
false, item.Name, item.ID,
Vector3.Zero, bucket);
// send bulk update inventory message and GridInstantMessage
avatar.ControllingClient.SendBulkUpdateInventory(item);
avatar.ControllingClient.SendInstantMessage(im);
[/c-sharp]
-
though, i was reminded of windows’s tendency of asking you to reboot ever time you installed some piece of software…4 ↩
-
yes, i’m a bit dense sometimes…or…too focused!
↩ -
no, not that one. emacs’s
M-x grep-find! ↩ -
on second thoughts, that just proves the earlier point about this not being very user friendly… ↩

Don’t you mean server side inventory sending, or is there some client component to this?
You might also want to look at the IAR code which also does a similar thing if inventory is uploaded while a user is online.
comment by Justin Clark-Casey — August 17, 2009 @ 16:39