Universal Translator
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Universal Translator Engine
<lsl> //Universal Translator //Version 1.9.0 //November 12, 2009 //LSL Script copyright 2006-2009 by Hank Ramos //Web Server Services powered by Google
//Variables list agentsInTranslation; list agentsInTranslationOptions; list requestList; integer listenID;
integer isMaster = 1; integer autoLanguage = TRUE; integer enabled = FALSE; integer showTranslation = FALSE; integer tranObjects = TRUE;
integer lastHeartBeat; list languageCodes = [ "zh-CN", "zh-TW", "hr", "bg", "be", "ca", "af", "sq", "ar",
"tl", "fr", "gl", "fi", "en", "et", "cs", "da", "nl",
"id", "ga", "it", "hi", "hu", "is", "de", "el", "iw",
"mt", "no", "fa", "lt", "mk", "ms", "ja", "ko", "lv",
"sl", "es", "sw", "ru", "sr", "sk", "pl", "pt-PT", "ro",
"yi", "", "", "uk", "vi", "cy", "sv","th", "tr"];
list translators; list sayCache; list sayCachePrivate; integer priorityNumber; integer priorityNumListenID; integer isInitialized = FALSE; string options;
//Options //integer debug = TRUE; integer broadcastChannel = -9999999; //note this is not the channel used by the HR Universal Translator string password = "password"; //note this is not the password used to encrypt comms of the HR Universal Translator integer version = 190; sendIM(key id, string str) {
if (llGetParcelFlags(llGetPos()) & PARCEL_FLAG_ALLOW_SCRIPTS) { llMessageLinked(LINK_ALL_CHILDREN, 85234119, str, id); } else { llMessageLinked(LINK_THIS, 85304563, str, id); }
}
sendTextBatch(integer channel, string sendText) {
sendText = llXorBase64StringsCorrect(llStringToBase64(sendText), llStringToBase64(password));; while (llStringLength(sendText) > 508) //If string is 509 characters or longer { llSay(channel, llGetSubString(sendText, 0, 507)); //send 508 character chunk sendText = llGetSubString(sendText, 508, -1); //delete 508 character chunk } llSay(channel, sendText); //send out any remainder chunk or original chunk if (llStringLength(sendText) == 508) llSay(channel, (string)(channel*4958654)); llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0.25, 0, 0.25>, "");
}
string receiveTextBatch(key id, string message) {
integer listPos; string tempString = ""; listPos = llListFindList(sayCache, [id]); if (listPos >= 0) { while (listPos >= 0) { tempString = tempString + llList2String(sayCache, listPos + 1); sayCache = llDeleteSubList(sayCache, listPos, listPos + 1); listPos = llListFindList(sayCache, [id]); } message = tempString + message; } message = llBase64ToString(llXorBase64StringsCorrect(message, llStringToBase64(password))); return message;
} string receiveTextBatchPrivate(key id, string message) {
integer listPos; string tempString = ""; listPos = llListFindList(sayCachePrivate, [id]); if (listPos >= 0) { while (listPos >= 0) { tempString = tempString + llList2String(sayCachePrivate, listPos + 1); sayCachePrivate = llDeleteSubList(sayCachePrivate, listPos, listPos + 1); listPos = llListFindList(sayCachePrivate, [id]); } message = tempString + message; } message = llBase64ToString(llXorBase64StringsCorrect(message, llStringToBase64(password))); return message;
} updateTranslatorList() {
integer x; integer listLength; list newList; string tempString; integer newMaster; //Scan and remove translators not in the area for (x = 0; x < llGetListLength(translators); x += 2) { tempString = llList2String(llGetObjectDetails(llList2Key(translators, x + 1), [OBJECT_POS]), 0); if ((llVecDist(llGetPos(), (vector)tempString) <= 20.0) && (tempString != "")) newList += llList2List(translators, x, x + 1); } translators = newList;
listLength = llGetListLength(translators); llMessageLinked(LINK_THIS, 65635544, (string)listLength, "");
if (listLength == 0) { newMaster = 1; } else { if (enabled) { newMaster = 2; for (x = 0; x < llGetListLength(translators); x += 2) { //llOwnerSay("Checking Priority Number(" + (string)priorityNumber + "): " + (string)llList2Integer(translators, x)); if (llList2Integer(translators, x) > priorityNumber) { newMaster = 0; } } } else { newMaster = 0; } }
if ((isMaster > 0) && (newMaster == 0)) { //We are being demoted from master to slave //Flush agentsInTranslation to master if (llGetListLength(agentsInTranslation) > 0) { //Demotion Dump of agentsInTranslation to Master sendTextBatch(broadcastChannel, llList2CSV([1003, llList2CSV(agentsInTranslation)])); if (isInitialized == FALSE) return; sendTextBatch(broadcastChannel, llList2CSV([1004, options])); //error } llListenRemove(listenID); } if ((isMaster == 0) && (newMaster > 0)) { llListenRemove(listenID); listenID = llListen(0, "", "", ""); } isMaster = newMaster; llMessageLinked(LINK_THIS, 34829304, (string)isMaster, "");
}
sendHeartbeat() {
updateTranslatorList(); sendTextBatch(broadcastChannel, llList2CSV([1001, priorityNumber]));
//Broadcast agentList to Slaves if (isMaster == 2) { sendTextBatch(broadcastChannel, llList2CSV([1002, llList2CSV(agentsInTranslation)])); }
}
//Functions checkThrottle(integer num, string msg, list params) {
integer x; integer maxCount; float oldTime; float sleepTime; list newList; key returnValue; integer channelToSpeak; //loop though list and remove items older than 25 seconds for (x = 0; x < llGetListLength(requestList); x += 1) { oldTime = llList2Float(requestList, x); //Construct new list with only times less than 25 seconds if ((llGetTime() - oldTime) <= 25.0) newList += oldTime; } requestList = newList; x = llGetListLength(requestList); //Shunt all translations to linked translators if master if (isMaster == 2) { if (num == 0) { //Send HTTP request to other translator //Send out Request to Random Translator Channel
channelToSpeak = llList2Integer(llListRandomize(llList2ListStrided(translators, 0, -1, 2), 1), 0); if (channelToSpeak > 0) { sendTextBatch(channelToSpeak, llList2CSV([num, llList2CSV(params)]) + "~" + msg); return; } } }
if (x == 19) { sleepTime = 25.0 - (llGetTime() - llList2Float(requestList, 0)); if (sleepTime > 0) { llSleep(sleepTime); } requestList = llDeleteSubList(requestList, 0, 0); } if (num == 0) { msg = "translate?v=1.0&q=" + msg; } else msg = "detect?v=1.0&q=" + msg;
requestList += llGetTime(); returnValue = llHTTPRequest("http://ajax.googleapis.com/ajax/services/language/" + msg, [HTTP_METHOD, "GET", HTTP_MIMETYPE, "plain/text;charset=utf-8"], " "); if (returnValue != NULL_KEY) { if (num == 0) llMessageLinked(LINK_THIS, 235365342, llList2CSV(params), returnValue); else llMessageLinked(LINK_THIS, 235365343, llList2CSV(params), returnValue); } else { llSleep(40.0); //Something has gone horribly wrong, sleep 40 seconds to clear throttle }
}
string checkLanguage(string tempString) {
if (llGetSubString(tempString, 0, 1) == "zh") tempString = "zh-CN"; else if (tempString == "und") tempString = "el"; else if (llListFindList(languageCodes, [tempString]) < 0) tempString = ""; tempString = llGetSubString(tempString, 0, 1); return tempString;
} addAgent(key id, string language, integer recheckLangauge) {
integer listPos; integer listPosID; integer idNum; string tempString;
listPos = llListFindList(agentsInTranslation, [id]); if (listPos < 0) { while (listPosID >= 0) { idNum = llRound(llFrand(2000000)) + 1; listPosID = llListFindList(agentsInTranslation, [idNum]); } agentsInTranslation += [id, language, recheckLangauge, idNum]; llMessageLinked(LINK_THIS, 64562349, language, id); } else agentsInTranslation = llListReplaceList(agentsInTranslation, [language, recheckLangauge], listPos + 1, listPos + 2);
}
string addNewAgent(key id) {
string speakerLanguage; if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY) { speakerLanguage = checkLanguage(llGetAgentLanguage(id)); if (speakerLanguage == "") { speakerLanguage = "en"; addAgent(id, speakerLanguage, TRUE); } else { addAgent(id, speakerLanguage, FALSE); } } return speakerLanguage;
}
key getAgentKey(integer agentID) {
integer listPos = llListFindList(agentsInTranslation, [agentID]); if (listPos < 0) { return ""; } else { return llList2Key(agentsInTranslation, listPos - 3); }
} processHTTPResponse(integer type, string body, list params) {
integer listPos; list recepientList; key recepientID; string recepientLanguage; string languagePair; key speakerID; string speakerName; string speakerLanguage; string translatedText; string tempString; integer x; integer speakerLanguageReliable; float speakerLanguageConfidence; list tempList; //=================== //Process Translation //=================== if (type == 0) { speakerID = llList2Key(params, 1); speakerName = llKey2Name(speakerID); if (speakerName == "") speakerName = llList2String(llGetObjectDetails(speakerID, [OBJECT_NAME]), 0); recepientList = llParseString2List(llList2String(params, 2), ["@"], []); tempList = llParseStringKeepNulls(llList2String(params, 3), ["|"],[]); recepientLanguage = llList2String(tempList, 1); languagePair = llDumpList2String(tempList, ">>"); //Perform Text Cleanup x = llSubStringIndex(body, "\",\"detectedSourceLanguage\":\""); if (x >= 0) { translatedText = llGetSubString(body, llSubStringIndex(body, "{\"translatedText\":\"") + 18, x); speakerLanguage = checkLanguage(llGetSubString(body, x + 28, llSubStringIndex(body, "\"}, \"responseDetails\":") - 1)); listPos = llListFindList(agentsInTranslation, [speakerID]); if (listPos >= 0) { if (speakerLanguage != llList2String(agentsInTranslation, listPos + 1)) agentsInTranslation = llListReplaceList(agentsInTranslation, [TRUE], listPos + 2, listPos + 2); //Mark for recheck of actual spoken language. } } else { translatedText = llGetSubString(body, llSubStringIndex(body, "{\"translatedText\":\"") + 18, llSubStringIndex(body, "\"}, \"responseDetails\"")); } //Reverse order if Recepient Language is Hebrew or Arabic if ((recepientLanguage == "iw") || (recepientLanguage == "ar")) { tempString = ""; for(x = llStringLength(translatedText);x >= 0; x--) { tempString += llGetSubString(translatedText, x, x); } translatedText = tempString; } tempString = speakerName + "(" + languagePair + "): " + translatedText; if (showTranslation) sendIM(speakerID, tempString); for (x = 0; x < llGetListLength(recepientList); x += 1) { recepientID = getAgentKey(llList2Integer(recepientList, x)); if (recepientID != "") { recepientLanguage = llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [recepientID]) + 1); if (recepientLanguage != speakerLanguage) sendIM(recepientID, tempString); } } return; } //=========================== //Process Language Detection //=========================== if (type == 1) { speakerID = llList2Key(params, 1); speakerLanguageReliable = llToLower(llGetSubString(body, llSubStringIndex(body, "\",\"isReliable\":") + 15, llSubStringIndex(body, ",\"confidence\":") - 1)) == "true"; speakerLanguageConfidence = (float)llGetSubString(body, llSubStringIndex(body, ",\"confidence\":") + 14, llSubStringIndex(body, "}, \"responseDetails\":") - 1); listPos = llListFindList(agentsInTranslation, [speakerID]);
if (((listPos < 0) && (speakerLanguageReliable) || (speakerLanguageConfidence >= 0.18))) { //Analyze Data tempString = checkLanguage(llToLower(llGetSubString(body, llSubStringIndex(body, "{\"language\":\"") + 13, llSubStringIndex(body, "\",\"isReliable\":") - 1))); if (tempString == "") return; if (speakerLanguageConfidence < 0.14) addAgent(speakerID, tempString, TRUE); else addAgent(speakerID, tempString, FALSE); } }
}
default
{
state_entry() { //Multiplexor Initialization priorityNumber = version*1000000 + llRound(llFrand(499999) + 50000); llListen(broadcastChannel, "", NULL_KEY, ""); priorityNumListenID = llListen(priorityNumber, "", NULL_KEY, ""); //Send out initial heartbeat lastHeartBeat = llGetUnixTime(); sendTextBatch(broadcastChannel, llList2CSV([1001, priorityNumber])); //Wait for the network to settle down llSetTimerEvent(5); //llSetTimerEvent(10 + ((1-llGetRegionTimeDilation()) * 1)); } sensor(integer num_detected) { integer x; key id;
for (x = 0; x < num_detected; x += 1) { id = llDetectedKey(x); if (llListFindList(agentsInTranslation, [id]) < 0) { addNewAgent(id); } } } link_message(integer sender_num, integer num, string str, key id) { integer x; integer listPos; list tempList; integer channelToSpeak; //Old Multiplexor if (num == 8434532) { enabled = (integer)str; } else if (num == 3342976) { //Send Preferences options = str; if (isInitialized == FALSE) return; tempList = llCSV2List(options); showTranslation = llList2Integer(tempList, 0); tranObjects = llList2Integer(tempList, 1); autoLanguage = llList2Integer(tempList, 2); sendTextBatch(broadcastChannel, llList2CSV([1004, options]));
} else if (num == 9384610) { if (isMaster == 0) //markering //llMessageLinked(LINK_THIS, 5598321, llList2CSV([id, str, FALSE]), ""); sendTextBatch(broadcastChannel, llList2CSV([1003, id, str, FALSE])); else addAgent(id, str, TRUE); } else if (num == 345149625) { //Return Translation processHTTPResponse(0, str, llCSV2List(id)); } else if (num == 345149626) { //Return Detection processHTTPResponse(1, str, llCSV2List(id)); } } timer() { integer x; string tempString; list newList; integer translatorCount = llGetListLength(translators)/2; if (isInitialized == FALSE) { isInitialized = TRUE; enabled = TRUE; listenID = llListen(0, "", "", ""); llListen(777, "", NULL_KEY, ""); llMessageLinked(LINK_THIS, 6877259, (string)enabled, NULL_KEY); }
llMessageLinked(LINK_THIS, 94558323, llList2CSV(agentsInTranslation), ""); if (isMaster > 0) { for (x = 0; x < llGetListLength(agentsInTranslation); x += 4) { tempString = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, x), [OBJECT_POS]), 0); if ((llVecDist(llGetPos(), (vector)tempString) <= 20.0) && (tempString != "")) newList += llList2List(agentsInTranslation, x, x + 3); } agentsInTranslation = newList; if ((llGetUnixTime() - lastHeartBeat) >= 5) { //Send heartbeat sendHeartbeat(); lastHeartBeat = llGetUnixTime(); } } else { if ((llGetUnixTime() - lastHeartBeat) >= `0 + llGetListLength(agentsInTranslation)*2 + llPow(translatorCount, 1.4) + translatorCount + ((1-llGetRegionTimeDilation()) * 5)) { //Send heartbeat sendHeartbeat(); lastHeartBeat = llGetUnixTime(); } } //turn on and off scanner if ((autoLanguage) && (isMaster > 0)) { llSensor("", NULL_KEY, AGENT, 20.0, PI); } //llSetTimerEvent(4 + ((1-llGetRegionTimeDilation()) * 5)); } listen(integer channel, string name, key id, string message) { integer x; string speakerLanguage; string recepientLanguage; integer recepientID; integer listPos; string languagePair; list translationCache; list tempList; integer ImessageType; string Imessage; string tempString; string tempString2; //Multiplexor Code if ((channel == broadcastChannel) || (channel == priorityNumber)) { //========================== //Process Proxy HTTP Request //==========================
if (channel == priorityNumber) { if (llStringLength(message) >= 508) { if (((integer)message/channel) != 4958654) { sayCachePrivate += [id, message]; return; } message = ""; } message = receiveTextBatchPrivate(id, message); //Received packet to translate llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0.25, 0.05, 0.25>, ""); tempList = llParseString2List(message, ["~"], []); tempString = llList2String(tempList, 0); tempList = llDeleteSubList(tempList, 0, 0);
tempString2 = llDumpList2String(tempList, "|"); tempList = llCSV2List(tempString); listPos = llList2Integer(tempList, 0); tempList = llDeleteSubList(tempList, 0, 0);
checkThrottle(listPos, tempString2, tempList);
return; } //======================= //Process Global Messages //======================= if (llStringLength(message) >= 508) { if (((integer)message/channel) != 4958654) { sayCache += [id, message]; return; } message = ""; } message = receiveTextBatch(id, message); tempList = llCSV2List(message); if (llGetListLength(tempList) >= 2) { ImessageType = llList2Integer(tempList, 0); tempList = llDeleteSubList(tempList, 0, 0); Imessage = llList2CSV(tempList); llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0.25, 0, 0.25>, ""); //Process Message Here if (ImessageType == 1001) { //Incoming Heartbeat if ((integer)Imessage == priorityNumber) { llOwnerSay("Priority Number Conflict! Resetting Script..."); llResetScript(); //Reset if conflicting priority number } listPos = llListFindList(translators, [id]); if (listPos < 0) { translators += [(integer)Imessage, id]; if ((isMaster > 0) && (isInitialized)) { sendTextBatch((integer)Imessage, llList2CSV([1002, llList2CSV(agentsInTranslation)])); sendTextBatch((integer)Imessage, llList2CSV([1004, options])); } } else { translators = llListReplaceList(translators, [(integer)Imessage], listPos - 1, listPos - 1); } } else if (ImessageType == 1002) { //Incoming agentsInTranslation Master Broadcast if (isMaster == 0) { //llMessageLinked(LINK_THIS, 9458021, Imessage, ""); tempList = llCSV2List(Imessage); agentsInTranslation = []; for (x = 0; x < llGetListLength(tempList); x += 4) { agentsInTranslation += [llList2Key(tempList, x), llList2String(tempList, x + 1), llList2Integer(tempList, x + 2), llList2Integer(tempList, x + 3)]; } } } else if (ImessageType == 1003) { //Incoming agentsInTranslation dump from Slave tempList = llCSV2List(Imessage); for (x = 0; x < llGetListLength(tempList); x += 4) { addAgent(llList2Key(tempList, x), llList2String(tempList, x + 1), llList2Integer(tempList, x + 2)); } } else if (ImessageType == 1004) { //Incoming Preferences options = Imessage; tempList = llCSV2List(options); showTranslation = llList2Integer(tempList, 0); tranObjects = llList2Integer(tempList, 1); autoLanguage = llList2Integer(tempList, 2);
llMessageLinked(LINK_THIS, 3342977, Imessage, ""); } } return; } //Translator Engine Code if ((llToLower(message) == "translator") && (isMaster > 0)) { llMessageLinked(LINK_THIS, 2540664, message, id); return; } if ((!enabled) && (isMaster == 1)) return; if (!tranObjects) { if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) != NULL_KEY) return; } listPos = llListFindList(agentsInTranslation, [id]); if (listPos >= 0) { speakerLanguage = llList2String(agentsInTranslation, listPos + 1); } else { speakerLanguage = addNewAgent(id); } if (speakerLanguage == "xx") return; //Agent Opt-Out llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 1, 0>, ""); //=============================== //Formulate Translation Requests //=============================== for (x = 0; x < llGetListLength(agentsInTranslation); x += 4) { //Loop through translation group and do appropriate translations as needed recepientID = llList2Integer(agentsInTranslation, x + 3); recepientLanguage = checkLanguage(llList2Key(agentsInTranslation, x + 1)); if ((speakerLanguage != recepientLanguage) && (recepientLanguage != "") && (recepientLanguage != "xx")) { languagePair = speakerLanguage + "|" + recepientLanguage; listPos = llListFindList(translationCache, [languagePair]); if (listPos < 0) translationCache += [languagePair, recepientID]; else translationCache = llListReplaceList(translationCache, [llList2String(translationCache, listPos + 1) + "@" + (string)recepientID], listPos + 1, listPos + 1); } } //Process Requests if (llGetListLength(translationCache) > 0) { for (x = 0; x < llGetListLength(translationCache); x += 2) { //==================================== //Translation //==================================== //Forumulate and Send Translation Request languagePair = "|" + llList2String(llParseStringKeepNulls(llList2String(translationCache, x), ["|"],[]), 1); checkThrottle(0, llEscapeURL(message) + "&langpair=" + llEscapeURL(languagePair), [llGetTime(), id , llList2String(translationCache, x + 1), llList2String(translationCache, x)]); } } else speakerLanguage = "";
//==================================== //Language Detection //==================================== if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY) { if (((speakerLanguage == "") || (llList2Integer(agentsInTranslation, llListFindList(agentsInTranslation, [id]) + 2) == TRUE)) || (isMaster == 2)) { //Forumulate and Send Language Detect Request checkThrottle(1, llEscapeURL(message), [llGetTime(), id]); } } } http_response(key request_id, integer status, list metadata, string body) { string tempString;
if (status != 200) { //llOwnerSay("WWW Error:" + (string)status); llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 0, 0>, ""); //llOwnerSay(body); return; } //Process Resonse Code tempString = llGetSubString(body, llSubStringIndex(body, "\"responseStatus\":"), -1); status = (integer)llGetSubString(tempString, 17, llSubStringIndex(tempString, "}") - 1); if (status != 200) { //llOwnerSay("Language Server Returned Error Code: " + (string)status); //llOwnerSay(body); llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 0, 0>, ""); return; } llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0, 0, 1>, ""); llMessageLinked(LINK_THIS, 345149624, body, request_id); }
} </lsl>
HTTP Handler
<lsl> //HTTP Handler //Copyright 2006-2009 by Hank Ramos
list requestedTranslations; list requestedDetections;
default {
state_entry() { llSetTimerEvent(5); }
timer() { integer x; list newList; float timeElapsed; for (x = 0; x < llGetListLength(requestedDetections); x += 2) { timeElapsed = llGetTime() - llList2Float(llCSV2List(llList2String(requestedDetections, x + 1)), 0); if (timeElapsed < 60.0) newList += llList2List(requestedDetections, x, x + 1); } requestedDetections = newList; newList = []; for (x = 0; x < llGetListLength(requestedTranslations); x += 2) { timeElapsed = llGetTime() - llList2Float(llCSV2List(llList2String(requestedTranslations, x + 1)), 0); if (timeElapsed < 60.0) { newList += llList2List(requestedTranslations, x, x + 1); } } requestedTranslations = newList; }
link_message(integer sender_num, integer num, string str, key id) { integer listPos; if (num == 235365342) { //Translation requestedTranslations += [id, str]; } else if (num == 235365343) { //Detection requestedDetections += [id, str]; } else if (num == 345149624) { listPos = llListFindList(requestedTranslations, [id]); if (listPos >= 0) { llMessageLinked(LINK_THIS, 345149625, str, llList2String(requestedTranslations, listPos + 1)); requestedTranslations = llDeleteSubList(requestedTranslations, listPos, listPos + 1); return; } listPos = llListFindList(requestedDetections, [id]); if (listPos >= 0) { llMessageLinked(LINK_THIS, 345149626, str, llList2String(requestedDetections, listPos + 1)); requestedDetections = llDeleteSubList(requestedDetections, listPos, listPos + 1); } } }
} </lsl>
Interface Handler
<lsl> //Menu System //Copyright 2006-2009 by Hank Ramos
//Variables integer randomDialogChannel; integer lastAttachPoint; list detectedAgentKeyList; list detectedAgentNameList; key agentInDialog; integer isInitialized = FALSE; list agentsInTranslation; integer translatorCount;
//Options integer groupAccess = FALSE; integer autoLanguage = TRUE; integer deviceAttached; integer enabled = FALSE; integer isShowTran = FALSE; integer showAgents = TRUE; string displayStringMD5; integer isMaster = 1; integer tranObjects = TRUE;
//Constants list languages= [ "Chinese-Simple", "Chinese-Trad", "Croatian", "Bulgarian", "Belarusian", "Catlan", "Afrikaans", "Albanian", "Arabic",
"Filipino", "French", "Galician", "Finnish", "English", "Estonian", "Czech", "Danish", "Dutch",
"Indonesian", "Irish", "Italian", "Hindi", "Hungarian", "Icelandic", "German", "Greek", "Hebrew",
"Maltese", "Norwegian", "Persian", "Lithuanian", "Macedonian", "Malay", "Japanese", "Korean", "Latvian",
"Slovenian", "Spanish", "Swahili", "Russian", "Serbian", "Slovak", "Polish", "Portuguese", "Romanian",
"Yiddish", "\t ", "\t ", "Ukrainian", "Vietnamese", "Welsh", "Swedish", "Thai", "Turkish"];
list languageCodes = [ "zh-CN", "zh-TW", "hr", "bg", "be", "ca", "af", "sq", "ar",
"tl", "fr", "gl", "fi", "en", "et", "cs", "da", "nl",
"id", "ga", "it", "hi", "hu", "is", "de", "el", "iw",
"mt", "no", "fa", "lt", "mk", "ms", "ja", "ko", "lv",
"sl", "es", "sw", "ru", "sr", "sk", "pl", "pt-PT", "ro",
"yi", "", "", "uk", "vi", "cy", "sv", "th", "tr"];
//Functions //Takes in the offsets, and the attach point vector fn_makePos(integer attach_point, vector offset) {
if ((attach_point == 31) || (attach_point == 35)) { //center 2 & center return <0,0,0>; } else if (attach_point == 32) { // Top right return <offset.x, offset.y, offset.z * -1>; } else if (attach_point == 33) { // Top return <offset.x, 0, offset.z * -1>; } else if (attach_point == 34) { // Top Left return <offset.x, offset.y * -1, offset.z * -1>; } else if (attach_point == 36) { // Bottom Left return <offset.x, offset.y * -1 , offset.z>; } else if (attach_point == 37) { // Bottom return <offset.x, 0, offset.z>; } else if (attach_point == 38) { // Bottom Right - Baseline return offset; } else { //Not a HUD point? Then return it's current pos return llGetLocalPos(); }
}
updateDisplay() {
string tempString; integer listLength; integer x; string agentName; if (isInitialized == FALSE) return; tempString = "Universal Translator"; if (isMaster != 1) tempString += " (Link-" + (string)(translatorCount + 1) + ")"; tempString += "\n==============="; if (enabled) { listLength = llGetListLength(agentsInTranslation); if (((showAgents) && (listLength <= 40)) && (listLength != 0)) { for (x = 0; x < listLength; x += 4) { agentName = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, x), [OBJECT_NAME]), 0); if (llStringLength(agentName) > 25) agentName = llGetSubString(agentName, 0, 24); if (agentName != "") tempString += "\n" + agentName + "(" + llList2String(agentsInTranslation, x + 1) + ")"; } } else { tempString += "\n# Agents Translated: " + (string)llRound(listLength/3); } } else { tempString += "\n>> Disabled <<"; }
if (llMD5String(tempString, 0) != displayStringMD5) { displayStringMD5 = llMD5String(tempString, 0); llSetText(tempString, <1,1,1>, 1); }
}
showMainMenu(key id) {
if (isInitialized == FALSE) return; integer avatarParticipating; list buttonList = ["Language", "Help"]; string dialogMsg = "Main Menu\nLANGUAGE: manually choose your source language. Target languages are detected automatically\nHELP: get help notecard"; buttonList += "FREE Copy"; dialogMsg += "\nFREE COPY: receive FREE copy of Universal Translator."; if (llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [(string)id]) + 1) != "xx") { buttonList += "Opt-Out"; dialogMsg += "\nOPT-OUT: disable receipt of translations"; } else { buttonList += "Opt-In"; dialogMsg += "\nOPT-IN: join the translations"; }
if (id == llGetOwner()) { buttonList += "Donate"; dialogMsg += "\nDONATE: donate L$ to the developer of Universal Translator."; } if ((id == llGetOwner()) || ((groupAccess) && (llSameGroup(id)))) { buttonList += "Reset"; buttonList += "Options"; buttonList += "Send Copy"; dialogMsg += "\nSEND COPY: send FREE copy of Universal Translator.";
if (enabled) { buttonList += "Disable"; } else { buttonList += "Enable"; }
dialogMsg += "\nRESET: reset all scripts in translator"; }
llDialog(id, dialogMsg, buttonList, randomDialogChannel);
}
showOptionsMenu(key id) {
integer avatarParticipating; list buttonList = []; string dialogMsg = "Options Menu."; if (id == llGetOwner()) { if (groupAccess) { buttonList += "Group OFF"; } else { buttonList += "Group ON"; } dialogMsg += "\nGROUP: allow group members to admin."; } if ((id == llGetOwner()) || ((groupAccess) && (llSameGroup(id)))) { buttonList += "Main Menu"; if (!deviceAttached) { if (autoLanguage) { buttonList += "Scan OFF"; } else { buttonList += "Scan ON"; } } dialogMsg += "\nSCAN: scan for Avatars and automatically add to translation matrix.";
if (isShowTran) { buttonList += "Echo OFF"; } else { buttonList += "Echo ON"; } dialogMsg += "\nECHO: show translations of your chat sent to others.";
if (tranObjects) { buttonList += "Objects OFF"; } else { buttonList += "Objects ON"; } dialogMsg += "\nOBJECTS: translate chat of scripted objects";
if (showAgents) { buttonList += "Agents OFF"; } else { buttonList += "Agents ON"; } dialogMsg += "\AGENTS: show list of agents translated."; } llDialog(id, dialogMsg, buttonList, randomDialogChannel);
}
showLanguageDialog1(key id) {
llDialog(id, "Select your TARGET language...", ["\t", "\t", ">> NEXT"] + llList2List(languages, 0, 8), randomDialogChannel);
} showLanguageDialog2(key id) {
llDialog(id, "Select your TARGET language..", ["<< BACK", "\t ", ">> NEXT "] + llList2List(languages, 9, 17), randomDialogChannel);
} showLanguageDialog3(key id) {
llDialog(id, "Select your TARGET language..", ["<< BACK ", "\t ", ">> NEXT "] + llList2List(languages, 18, 26), randomDialogChannel);
} showLanguageDialog4(key id) {
llDialog(id, "Select your TARGET language..", ["<< BACK ", "\t ", ">> NEXT "] + llList2List(languages, 27, 35), randomDialogChannel);
} showLanguageDialog5(key id) {
llDialog(id, "Select your TARGET language..", ["<< BACK ", "\t ", ">> NEXT "] + llList2List(languages, 36, 44), randomDialogChannel);
}showLanguageDialog6(key id) {
llDialog(id, "Select your TARGET language..", ["<< BACK ", "\t ", "\t "] + llList2List(languages, 45, 53), randomDialogChannel);
} processListen(string name, key id, string message) {
key listenKey; if (llListFindList(languages, [message]) > -1) //Language Selected in Dialog { if (message != "") llMessageLinked(LINK_THIS, 9384610, llList2String(languageCodes, llListFindList(languages, [message])), id); } else if (llToLower(message) == "help") { llGiveInventory(id, "Universal Translator Help"); } else if (message == "Main Menu") { showMainMenu(id); } else if (message == "Options") { showOptionsMenu(id); } else if (message == "Language") { showLanguageDialog1(id); } else if (message == "Opt-In") { showLanguageDialog1(id); } else if (message == "Opt-Out") { llMessageLinked(LINK_THIS, 9384610, "xx", id); } else if (message == "FREE Copy") { llMessageLinked(LINK_THIS, 9455209, llKey2Name(id), id); } if (id == llGetOwner()) { if (message == "Group ON") { groupAccess = TRUE; showMainMenu(id); } else if (message == "Group OFF") { groupAccess = FALSE; showMainMenu(id); } else if (message == "Donate") { llMessageLinked(LINK_THIS, 324235353254, "", llGetOwner()); } } if ((id == llGetOwner()) || ((groupAccess) && (llSameGroup(id)))) { if (message == "Reset") { llResetScript(); } else if (message == "Enable") { enabled = TRUE; llMessageLinked(LINK_THIS, 8434532, (string)enabled, id); } else if (message == "Disable") { enabled = FALSE; llMessageLinked(LINK_THIS, 8434532, (string)enabled, id); } else if (message == "Echo ON") { isShowTran = TRUE; //llMessageLinked(LINK_THIS, 2734322, (string)isShowTran, id); } else if (message == "Echo OFF") { isShowTran = FALSE; } else if (message == "Objects OFF") { tranObjects = FALSE; } else if (message == "Objects ON") { tranObjects = TRUE; } else if (message == "Agents OFF") { showAgents = FALSE; llMessageLinked(LINK_THIS, 455832, (string)showAgents, id); } else if (message == "Agents ON") { showAgents = TRUE; llMessageLinked(LINK_THIS, 455832, (string)showAgents, id); } else if (message == "Scan ON") { autoLanguage = TRUE; showMainMenu(id); } else if (message == "Scan OFF") { autoLanguage = FALSE; showMainMenu(id); } else if ((message == "Send Copy") || (message == ">>RESCAN<<")) { agentInDialog = id; llSensor("", NULL_KEY, AGENT, 20.0, TWO_PI); } else { if (llGetListLength(detectedAgentNameList) > 0) { listenKey = llList2Key(detectedAgentKeyList, llListFindList(detectedAgentNameList, [message])); if (listenKey != "") { llMessageLinked(LINK_THIS, 9455209, message, listenKey); } detectedAgentNameList = []; } } } if (message == ">> NEXT") { showLanguageDialog2(id); } else if (message == ">> NEXT ") { showLanguageDialog3(id); } else if (message == ">> NEXT ") { showLanguageDialog4(id); } else if (message == ">> NEXT ") { showLanguageDialog5(id); } else if (message == ">> NEXT ") { showLanguageDialog6(id); } else if (message == "<< BACK") { showLanguageDialog1(id); } else if (message == "<< BACK ") { showLanguageDialog2(id); } else if (message == "<< BACK ") { showLanguageDialog3(id); } else if (message == "<< BACK ") { showLanguageDialog4(id); } else if (message == "<< BACK ") { showLanguageDialog5(id); } if (message == "\t") { showLanguageDialog1(id); } else if (message == "\t ") { showLanguageDialog2(id); } else if (message == "\t ") { showLanguageDialog3(id); } else if (message == "\t ") { showLanguageDialog4(id); } else if (message == "\t ") { showLanguageDialog5(id); } else if (message == "\t ") { showLanguageDialog6(id); }
llMessageLinked(LINK_THIS, 3342976, llList2CSV([isShowTran, tranObjects, autoLanguage]), id);
} checkAttach() {
if (llGetAttached() > 0) { llSetScale(<0.125, 0.125, 0.087>); if(lastAttachPoint != llGetAttached()) { llSetPos(fn_makePos(llGetAttached(), <0.00000, 0.13500, 0.15433>)); llSetRot(<0,0,0,1>); lastAttachPoint = llGetAttached(); } llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS); llMessageLinked(llGetLinkNumber(), 3792114, (string)TRUE, NULL_KEY); } else { llSetScale(<0.5, 0.5, 0.750>); llReleaseControls(); llMessageLinked(llGetLinkNumber(), 3792114, (string)FALSE, NULL_KEY); }
}
default {
run_time_permissions(integer perms) { //integer hasPerms = llGetPermissions(); llTakeControls( CONTROL_UP , TRUE, TRUE); } state_entry() { //llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS ); string speakerLanguage; //llOwnerSay("Welcome to the Universal Translator, the best FREE translator in SL! Please consider making a L$ donation to help with maintenance and further updates. Select DONATE in the translator menu to make a donation."); //llSetText("Initializing...", <1,1,1>, 1); llSetText("Searching for\nnearby translators...", <1,1,1>, 1); checkAttach(); randomDialogChannel = -(integer)llFrand(2147483647);
llMessageLinked(LINK_SET, 20957454, "", NULL_KEY); llResetOtherScript("Universal Translator Engine"); llResetOtherScript("HTTP Handler"); llResetOtherScript("No-Script IM Handler"); llResetOtherScript("Auto-Update"); llResetOtherScript("Donation"); //Other Setup llSleep(5); llListen(randomDialogChannel, "", NULL_KEY, ""); llMessageLinked(LINK_THIS, 3342976, llList2CSV([isShowTran, tranObjects, autoLanguage]), "");
//llOwnerSay("Mem Free=" + (string)llGetFreeMemory()); } on_rez(integer startup_param) { //checkAttach(); llResetScript(); } sensor(integer num_detected) { integer x; string tempString; if (num_detected > 11) num_detected = 11; detectedAgentKeyList = []; detectedAgentNameList = []; for (x = 0; x < num_detected; x += 1) { detectedAgentKeyList += llDetectedKey(x); tempString = llDetectedName(x); if (llStringLength(tempString) > 24) tempString = llGetSubString(tempString, 0, 23); detectedAgentNameList += tempString; } if (llGetListLength(detectedAgentNameList) > 0) { llDialog(agentInDialog, "Select someone nearby to receive FREE a copy of the Universal Translator...", [">>RESCAN<<"] + detectedAgentNameList, randomDialogChannel); } } link_message(integer sender_num, integer num, string str, key id) { integer listPos; list tempList; string tempString; if (num == 2540664) { showMainMenu(id); } else if (num == 3792114) { deviceAttached = (integer)str; if (deviceAttached) autoLanguage = TRUE; } else if (num == 65635544) { translatorCount = ((integer)str)/2; } else if (num == 6877259) { if (isInitialized == FALSE) { isInitialized = TRUE; //Owner Language Detection tempString = llGetAgentLanguage(llGetOwner()); if (llGetSubString(tempString, 0, 1) == "en") tempString = "en";
if (tempString == "") { tempString = "en"; } llMessageLinked(LINK_THIS, 9384610, tempString, llGetOwner()); }
enabled = (integer)str; //marker updateDisplay(); } else if (num == 34829304) { isMaster = (integer)str; updateDisplay(); } else if (num == 455832) { showAgents = (integer)str; updateDisplay(); } else if (num == 94558323) { agentsInTranslation = llCSV2List(str); updateDisplay(); } else if (num == 3342977) { //Options are Show Tran and tranObjects at this time tempList = llCSV2List(str); isShowTran = llList2Integer(tempList, 0); tranObjects = llList2Integer(tempList, 1); autoLanguage = llList2Integer(tempList, 2); } else if (num == 32364364) { //Send Options llMessageLinked(LINK_THIS, 8434532, (string)enabled, NULL_KEY); } } touch_start(integer num_detected) { integer x; key avatarKey; for (x = 0; x < num_detected; x++) { avatarKey = llDetectedKey(x); showMainMenu(avatarKey); } } listen(integer channel, string name, key id, string message) { processListen(name, id, message); } attach(key id) { checkAttach(); if (id) //tests if it is a valid key and not NULL_KEY { llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS ); } } control(key id,integer held, integer change) { return; }
} </lsl>