Difference between revisions of "LlRemoteLoadScriptPin"

From Second Life Wiki
Jump to navigation Jump to search
m (than->then typo fix)
 
(31 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{LSL_Function/inventory|name|uuid=false|type=script}}
{{LSL_Function
{{LSL_Function
|inject-2={{Issues/SVC-3321}}
{{LSL_Function/give|target|name|sim=*|uuid=false|type=script|prim=*}}{{LSL Function/boolean|running|if=*|bool=*|non-zero=*|td=the script is set as running|fd=the script is not set as running}}
|func_id=253|func_sleep=3.0|func_energy=10.0
|func_id=253|func_sleep=3.0|func_energy=10.0
|func=llRemoteLoadScriptPin
|func=llRemoteLoadScriptPin
|p1_type=key|p1_name=target|p1_desc=A prim in the same sim
|func_desc=Copy script {{LSLP|name}} into {{LSLP|target}} and set to {{LSLP|running}} with a {{LSLP|start_param}} only if {{LSLP|target}}'s [[llSetRemoteScriptAccessPin|pin]] matches {{LSLP|pin}}
|p1_type=key|p1_name=target|p1_desc
|p2_type=string|p2_name=name|p2_desc
|p2_type=string|p2_name=name|p2_desc
|p3_type=integer|p3_name=pin|p3_desc=Must match pin set by [[llSetRemoteScriptAccessPin]]
|p3_type=integer|p3_name=pin|p3_desc=Must match pin set by [[llSetRemoteScriptAccessPin]]
|p4_type=integer|p4_name=running|p4_desc=boolean, if the script is to be set as running.
|p4_type=integer|p4_subtype=boolean|p4_name=running
|p5_type=integer|p5_name=start_param|p5_desc=value returned by [[llGetStartParameter]] in the target script.
|p5_type=integer|p5_name=start_param|p5_desc=value returned by [[llGetStartParameter]] in the target script.
|func_footnote=Only works if the owner of the object this script is attached to can modify '''target'''.
|func_footnote=Only works if the [[LSL Glossary#script owner|script owner]] can modify {{LSLP|target}}.
|func_desc=Copy script '''name''' into '''target''' and if '''running''' start with '''start_param'''.
|return_text
|return_text
|spec
|spec
|caveats=*'''start_param''' survives script reset, and will only be set to the default if the object is taken into inventory.
|caveats=
* If {{LSLP|name}} is present in the {{LSLP|target}} prim's inventory then it is silently replaced.
* {{LSLP|start_param}} only lasts until the script is reset.
* Only the owner of an {{LSLGC|Attachment|attachment}} can modify it while it is being worn.
** If {{LSLP|target}} is an {{LSLGC|Attachment|attachment}} owned by a different user, regardless of object modify rights granted, this function will silently fail.
* If {{LSLP|target}} is owned by a different user and modify permission has been granted to the script owner via [http://community.secondlife.com/t5/tkb/articleprintpage/tkb-id/English_KB@tkb/article-id/215 Edit, delete, or take my objects], the script owner must be connected to the sim for this function to succeed.
* If {{LSLP|pin}} fails to match, the error "Task ~Prim~ trying to illegally load script onto task ~Other_Prim~!" is shouted on [[DEBUG_CHANNEL]]. "~Prim~" and "~Other_Prim~" are substituted with the applicable prim names.
* If {{LSLP|target}} is the script's parent (<code>{{LSLPT|target}} == [[llGetKey]]()</code>) then "Unable to add item!" is shouted on [[DEBUG_CHANNEL]].
* If the object containing this script is deeded to a group, then script {{LSLP|name}} needs transfer permissions; even if {{LSLP|target}} is deeded to the same group.
* When the script is set to run (with {{LSLP|running}}, the running checkbox or [[llSetScriptState]]) [[state_entry]] will be queued.
|constants
|constants
|examples=
|examples=
These three scripts show how to build a linked set of prims that documents itself with a psuedo-XML output.
==== Basic Example ====
The PIN setter script is placed in all child prims.  The remaining two are placed in the root prim.
=====Script copier=====
When the set is touched, a dialog is presented.  If the description button is clicked the root prim will try to
<source lang="lsl2">//Copy a script to the second prim
insert the child prim describer script in every other linked prim in a running state.  If the insertion is a success,
integer PIN=1341134;
the child prim describes itself to the owner through llOwnerSay and then deletes itself from the child prim.


Choose any legal integer as a PIN before loading the scripts into the prims.
default {
The face details function on the child describer doesn't work right now due to script size limitations.
    state_entry() {
<lsl>
        llRemoteLoadScriptPin( llGetLinkKey(2), "some script", PIN, TRUE, 0xBEEEEEEF );
//Child Prim PIN setter
    }
}</source>
=====Pin setter=====
Simple script used for setting the pin for a prim, so you can later send scripts to it with llRemoteLoadScriptPin.
<source lang="lsl2">//Child Prim PIN setter
integer PIN=1341134;
integer PIN=1341134;


default {
default {
state_entry() {
    state_entry() {
         llOwnerSay(llGetObjectName()+" : "+(string)llGetKey()+" is ready to accept a describer script using the agreed upon PIN.");
         llOwnerSay(llGetObjectName()+" : "+(string)llGetKey()+" is ready to accept a describer script using the agreed upon PIN.");
         llSetRemoteScriptAccessPin(PIN);
         llSetRemoteScriptAccessPin(PIN);
     }
     }
}
}</source>


==== Rez and copy a file from a control object ====
Notes: There is currently no signing on the starting messages only the owner is checked.


//Root Prim Describer
this example rezs a prim from inventory that has a basic control file inside of it and does a basic handshake to setup the
//************
pin and transfer the script.  
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// written by Alfred Differ
// date ~June 2008
// copyright 2008
//
//************


integer channel;
after the transfert the helper script in the rezzed prim deletes itself.
integer PIN = 1341134;


linkSetCommand()
===== Control prim =====
<source lang="lsl2">
integer controlchan = 0;
integer controlid = -1;
start()
{
    llSetTimerEvent(0);
    talkingto = NULL_KEY;
    integer a = (integer)llFrand(43);
    controlchan = a * a;
    controlchan -= controlchan * 3;
    controlid = llListen(controlchan,"","","set-connect");
    llRezObject("card",llGetPos()+<0,0,0.1>,<0,0,0>,ZERO_ROTATION,a);
    llSetTimerEvent(60);
}
key talkingto = NULL_KEY;
integer busy = FALSE;
integer accesspin = 0;
default
{
{
integer linkcount=llGetNumberOfPrims();
     timer()
    llMessageLinked(1, 1, "describe", "");
    integer loop=1;
    integer startparam=0;
     while (loop<=linkcount)
     {
     {
    if(loop>1) {llRemoteLoadScriptPin(llGetLinkKey(loop), "PrimChildDescriber", PIN, TRUE, startparam);}
        llSetTimerEvent(0);
         llMessageLinked(loop, loop, "describe", "");  
        llOwnerSay("Lost connection!");
         loop++;  
         llListenRemove(controlid);
         busy = FALSE;
     }
     }
}
     listen(integer chan,string name,key id,string message)
 
default {
     state_entry()  
     {
     {
         llOwnerSay(llGetObjectName()+" : "+(string)llGetKey()+" is ready to push a describer script to all linked prims using the agreed upon PIN.");
         if(chan == controlchan)
        {
            if(llGetOwnerKey(id) == llGetOwner())
            {
                if(talkingto == NULL_KEY)
                {
                    if(message == "set-connect")
                    {
                        llSetTimerEvent(0);
                        talkingto = id;
                        llListenRemove(controlid);
                        controlid = llListen(controlchan,"",talkingto,"ready");
                        llRegionSayTo(id,controlchan,"auto-connect");
                        llSetTimerEvent(60);
                    }
                } 
                else if(id == talkingto)
                {
                    if(message == "ready")
                    {
                        llSetTimerEvent(0);
                        accesspin = (integer)llFrand(2345)+213;
                        llListenRemove(controlid);
                        controlid = llListen(controlchan,"",talkingto,"pinset");
                        llSleep(1);
                        llRegionSayTo(talkingto,controlchan,(string)accesspin);
                        llSetTimerEvent(60);
                    }
                    else if(message == "pinset")
                    {
                        llSetTimerEvent(0);
                        llListenRemove(controlid);
                        llRemoteLoadScriptPin(talkingto,"demo.lsl",accesspin,1,0);
                        llSleep(3);
                        llRegionSayTo(talkingto,controlchan,"finished");
                        llOwnerSay("Transfer of file finished - control file should have auto deleted itself!");
                        busy = FALSE;
                    }
                }
            } 
        }
     }
     }
 
    touch_end(integer a)
listen(integer chan, string name, key id, string mes)
     {
     {
         if(id == llGetOwnerKey(id))//won't listen to objects unless they aren't in the region.
         if(busy == FALSE)
        if (llSubStringIndex(mes, "Descriptions") >= 0 )
        {
            busy = TRUE;
            if(llGetOwner() == llDetectedKey(0))
             {
             {
            llSay(0, "Starting Description Work");
                start();
            linkSetCommand();
             }
             }
    }
        }
 
    touch_start(integer total_number)
    {   
    // Create random channel within range [-1000000000,-2000000000]
channel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
llListen(channel,"", "","");
    llDialog(llDetectedKey(0), "Please choose the function to run.",
                ["Test Idea", "Descriptions"], channel);
    llListenRemove(channel);
     }
     }
}
}
//Child Prim Describer
</source>
//(Face Detail functions commented out for now due to script size limits)


// Original created by Anylyn Hax in the hot summer of 2007.
===== rezzed prim =====
// Alteration for psuedo-xml output by Alfred Differ July 2008.
<source lang="lsl2">
// This derivativee version of the code is copyright 2008.
integer listen_id = -1;
//
integer listen_chan = -1;
// This program is free software: you can redistribute it and/or modify
key details_from = NULL_KEY;
// it under the terms of the GNU General Public License as published by
default
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// The primary difference for this new version is to switch from ouput
// appropriate for the llSetPrimitiveParams() function to psuedo-XML for
// use in documentation of large builds.
 
string header_str;
string footer_str = "</prim>";
string pos_str;
string rot_str;
string size_str;
string type_str;
//string face_str;
string mat_str;
string phyz_str;
string phan_str;
string temp_str;
string flex_str;
string point_str;
 
list booleans = ([
        "FALSE",                    // 0
        "TRUE"                      // 1
        ]);
list texgens = ([
        "DEFAULT",      // 0
        "PLANAR"        // 1
        ]);
list holeshape = ([
        "DEFAULT",        //  0  default (matches the prim type: square for box, circle for cylinder, etc.)
        "","","","","","","","","","","","","","","",
        "CIRCLE",        //  16  circle
        "","","","","","","","","","","","","","","",
        "SQUARE",        //  32  square
        "","","","","","","","","","","","","","","",
        "TRIANGLE"        //  48  triangle
        ]);
list sculpttype = ([
        "SPHERE",  //  1  sphere (Converge top & bottom, stitch left side to right) 
        "TORUS",  //  2  torus (Stitch top to bottom, stitch left side to right) 
        "PLANE",  //  3  plane (No stitching or converging) 
        "CYLINDER" //  4  cylinder (Stitch left side to right, leave top and bottom open)
        ]);
list bumpmapping = ([
        "NONE",          //  0  none: no bump map 
        "BRIGHT",        //  1 brightness: generate bump map from highlights 
        "DARK",          //  2  darkness: generate bump map from lowlights 
        "WOOD",          //  3  woodgrain 
        "BARK",          //  4  bark 
        "BRICKS",        //  5  bricks 
        "CHECKER",        //  6  checker 
        "CONCRETE",      //  7  concrete 
        "TILE",          //  8  crustytile 
        "TONE",          //  9  cutstone: blocks 
        "DISKS",          //  10  discs: packed circles 
        "GRAVEL",        //  11  gravel 
        "SIDING",        //  13  siding 
        "LARGETILE",      //  14  stonetile 
        "STUCCO",        //  15  stucco 
        "SUCTION",        //  16  suction: rings 
        "WEAVE"          //  17  weave 
        ]);
list shinys = ([
        "PRIM_SHINY_NONE",          //  0  none 
        "PRIM_SHINY_LOW",          //  1 low 
        "PRIM_SHINY_MEDIUM",        //  2  medium
        "PRIM_SHINY_HIGH"          //  3  high 
        ]);
list materials =([
        "STONE",      //  0  stone 
        "METAL",      //  1  metal 
        "GLASS",      //  2  glass 
        "WOOD",      //  3  wood 
        "FLESH",      //  4  flesh 
        "PLASTIC",    //  5  plastic 
        "RUBBER",    //  6  rubber 
        "LIGHT"      //  7  light
        ]);
 
string fillHeader(integer number)
{
{
return "\n<prim\n    name="+llGetObjectName()+"\n\tkey="+(string)llGetKey()+",\n\tlinkNumber="+(string)number+">\n<description>"+llGetObjectDesc()+"</description>\n";
     on_rez(integer a)
}
     {
 
        if(a == 0)
string fillPos(list pos)
        {
{
            llOwnerSay("- Direct rez -");
     return "<position value="+(string)llList2Vector(pos, 0)+" />\n";
        }
}
        else
 
        {
string fillRot(list rot)
            llOwnerSay("- Awaiting config connection -");
{
            listen_chan = a * a;
     return "<rotation value="+(string)llList2Vector(rot, 0)+" />\n";
            listen_chan -= listen_chan * 3;
}
            listen_id = llListen(listen_chan,"","","auto-connect");
 
            llWhisper(listen_chan,"set-connect");
string fillSize(list size)
            llSetTimerEvent(30);
{
        }
    return "<size value="+(string)llList2Vector(size, 0)+" />\n";
    }
}
    timer()
 
string fillTypeDetails(list prim_type)
{
string output;
if(llList2Integer(prim_type,0)==0){output = fillTypeBox(prim_type);}
    if(llList2Integer(prim_type,0)==1){output = fillTypeCylinder(prim_type);}
if(llList2Integer(prim_type,0)==2){output = fillTypePrism(prim_type);}
if(llList2Integer(prim_type,0)==3){output = fillTypeSphere(prim_type);}
if(llList2Integer(prim_type,0)==4){output = fillTypeTorus(prim_type);}
if(llList2Integer(prim_type,0)==5){output = fillTypeTube(prim_type);}
if(llList2Integer(prim_type,0)==6){output = fillTypeRing(prim_type);}
if(llList2Integer(prim_type,0)==7){output = fillTypeSculpt(prim_type);}
return output;
}
 
string fillTypeBox(list prim_type)
{
string output = "<type value=box>\n";
    output += "\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
    output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
    output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
    output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
    output += "\t<topsize value="+(string)llList2Vector(prim_type,5)+" />\n";
    output += "\t<topshear value="+(string)llList2Vector(prim_type,6)+" />\n";
    output += "</type>\n";
    return output;
}
 
string fillTypeCylinder(list prim_type)
{
string output = "<type value=cylinder>\n";
output += "\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
output += "\t<topsize value="+(string)llList2Vector(prim_type,5)+" />\n";
output += "\t<topshear value="+(string)llList2Vector(prim_type,6)+" />\n";
output += "</type>\n";
return output;
}
 
string fillTypePrism(list prim_type)
{
string output = "<type value=Prism>\n";
output += "\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
output += "\t<topsize value="+(string)llList2Vector(prim_type,5)+" />\n";
output += "\t<topshear value="+(string)llList2Vector(prim_type,6)+" />\n";
output += "</type>\n";
return output;
}
 
string fillTypeSphere(list prim_type)
{
string output = "<type value=Sphere>\n";
output += "\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
output += "\t<dimple value="+(string)llList2Vector(prim_type,5)+" />\n";
output += "</type>\n";
return output;
}
 
string fillTypeTorus(list prim_type)
{
string output = "<type value=Torus>\n";
output += "\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
output += "\t<holesize value="+(string)llList2Vector(prim_type,5)+" />\n";
output += "\t<topshear value="+(string)llList2Vector(prim_type,6)+" />\n";
output += "\t<advancedcut value="+(string)llList2Vector(prim_type,7)+" />\n";
output += "\t<taper value="+(string)llList2Vector(prim_type,8)+" />\n";
output += "\t<revs value="+(string)llList2Float(prim_type,9)+" />\n";
output += "\t<radoffset value="+(string)llList2Float(prim_type,10)+" />\n";
output += "\t<skew value="+(string)llList2Float(prim_type,11)+"</element>\n";
output += "</type>\n";
return output;
}
 
string fillTypeTube(list prim_type)
{
string output = "<type value=Tube>\n";
output += "\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
output += "\t<holesize value="+(string)llList2Vector(prim_type,5)+" />\n";
output += "\t<topshear value="+(string)llList2Vector(prim_type,6)+" />\n";
output += "\t<advancedcut value="+(string)llList2Vector(prim_type,7)+" />\n";
output += "\t<taper value="+(string)llList2Vector(prim_type,8)+" />\n";
output += "\t<revs value="+(string)llList2Float(prim_type,9)+" />\n";
output += "\t<radoffset value="+(string)llList2Float(prim_type,10)+" />\n";
output += "\t<skew value="+(string)llList2Float(prim_type,11)+" />\n";
output += "</type>\n";
return output;
}
 
string fillTypeRing(list prim_type)
{
string output = "<type value=Ring>\n";
output += "\t<\t<holeshape value="+(string)llList2String(holeshape ,llList2Integer(prim_type,1))+" />\n";
output += "\t<cut value="+(string)llList2Vector(prim_type,2)+" />\n";
output += "\t<hollow value="+(string)llList2Float(prim_type,3)+" />\n";
output += "\t<twist value="+(string)llList2Vector(prim_type,4)+" />\n";
output += "\t<holesize value="+(string)llList2Vector(prim_type,5)+" />\n";
output += "\t<topshear value="+(string)llList2Vector(prim_type,6)+" />\n";
output += "\t<advancedcut value="+(string)llList2Vector(prim_type,7)+" />\n";
output += "\t<taper value="+(string)llList2Vector(prim_type,8)+" />\n";
output += "\t<revs value="+(string)llList2Float(prim_type,9)+" />\n";
output += "\t<radoffset value="+(string)llList2Float(prim_type,10)+" />\n";
output += "\t<skew value="+(string)llList2Float(prim_type,11)+" />\n";
output += "</type>\n";
return output;
}
 
string fillTypeSculpt(list prim_type)
{
string output = "<type value=Sculpt>\n";
output += "\t<map value="+(string)llList2String(prim_type,1)+" />\n";
output += "\t<type value="+(string)llList2Integer(prim_type,2)+" />\n";
output += "</type>\n";
return output;
}
 
string fillFaceDetail(integer sides)
{
integer i=0;
list bump_shiny;
list color;
list bright;
list texgen;
list texture;
string output="\n<property name=face>\n";
 
while(i <= sides)  
     {
     {
    bump_shiny=llGetPrimitiveParams([PRIM_BUMP_SHINY,i]);
        llOwnerSay("Failed to connect to rezzer deleting myself!");
color=llGetPrimitiveParams([PRIM_COLOR,i]);
        llSetTimerEvent(0);
bright=llGetPrimitiveParams([PRIM_FULLBRIGHT,i]);
        llDie();
texgen=llGetPrimitiveParams([PRIM_TEXGEN ,i]);
texture=llGetPrimitiveParams([PRIM_TEXTURE,i]);
    output += "\t<facenumber value="+(string)i+" />\n";
       
if (bump_shiny != [])
{
output += "\t<element name=bumpshiny>\n";
output += "\t\t<shine value="+llList2String(shinys,llList2Integer(bump_shiny,0))+" />\n";
output += "\t\t<bump value="+llList2String(bumpmapping ,llList2Integer(bump_shiny,1))+" />\n";
output += "\t</element>\n";
bump_shiny = [];
}
if (color != [])  
{
output += "\t<element name=color>\n";
output += "\t\t<color value=>"+(string)llList2Vector(color,0)+" />\n";
output += "\t\t<alpha value=>"+(string)llList2Float(color,1)+" />\n";
output += "\t</element>\n";
color = [];
}
if (bright != [])
{
output += "\t<element name=fullbright>\n";
output += "\t\t<light value=>"+(string)llList2String(booleans ,llList2Integer(bright,0))+" />\n";
output += "\t</element>\n";
bright = [];
}
if (texgen != [])
{
output += "\t<element name=textgen>\n";
output += "\t\t<mode value="+llList2String(texgens,llList2Integer(texgen,0))+" />\n";
output += "\t</element>\n";
texgen = [];
}
if (texture != [])
{
output += "\t<element name=texture>\n";
            output += "\t\t<key value="+(string)llList2String(texture,0)+" />\n";
output += "\t\t<repeats value="+(string)llList2Vector(texture,1)+" />\n";
            output += "\t\t<offsets value="+(string)llList2Vector(texture,2)+" />\n";
output += "\t\t<rotation value="+(string)llList2Float(texture,3)+" />\n";
            output += "\t</element>\n";
texture = [];
}
    i++;
     }
     }
output = "\n</property>\n";
     listen(integer chan,string name,key id,string message)
return output;
}
 
string fillMatDetail(list mat)
{
  return "<material value="+(string)llList2String(materials ,llList2Integer(mat,0))+" />\n";
}
 
string fillPhyzDetail(list physics)
{
string output = "<physics value="+(string)llList2String(booleans ,llList2Integer(physics ,0))+" />\n";
if (llSubStringIndex(output, "FALSE") >= 0 ) {output="";}
return output;
}
 
string fillPhanDetail(list phantom)
{
     string output = "<phantom value="+(string)llList2String(booleans ,llList2Integer(phantom ,0))+" />\n";
    if (llSubStringIndex(output, "FALSE") >= 0 ) {output="";}
    return output;
}
 
string fillTempDetail(list temprez)
{
string output = "<temprez value="+(string)llList2String(booleans ,llList2Integer(temprez ,0))+" />\n";
if (llSubStringIndex(output, "FALSE") >= 0 ) {output="";}
return output;
}
 
string fillLightDetail(list light)
{
string output = "<pointlight>\n";
output += "\t<enabled value="+(string)llList2String(booleans ,llList2Integer(light,0))+" />\n";
output += "\t<color value="+(string)llList2Vector(light,1)+" />\n";
output += "\t<intensity value="+(string)llList2Float(light,2)+" />\n";
output += "\t<radius value="+(string)llList2Float(light,3)+" />\n";
output += "\t<falloff value="+(string)llList2Float(light,4)+" />\n";
    output += "</pointlight>\n";
    if (llSubStringIndex(output, "FALSE") >= 0 ) {output="";}
return output;
}
 
string fillFlexDetail(list flex)
{
string output = "<flex>\n";
output += "\t<enabled value="+(string)llList2String(booleans ,llList2Integer(flex,0))+" />\n";
output += "\t<softness value="+(string)llList2Integer(flex,1)+" />\n";
output += "\t<gravity value="+(string)llList2Float(flex,2)+" />\n";
output += "\t<friction value="+(string)llList2Float(flex,3)+" />\n";
output += "\t<wind value="+(string)llList2Float(flex,4)+" />\n";
output += "\t<tension value="+(string)llList2Float(flex,5)+" />\n";
output += "\t<force value="+(string)llList2Vector(flex,6)+" />\n";
output += "</flex>\n";
if (llSubStringIndex(output, "FALSE") >= 0 ) {output="";}
return output;
}
 
default
{
    link_message(integer sender_number, integer number, string message, key id)
     {
     {
header_str = fillHeader(number);
         if(llGetOwnerKey(id) == llGetOwner())
         pos_str = fillPos(llGetPrimitiveParams([PRIM_POSITION]));
rot_str = fillRot(llGetPrimitiveParams([PRIM_ROTATION]));
size_str = fillSize(llGetPrimitiveParams([PRIM_SIZE]));
        type_str = fillTypeDetails(llGetPrimitiveParams([PRIM_TYPE]));
        //face_str = fillFaceDetail(llGetNumberOfSides());
        mat_str = fillMatDetail(llGetPrimitiveParams([PRIM_MATERIAL]));
phyz_str = fillPhyzDetail(llGetPrimitiveParams([PRIM_PHYSICS]));
phan_str = fillPhanDetail(llGetPrimitiveParams([PRIM_PHANTOM]));
temp_str = fillTempDetail(llGetPrimitiveParams([PRIM_TEMP_ON_REZ]));
point_str = fillLightDetail(llGetPrimitiveParams([PRIM_POINT_LIGHT]));
flex_str = fillFlexDetail(llGetPrimitiveParams([PRIM_FLEXIBLE]));
 
llOwnerSay(header_str+pos_str+rot_str+size_str+type_str+point_str+mat_str+phyz_str+phan_str+temp_str+flex_str+footer_str);
        llOwnerSay((string)llGetFreeMemory() + " Bytes"); 
        if (number != 1)  
         {
         {
        llRemoveInventory(llGetScriptName());
            if(message == "auto-connect")
         }    
            {
                llSetTimerEvent(0);
                llListenRemove(listen_id);
                listen_id = llListen(listen_chan,"",id,"");
                llRegionSayTo(id,listen_chan,"ready");
                details_from = id;
                llSetTimerEvent(30);               
            }
            else if(details_from != NULL_KEY)
            {
                llSetTimerEvent(0); 
                if(message == "finished")
                {
                    llSetRemoteScriptAccessPin((integer)message);
                    llRemoveInventory(llGetScriptName());        
                }
                else
                {
                    llSetRemoteScriptAccessPin((integer)message);
                    llRegionSayTo(id,listen_chan,"pinset");
                }
                llSetTimerEvent(30); 
            }
         }
     }
     }
}
}
</lsl>
</source>


|helpers
|helpers
|also_functions={{LSL DefineRow||[[llSetRemoteScriptAccessPin]]|Used to setup a prim for remote loading}}
|also_functions={{LSL DefineRow||[[llSetRemoteScriptAccessPin]]|Used to setup a prim for remote loading}}
{{LSL DefineRow||[[llSetScriptState]]|Set a scripts running state}}
{{LSL DefineRow||[[llResetOtherScript]]|Reset another script in the prim}}
|also_tests
|also_tests
|also_events
|also_events
|also_articles
|also_articles
|history=
* Added in 1.2.6
* In SL 1.25.4 this function will not copy/move any script into an attachment unless the script is full perm. ([https://jira.secondlife.com/browse/SVC-3725 SVC-3725])
* SL 1.25.5 will allow this function to copy/move a script into an attachment so long as the target has matching (or more restrictive) copy and transfer permissions. ([https://jira.secondlife.com/browse/SVC-3738 SVC-3738])
|notes
|notes
|cat1=Script
|cat1=Script
|cat2
|cat2=Inventory
|cat3
|cat3
|cat4
|cat4
}}
}}

Latest revision as of 20:55, 1 April 2019

Summary

Function: llRemoteLoadScriptPin( key target, string name, integer pin, integer running, integer start_param );

Copy script name into target and set to running with a start_param only if target's pin matches pin

• key target prim UUID that is in the same region
• string name a script in the inventory of the prim this script is in
• integer pin Must match pin set by llSetRemoteScriptAccessPin
• integer running boolean, if TRUE[1] the script is set as running, if FALSE the script is not set as running
• integer start_param value returned by llGetStartParameter in the target script.

Only works if the script owner can modify target.

Caveats

  • This function causes the script to sleep for 3.0 seconds.
  • If target is not owned by the same person, and name does not have transfer permissions, an error is shouted on DEBUG_CHANNEL.
  • If name permissions do not allow copy, the transfer fails and an error is shouted on DEBUG_CHANNEL.
  • If target is not in the same region an error is shouted on DEBUG_CHANNEL.
  • When scripts are copied or moved between inventories, their state does not survive the transfer. Memory, event queue and execution position are all discarded.
  • If name is missing from the prim's inventory or it is not a script then an error is shouted on DEBUG_CHANNEL.
  • If name is present in the target prim's inventory then it is silently replaced.
  • start_param only lasts until the script is reset.
  • Only the owner of an attachment can modify it while it is being worn.
    • If target is an attachment owned by a different user, regardless of object modify rights granted, this function will silently fail.
  • If target is owned by a different user and modify permission has been granted to the script owner via Edit, delete, or take my objects, the script owner must be connected to the sim for this function to succeed.
  • If pin fails to match, the error "Task ~Prim~ trying to illegally load script onto task ~Other_Prim~!" is shouted on DEBUG_CHANNEL. "~Prim~" and "~Other_Prim~" are substituted with the applicable prim names.
  • If target is the script's parent (target == llGetKey()) then "Unable to add item!" is shouted on DEBUG_CHANNEL.
  • If the object containing this script is deeded to a group, then script name needs transfer permissions; even if target is deeded to the same group.
  • When the script is set to run (with running, the running checkbox or llSetScriptState) state_entry will be queued.

Important Issues

~ All Issues ~ Search JIRA for related Bugs
   stack trace error while running scripts after llRemoteLoadScriptPin

Examples

Basic Example

Script copier
//Copy a script to the second prim
integer PIN=1341134;

default {
    state_entry() {
        llRemoteLoadScriptPin( llGetLinkKey(2), "some script", PIN, TRUE, 0xBEEEEEEF );
    }
}
Pin setter

Simple script used for setting the pin for a prim, so you can later send scripts to it with llRemoteLoadScriptPin.

//Child Prim PIN setter
integer PIN=1341134;

default {
    state_entry() {
        llOwnerSay(llGetObjectName()+" : "+(string)llGetKey()+" is ready to accept a describer script using the agreed upon PIN.");
        llSetRemoteScriptAccessPin(PIN);
    }
}

Rez and copy a file from a control object

Notes: There is currently no signing on the starting messages only the owner is checked.

this example rezs a prim from inventory that has a basic control file inside of it and does a basic handshake to setup the pin and transfer the script.

after the transfert the helper script in the rezzed prim deletes itself.

Control prim
integer controlchan = 0;
integer controlid = -1;
start()
{
    llSetTimerEvent(0);
    talkingto = NULL_KEY;
    integer a = (integer)llFrand(43);
    controlchan = a * a;
    controlchan -= controlchan * 3;
    controlid = llListen(controlchan,"","","set-connect");
    llRezObject("card",llGetPos()+<0,0,0.1>,<0,0,0>,ZERO_ROTATION,a);
    llSetTimerEvent(60);
}
key talkingto = NULL_KEY;
integer busy = FALSE;
integer accesspin = 0;
default
{
    timer()
    {
        llSetTimerEvent(0);
        llOwnerSay("Lost connection!");
        llListenRemove(controlid);
        busy = FALSE;
    }
    listen(integer chan,string name,key id,string message)
    {
        if(chan == controlchan)
        {
            if(llGetOwnerKey(id) == llGetOwner())
            {
                if(talkingto == NULL_KEY)
                {
                    if(message == "set-connect")
                    {
                        llSetTimerEvent(0);
                        talkingto = id;
                        llListenRemove(controlid);
                        controlid = llListen(controlchan,"",talkingto,"ready");
                        llRegionSayTo(id,controlchan,"auto-connect");
                        llSetTimerEvent(60);
                    }
                }   
                else if(id == talkingto)
                {
                    if(message == "ready")
                    {
                        llSetTimerEvent(0);
                        accesspin = (integer)llFrand(2345)+213;
                        llListenRemove(controlid);
                        controlid = llListen(controlchan,"",talkingto,"pinset");
                        llSleep(1);
                        llRegionSayTo(talkingto,controlchan,(string)accesspin);
                        llSetTimerEvent(60);
                    }
                    else if(message == "pinset")
                    {
                        llSetTimerEvent(0);
                        llListenRemove(controlid);
                        llRemoteLoadScriptPin(talkingto,"demo.lsl",accesspin,1,0);
                        llSleep(3);
                        llRegionSayTo(talkingto,controlchan,"finished");
                        llOwnerSay("Transfer of file finished - control file should have auto deleted itself!");
                        busy = FALSE;
                    }
                } 
            }   
        }
    }
    touch_end(integer a)
    {
        if(busy == FALSE)
        {
            busy = TRUE;
            if(llGetOwner() == llDetectedKey(0))
            {
                start();
            }
        }
    }
}
rezzed prim
integer listen_id = -1;
integer listen_chan = -1;
key details_from = NULL_KEY;
default
{
    on_rez(integer a)
    {
        if(a == 0)
        {
            llOwnerSay("- Direct rez -");
        }
        else
        {
            llOwnerSay("- Awaiting config connection -");
            listen_chan = a * a;
            listen_chan -= listen_chan * 3;
            listen_id = llListen(listen_chan,"","","auto-connect");
            llWhisper(listen_chan,"set-connect");
            llSetTimerEvent(30);
        }
    }
    timer()
    {
        llOwnerSay("Failed to connect to rezzer deleting myself!");
        llSetTimerEvent(0);
        llDie();
    }
    listen(integer chan,string name,key id,string message)
    {
        if(llGetOwnerKey(id) == llGetOwner())
        {
            if(message == "auto-connect")
            {
                llSetTimerEvent(0);
                llListenRemove(listen_id);
                listen_id = llListen(listen_chan,"",id,"");
                llRegionSayTo(id,listen_chan,"ready");
                details_from = id;
                llSetTimerEvent(30);                 
            }
            else if(details_from != NULL_KEY)
            {
                llSetTimerEvent(0);  
                if(message == "finished")
                {
                    llSetRemoteScriptAccessPin((integer)message);
                    llRemoveInventory(llGetScriptName());         
                }
                else
                {
                    llSetRemoteScriptAccessPin((integer)message);
                    llRegionSayTo(id,listen_chan,"pinset");
                } 
                llSetTimerEvent(30);  
            }
        }
    }
}

See Also

Functions

•  llSetRemoteScriptAccessPin Used to setup a prim for remote loading
•  llSetScriptState Set a scripts running state
•  llResetOtherScript Reset another script in the prim

Deep Notes

History

  • Added in 1.2.6
  • In SL 1.25.4 this function will not copy/move any script into an attachment unless the script is full perm. (SVC-3725)
  • SL 1.25.5 will allow this function to copy/move a script into an attachment so long as the target has matching (or more restrictive) copy and transfer permissions. (SVC-3738)

All Issues

~ Search JIRA for related Issues
   stack trace error while running scripts after llRemoteLoadScriptPin

Footnotes

  1. ^ Any value that is not zero/FALSE is treated the same as TRUE. This behavior should not be depended upon.

Signature

function void llRemoteLoadScriptPin( key target, string name, integer pin, integer running, integer start_param );