User:Allen Kerensky/Myriad Lite Dev/Myriad Lite Skills Server-v0.0.1-20120527.lsl

From OpenSimulator

Jump to: navigation, search

Myriad_Lite_Skills_Server-v0.0.1-20120527.lsl

// Myriad_Lite_Skill_Server-v0.0.1-20120527.lsl
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG licensed under the Creative Commons Attribution 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
// Myriad Lite software Copyright (c) 2011 by Allen Kerensky (OSG/SL)
// Myriad Lite licensed under the
// Creative Commons Attribution-Share Alike-Non-Commercial 3.0 Unported
// http://creativecommons.org/licenses/by-nc-sa/3.0/
 
// CONSTANTS - DO NOT CHANGE DURING RUN
string VERSION = "0.0.1"; // Allen Kerensky's script version
string VERSIONDATE = "20120527"; // Allen Kerensky's script yyyymmdd
integer CHAN_MYRIAD = -999; // regionwide channel for Myriad events
string CARD = "Myriad_Lite_Skills-v0.0.2-20120527.csv"; // notecard data table
 
// RUNTIME GLOBALS - CAN CHANGE DURING RUN
integer HAND_MYRIAD; // llListenRemove handle for Myriad regional channel
 
list SKILLS; // the skill names
list BASESTATS; // the skill base statistics, indexed by name order
list GENRES; // the skill genre, indexed by name order
list DESCRIPTIONS; // the skill descriptions, indexed by name order
 
integer LINE = 0; // reading line number
key QUERY = NULL_KEY; // track notecard queries
 
// DEBUG - show debug messages
DEBUG(string dmessage) {
    llOwnerSay("DEBUG: "+dmessage);
}
 
// SETUP - begin
SETUP() {
    if ( HAND_MYRIAD != 0 ) llListenRemove(HAND_MYRIAD); // is there already a listener? clear it  
    HAND_MYRIAD = llListen(CHAN_MYRIAD,"",NULL_KEY,""); // start region channel listener
    DEBUG("Skills server "+VERSION+" "+VERSIONDATE+" loading Skills. Please wait..."); // tell player we're waiting for data server
    QUERY = llGetNotecardLine(CARD,LINE++); // ask for line from notecard and advance to next line
}
 
// RESET - reload
RESET() {
    llResetScript(); // now reset
}
 
LIST_SKILLS(key id) {
    integer replyto = (integer)("0x"+llGetSubString((string)id,0,6)); // calculate requestor-specific chat channel to reply to
    // we have to work around llRegionSay max string length 1023 characters
    integer items = llGetListLength(SKILLS); // how many total items to send?
    integer count; // which item are we processing now?
    string out = "SKILLS|"; // start an output list
    integer firstflag = TRUE; // is this first item in new list?
    while (count < items ) { // do we still have items in list to send?
        string name = llList2String(SKILLS,count); // get the name of current item
        if (  llStringLength(out+","+name) <= 1016) { // is our output list under the string length limit?
            if ( firstflag == TRUE ) { // first item in list does not need a comma prefix
                out += name; // add this item as first in the output list
                firstflag = FALSE; // turn off first flag since next item won't be
            } else { // not first item in list, prefix with comma
                out += ","+name; // add a comma and this skill to existing list
            }
        } else { // output string > 1016 chars long
            llRegionSay(replyto,out); // send current output string
            out = "SKILLS|"+name; // start a new one and add current item to that
        }
        count++; // done putting this item in a list, set counter to next
    }   
    llRegionSay(replyto,out); // say last line of output                
}
 
GET_SKILL(key id,string msg) {
    integer replyto = (integer)("0x"+llGetSubString((string)id,0,6)); // calculate requestor-specific chat channel to reply to
    list tokens = llParseString2List(msg,["|"],[]); // split msg into list around pipe symbols
    string skill = llList2String(tokens,1); // the name of the item to get
    integer listpos = llListFindList(SKILLS,[skill]); // get the position of that item in the list
    string reply = "SKILL"; // start output item data NO PLURAL here - we're sending 1 skill
    if ( listpos != -1 ) { // was item name in the list?
        reply += "|NAME="+llList2String(SKILLS,listpos); // add skill name to output
        reply += "|BASESTAT="+llList2String(BASESTATS,listpos); // add skill base stat to output
        reply += "|GENRE="+llList2String(GENRES,listpos); // add skill genre to output
        reply += "|DESCRIPTION="+llList2String(DESCRIPTIONS,listpos); // add description to output
        llRegionSay(replyto,reply); // send it to requestor FIXME what if output greater than 1016 chars?
    } else {
        llRegionSay(replyto,"SKILL|ERROR=Requested Skill ("+skill+") not found"); // item requested does not exist, return an error
    }
}
 
SET_SKILL() {
    // FIXME - do we need this?
}
 
// DEFAULT STATE
default {
 
    // STATE ENTRY - called on Reset
    state_entry() {
        SETUP(); // show credits and start notecard data load
    }
 
    // on_rez - when rezzed to ground or from inventory as attachment during login
    on_rez(integer params) {
        params = 0; // LSLINT
        RESET(); // force to go through state entry
    }
 
    // attach - when attached or detached from inventory or during login
    attach(key id) {
        id = NULL_KEY; // LSLINT
        RESET(); // force to go through state entry
    }
 
    // dataserver called for each line of notecard requested 
    dataserver(key queryid,string data) {
        if ( queryid == QUERY ) { // dataserver gave us line we asked for?
            if ( data != EOF ) { // we're not at end of notecard file?
                if ( llGetSubString(data,0,0) == "#" ) { // does this line start with comment mark?
                    QUERY = llGetNotecardLine(CARD,LINE++); // ignore comment and ask for the next line
                    return;
                }
                // Parse non-comment lines in keyword = value[,value,...] format
                list fields = llParseString2List(data,[","],[]); // break line of text into = delimited fields
                SKILLS      = SKILLS + [llStringTrim(llList2String(fields,0),STRING_TRIM)]; // add skill name field to list
                BASESTATS   = BASESTATS + [llStringTrim(llList2String(fields,1),STRING_TRIM)]; // add skill base stat to list
                GENRES      = GENRES + [llStringTrim(llList2String(fields,2),STRING_TRIM)]; // add skill genre field to list
                DESCRIPTIONS    = DESCRIPTIONS + [llStringTrim(llList2String(fields,3),STRING_TRIM)]; // add skill description field to list
                QUERY = llGetNotecardLine(CARD,LINE++); // finished with known keywords, get next line
            } else { // end of notecard
                DEBUG("Skills loaded. Server ready. Free Memory: "+(string)llGetFreeMemory()); // done, ready to serve            
            } // end if data not equal eof
        } // end if query id equal
    } // end if data server event
 
    listen(integer channel,string name,key id,string msg) {
        channel = 0; // LSLINT
        name = ""; // LSLINT                
        list tokens = llParseString2List(msg,["|"],[ ]); // split msg into list around pipe symbols
        string command = llList2String(tokens,0); // first field is some sort of command
        if ( command == "LIST_SKILLS" ) { // is this a list all SFX request?
            LIST_SKILLS(id); // call it
            return; // return early instead of processing more
        }
        if ( command == "GET_SKILL" ) { // GET_SKILL|string skillname
            GET_SKILL(id,msg); // call it
            return; // return early instead of processing more
        }
        if ( command == "SET_SKILL" ) { // is this a set-skill request?
            SET_SKILL(); // call it
            return; // return early in case we add more later
        }
    }
} // end default state
Personal tools
General
About This Wiki