Difference between revisions of "LSL languageAPI"
(New page: {{LSL Header}} <lsl> // LSL_languageAPI // License Info - LGPL // Version 0.20 // Author: Gypsy Paz //============== // CONFIG //============== integer autoLoad = FALSE; // l...) |
(MultiLingual API to handle script output from notecard based language files) |
||
Line 1: | Line 1: | ||
{{LSL Header}} | {{LSL Header}} | ||
This is an API that will handle chat messages and HUD menus in multiple languages based on language files in notecards. | |||
Included are two LSL files, the API itself, a simple example usage script and two language files ( English and French ) | |||
todo: floating text support is not yet included in this script. | |||
<lsl> | <lsl> | ||
// LSL_languageAPI | // LSL_languageAPI | ||
// License | // License: LGPL | ||
// Version 0.20 | // Version: 0.20 | ||
// Author: Gypsy Paz | // Author: Gypsy Paz | ||
Revision as of 05:49, 15 April 2008
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
This is an API that will handle chat messages and HUD menus in multiple languages based on language files in notecards. Included are two LSL files, the API itself, a simple example usage script and two language files ( English and French )
todo: floating text support is not yet included in this script.
<lsl> // LSL_languageAPI // License: LGPL // Version: 0.20 // Author: Gypsy Paz
//==============
// CONFIG
//==============
integer autoLoad = FALSE; // load the first notecard on CHANGED_INVENTORY
float menuTimeout = 10; // Set the blue menu time out ( in seconds )
//================================================================================================ // LINK CODES: //================================================================================================ list langLinkCodes = [
"INIT", 0x88000, //Initialize "INIT_R", 0x88001, //Confirm Initialized "LOAD", 0x88002, //Load Language lang file name (blank loads first one) "LOAD_R", 0x88003, //Confirm Lanugage Loaded "MENU", 0x88004, //langMenu caption|button1|button2|etc... avkey "MENU_R", 0x88005, //langMenu Response button uuid "MENU_C", 0x88006, //Close the menu (turn off the listener) "WHISPER", 0x88007, //langWhisper message uuid "SAY", 0x88008, //langSay message uuid "SHOUT", 0x88009, //langShout message uuid "OSAY", 0x8800A, //langOwnerSay message uuid "IM", 0x8800B, //langIM message|avkey uuid "FTEXT", 0x8800C, //floating text message color alpha "DUMP", 0x8800D, //dump lang from memory to chat (for debugging) "ERROR", 0x8800E // return an error message ( not sure how I'll handle this yet
];
//================================================================================================
// LANGUAGE FUNCTIONS:
//================================================================================================
integer langGetCode(string langCode){
integer i = llListFindList(langLinkCodes, [langCode]); return llList2Integer(langLinkCodes, i+1);
}
// Language Vars
string Language;
list langData;
list langIndex;
string curLangFile;
// llDialog Vars string menuCaption; list menuButtons; key menuUser; integer menuChannel; integer menuListener;
// Data Server Vars integer lines; integer line; key request = NULL_KEY;
string translate(string index, string id){
string val; integer i = llListFindList(langIndex,[index]); if ( i != -1 ){ return parse(llList2String(langData,i),id); } else{ return ">>>error<<<"; }
}
string parse(string val, string id){
// Memory integer i; i = llSubStringIndex(val,"<<memory>>"); if ( i != -1 ){ val = llDeleteSubString(val,i,llStringLength("<<memory>>")-1); val = llInsertString(val,i,(string)llGetFreeMemory()); } i = llSubStringIndex(val,"<<key2name>>"); if ( i != -1 ){ val = llDeleteSubString(val,i,i+llStringLength("<<key2name>>")); val = llInsertString(val,i,llKey2Name((key)id)); } return val;
}
integer processing = FALSE;
processData(string data){
if ( processing ){ if ( data == ">>>STOP<<<" ){ processing = FALSE; return; } string prefix = llGetSubString(data,0,1); if ( ( prefix == "//" ) || ( llStringLength(data) == 0 ) ){ return; } list s = llParseString2List(data,["|"],[]); string cmd = llStringTrim(llList2String(s,0),STRING_TRIM); string val = llStringTrim(llList2String(s,1),STRING_TRIM);
if ( cmd == "!PRINT" ){ llSay(0,parse(val,"")); } else if ( cmd == "!SET_LANG" ){ Language = val; } else{ integer i = llListFindList(langIndex,[cmd]); if ( i == -1 ) return; //<<<<<<<<<<<<<< this will silently fail missing indexes langData = llListReplaceList(langData,[val],i,i); }
} else if ( data == ">>>START<<<" ){ processing = TRUE; }
}
dumpData(){
integer i; for ( i=0; i<llGetListLength(langIndex); i++ ){ llSay(0,llList2String(langIndex,i)+" | "+llList2String(langData,i)); }
}
default{
link_message(integer sender, integer num, string msg, key id){ list s; integer i; if ( num == langGetCode("INIT") ){ //Initialize curLangFile = ""; Language = ""; langIndex = llParseString2List(msg,["|"],[]); langData = []; for ( i = 0; i < llGetListLength(langIndex); i++ ){ langData += ["..."]; } llMessageLinked(LINK_THIS,langGetCode("INIT_R"),"ok"," "); } else if ( num == langGetCode("LOAD") ){ // Load Language if ( llStringLength(msg) == 0 ){ curLangFile = llGetInventoryName(INVENTORY_NOTECARD,0); } else{ curLangFile = msg; } if ( llGetInventoryType(curLangFile) != INVENTORY_NOTECARD ){ llSay(0,"Error, Language File Doesn't Exist"); return; } state prep; } else if ( num == langGetCode("MENU") ){ // llDialog s = llParseString2List(msg,["|"],[]); menuCaption = translate(llList2String(s,0),""); menuButtons = []; for ( i=1; i<llGetListLength(s); i++ ){ menuButtons += translate(llList2String(s,i),""); } menuUser = id; state menu; } else if ( num == langGetCode("WHISPER") ){ // Whisper llWhisper(0,translate(msg,id)); } else if ( num == langGetCode("SAY") ){ // Say llSay(0,translate(msg,id)); } else if ( num == langGetCode("SHOUT") ){ // Shout llShout(0,translate(msg,id)); } else if ( num == langGetCode("OSAY") ){ // OwnerSay llOwnerSay(translate(msg,id)); } else if ( num == langGetCode("IM") ){ // Instant Message s = llParseString2List(msg,["|"],[]); llInstantMessage(llList2Key(s,1),translate(llList2String(s,0),id)); } else if ( num == langGetCode("DUMP") ){ dumpData(); } } changed(integer change){ if ( change & CHANGED_INVENTORY ){ } }
}
state menu{
state_entry(){ menuChannel = 0; while(menuChannel == 0 ){ menuChannel = (integer)llRound(llFrand(5)*10000000); } llDialog(menuUser,menuCaption,menuButtons,menuChannel); llSetTimerEvent(menuTimeout); menuListener = llListen(menuChannel, "", menuUser, ""); } listen(integer channel, string name, key id, string msg){ llSetTimerEvent(0); integer i = llListFindList(langData,[msg]); if ( i != -1 ){ llMessageLinked(LINK_THIS,langGetCode("MENU_R"),llList2String(langIndex,i),id); } else{ llMessageLinked(LINK_THIS,langGetCode("MENU_R"),">>>error<<<",id); } state default; }
timer(){ llSetTimerEvent(0); llMessageLinked(LINK_THIS,langGetCode("MENU_R"),">>>timeout<<<", menuUser); state default; } link_message(integer sender, integer num, string str, key id){ if ( num == langGetCode("MENU_C") ){ llSetTimerEvent(0); state default; } } state_exit(){ llSetTimerEvent(0); }
}
state prep{
state_entry(){ if ( llGetInventoryType(curLangFile) == INVENTORY_NOTECARD ){ request = llGetNumberOfNotecardLines(curLangFile); llSetTimerEvent(5); } else{ llOwnerSay("Error, Language File Does Not Exist"); } } dataserver(key query_id, string data){ if (query_id == request){ llSetTimerEvent(0); lines = (integer)data; state read; } } timer(){ state timeout; }
}
state read{
state_entry(){ line = 0; request = llGetNotecardLine(curLangFile, line); llSetTimerEvent(5); } dataserver(key query_id, string data){ if (query_id == request){ llSetTimerEvent(0); processData(data); line++; if ( line <= lines ){ request = llGetNotecardLine(curLangFile, line); llSetTimerEvent(5); } else{ state default; } } } timer(){ state timeout; }
}
state timeout{
state_entry(){ llSetTimerEvent(0); llSay(0,"Error, reading the language file timed out"); llMessageLinked(LINK_THIS,51,"error","timeout"); state default; }
} </lsl>
<lsl>
//================================================================================================ // LANGUAGE API: //------------------------------------------------------------------------------------------------
//================================================================================================ string langName; list langIndex = [
"HELLO_WORLD", "HELLO_AVATAR", "OBJECT_NAME", "OWNED_BY", "CAPTION", "BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_4", "BUTTON_5", "BUTTON_6"
];
//================================================================================================ // LINK CODES: //================================================================================================ list langLinkCodes = [
"INIT", 0x88000, //Initialize "INIT_R", 0x88001, //Confirm Initialized "LOAD", 0x88002, //Load Language lang file name (blank loads first one) "LOAD_R", 0x88003, //Confirm Lanugage Loaded "MENU", 0x88004, //langMenu caption|button1|button2|etc... avkey "MENU_R", 0x88005, //langMenu Response button uuid "MENU_C", 0x88006, //Close the menu (turn off the listener) "WHISPER", 0x88007, //langWhisper message uuid "SAY", 0x88008, //langSay message uuid "SHOUT", 0x88009, //langShout message uuid "OSAY", 0x8800A, //langOwnerSay message uuid "IM", 0x8800B, //langIM message|avkey uuid "FTEXT", 0x8800C, //floating text message color alpha "DUMP", 0x8800D, //dump lang from memory to chat (for debugging) "ERROR", 0x8800E // return an error message ( not sure how I'll handle this yet
];
//================================================================================================
// LANGUAGE FUNCTIONS:
//================================================================================================
integer langGetCode(string langCode){
integer i = llListFindList(langLinkCodes, [langCode]); return llList2Integer(langLinkCodes, i+1);
}
langInit(){
llMessageLinked(LINK_THIS,langGetCode("INIT"),llDumpList2String(langIndex,"|")," ");
}
langLoad(string notecard){
langName = ""; llMessageLinked(LINK_THIS,langGetCode("LOAD"),notecard, " ");
}
langWhisper(string msg, key id){
llMessageLinked(LINK_THIS,langGetCode("WHISPER"),msg,id);
}
langSay(string msg, key id){
llMessageLinked(LINK_THIS,langGetCode("SAY"),msg,id);
}
langShout(string msg, key id){
llMessageLinked(LINK_THIS,langGetCode("SHOUT"),msg,id);
}
langMenu(string caption, list buttons, key id){
llMessageLinked(LINK_THIS,langGetCode("MENU"),caption+"|"+llDumpList2String(buttons,"|"),id);
}
default{
state_entry(){ langInit(); } link_message(integer sender, integer num, string msg, key id){ // Language is initialized if ( num == langGetCode("INIT_R") ){ if ( msg == "ok" ){ // load the default language (first notecard) langLoad(""); } else if ( msg == "error" ){ // something went wrong llOwnerSay((string)id); } } // Language is loaded else if ( num == langGetCode("LOAD_R") ){ if ( msg == "ok" ){ // load the default language (first notecard) langName = (string)id; } else if ( msg == "error" ){ // something went wrong llOwnerSay((string)id); }
llMessageLinked(LINK_THIS,langGetCode("DUMP"),"dump data"," ");
} // Blue Menu Response else if ( num == langGetCode("MENU_R") ){ if ( msg == "BUTTON_1" ){ langSay("HELLO_AVATAR", id); } else if ( msg == "BUTTON_2" ){ langSay("OBJECT_NAME", llGetKey()); } else if ( msg == "BUTTON_3" ){ langSay("OWNED_BY", llGetOwner()); } else if ( msg == "BUTTON_4" ){ llMessageLinked(LINK_THIS,langGetCode("DUMP"),"dump"," "); } else if ( msg == "BUTTON_5" ){ langLoad("language - ENGLISH"); } else if ( msg == "BUTTON_6" ){ langLoad("language - FRENCH"); } } } touch_start(integer n){ langMenu("CAPTION", ["BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_4", "BUTTON_5", "BUTTON_6"], llDetectedKey(0));
}
} </lsl>
<lsl>
Instructions go up here
>>>START<<< // start processing the notecard !SET_LANG | Engilish !PRINT | Loading Language File...
HELLO_WORLD | Hello, I'm a multi-lingual api HELLO_AVATAR | Hello <<key2name>> OBJECT_NAME | I am a <<key2name>> OWNED_BY | I belong to <<key2name>> CAPTION | Language API Sample, choose your option BUTTON_1 | Avatar BUTTON_2 | Object BUTTON_3 | Owner BUTTON_4 | Dump BUTTON_5 | ENGLISH BUTTON_6 | FRENCH
!PRINT | Language file loaded. !PRINT | <<memory>> bytes free
>>>STOP<<< </lsl>
<lsl> Mettez vos instructions ici
>>>START<<< // commencez à traiter le notecard !SET_LANG | Francais !PRINT | Chargement du Dossier de Langue...
HELLO_WORLD | Bonjour, je suis api multilingue HELLO_AVATAR | Bonjour <<key2name>> OBJECT_NAME | Je suis <<key2name>> OWNED_BY | J'appartiens à <<key2name>> CAPTION | L'Échantillon d'API de langue, choisissez votre option BUTTON_1 | Avatar BUTTON_2 | Objet BUTTON_3 | Propriétaire BUTTON_4 | Décharge publique
!PRINT | Le dossier de langue a chargé. !PRINT | octets de <<memory>> libres
>>>STOP<< </lsl>