Philip P. Ide

Author, programmer, science enthusiast, half-wit.
Life is sweet. Have you tasted it lately?

User Tools

Site Tools


blog:opensim:scripts:prim_inv_trans

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);
            }
        }
    }
}
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
blog/opensim/scripts/prim_inv_trans.txt · Last modified: by Phil Ide

Except where otherwise noted, content on this wiki is licensed under the following license: Copyright © Phil Ide
Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki