Universal Translator: Difference between revisions
Hank Ramos (talk | contribs) |
Hank Ramos (talk | contribs) |
||
| Line 888: | Line 888: | ||
==Interface Handler== | ==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> | |||
Revision as of 19:22, 13 November 2009
| 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>