Difference between revisions of "User:Nexii Malthus/Script API"

From Second Life Wiki
Jump to navigation Jump to search
(New page: Based from LSL To Client Communication I decided to go ahead and attempt to fully implement a modified version of the protoc...)
 
m (<lsl> tag to <source>)
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Based from [[http://wiki.secondlife.com/wiki/LSL_To_Client_Communication|LSL To Client Communication]]
Based from [[LSL_To_Client_Communication|LSL To Client Communication]]
I decided to go ahead and attempt to fully implement a modified version of the protocol.
I decided to go ahead and attempt to fully implement a modified version of the protocol.


Please see Dale's implementation first, so not everything has to be repeated here and you might see the slight differences in my protocol.
Please see Dale's implementation first, so not everything has to be repeated here and you might see the slight differences in my protocol.


== Protocol ==
= Protocol =
Before anything can be queried, a connection has to be made with the client by agreeing on a common channel for receiving responses. The protocol uses tokens like Dale's implementation. Any message addressed to the viewer has to begin with 'Vwr'.
Before anything can be queried, a connection has to be made with the client by agreeing on a common channel for receiving responses. The protocol uses tokens like Dale's implementation. Any message addressed to the viewer has to begin with 'Vwr'.


The connection is made with the command Connect, followed by a channel number.
The connection is made with the command Connect, followed by a channel number.
Query:
Query:
$Vwr$Connect$123456
:$Vwr$Connect$123456


The client will then verify this connection by an 'Ok.' on the channel. Repeating the query with a different channel will change the agreed upon channel to the new one.
The client will then verify this connection by an 'Ok.' on the channel. Repeating the query with a different channel will change the agreed upon channel to the new one.
Line 16: Line 16:


There are some general basic functions.
There are some general basic functions.
$Vwr$Capabilities
:$Vwr$Capabilities
$Vwr$Client
:$Vwr$Client
$Vwr$Creator
:$Vwr$Creator
$Vwr$OperatingSystem
:$Vwr$OperatingSystem


Then there are 'Packages' or 'Extensions', much like in Dale's implementation, but not really requiring a full name of the creator.
Then there are 'Packages' or 'Extensions', much like in Dale's implementation, but not really requiring a full name of the creator.


The two current extensions are 'Nexii' and 'Permission'.
The current extension available is 'Nexii', this contains some client side processing like Raycasting (custom raytraces of a line), or special features like the Picker (third-person click-triggered raycasting).


Permission is used to request permission from the user for client-side powers of various functions that may need special User permission granted first.
Some or most functions require special permissions (using the normal permission system but with custom bits) that may contain sensitive data or incorrect use causing potential system instability, this makes sure that rouge scripts won't be able to cause havoc or pry on private information unless explicit permission is given by the user.
$Vwr$Permission$NexiiPicker


'Nexii' is empty at the time of writing but im implementing a function for being able to receive 'touches' in the world or clicks aka Picker.
(Note: Dialogs are incorrectly referenced currently, despite being the correct permissions given, not sure why its doing this exactly)
$Vwr$Nexii$Picker$<Arguments>
$Vwr$Nexii$Picker$World|Once
$Vwr$Nexii$Picker$HUD|All
$Vwr$Nexii$Picker$Once|HUD|World


== Example ==
= Components =
This is a working example LSL Script
 
<lsl>
== Picker ==
;Brief :Allows a script to subscribe to the 'picker', which is basically to know where a user clicks/touches (''Actions'') on certain surfaces/objects/geometry (''SurfaceType'') and what kind of data the script wants (''Output'') back out of the actions. The subscribe function expects 'bits' that are OR'd together ("|") (OR is a bitwise operator).
 
;Call :'''$Vwr$Nexii$Picker$Subscribe$'''''ActionBits'' OR'd ''SurfaceTypeBits'' OR'd ''OutputBits''
=== Bits ===
;Actions:
:'''Start, Stop,''' for touchable surfaces, any prim with scripts that have a touch event handler.
:'''Start Click, Stop Click,''' just ordinary empty clicks that didn't lead to anything.
 
;Surface Types:
:'''HUD, Av, Prims, Terrain, Water,''' Water is untested
 
;Output:
:'''Pos,''' equivilant to [[llDetectedTouchST]].
:'''Normal,''' equivilant to [[llDetectedTouchNormal]].
:'''Binormal,''' equivilant to [[llDetectedTouchBinormal]].
:'''UUID,''' the key of the object hit.
:'''Get Touch,''' the type of the touch for this message.
:'''Get Type''' the (internal) object type of the surface hit.
 
=== Picker Example ===
;$Vwr$Nexii$Picker$Subscribe$Start Click|Stop Click|Prims|Pos
:This subscription would cause any ''start and stop clicks'' on ''prims'', to cause a message to be returned to the connected channel, simply with the ''Pos'', which is the intersection and precise location in world coordinates where these clicks ocurred by the connected user. For example "''<125.45,23.8,123.456>''", which could then be easily converted into a vector and plugged into functions directly.
 
;$Vwr$Nexii$Picker$Subscribe$Start Click|Av|UUID
:This simply returns the ''UUID'' of any ''Av''atars that were clicked on into the connected channel.
 
== Picker Ghosting ==
;Brief :A function to position any single prim or linked object wherever the cursor 'hovers'. Only one Ghost may exist. A ghost may be removed via setting the target key to a null key, this may cause the target to disappear from the users screen and an update may be needed to return it to the original location.
 
;Call: :'''$Vwr$Nexii$Picker$Ghost$'''''Key1'':''Value1''|''Key2'':''Value2'':''Value3''|''Key3'':''Value4''|...
 
;Keys
:'''uuid,''' the target object to ghost.
:'''Mode,''' Argument takes a single integer defining the mode of the ghosting. 0: Instant, 1: Damped, 2: No Rotation, 3: Limit Rotation (Arc Max/Min/Dir)
:'''Arc,''' Value 1 is the maximum of arc (1.0 ~> -1.0, Default 1.0), Value 2 is the minimum of the arc (-1.0 ~> 1.0, Default -1.0). Equivilance: 1.0 is horizontal, 0.0 is vertical, -1.0 is upside down, 0.5 is 45 degrees.
:'''Dir,''' direction to test the arc against.
 
Arc can easily be imagined as llSensor or more specifically a dimpled sphere. Dir (Direction) is a normalised vector that points into the direction of the dimpled sphere's rotation or where the sphere is looking towards.
 
== Selection ==
;Brief :Allows scripts to connect to the Selection Manager of the client which handles prim selections.
 
;Call: :'''$Vwr$Nexii$Selection$Selection$'''''Mode''
 
;Mode: :Only ''FirstObject'' available at the moment, which immediately returns the UUID of the root object in a selection.
 
= Examples =
These work from Vertical Life v1.5 on up to v1.5.3. v1.5.4 has had some changes in Picker.
 
=== Picker ===
<source lang="lsl2">
default {
    state_entry(){
        llListen( 9000, "", llGetOwner(), "" );
        llOwnerSay( "$Vwr$Ping$9000" );
    }
   
    listen( integer ch, string nm, key k, string msg ){
        if( msg == "pong:0" ) state Main;
    }
   
    on_rez( integer p ){ llResetScript(); }
}
 
state Main {
    state_entry(){
        llListen( 9001, "", llGetOwner(), "" );
        llOwnerSay( "$Vwr$Connect$9001" );
    }
   
    run_time_permissions( integer p ){
        if( p & (0x1<<31) ) llOwnerSay( "$Vwr$Nexii$Picker$World|All" );
    }
   
    listen( integer ch, string nm, key k, string msg ){
        if( msg == "Ok." ){
            llOwnerSay( "Connection Created" );
            llRequestPermissions( llGetOwner(), (0x1<<31) );
        } else {
            list t = llParseString2List( msg, ["$"], [] );
            vector Pos = (vector)llList2String(t,0);
            vector Scale = llGetScale();
            rotation Rot = llRotBetween( <0,0,1>, (vector)llList2String(t,1) );
            if( Pos != ZERO_VECTOR && Pos != llGetPos() )// Sanity Check
                llSetPrimitiveParams([PRIM_POSITION,Pos+(<0,0,Scale.z/2>*Rot),PRIM_ROTATION,Rot]);
        }
    }
   
    on_rez( integer p ){ llResetScript(); }
}
</source>
 
=== Benchmark ===
<source lang="lsl2">
list Data = [];
list Data = [];
integer Tick;
integer Tick;
Line 43: Line 132:
     state_entry(){
     state_entry(){
         llSetColor( <1,0,0>, -1 );
         llSetColor( <1,0,0>, -1 );
         llListen( 30, "", "", "" );
         llListen( 30, "", llGetOwner(), "" );
     }
     }
      
      
     touch_start( integer dn ){
     touch_start( integer dn ){
         llSetColor( <1,0,0>, -1 );
         llSetColor( <1,0,0>, -1 );
         llSay( 0,"Creating connection to owner..." );
         llOwnerSay( "Creating connection to owner..." );
         llOwnerSay( "$Vwr$Connect$30" );
         llOwnerSay( "$Vwr$Connect$30" );
     }
     }
Line 59: Line 148:
state Two{
state Two{
     state_entry(){
     state_entry(){
         llSay( 0, "Connection successful." );
         llOwnerSay( "Connection successful." );
         llSetColor( <1,1,0>, -1 );
         llSetColor( <1,1,0>, -1 );
         llListen( 30, "", "", "" );
         llListen( 30, "", llGetOwner(), "" );
         Tick = 0; Data = [];
         Tick = 0; Data = [];
         llSay( 0, "Executing functions..." );
         llOwnerSay( "Executing functions..." );
         llOwnerSay( "$Vwr$Capabilities" );
         llOwnerSay( "$Vwr$Capabilities" );
     }
     }
Line 84: Line 173:
     state_entry(){
     state_entry(){
         llSetColor( <0,1,0>, -1 );
         llSetColor( <0,1,0>, -1 );
         llSay( 0,"Complete. Debug:\n"+
         llOwnerSay( "Complete. Debug:\n"+
             "Capabilities: "+llList2String(Data,0) +"\n"+
             "Capabilities: "+llList2String(Data,0) +"\n"+
             "Creator: "+llList2String(Data,1) +"\n"+
             "Creator: "+llList2String(Data,1) +"\n"+
             "OS: "+llList2String(Data,2) );
             "OS: "+llList2String(Data,2) );
        llListen( 30, "", llGetOwner(), "" );
        llRequestPermissions( llGetOwner(), (0x1<<32)|(0x1<<31) );
    }
   
    run_time_permissions( integer p ){
        if( p && 1073741824 ){
            llOwnerSay( "Selection Permission granted." );
        }
    }
       
    touch_start( integer dn ){
        if( llDetectedKey(0) == llGetOwner() ){
            llOwnerSay( "$Vwr$Nexii$Picker$World|All" );
            //llOwnerSay( "$Vwr$Nexii$Selection$FirstObject" );
        }
    }
   
    listen( integer ch, string nm, key k, string msg ){
        list t = llParseString2List( msg, ["$"], [] );
        vector Pos = (vector)llList2String(t,0);
        rotation Rot = llRotBetween(<0,0,1>,(vector)llList2String(t,1));
        if( Pos != ZERO_VECTOR ){
            llSetPrimitiveParams([PRIM_POSITION,Pos,PRIM_ROTATION,Rot]);
        }
        //if( llStringLength(msg) == 36 ){
        //    list t = llGetObjectDetails( msg, [OBJECT_NAME, OBJECT_POS] );
        //    llSay( 0, "Selected Object: "+llList2String(t,0)+" @ "+(string)llList2Vector(t,1) );
        //} else {
        //    llOwnerSay( msg );
        //}
     }
     }
}
}
</lsl>
</source>
 
== Supported Clients ==
Currently the Vertical Life Client is the only client currently with a working version of "Script Collaboration" LSL-Client communication.
 
Official Vertical Life Client Forum
http://nexii.ordoimperialis.com/index.php
 
<FYI this is a dead link. Wolt Amat>




[[Category:AW Groupies User Pages]]
[[Category:AW Groupies User Pages]]

Latest revision as of 13:30, 25 January 2015

Based from LSL To Client Communication I decided to go ahead and attempt to fully implement a modified version of the protocol.

Please see Dale's implementation first, so not everything has to be repeated here and you might see the slight differences in my protocol.

Protocol

Before anything can be queried, a connection has to be made with the client by agreeing on a common channel for receiving responses. The protocol uses tokens like Dale's implementation. Any message addressed to the viewer has to begin with 'Vwr'.

The connection is made with the command Connect, followed by a channel number. Query:

$Vwr$Connect$123456

The client will then verify this connection by an 'Ok.' on the channel. Repeating the query with a different channel will change the agreed upon channel to the new one.

Once a connection is made, the LSL Script can execute all the other queries

There are some general basic functions.

$Vwr$Capabilities
$Vwr$Client
$Vwr$Creator
$Vwr$OperatingSystem

Then there are 'Packages' or 'Extensions', much like in Dale's implementation, but not really requiring a full name of the creator.

The current extension available is 'Nexii', this contains some client side processing like Raycasting (custom raytraces of a line), or special features like the Picker (third-person click-triggered raycasting).

Some or most functions require special permissions (using the normal permission system but with custom bits) that may contain sensitive data or incorrect use causing potential system instability, this makes sure that rouge scripts won't be able to cause havoc or pry on private information unless explicit permission is given by the user.

(Note: Dialogs are incorrectly referenced currently, despite being the correct permissions given, not sure why its doing this exactly)

Components

Picker

Brief
Allows a script to subscribe to the 'picker', which is basically to know where a user clicks/touches (Actions) on certain surfaces/objects/geometry (SurfaceType) and what kind of data the script wants (Output) back out of the actions. The subscribe function expects 'bits' that are OR'd together ("|") (OR is a bitwise operator).
Call
$Vwr$Nexii$Picker$Subscribe$ActionBits OR'd SurfaceTypeBits OR'd OutputBits

Bits

Actions
Start, Stop, for touchable surfaces, any prim with scripts that have a touch event handler.
Start Click, Stop Click, just ordinary empty clicks that didn't lead to anything.
Surface Types
HUD, Av, Prims, Terrain, Water, Water is untested
Output
Pos, equivilant to llDetectedTouchST.
Normal, equivilant to llDetectedTouchNormal.
Binormal, equivilant to llDetectedTouchBinormal.
UUID, the key of the object hit.
Get Touch, the type of the touch for this message.
Get Type the (internal) object type of the surface hit.

Picker Example

$Vwr$Nexii$Picker$Subscribe$Start Click|Stop Click|Prims|Pos
This subscription would cause any start and stop clicks on prims, to cause a message to be returned to the connected channel, simply with the Pos, which is the intersection and precise location in world coordinates where these clicks ocurred by the connected user. For example "<125.45,23.8,123.456>", which could then be easily converted into a vector and plugged into functions directly.
$Vwr$Nexii$Picker$Subscribe$Start Click|Av|UUID
This simply returns the UUID of any Avatars that were clicked on into the connected channel.

Picker Ghosting

Brief
A function to position any single prim or linked object wherever the cursor 'hovers'. Only one Ghost may exist. A ghost may be removed via setting the target key to a null key, this may cause the target to disappear from the users screen and an update may be needed to return it to the original location.
Call
:$Vwr$Nexii$Picker$Ghost$Key1:Value1|Key2:Value2:Value3|Key3:Value4|...
Keys
uuid, the target object to ghost.
Mode, Argument takes a single integer defining the mode of the ghosting. 0: Instant, 1: Damped, 2: No Rotation, 3: Limit Rotation (Arc Max/Min/Dir)
Arc, Value 1 is the maximum of arc (1.0 ~> -1.0, Default 1.0), Value 2 is the minimum of the arc (-1.0 ~> 1.0, Default -1.0). Equivilance: 1.0 is horizontal, 0.0 is vertical, -1.0 is upside down, 0.5 is 45 degrees.
Dir, direction to test the arc against.

Arc can easily be imagined as llSensor or more specifically a dimpled sphere. Dir (Direction) is a normalised vector that points into the direction of the dimpled sphere's rotation or where the sphere is looking towards.

Selection

Brief
Allows scripts to connect to the Selection Manager of the client which handles prim selections.
Call
:$Vwr$Nexii$Selection$Selection$Mode
Mode
:Only FirstObject available at the moment, which immediately returns the UUID of the root object in a selection.

Examples

These work from Vertical Life v1.5 on up to v1.5.3. v1.5.4 has had some changes in Picker.

Picker

default {
    state_entry(){
        llListen( 9000, "", llGetOwner(), "" );
        llOwnerSay( "$Vwr$Ping$9000" );
    }
    
    listen( integer ch, string nm, key k, string msg ){
        if( msg == "pong:0" ) state Main;
    }
    
    on_rez( integer p ){ llResetScript(); }
}

state Main {
    state_entry(){
        llListen( 9001, "", llGetOwner(), "" );
        llOwnerSay( "$Vwr$Connect$9001" );
    }
    
    run_time_permissions( integer p ){
        if( p & (0x1<<31) ) llOwnerSay( "$Vwr$Nexii$Picker$World|All" );
    }
    
    listen( integer ch, string nm, key k, string msg ){
        if( msg == "Ok." ){
            llOwnerSay( "Connection Created" );
            llRequestPermissions( llGetOwner(), (0x1<<31) );
        } else {
            list t = llParseString2List( msg, ["$"], [] );
            vector Pos = (vector)llList2String(t,0);
            vector Scale = llGetScale();
            rotation Rot = llRotBetween( <0,0,1>, (vector)llList2String(t,1) );
            if( Pos != ZERO_VECTOR && Pos != llGetPos() )// Sanity Check
                llSetPrimitiveParams([PRIM_POSITION,Pos+(<0,0,Scale.z/2>*Rot),PRIM_ROTATION,Rot]);
        }
    }
    
    on_rez( integer p ){ llResetScript(); }
}

Benchmark

list Data = [];
integer Tick;

default{
    state_entry(){
        llSetColor( <1,0,0>, -1 );
        llListen( 30, "", llGetOwner(), "" );
    }
    
    touch_start( integer dn ){
        llSetColor( <1,0,0>, -1 );
        llOwnerSay( "Creating connection to owner..." );
        llOwnerSay( "$Vwr$Connect$30" );
    }
    
    listen( integer ch, string nm, key k, string msg ){
        if( msg == "Ok." ) state Two;
    }
}

state Two{
    state_entry(){
        llOwnerSay( "Connection successful." );
        llSetColor( <1,1,0>, -1 );
        llListen( 30, "", llGetOwner(), "" );
        Tick = 0; Data = [];
        llOwnerSay( "Executing functions..." );
        llOwnerSay( "$Vwr$Capabilities" );
    }
    
    listen( integer ch, string nm, key k, string msg ){
        if( Tick == 0 ){
            Data += msg; ++Tick;
            llOwnerSay( "$Vwr$Creator" );
        } else if( Tick == 1 ){
            Data += msg; ++Tick;
            llOwnerSay( "$Vwr$OperatingSystem" );
        } else if( Tick == 2 ){
            Data += msg;
            state Three;
        }
    }
}

state Three{
    state_entry(){
        llSetColor( <0,1,0>, -1 );
        llOwnerSay( "Complete. Debug:\n"+
            "Capabilities: "+llList2String(Data,0) +"\n"+
            "Creator: "+llList2String(Data,1) +"\n"+
            "OS: "+llList2String(Data,2) );
        llListen( 30, "", llGetOwner(), "" );
        llRequestPermissions( llGetOwner(), (0x1<<32)|(0x1<<31) );
    }
    
    run_time_permissions( integer p ){
        if( p && 1073741824 ){
            llOwnerSay( "Selection Permission granted." );
        }
    }
        
    touch_start( integer dn ){
        if( llDetectedKey(0) == llGetOwner() ){
            llOwnerSay( "$Vwr$Nexii$Picker$World|All" );
            //llOwnerSay( "$Vwr$Nexii$Selection$FirstObject" );
        }
    }
    
    listen( integer ch, string nm, key k, string msg ){
        list t = llParseString2List( msg, ["$"], [] );
        vector Pos = (vector)llList2String(t,0);
        rotation Rot = llRotBetween(<0,0,1>,(vector)llList2String(t,1));
        if( Pos != ZERO_VECTOR ){
            llSetPrimitiveParams([PRIM_POSITION,Pos,PRIM_ROTATION,Rot]);
        }
        //if( llStringLength(msg) == 36 ){
        //    list t = llGetObjectDetails( msg, [OBJECT_NAME, OBJECT_POS] );
        //    llSay( 0, "Selected Object: "+llList2String(t,0)+" @ "+(string)llList2Vector(t,1) );
        //} else {
        //    llOwnerSay( msg );
        //}
    }
}

Supported Clients

Currently the Vertical Life Client is the only client currently with a working version of "Script Collaboration" LSL-Client communication.

Official Vertical Life Client Forum http://nexii.ordoimperialis.com/index.php

<FYI this is a dead link. Wolt Amat>