User:Allen Kerensky/Myriad Lite Preview 5/Template Server

From OpenSimulator

Jump to: navigation, search

Myriad Lite Template Server

Myriad_Lite_Template_Server-v0.0.0-20120106.lsl

// Myriad_Lite_Template_Server-v0.0.0-20120106.lsl
// Copyright (c) 2012 By Allen Kerensky (OSG/SL)
// 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-2012 by Allen Kerensky (OSG/SL)
// Baroun's Adventure Machine Copyright (c) 2008-2011 by Baroun Tardis (SL)
// Myriad Lite and Baroun's Adventure Machine licensed under the
// Creative Commons Attribution-Share Alike-Non-Commercial 3.0 Unported
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// You must agree to the terms of this license before making any use of this software.
// If you do not agree to this license, simply delete these materials.
// There is no warranty, express or implied, for your use of these materials.

// CONSTANTS - DO NOT CHANGE DURING RUN
string VERSION = "0.0.0"; // Allen Kerensky's script version
string VERSIONDATE = "20120106"; // Allen Kerensky's script yyyymmdd
integer CHAN_MYRIAD = -999; // regionwide channel for Myriad events

// RUNTIME GLOBALS - CAN CHANGE DURING RUN
integer HAND_MYRIAD;

list TABLES; // list of all notecard tables in server
list TEMPLATENAMES; // list of names by template number
list TEMPLATETYPES; // list of types by template number
list TEMPLATECOSTS; // list of costs by template number

list BACKGROUNDS; //list of template backgrounds data
list CAREERS; // list of template careers data
list SPECIES; // list of template species data

string SCRATCH; // temporary template building string
string TYPE; // flag to hold type of current template

string CARD; // current notecard to load from
integer LINE = 0; // reading line number
key QUERY = NULL_KEY; // track notecard queries

// DEBUG - show debug chat with wearer name for sorting
DEBUG(string dmessage) {
    llOwnerSay("DEBUG: "+dmessage);
}

// SETUP - begin
SETUP() {
    llSetText("Server: Templates",<1,1,1>,1);
    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("Template server "+VERSION+" "+VERSIONDATE+" loading Templates. Please wait..."); // tell player we're waiting for data server
    // make a list of all species, background, and career templates in server
    integer numcards = llGetInventoryNumber(INVENTORY_NOTECARD); // count number of notecards
    integer count; // temporary place to count which card we're on
    for ( count = 0; count < numcards; count++ ) { // step through each card in a loop
        string cardname = llGetInventoryName(INVENTORY_NOTECARD,count); // get the name of the current card to read
        if (llGetSubString(cardname,0,10) == "Background:" ||
            llGetSubString(cardname,0,6 ) == "Career:" ||
            llGetSubString(cardname,0,7 ) == "Species:" ) { // is the notecard a species, background, or career notecard?          
            TABLES = TABLES + [cardname]; // add it to list of cards to load
        }
    }
    // start reading content of each template notecard
    if ( llGetListLength(TABLES) > 0 ) { // do we have notecard names in list?
        CARD = llList2String(TABLES,0); // set current card to first list item
        TABLES = llDeleteSubList(TABLES,0,0); // delete first list item
        QUERY = llGetNotecardLine(CARD,LINE++); // ask for line from notecard and advance to next line
    }
}

// RESET - reload
RESET() {
    llResetScript(); // now reset
}

