Sample Notecard

All the agents listed in the Agents notecard should contain all your sales agents line-by-line. The format is given by the avatar key and the name of the avatar separated by a hash (#) sign. You can see an example below:

febf982d-c541-4e73-a807-a2faf7c878c0#Morgan LeFay
8ed5bedb-3e15-4a50-86a1-41c4c8ec1b74#Some Agent

Please remember to leave a blank line in the notecard after the agent lines.

Code: Agent Registry

agentregistry.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////
//                   CONFIGURATION                      //
//////////////////////////////////////////////////////////
// Permanent short URL map name using external database.
string SHORT_URL = "sales";
 
// API key - can be anything, used as a password.
string API_KEY = "A1364788-B702-4413-B937-7A57E32B43CE";
///////////////////////////////////////////////////////////////////////////
//                              INTERNALS                                //
///////////////////////////////////////////////////////////////////////////
 
integer nLine = 0;
list aList = [];
list vList = [];
key nQuery = NULL_KEY;
string llURL = "";
string visitor = "";
key agentKey = NULL_KEY;
string agentName = "";
 
// The following is an activity indicator that can be found
// separately at: http://grimore.org/secondlife:spinner
list spinChars = [ "↑", "↗", "→", "↘", "↓", "↙", "←", "↖" ];
string spin() {
    string text = llList2String(llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXT]), 0);
    do {
        string tok = llGetSubString(text, llStringLength(text)-1, llStringLength(text)-1);
        if(!~llListFindList(spinChars, (list)tok) && tok != "\n" && tok != "[" && tok != "]") jump show;
        text = llDeleteSubString(text, llStringLength(text)-1, llStringLength(text)-1);
    } while(llStringLength(text));
@show;
    string next = llList2String(spinChars,  0);
    spinChars = llDeleteSubList(spinChars, 0, 0);
    spinChars += next;
    return "[" + next + "]";
}
 
integer isAgentKey(key k) {
    if(k) if(k != NULL_KEY) return 1;
    return 0;
}
 
default {
    state_entry() {
        llSetText("Reading agent list..." + "\n" + spin(), <1,1,0>, 1);
        integer itra = llGetInventoryNumber(INVENTORY_NOTECARD)-1;
        do {
            if(llGetInventoryName(INVENTORY_NOTECARD, itra) == "Agents")
                jump notecard;
        } while(--itra>=0);
        llSetText("Failed to find Agents notecard." + "\n" + spin(), <1,1,1>, 1);
        return;
@notecard;
        nQuery = llGetNotecardLine("Agents", nLine);
    }
    dataserver(key id, string data) {
        if(id != nQuery) return;
        if(data == EOF) {
            llSetText("Notecard read..." + "\n" + spin(), <0,1,0>, 1);
            state url;
        }
        if(data == "") jump next;
        aList += data;
@next;
        nQuery = llGetNotecardLine("Agents", ++nLine);
    }
    changed(integer change) {
        if (change & (CHANGED_REGION | CHANGED_REGION_START))
            llResetScript();
    }
    on_rez(integer param) {
        llResetScript();
    }
}
 
state url
{
    state_entry() {
        llSetText("Requesting URL..." + "\n" + spin(), <1,1,0>, 1);
        llReleaseURL(llURL);
        llRequestURL();
        // alarm 60s
        llSetTimerEvent(60);
    }
    http_request(key id, string method, string body) {
        if (method != URL_REQUEST_GRANTED) return;
        llSetText("Registering with website..." + "\n" + spin(), <1,1,0>, 1);
        llURL = body;
        nQuery = llHTTPRequest("http://server.tld:90/SIM/registerURL.php?action=register&apiKey=" + API_KEY + "&shortURL=" + SHORT_URL + "&llURL=" + body, [HTTP_METHOD, "GET"], "");
    }
    timer() {
        llResetScript();
    }
    http_response(key reqID, integer status, list metadata, string body) {
        if(nQuery != reqID) return;
        if(body != SHORT_URL) return;
        llHTTPResponse(nQuery, 200, "OK");
        state agents;
    }
    changed(integer change) {
        if (change & (CHANGED_REGION | CHANGED_REGION_START))
            llResetScript();
    }
    on_rez(integer param) {
        llResetScript();
    }
}
 
