LSL Protocol/Restrained Life Relay/How to Test/Relay Test 01
Instructions
- Rez a box with the below code in world
- Make sure you are only using one relay
- Click it and wait
- Look for "PASS:" and "FAIL:" lines
Code
<lsl> integer CHANNEL_RELAY = -1812221819; // Relay Channel integer CHANNEL_VIEWER = 1812221819; // avatars cannot speak on negative channels
integer INDEX_RELAY_VERSION = 0; integer INDEX_RELAY_IMPLVERSION = 1; integer INDEX_RELAY_RLV_VERSION = 2; integer INDEX_RLV_VERSION = 3;
list RESPONSE_NAMES = ["!version,xxxx", "!implversion", "@version,ok", "@version viewer reply"];
list waitFor;
// handles a response from the viewer
handleRLVResponse(string message)
{
if (llSubStringIndex(message, "Restrained") > -1) { gotMessage(INDEX_RLV_VERSION); }
}
// handles a response from the relay
handleRelayResponse(string message)
{
list tokens = llParseString2List(message, [","], []); string question = llList2String(tokens, 2); string response = llList2String(tokens, 3);
if (question == "!version") { integer version = (integer) response; if (version < 1000) { llSay(0, "FAIL: Illegal response to !version: " + response); } gotMessage(INDEX_RELAY_VERSION); }
else if (question == "!implversion") { if (llStringLength(response) < 3) { llSay(0, "FAIL: Response to !implversion is too short"); } gotMessage(INDEX_RELAY_IMPLVERSION); }
else if (question == "@version=" + (string) CHANNEL_VIEWER) { if (response != "ok") { llSay(0, "FAIL: Relay Response to @version is not \"ok\" but: " + response); } gotMessage(INDEX_RELAY_RLV_VERSION); }
}
// checks whether we are still waiting for this kind of response and remembers it
gotMessage(integer index)
{
integer expected = llList2Integer(waitFor, index); if (!expected) { llSay(0, "FAIL: Got unexpected message. Did you click too fast again or are you using more than one relay?"); }
waitFor = llListReplaceList(waitFor, [FALSE], index, index);
if (!areWeStillWaitingForMessages()) { llSay(0, "PASSED: Got all expected messages."); llSetTimerEvent(0); }
}
// checks whether we are still waiting for replies
integer areWeStillWaitingForMessages()
{
integer i; integer count = llGetListLength(waitFor); for (i = 0; i < count; i++) { if (llList2Integer(waitFor, i)) { return TRUE; } } return FALSE;
}
// reports which message are still missing
reportTimeout()
{
integer i; integer count = llGetListLength(waitFor); string missing = "FAIL: We did not get all expected responses to !version, !implversion and @version in time. Missing: "; for (i = 0; i < count; i++) { if (llList2Integer(waitFor, i)) { missing += llList2String(RESPONSE_NAMES, i) + ", "; } } llSay(0, missing); llSetTimerEvent(0);
}
default {
state_entry() { llSetText(llGetObjectName(), <1, 1, 1>, 1); llListen(CHANNEL_RELAY, "", "", ""); llListen(CHANNEL_VIEWER, "", "", ""); }
on_rez(integer ignored) { llSay(0, "Make sure that you are only wearing one relay and touch me."); }
listen(integer channel, string name, key id, string message) { if ((llGetOwnerKey(id) == id) && (channel == CHANNEL_VIEWER)) { handleRLVResponse(message); }
if ((llGetOwnerKey(id) == llGetOwner()) && (channel == CHANNEL_RELAY)) { handleRelayResponse(message); } llOwnerSay(name + ": " + message); } touch_start(integer i) { if (llDetectedKey(0) != llGetOwner()) { llSay(0, "Hey, " + llDetectedName(0) + " don't mess with me!"); return; }
llSay(CHANNEL_RELAY, "relaytest," + (string) llGetOwner() + ",!version|!implversion|@version=" + (string) CHANNEL_VIEWER); waitFor = [TRUE, TRUE, TRUE, TRUE]; llSetTimerEvent(10); }
timer() { reportTimeout(); }
}
</lsl>