Difference between revisions of "User:Nexii Malthus/Script API"
Line 216: | Line 216: | ||
Official Vertical Life Client Forum | Official Vertical Life Client Forum | ||
http://nexii.ordoimperialis.com/index.php | http://nexii.ordoimperialis.com/index.php | ||
<FYI this is a dead link. Wolt Amat> | |||
[[Category:AW Groupies User Pages]] | [[Category:AW Groupies User Pages]] |
Revision as of 13:45, 9 August 2011
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
<lsl> 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(); }
} </lsl>
Benchmark
<lsl> 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 ); //} }
} </lsl>
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>