state agents {
    state_entry() {
        llSetTimerEvent(1);
    }
    http_request(key id, string method, string body) {
        list data = llParseString2List(body, ["="], []);
        string action = llList2String(data, 0);
        // Sign ping-pong to make sure all links are established.
        if(action != "ping") jump step_process;
        llHTTPResponse(id, 200, "pong");
        return;
@step_process;
        // This is not for us, return.
        if(llGetListLength(data) != 2) return;
        // Alright, this is something for us...
        string agentLine = llList2String(data, 1);
        // A sales agent cannot be a visitor so we knock that possiblity off.
        if(action != "visitor") jump step_signoff;
        list al = llParseString2List(agentLine, ["|"], []);
        if(~llListFindList(aList, (list)(llList2String(al, 0) + "#" + llList2String(al, 1)))) {
            llHTTPResponse(id, 200, "");
            return;
        }
        llSetText("Visitor on land..." + "\n" + spin() , <1,1,0>, 1);
        if(llGetListLength(vList) == 0) {
            llSetText("☹ Visitor detected, but no agents registered. ☹" + "\n" + spin(), <1,0,0>, 1);
            llHTTPResponse(id, 200, "");
            return;
        }
        // Store visitor over state change.
        visitor = llList2String(al, 0) + "|" + llList2String(al, 2);
        // Confirm receiving request.
        llHTTPResponse(id, 200, "");
        // stop timer
        llSetTimerEvent(0);
        // jump to searching for agents.
        state onlineagents;
@step_signoff;
        // Any signon or signoff requests must be matched to the agents the notecard.
        if(!~llListFindList(aList, (list)agentLine)) {
            llHTTPResponse(id, 200, "");
            return;
        }
        if(action != "signoff") jump step_signon;
        nLine = llListFindList(vList, (list)agentLine);
        if(~nLine) vList = llDeleteSubList(vList, nLine, nLine);
        llHTTPResponse(id, 200, "ACK");
        return;
@step_signon;
        if(action != "signon") return;
        if(~llListFindList(vList, (list)agentLine)) {
            llHTTPResponse(id, 200, "");
            return;
        }
        vList += agentLine;
        llHTTPResponse(id, 200, "ACK");
    }
    timer() {
        if(llGetListLength(vList) != 0) jump step_agents;
        llSetText("☹ No agents registered. ☹" + "\n" + spin(), <1,0,0>, 1);
        jump send_time;
@step_agents;
        list nList = [];
        integer itra = llGetListLength(vList)-1;
        do {
            nList += llList2String(llParseString2List(llList2String(vList, itra), ["#"], []), 1);
        } while(--itra>=0);
        llSetText("☺ Registered Agents ☺\n" + llDumpList2String(nList, "\n") + "\n" + spin(), <0,1,0>, 1);
@send_time;
        llMessageLinked(LINK_THIS, 0, llDumpList2String(vList, "|"), (key)API_KEY);
    }
    changed(integer change) {
        if (change & (CHANGED_REGION | CHANGED_REGION_START))
            llResetScript();
    }
    on_rez(integer param) {
        llResetScript();
    }
}
 
//////////////////////////////////////////////////////////
// We use the list of sales agents as a queue,          //
// dequeueing and checking whether they are online and  //
// enqueueing them back if they are online and active.  //
// This achieves a permutation of all online agents.    //
//////////////////////////////////////////////////////////
state onlineagents {
    state_entry() {
        // stop timer
        llSetTimerEvent(0);
        // searching...
        llSetText("Searching online agents..." + "\n" + spin() , <1,1,0>, 1);
        // pop stack
@next_agent;
        if(llGetListLength(vList) == 0) state agents;
        list agentData = llParseString2List(llList2String(vList, 0), ["#"], []);
        if(llGetListLength(agentData) != 2) {
            vList = llDeleteSubList(vList, 0, 0);
            jump next_agent;
        }
        agentKey = llList2Key(agentData, 0);
        if(!isAgentKey(agentKey)) {
            vList = llDeleteSubList(vList, 0, 0);
            jump next_agent;
        }
        agentName = llList2String(agentData, 1);
        // remove them
        vList = llDeleteSubList(vList, 0, 0);
        // alarm 60
        llSetTimerEvent(60);
        // ask for online status
        nQuery = llRequestAgentData(agentKey, DATA_ONLINE);
    }
    dataserver(key id, string data)
    {
        if(nQuery != id) return;
        llSetTimerEvent(0);
        if(data != "1") jump step_offline;
        // show who we're going to page.
        llSetText("☎ Paging: " + agentName + " ☎\n" + spin(), <0,1,0>, 1);
        // send visitor message
        key visitorKey = llList2Key(llParseString2List(visitor, ["|"], []), 0);
        llInstantMessage(agentKey, llKey2Name(visitorKey) + " ( secondlife:///app/agent/" + (string)visitorKey + "/about ) is visiting the land parcel at: " + llList2String(llParseString2List(visitor, ["|"], []), 1));
        // push stack
        // add them
        vList += (string)agentKey + "#" + agentName;
        state agents;
@step_offline;
        // extract next agent since they are offline.
        // searching...
        llSetText("Searching online agents..." + "\n" + spin() , <1,1,0>, 1);
        // pop stack
@next_agent;
        if(llGetListLength(vList) == 0) state agents;
        list agentData = llParseString2List(llList2String(vList, 0), ["#"], []);
        if(llGetListLength(agentData) != 2) {
            vList = llDeleteSubList(vList, 0, 0);
            jump next_agent;
        }
        agentKey = llList2Key(agentData, 0);
        if(!isAgentKey(agentKey)) {
            vList = llDeleteSubList(vList, 0, 0);
            jump next_agent;
        }
        agentName = llList2String(agentData, 1);
        // remove them
        vList = llDeleteSubList(vList, 0, 0);
        // alarm 60
        llSetTimerEvent(60);
        // ask for online status
        nQuery = llRequestAgentData(agentKey, DATA_ONLINE);
    }
    timer() {
        // extract next agent since they are offline.
        // searching...
        llSetText("Searching online agents..." + "\n" + spin() , <1,1,0>, 1);
        // pop stack
@next_agent;
        if(llGetListLength(vList) == 0) state agents;
        list agentData = llParseString2List(llList2String(vList, 0), ["#"], []);
        if(llGetListLength(agentData) != 2) {
            vList = llDeleteSubList(vList, 0, 0);
            jump next_agent;
        }
        agentKey = llList2Key(agentData, 0);
        if(!isAgentKey(agentKey)) {
            vList = llDeleteSubList(vList, 0, 0);
            jump next_agent;
        }
        agentName = llList2String(agentData, 1);
        // remove them
        vList = llDeleteSubList(vList, 0, 0);
        // alarm 60
        llSetTimerEvent(60);
        // ask for online status
        nQuery = llRequestAgentData(agentKey, DATA_ONLINE);
    }
    changed(integer change) {
        if (change & (CHANGED_REGION | CHANGED_REGION_START))
            llResetScript();
    }
    on_rez(integer param) {
        llResetScript();
    }
}

secondlife/sales_agent_tool/agent_registry/core.txt · Last modified: 2022/11/24 07:46 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.