LSL Protocol/Restrained Love Open Relay Group/Satomi's Damn Fast Relay

From Second Life Wiki
Jump to: navigation, search

Satomi's Damn Fast Relay

This is the shortest known implementation of an ORG compliant relay.

This relay only makes the minimal verifications (no ask mode, no distance checks, ping on relog only but safe-word on touch).

Code is under a BSD-style license, feel free to use in your own projects, provided you credit Satomi Ahn for the original script.

<lsl> //Damn Fast Relay, by Satomi Ahn // //This is a minimalist RLV Relay intended for laggy playgrounds, with the aim of making the answer to scan requests as fast as possible and decreasing the global lag. //It only features the auto-accept mode but tries to fully comply to ORG 003 specifications. //Touching the relay will make it release restrictions and reset (in other words: safewording). // //This script is provided as-is with mo guarrantee whatsoever. //Feel free to use the code in anyway you want, provided you credit the original author, ie: myself, Satomi Ahn. //(can be seen as a BSD-style license)

integer rlvrc = -1812221819; key source = NULL_KEY; key wearer = NULL_KEY; integer viewerlistener; key sitid; list restrictions = [];

release(key id) {

   llOwnerSay("@clear");
   llRegionSayTo(id, rlvrc, "release,"+(string)id+",!release,ok");
   llResetScript();

}

default {

   state_entry() {
       wearer = llGetOwner();
       llListen(rlvrc,"", NULL_KEY, "");
   }
   touch_start(integer total_number) {
       llOwnerSay("Now safewording. Restrictions will be removed and the relay reset.");
       release(source);
   }
   
   listen(integer c, string w, key id, string msg) {
       if (c == 12345) {
           if (msg) sitid = (key) msg;
           llListenRemove(viewerlistener);
           return;
       }
       if (source) { if (source != id) return; } // already grabbed by another device
       list args = llParseStringKeepNulls(msg,[","],[]);
       if (llGetListLength(args)!=3) return;
       if (llList2Key(args,1)!=wearer && llList2Key(args, 1)!=(key)"ffffffff-ffff-ffff-ffff-ffffffffffff") return;
       string ident = llList2String(args,0);
       list commands = llParseString2List(llList2String(args,2),["|"],[]);
       integer i;
       string command;
       integer nc = llGetListLength(commands);
       for (i=0; i<nc; ++i) {
           command = llList2String(commands,i);
           if (llGetSubString(command,0,0)=="@") {
               llOwnerSay(command);
               llRegionSayTo(id, rlvrc, ident+","+(string)id+","+command+",ok");
               list subargs = llParseString2List(command, ["="], []);
               string behav = llGetSubString(llList2String(subargs, 0), 1, -1);
               integer index = llListFindList(restrictions, [behav]);
               string comtype = llList2String(subargs, 1);                
               if (comtype == "n" || comtype == "add") {
                   if (index == -1) restrictions += [behav];
                   if (behav == "unsit" && llGetAgentInfo(wearer) & AGENT_SITTING) {
                       viewerlistener = llListen(12345, "", wearer, "");
                       llOwnerSay("@getsitid=12345");
                   }
               }
               else if (comtype=="y" || comtype == "rem") {
                   if (index != -1) restrictions = llDeleteSubList(restrictions, index, index);
                   if (behav == "unsit") sitid = NULL_KEY;
               }
           }
           else if (command=="!pong") {
                   llOwnerSay("@sit:"+(string)sitid+"=force,"+llDumpList2String(restrictions, "=n,")+"=n");
                   llSetTimerEvent(0);
           }
           else if (command=="!version") llRegionSayTo(id, rlvrc, ident+","+(string)id+",!version,1100");
           else if (command=="!implversion") llRegionSayTo(id, rlvrc, ident+","+(string)id+",!implversion,ORG=0003/Satomi's Damn Fast Relay v2");
           else if (command=="!x-orgversions") llRegionSayTo(id, rlvrc, ident+","+(string)id+",!x-orgversions,ORG=0003");
           else if (command=="!release") release(id);
           else llRegionSayTo(id, rlvrc, ident+","+(string)id+","+command+",ko");            
       }
       if (restrictions) { source = id; llOwnerSay("@detach=n"); }
       else { llOwnerSay("@clear"); llResetScript(); }
   }
   
   changed(integer c) {
       if (c & CHANGED_OWNER) llResetScript();
   }
   
   on_rez(integer i) {
       if (source) {
           llSleep(30);
           llRegionSayTo(source, rlvrc, "ping,"+(string)source+",ping,ping");
           llSetTimerEvent(30);
       }
   }
   
   timer() {
       llResetScript();
   }

}

</lsl>