Table of Contents
Prim Inventory Transfer
These are the OpenSimulator scripts used in the demonstration video prim inventory transfer for transferring inventory from one object to another, and allowing transferred scripts to be set to a running state.
How They Work
Place the sender prim within 10m of the receiver and touch the receiver. The receiver will now be in a listening state on a specific channel.
Touch the sender. This will now send a message on the channel.
The receiver hears the message and gets the UUID of the sender. It sends a message back that only the sender can hear.
The sender receives the message from the receiver, and learns its UUID. It sends a list of inventory containing everything it wants to send except the scripts.
The sender now sends the scripts it wants to give, using the special function llRemoteLoadScriptPin()
, which allows the scripts to be set to a running state. It does this because it knows a secret (the PIN) which has been previously set on the receiver prim.
Note that each script sent by llRemoteLoadScriptPin()
incurs a three second penalty (the script sleeps for three seconds). It is also possible to send all the scripts with the other inventory, where they will arrive in a non-running state, then send a single script with llRemoteLoadScriptPin()
which will set the state of those scripts to running.
The scripts below use the less efficient method as they are only intended to demonstrate the setting of a PIN and the transfer of inventory.
Receiver
- receiver.ossl
//YEngine: yoptions; constant __DEBUG__ = TRUE; constant SCRIPT_PIN = 72743825; constant updateChan = -4744320; integer lhandle; debug( string text ){ if( __DEBUG__ ){ llOwnerSay( text ); } } endListen(){ if( lhandle != 0 ){ llListenRemove( lhandle ); lhandle = 0; } llSetTimerEvent(0.0); } default { state_entry() { llSetText("Receiver",<1,0.685,0>,1.0); llSetRemoteScriptAccessPin(SCRIPT_PIN); debug("Access pin set"); } touch_start(integer num){ if( llDetectedKey(0) == llGetOwner() ){ lhandle = llListen( updateChan, "", "", "" ); llSetTimerEvent(60.0); debug("Waiting for updater"); } } timer(){ endListen(); } listen(integer channel, string name, key id, string msg){ if( llGetOwnerKey( id ) == llGetOwner() ){ if( msg == "UPDATE-PING" ){ debug("Updater identified, sending READY"); endListen(); llRegionSayTo( id, updateChan, "UPDATE-PONG" ); } } } }
Sender
- sender.ossl
//YEngine: yoptions; constant __DEBUG__ = TRUE; constant SCRIPT_PIN = 72743825; constant updateChan = -4744320; integer lhandle; debug( string text ){ if( __DEBUG__ ){ llOwnerSay( text ); } } endListen(){ if( lhandle != 0 ){ llListenRemove( lhandle ); lhandle = 0; } llSetTimerEvent(0.0); } // Get inventory list // remove this script from list integer deliverItems( key id ){ list items = osGetInventoryNames( INVENTORY_ALL ); integer l = llGetListLength( items ); integer sent = 0; list results; list scripts; for( integer i = 0; i < l; i++ ){ string name = llList2String( items, i ); if( llGetInventoryType( name ) != INVENTORY_SCRIPT ){ results += [name]; } else if( name != llGetScriptName() ){ scripts += [name]; } } // make sure we deliver items before scripts if( results != [] ){ // deliver everything except the scripts // We need to give a folder name, but no folder is created in an object llGiveInventoryList( id, "AnyName", results ); sent = llGetListLength( results ); } if( scripts != [] ){ l = llGetListLength( scripts ); for( integer i = 0; i < l; i++ ){ debug("Delivering script #"+(i+1)+"/"+l); llRemoteLoadScriptPin( id, llList2String( scripts, i ), SCRIPT_PIN, TRUE, 15 ); sent++; } } return sent; } default { state_entry() { llSetText("Sender",<1,0.685,0>,1.0); debug("Script running"); } touch_start(integer num){ if( llDetectedKey(0) == llGetOwner() ){ lhandle = llListen( updateChan, "", "", "" ); llSetTimerEvent(5.0); debug("Seaching for receiver"); llWhisper( updateChan, "UPDATE-PING" ); } } timer(){ endListen(); } listen(integer channel, string name, key id, string msg){ if( llGetOwnerKey( id ) == llGetOwner() ){ if( msg == "UPDATE-PONG" ){ debug("Receiver found"); endListen(); integer sent = deliverItems( id ); debug("Inventory sent: "+sent); } } } }