LIST_TEMPLATES(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(TEMPLATENAMES); // how many total items to send?
    integer count; // which item are we processing now?
    string out = "TEMPLATES|"; // 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(TEMPLATENAMES,count); // get the name of current item
        if (  llStringLength(out+","+name) <= 1000) { // 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 template to existing list
            }
        } else { // output string > 1016 chars long
            llRegionSay(replyto,out); // send current output string
            out = "TEMPLATES|"+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_TEMPLATE(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 template = llList2String(tokens,1); // the name of the item to get
    integer listpos = llListFindList(TEMPLATENAMES,[template]); // get the position of that item in the list
    if ( listpos != -1 ) { // found template by name
        string type = llList2String(TEMPLATETYPES,llListFindList(TEMPLATENAMES,[template])); // check template type to see which list to pull from
        if ( type == "Background" ) { // if a background template, get from list of background template data
            integer count; // set a temporary counter
            integer numitems = llGetListLength(BACKGROUNDS); // how many background templates
            for ( count = 0; count < numitems; count++ ) { // step through each one
                string curitem = llList2String(BACKGROUNDS,count); // get the name
                if ( llSubStringIndex(curitem,"NAME="+template) == 0 ) { // does name match the one we want?
                    llRegionSay(replyto,"TEMPLATE|"+curitem); // send the data
                }
            }
        } else if ( type == "Career" ) { // if a career template, get from list of career template data
            integer count; // set a temporary counter
            integer numitems = llGetListLength(CAREERS); // how many career templates
            for ( count = 0; count < numitems; count++ ) { // step through each one
                string curitem = llList2String(CAREERS,count); // get the name of current one
                if ( llSubStringIndex(curitem,"NAME="+template) == 0 ) { // does name match the one we want?
                    llRegionSay(replyto,"TEMPLATE|"+curitem); // send the data
                }
            }
        } else if ( type == "Species" ) { // if a species template. get from list of species template data
            integer count; // set a temporary counter
            integer numitems = llGetListLength(SPECIES); // how many species templates?
            for ( count = 0; count < numitems; count++ ) { // step through teach one
                string curitem = llList2String(SPECIES,count); // get the name of current one
                if ( llSubStringIndex(curitem,"NAME="+template) == 0 ) { // does name match the one we want?
                    llRegionSay(replyto,"TEMPLATE|"+curitem); // send the data
                }
            }
        }
    } else {
        llRegionSay(replyto,"TEMPLATE|ERROR=Requested template ("+template+") not found"); // item requested does not exist, return an error
    }
}

SET_TEMPLATE() {
    // FIXME - do we need this?    
}

// DEFAULT STATE
default {

    // STATE ENTRY - called on Reset
    state_entry() {
        SETUP(); // show credits and start character sheet 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
                string cmd = llStringTrim(llList2String(fields,0),STRING_TRIM); // field zero is the "command"
                string values = llStringTrim(llList2String(fields,1),STRING_TRIM); // field one is the data
                if ( cmd == "NAME" ) {
                    SCRATCH = data; // start the scratch template with this field
                    TEMPLATENAMES = TEMPLATENAMES + [values]; // add name to template name array
                }
                if ( cmd == "TYPE" ) {
                    SCRATCH = SCRATCH + "|" + data; // add the type
                    TYPE = values; // save the template type too
                    TEMPLATETYPES = TEMPLATETYPES + [values]; // add type to type array
                }
                if ( cmd == "GENRES" ) {
                    SCRATCH = SCRATCH + "|" + data; // add the genres
                }
                if ( cmd == "GPCOST" ) {
                    SCRATCH = SCRATCH + "|" + data; // add the cost
                    TEMPLATECOSTS = TEMPLATECOSTS + [(integer)values]; // add cost to the template cost array
                }
                if ( cmd == "ADDSTATISTIC" ) {
                    SCRATCH = SCRATCH + "|" + data; // add a statistic
                }
                if ( cmd == "ADDSKILL" ) {
                    SCRATCH = SCRATCH + "|" + data; // add a skill
                }
                if ( cmd == "ADDBOON" ) {
                    SCRATCH = SCRATCH + "|" + data; // add a boon
                }
                if ( cmd == "ADDFLAW" ) {
                    SCRATCH = SCRATCH + "|" + data; // add a flaw
                }
                if ( cmd == "ADDSFX" ) {
                    SCRATCH = SCRATCH + "|" + data; // add a special effect ability
                }
                if ( cmd == "ADDEQUIPMENT" ) {
                    SCRATCH = SCRATCH + "|" + data; // add an equipment
                }
                if ( cmd == "ADAPTATIONS" ) {
                    SCRATCH = SCRATCH + "|" + data; // add an adaptation type for this template
                }
                if ( cmd == "DESCRIPTION" ) {
                    SCRATCH = SCRATCH + "|" + data; // add the description
                }                
                //DEBUG("POWER_LEVEL=["+llList2String(POWER_LEVELS,LINE)+"] STAT_POOL=["+(string)                
                QUERY = llGetNotecardLine(CARD,LINE++); // finished with known keywords, get next line
            } else { // end of notecard
                // notecard done - save template to memory
                // since template data is a variable length list for each template
                // we'll prefix a count of items in each template ahead of the template data itself
                if ( TYPE == "Background" ) {
                    DEBUG("Adding Background: "+SCRATCH);
                    BACKGROUNDS += [SCRATCH]; // add background template to list of background templates
                }
                if ( TYPE == "Career" ) {
                    DEBUG("Adding Career: "+SCRATCH);
                    CAREERS += [SCRATCH]; // add career template to list of career templates
                }
                if ( TYPE == "Species" ) {
                    DEBUG("Adding Species: "+SCRATCH);
                    SPECIES += [SCRATCH]; // add species to list of species templates
                }
                // clean up scratch space
                SCRATCH = "";
                TYPE = "";
                // keep reading in more cards?
                if ( llGetListLength(TABLES) > 0 ) { // do we have notecard names in list?
                    CARD = llList2String(TABLES,0); // set current card to first list item
                    TABLES = llDeleteSubList(TABLES,0,0); // delete first list item
                    LINE = 0; // reset line count to zero for start of read
                    QUERY = llGetNotecardLine(CARD,LINE++); // ask for line from notecard and advance to next line
                } else {
                    DEBUG("Templates 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_TEMPLATES" ) { // is this a list all templates request?
            LIST_TEMPLATES(id); // call it
            return; // return early instead of processing more
        }
        if ( command == "GET_TEMPLATE" ) { // GET_TEMPLATE|string templatename
            GET_TEMPLATE(id,msg); // call it
            return; // return early instead of processing more
        }
        if ( command == "SET_TEMPLATE" ) { // is this a set-template request?
            SET_TEMPLATE(); // call it
            return; // return early in case we add more later
        }
    }
} // end default state

Personal tools
General
About This Wiki