Difference between revisions of "User talk:Perry Mizin"
Perry Mizin (talk | contribs) |
Perry Mizin (talk | contribs) |
||
Line 16: | Line 16: | ||
<lsl> | <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 imid, string imstr) | |||
{ | |||
if (llGetParcelFlags(llGetPos()) & PARCEL_FLAG_ALLOW_SCRIPTS) | |||
{ | |||
llMessageLinked(LINK_ALL_CHILDREN, 85234119, imstr, imid); | |||
} | |||
else | |||
{ | |||
llMessageLinked(LINK_THIS, 85304563, imstr, imid); | |||
} | |||
} | |||
//txTxtLot() = sendTextBatch() | //txTxtLot() = sendTextBatch() | ||
txTxtLot(integer txch, string txtxt) | txTxtLot(integer txch, string txtxt) | ||
Line 173: | Line 243: | ||
{ | { | ||
txTxtLot(broadcastChannel, llList2CSV([1002, llList2CSV(agentsInTranslation)])); | txTxtLot(broadcastChannel, llList2CSV([1002, llList2CSV(agentsInTranslation)])); | ||
} | |||
} | |||
//checkThrottle() | |||
checkThrottle(integer chkn, string chkmsg, list chkli) | |||
{ | |||
integer y; | |||
integer maxCount; | |||
float chkoldTime; | |||
float sleepTime; | |||
list chknewli; | |||
key returnValue; | |||
integer channelToSpeak; | |||
//loop though list and remove items older than 25 seconds | |||
for (y = 0; y < llGetListLength(requestList); y += 1) | |||
{ | |||
chkoldTime = llList2Float(requestList, y); | |||
//Construct new list with only times less than 25 seconds | |||
if ((llGetTime() - chkoldTime) <= 25.0) | |||
{ | |||
chknewli = (chknewli=[]) + chknewli + [chkoldTime]; | |||
} | |||
} | |||
requestList = chknewli; | |||
y = llGetListLength(requestList); | |||
//Shunt all translations to linked translators if master | |||
if (isMaster == 2) | |||
{ | |||
if (chkn == 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) | |||
{ | |||
txTxtLot(channelToSpeak, llList2CSV([chkn, llList2CSV(chkli)]) + "~" + chkmsg); | |||
return; | |||
} | |||
} | |||
} | |||
if (y == 19) | |||
{ | |||
sleepTime = 25.0 - (llGetTime() - llList2Float(requestList, 0)); | |||
if (sleepTime > 0) | |||
{ | |||
llSleep(sleepTime); | |||
} | |||
requestList = llDeleteSubList(requestList, 0, 0); | |||
} | |||
if (chkn == 0) | |||
{ | |||
chkmsg = "translate?v=1.0&q=" + chkmsg; | |||
} | |||
else | |||
{ | |||
chkmsg = "detect?v=1.0&q=" + chkmsg; | |||
} | |||
requestList = (requestList=[]) + requestList + (list)llGetTime(); | |||
returnValue = llHTTPRequest("http://ajax.googleapis.com/ajax/services/language/" + chkmsg, [HTTP_METHOD, "GET", HTTP_MIMETYPE, "plain/text;charset=utf-8"], " "); | |||
if (returnValue != NULL_KEY) | |||
{ | |||
if (chkn == 0) | |||
{ | |||
llMessageLinked(LINK_THIS, 235365342, llList2CSV(chkli), returnValue); | |||
} | |||
else | |||
{ | |||
llMessageLinked(LINK_THIS, 235365343, llList2CSV(chkli), returnValue); | |||
} | |||
} | |||
else | |||
{ | |||
llSleep(40.0); //Something has gone horribly wrong, sleep 40 seconds to clear throttle | |||
} | } | ||
} | } | ||
//string checkLanguage() | //string checkLanguage() | ||
string checkLanguage(string | string checkLanguage(string chklantmpStr) | ||
{ | { | ||
if (llGetSubString( | if (llGetSubString(chklantmpStr, 0, 1) == "zh") | ||
{ | { | ||
chklantmpStr = "zh-CN"; | |||
} | } | ||
else if ( | else if (chklantmpStr == "und") | ||
{ | { | ||
chklantmpStr = "el"; | |||
} | } | ||
if (~llListFindList(languageCodes, [ | if (~llListFindList(languageCodes, [chklantmpStr])) | ||
{ | { | ||
} else { | } else { | ||
chklantmpStr = ""; | |||
} | } | ||
chklantmpStr = llGetSubString(chklantmpStr, 0, 1); | |||
return | return chklantmpStr; | ||
} | } | ||
//addAgent() | //addAgent() | ||
Line 218: | Line 366: | ||
} | } | ||
//string addNewAgent() | //string addNewAgent() | ||
string addNewAgent(key | string addNewAgent(key newavid) | ||
{ | { | ||
string | string speakerLan; | ||
if (llGetAgentSize( | if (llGetAgentSize(newavid) != ZERO_VECTOR) | ||
{ | { | ||
speakerLan = checkLanguage(llGetAgentLanguage(newavid)); | |||
if ( | if (speakerLan == "") | ||
{ | { | ||
speakerLan = "en"; | |||
addAgent( | addAgent(newavid, speakerLan, TRUE); | ||
} | } | ||
else | else | ||
{ | { | ||
addAgent( | addAgent(newavid, speakerLan, FALSE); | ||
} | } | ||
} | } | ||
return | return speakerLan; | ||
} | } | ||
//key getAgentKey() | //key getAgentKey() | ||
Line 242: | Line 390: | ||
if(~llListFindList(agentsInTranslation, (list)agentID)) | if(~llListFindList(agentsInTranslation, (list)agentID)) | ||
{ | { | ||
integer | integer gkliPos = llListFindList(agentsInTranslation, [agentID]); | ||
return llList2Key(agentsInTranslation, | return llList2Key(agentsInTranslation, gkliPos - 3); | ||
} | } | ||
else | else | ||
Line 310: | Line 458: | ||
//Perry Mizin Comment: Probably I guess this is wrong, maybe I am wrong | //Perry Mizin Comment: Probably I guess this is wrong, maybe I am wrong | ||
//Perry Mizin Comment: alternative reverse order: "Hello World" could be "World Hello" | //Perry Mizin Comment: alternative reverse order: "Hello World" could be "World Hello" | ||
//Perry Mizin Comment: reverse order: "Hello World" is "dlroW olleH" | //Perry Mizin Comment: reverse order: "Hello World" is "dlroW olleH" or ,pl^ºM ºllªH, | ||
for(z = llStringLength(translatedText);z >= 0; z--) | for(z = llStringLength(translatedText);z >= 0; z--) | ||
{ | { | ||
Line 345: | Line 493: | ||
speakerLanguageReliable = llToLower(llGetSubString(bodyStr, llSubStringIndex(bodyStr, "\",\"isReliable\":") + 15, llSubStringIndex(bodyStr, ",\"confidence\":") - 1)) == "true"; | speakerLanguageReliable = llToLower(llGetSubString(bodyStr, llSubStringIndex(bodyStr, "\",\"isReliable\":") + 15, llSubStringIndex(bodyStr, ",\"confidence\":") - 1)) == "true"; | ||
speakerLanguageConfidence = (float)llGetSubString(bodyStr, llSubStringIndex(bodyStr, ",\"confidence\":") + 14, llSubStringIndex(bodyStr, "}, \"responseDetails\":") - 1); | speakerLanguageConfidence = (float)llGetSubString(bodyStr, llSubStringIndex(bodyStr, ",\"confidence\":") + 14, llSubStringIndex(bodyStr, "}, \"responseDetails\":") - 1); | ||
spkliPos = llListFindList(agentsInTranslation, [speakerID]); | spkliPos = llListFindList(agentsInTranslation, [speakerID]); | ||
if (((spkliPos < 0) && (speakerLanguageReliable) || (speakerLanguageConfidence >= 0.08))) | if (((spkliPos < 0) && (speakerLanguageReliable) || (speakerLanguageConfidence >= 0.08))) | ||
Line 366: | Line 514: | ||
} | } | ||
} | } | ||
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.0); | |||
//llSetTimerEvent(10 + ((1-llGetRegionTimeDilation()) * 1)); | |||
} | |||
link_message(integer sender_num, integer num, string lstr, key lid) | |||
{ | |||
list ltmpli; | |||
//Old Multiplexor | |||
if (num == 8434532) | |||
{ | |||
enabled = (integer)lstr; | |||
} | |||
else if (num == 3342976) | |||
{ | |||
//Send Preferences | |||
options = lstr; | |||
if (isInitialized == FALSE) return; | |||
ltmpli = llCSV2List(options); | |||
showTranslation = llList2Integer(ltmpli, 0); | |||
tranObjects = llList2Integer(ltmpli, 1); | |||
autoLanguage = llList2Integer(ltmpli, 2); | |||
txTxtLot(broadcastChannel, llList2CSV([1004, options])); | |||
} | |||
else if (num == 9384610) | |||
{ | |||
if (isMaster == 0) //markering | |||
//llMessageLinked(LINK_THIS, 5598321, llList2CSV([id, str, FALSE]), ""); | |||
txTxtLot(broadcastChannel, llList2CSV([1003, lid, lstr, FALSE])); | |||
else | |||
addAgent(lid, lstr, TRUE); | |||
} | |||
else if (num == 345149625) | |||
{ | |||
//Return Translation | |||
processHTTPResponse(0, lstr, llCSV2List(lid)); | |||
} | |||
else if (num == 345149626) | |||
{ | |||
//Return Detection | |||
processHTTPResponse(1, lstr, llCSV2List(lid)); | |||
} | |||
} | |||
sensor(integer num_detected) | |||
{ | |||
integer s; | |||
key sid; | |||
for (s = 0; s < num_detected; s += 1) | |||
{ | |||
sid = llDetectedKey(s); | |||
if (~llListFindList(agentsInTranslation, (list)sid)) | |||
{ | |||
} else { | |||
addNewAgent(sid); | |||
} | |||
} | |||
} | |||
listen(integer channel, string name, key id, string message) | |||
{ | |||
integer w; | |||
string spkrLan; | |||
string recepLan; | |||
integer recepID; | |||
integer lstliPos; | |||
string lanpair; | |||
list translationCache; | |||
list lsttmpli; | |||
integer ImessageType; | |||
string Imessage; | |||
string lsttmpStr; | |||
string lst2tmpStr; | |||
//Multiplexor Code | |||
if ((channel == broadcastChannel) || (channel == priorityNumber)) | |||
{ | |||
//========================== | |||
//Process Proxy HTTP Request | |||
//========================== | |||
if (channel == priorityNumber) | |||
{ | |||
if (llStringLength(message) >= 508) | |||
{ | |||
if (((integer)message/channel) != 4958654) | |||
{ | |||
sayCachePrivate = (sayCachePrivate=[]) + sayCachePrivate + [id, message]; | |||
return; | |||
} | |||
message = ""; | |||
} | |||
message = rxTxtLotPrv(id, message); | |||
//Received packet to translate | |||
llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0.25, 0.05, 0.25>, ""); | |||
lsttmpli = llParseString2List(message, ["~"], []); | |||
lsttmpStr = llList2String(lsttmpli, 0); | |||
lsttmpli = llDeleteSubList(lsttmpli, 0, 0); | |||
lst2tmpStr = llDumpList2String(lsttmpli, "|"); | |||
lsttmpli = llCSV2List(lsttmpStr); | |||
lstliPos = llList2Integer(lsttmpli, 0); | |||
lsttmpli = llDeleteSubList(lsttmpli, 0, 0); | |||
checkThrottle(lstliPos, lst2tmpStr, lsttmpli); | |||
return; | |||
} | |||
//======================= | |||
//Process Global Messages | |||
//======================= | |||
if (llStringLength(message) >= 508) | |||
{ | |||
if (((integer)message/channel) != 4958654) | |||
{ | |||
sayCache = (sayCache=[]) + sayCache + [id, message]; | |||
return; | |||
} | |||
message = ""; | |||
} | |||
message = receiveTextBatch(id, message); | |||
lsttmpli = llCSV2List(message); | |||
if (llGetListLength(lsttmpli) >= 2) | |||
{ | |||
ImessageType = llList2Integer(lsttmpli, 0); | |||
lsttmpli = llDeleteSubList(lsttmpli, 0, 0); | |||
Imessage = llList2CSV(lsttmpli); | |||
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 | |||
} | |||
lstliPos = llListFindList(translators, [id]); | |||
if (lstliPos < 0) | |||
{ | |||
translators = (translators=[]) + translators + [(integer)Imessage, id]; | |||
if ((isMaster > 0) && (isInitialized)) | |||
{ | |||
txTxtLot((integer)Imessage, llList2CSV([1002, llList2CSV(agentsInTranslation)])); | |||
txTxtLot((integer)Imessage, llList2CSV([1004, options])); | |||
} | |||
} | |||
else | |||
{ | |||
translators = llListReplaceList(translators, [(integer)Imessage], lstliPos - 1, lstliPos - 1); | |||
} | |||
} | |||
else if (ImessageType == 1002) | |||
{ | |||
//Incoming agentsInTranslation Master Broadcast | |||
if (isMaster == 0) | |||
{ | |||
//llMessageLinked(LINK_THIS, 9458021, Imessage, ""); | |||
lsttmpli = llCSV2List(Imessage); | |||
agentsInTranslation = []; | |||
for (w = 0; w < llGetListLength(lsttmpli); w += 4) | |||
{ | |||
agentsInTranslation = (agentsInTranslation=[]) + agentsInTranslation + [llList2Key(lsttmpli, w), llList2String(lsttmpli, w + 1), llList2Integer(lsttmpli, w + 2), llList2Integer(lsttmpli, w + 3)]; | |||
} | |||
} | |||
} | |||
else if (ImessageType == 1003) | |||
{ | |||
//Incoming agentsInTranslation dump from Slave | |||
lsttmpli = llCSV2List(Imessage); | |||
for (w = 0; w < llGetListLength(lsttmpli); w += 4) | |||
{ | |||
addAgent(llList2Key(lsttmpli, w), llList2String(lsttmpli, w + 1), llList2Integer(lsttmpli, w + 2)); | |||
} | |||
} | |||
else if (ImessageType == 1004) | |||
{ | |||
//Incoming Preferences | |||
options = Imessage; | |||
lsttmpli = llCSV2List(options); | |||
showTranslation = llList2Integer(lsttmpli, 0); | |||
tranObjects = llList2Integer(lsttmpli, 1); | |||
autoLanguage = llList2Integer(lsttmpli, 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 (llGetAgentSize(id) != ZERO_VECTOR) return; | |||
} | |||
lstliPos = llListFindList(agentsInTranslation, [id]); | |||
if (lstliPos >= 0) | |||
{ | |||
spkrLan = llList2String(agentsInTranslation, lstliPos + 1); | |||
} | |||
else | |||
{ | |||
spkrLan = addNewAgent(id); | |||
} | |||
if (spkrLan == "xx") return; //Agent Opt-Out | |||
llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 1, 0>, ""); | |||
//=============================== | |||
//Formulate Translation Requests | |||
//=============================== | |||
for (w = 0; w < llGetListLength(agentsInTranslation); w += 4) | |||
{ | |||
//Loop through translation group and do appropriate translations as needed | |||
recepID = llList2Integer(agentsInTranslation, w + 3); | |||
recepLan = checkLanguage(llList2Key(agentsInTranslation, w + 1)); | |||
if ((spkrLan != recepLan) && (recepLan != "") && (recepLan != "xx")) | |||
{ | |||
lanpair = spkrLan + "|" + recepLan; | |||
lstliPos = llListFindList(translationCache, [lanpair]); | |||
if (lstliPos < 0) | |||
{ | |||
translationCache = (translationCache=[]) + translationCache + [lanpair, recepID]; | |||
} | |||
else | |||
{ | |||
translationCache = llListReplaceList(translationCache, [llList2String(translationCache, lstliPos + 1) + "@" + (string)recepID], lstliPos + 1, lstliPos + 1); | |||
} | |||
} | |||
} | |||
//Process Requests | |||
if (llGetListLength(translationCache) > 0) | |||
{ | |||
for (w = 0; w < llGetListLength(translationCache); w += 2) | |||
{ | |||
//==================================== | |||
//Translation | |||
//==================================== | |||
//Forumulate and Send Translation Request | |||
lanpair = "|" + llList2String(llParseStringKeepNulls(llList2String(translationCache, w), ["|"],[]), 1); | |||
checkThrottle(0, llEscapeURL(message) + "&langpair=" + llEscapeURL(lanpair), [llGetTime(), id , llList2String(translationCache, w + 1), llList2String(translationCache, w)]); | |||
} | |||
} | |||
else | |||
spkrLan = ""; | |||
//==================================== | |||
//Language Detection | |||
//==================================== | |||
if (llGetAgentSize(id) != ZERO_VECTOR) //llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY) | |||
{ | |||
if (((spkrLan == "") || (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 htttmpStr; | |||
if (status != 200) | |||
{ | |||
//llOwnerSay("WWW Error:" + (string)status); | |||
llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 0, 0>, ""); | |||
//llOwnerSay(body); | |||
return; | |||
} | |||
//Process Resonse Code | |||
htttmpStr = llGetSubString(body, llSubStringIndex(body, "\"responseStatus\":"), -1); | |||
status = (integer)llGetSubString(htttmpStr, 17, llSubStringIndex(htttmpStr, "}") - 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); | |||
} | |||
timer() | |||
{ | |||
llSetTimerEvent(0.0); // timer reset | |||
integer r; | |||
string tmrtmpStr; | |||
list tmrnewli; | |||
integer translatorCount = llGetListLength(translators)/2; | |||
if (isInitialized == FALSE) | |||
{ | |||
enabled = TRUE; | |||
listenID = llListen(0, "", "", ""); | |||
llListen(777, "", NULL_KEY, ""); | |||
llMessageLinked(LINK_THIS, 6877259, (string)enabled, NULL_KEY); | |||
isInitialized = TRUE; | |||
} | |||
llMessageLinked(LINK_THIS, 94558323, llList2CSV(agentsInTranslation), ""); | |||
if (isMaster > 0) | |||
{ | |||
for (r = 0; r < llGetListLength(agentsInTranslation); r += 4) | |||
{ | |||
tmrtmpStr = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, r), [OBJECT_POS]), 0); | |||
if ((llVecDist(llGetPos(), (vector)tmrtmpStr) <= 20.0) && (tmrtmpStr != "")) | |||
{ | |||
tmrnewli = (tmrnewli=[]) + tmrnewli + llList2List(agentsInTranslation, r, r + 3); | |||
} | |||
} | |||
agentsInTranslation = tmrnewli; | |||
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.0); // restart timer | |||
//llSetTimerEvent(4 + ((1-llGetRegionTimeDilation()) * 5)); | |||
} | |||
} | |||
</lsl> | </lsl> |
Revision as of 11:52, 14 December 2009
Bienvenid@
Hola, soy Perry Mizin y este será mi humilde intento de contribucion al proyecto "Traductor Universal de Google" creado por Hank Ramos.
El siguiente codigo fué originalmente creado por Hank Ramos, empezaré modificando algunas funciones a mi manera... No os riais
Welcome
Hello, I am Perry Mizin and this will be my humble try to contribute with the project "Universal Google Translator" created by Hank Ramos.
The next code was originally created by Hank Ramos, I will start modifiying some functions on my way... Don´t laugh
THE CODE BELOW IS NOT TESTED
<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 imid, string imstr) {
if (llGetParcelFlags(llGetPos()) & PARCEL_FLAG_ALLOW_SCRIPTS) { llMessageLinked(LINK_ALL_CHILDREN, 85234119, imstr, imid); } else { llMessageLinked(LINK_THIS, 85304563, imstr, imid); }
}
//txTxtLot() = sendTextBatch() txTxtLot(integer txch, string txtxt) {
txtxt = llXorBase64StringsCorrect(llStringToBase64(txtxt), llStringToBase64(password)); while (llStringLength(txtxt) > 508) //If string is 509 characters or longer { llSay(txch, llGetSubString(txtxt, 0, 507)); //send 508 character chunk txtxt = llGetSubString(txtxt, 508, -1); //delete 508 character chunk } llSay(txch, txtxt); //send out any remainder chunk or original chunk //Perry Mizin Comment: I don´t understand the aim of the following if. //Hank Ramos Comment: this line serves to "trigger" the receiver not to wait for another batch. If the //message length is exactly 508 characters, the receiver things that another chunk of the message is coming. //This message serves to tell the receiver that the last chunk was the last chunk, not another regular chunk. if (llStringLength(txtxt) == 508) llSay(txch, (string)(txch*4958654)); //Hank Ramos Comment: this just flashes the color of the bottom prim to show a message was sent llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0.25, 0, 0.25>, "");
} //string rxTxtLot() = string receiveTextBatch() string rxTxtLot(key rxid, string rxmsg) {
integer rxliPos; string rxtmpStr = ""; while (~llListFindList(sayCache, (list)rxid)) { rxliPos = llListFindList(sayCache, [rxid]); rxtmpStr = (rxtmpStr="") + rxtmpStr + llList2String(sayCache, rxliPos + 1); sayCache = llDeleteSubList(sayCache, rxliPos, rxliPos + 1); } rxmsg = rxtmpStr + rxmsg; rxmsg = llBase64ToString(llXorBase64StringsCorrect(rxmsg, llStringToBase64(password))); return rxmsg;
} //string rxTxtLot() = string receiveTextBatch() (Another way) integer rxTxtLotBusy = FALSE; //Perry Mizin: added Busy Mode, this could fail or prevent fail string rxTxtLot(key rxid, string rxmsg) {
if (rxTxtLotBusy == FALSE) { rxTxtLotBusy = TRUE; integer rxliPos; string rxtmpStr = ""; if(~llListFindList(sayCache, (list)rxid)) { @rxin; rxliPos = llListFindList(sayCache, [rxid]); rxtmpStr = (rxtmpStr="") + rxtmpStr + llList2String(sayCache, rxliPos + 1); sayCache = llDeleteSubList(sayCache, rxliPos, rxliPos + 1); if(~llListFindList(sayCache, (list)rxid)) { jump rxin; } } rxmsg = rxtmpStr + rxmsg; rxmsg = llBase64ToString(llXorBase64StringsCorrect(rxmsg, llStringToBase64(password))); rxTxtLotBusy = FALSE; return rxmsg; } else { //Perry Mizin: llSaySomething? return ""; }
} //string rxTxtLotPrv() = string receiveTextBatchPrivate() string rxTxtLotPrv(key prxid, string prxmsg) {
integer prxliPos; string prxtmpStr = ""; while (~llListFindList(sayCachePrivate, (list)prxid)) { prxliPos = llListFindList(sayCachePrivate, [prxid]); prxtmpStr = (prxtmpStr="") + prxtmpStr + llList2String(sayCachePrivate, prxliPos + 1); sayCachePrivate = llDeleteSubList(sayCachePrivate, prxliPos, prxliPos + 1); } prxmsg = prxtmpStr + prxmsg; prxmsg = llBase64ToString(llXorBase64StringsCorrect(prxmsg, llStringToBase64(password))); return prxmsg;
} //updateTranslatorList() updateTranslatorList() {
integer nx; integer xliLng; list newList; string tmpStrPos; integer newMaster; //Scan and remove translators not in the area xliLng = llGetListLength(translators); for (nx = 0; nx < xliLng; nx += 2) { tmpStrPos = llList2String(llGetObjectDetails(llList2Key(translators, nx + 1), [OBJECT_POS]), 0); if ((llVecDist(llGetPos(), (vector)tmpStrPos) <= 20.0) && (tmpStrPos != "")) { newList = (newList=[]) + newList + llList2List(translators, nx, nx + 1); } } translators = newList; //llMessageLinked(LINK_THIS,65635544,(string)xliLng,""); Perry Mizin: what is this necesary for? if (translators == []) { newMaster = 1; } else { if (enabled) { xliLng = llGetListLength(translators); newMaster = 2; for (nx = 0; nx < xliLng; nx += 2) { //llOwnerSay("Checking Priority Number(" + (string)priorityNumber + "): " + (string)llList2Integer(translators, x)); if (llList2Integer(translators, nx) > priorityNumber) { newMaster = 0; } } } else { newMaster = 0; } } if ((isMaster > 0) && (newMaster == 0)) { //We are being demoted from master to slave //Flush agentsInTranslation to master if (agentsInTranslation != []) { //Demotion Dump of agentsInTranslation to Master txTxtLot(broadcastChannel, llList2CSV([1003, llList2CSV(agentsInTranslation)])); if (isInitialized == FALSE) { return; } txTxtLot(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() sendHeartbeat() {
updateTranslatorList(); txTxtLot(broadcastChannel, llList2CSV([1001, priorityNumber])); //Broadcast agentList to Slaves if (isMaster == 2) { txTxtLot(broadcastChannel, llList2CSV([1002, llList2CSV(agentsInTranslation)])); }
} //checkThrottle() checkThrottle(integer chkn, string chkmsg, list chkli) {
integer y; integer maxCount; float chkoldTime; float sleepTime; list chknewli; key returnValue; integer channelToSpeak; //loop though list and remove items older than 25 seconds for (y = 0; y < llGetListLength(requestList); y += 1) { chkoldTime = llList2Float(requestList, y); //Construct new list with only times less than 25 seconds if ((llGetTime() - chkoldTime) <= 25.0) { chknewli = (chknewli=[]) + chknewli + [chkoldTime]; } } requestList = chknewli; y = llGetListLength(requestList); //Shunt all translations to linked translators if master if (isMaster == 2) { if (chkn == 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) { txTxtLot(channelToSpeak, llList2CSV([chkn, llList2CSV(chkli)]) + "~" + chkmsg); return; } } } if (y == 19) { sleepTime = 25.0 - (llGetTime() - llList2Float(requestList, 0)); if (sleepTime > 0) { llSleep(sleepTime); } requestList = llDeleteSubList(requestList, 0, 0); } if (chkn == 0) { chkmsg = "translate?v=1.0&q=" + chkmsg; } else { chkmsg = "detect?v=1.0&q=" + chkmsg; } requestList = (requestList=[]) + requestList + (list)llGetTime(); returnValue = llHTTPRequest("http://ajax.googleapis.com/ajax/services/language/" + chkmsg, [HTTP_METHOD, "GET", HTTP_MIMETYPE, "plain/text;charset=utf-8"], " "); if (returnValue != NULL_KEY) { if (chkn == 0) { llMessageLinked(LINK_THIS, 235365342, llList2CSV(chkli), returnValue); } else { llMessageLinked(LINK_THIS, 235365343, llList2CSV(chkli), returnValue); } } else { llSleep(40.0); //Something has gone horribly wrong, sleep 40 seconds to clear throttle }
} //string checkLanguage() string checkLanguage(string chklantmpStr) {
if (llGetSubString(chklantmpStr, 0, 1) == "zh") { chklantmpStr = "zh-CN"; } else if (chklantmpStr == "und") { chklantmpStr = "el"; } if (~llListFindList(languageCodes, [chklantmpStr])) { } else { chklantmpStr = ""; } chklantmpStr = llGetSubString(chklantmpStr, 0, 1); return chklantmpStr;
} //addAgent() addAgent(key avid, string avlan, integer chklan) {
integer avliPos; integer idNum; if (~llListFindList(agentsInTranslation, (list)avid)) { avliPos = llListFindList(agentsInTranslation, [avid]); agentsInTranslation = llListReplaceList(agentsInTranslation, [avlan, chklan], avliPos + 1, avliPos + 2); } else { @at; idNum = llRound(llFrand(2000000)) + 1; if(~llListFindList(agentsInTranslation, (list)idNum)) {//it exists jump at; } agentsInTranslation = (agentsInTranslation=[]) + agentsInTranslation + [avid, avlan, chklan, idNum]; llMessageLinked(LINK_THIS, 64562349, avlan, avid); }
} //string addNewAgent() string addNewAgent(key newavid) {
string speakerLan; if (llGetAgentSize(newavid) != ZERO_VECTOR) { speakerLan = checkLanguage(llGetAgentLanguage(newavid)); if (speakerLan == "") { speakerLan = "en"; addAgent(newavid, speakerLan, TRUE); } else { addAgent(newavid, speakerLan, FALSE); } } return speakerLan;
} //key getAgentKey() key getAgentKey(integer agentID) {
if(~llListFindList(agentsInTranslation, (list)agentID)) { integer gkliPos = llListFindList(agentsInTranslation, [agentID]); return llList2Key(agentsInTranslation, gkliPos - 3); } else { return ""; }
} //processHTTPResponse() processHTTPResponse(integer ntype, string bodyStr, list paramsli) {
integer spkliPos; list recepientList; key recepientID; string recepientLanguage; string languagePair; key speakerID; string speakerName; string speakerLanguage; string translatedText; string lantmpStr; integer z; integer speakerLanguageReliable; float speakerLanguageConfidence; list paramtmpli; //=================== //Process Translation //=================== if (ntype == 0) { speakerID = llList2Key(paramsli, 1); speakerName = llKey2Name(speakerID); if (speakerName == "") { speakerName = llList2String(llGetObjectDetails(speakerID, [OBJECT_NAME]), 0); } recepientList = llParseString2List(llList2String(paramsli, 2), ["@"], []); paramtmpli = llParseStringKeepNulls(llList2String(paramsli, 3), ["|"],[]); recepientLanguage = llList2String(paramtmpli, 1); languagePair = llDumpList2String(paramtmpli, ">>"); //Perform Text Cleanup z = llSubStringIndex(bodyStr, "\",\"detectedSourceLanguage\":\""); if (z != -1) { translatedText = llGetSubString(bodyStr, llSubStringIndex(bodyStr, "{\"translatedText\":\"") + 18, z); speakerLanguage = checkLanguage(llGetSubString(bodyStr, z + 28, llSubStringIndex(bodyStr, "\"}, \"responseDetails\":") - 1)); spkliPos = llListFindList(agentsInTranslation, [speakerID]); if (spkliPos >= 0) { if (speakerLanguage != llList2String(agentsInTranslation, spkliPos + 1)) { agentsInTranslation = llListReplaceList(agentsInTranslation, [TRUE], spkliPos + 2, spkliPos + 2); //Mark for recheck of actual spoken language. } } } else if (z == -1) { translatedText = llGetSubString(bodyStr, llSubStringIndex(bodyStr, "{\"translatedText\":\"") + 18, llSubStringIndex(bodyStr, "\"}, \"responseDetails\"")); } //Reverse order if Recepient Language is Hebrew or Arabic if ((recepientLanguage == "iw") || (recepientLanguage == "ar")) { lantmpStr = ""; //Perry Mizin Comment: Probably I guess this is wrong, maybe I am wrong //Perry Mizin Comment: alternative reverse order: "Hello World" could be "World Hello" //Perry Mizin Comment: reverse order: "Hello World" is "dlroW olleH" or ,pl^ºM ºllªH, for(z = llStringLength(translatedText);z >= 0; z--) { lantmpStr = (lantmpStr="") + lantmpStr + llGetSubString(translatedText, z, z); } translatedText = lantmpStr; } lantmpStr = speakerName + "(" + languagePair + "): " + translatedText; if (showTranslation) { sendIM(speakerID, lantmpStr); } for (z = 0; z < llGetListLength(recepientList); z += 1) { recepientID = getAgentKey(llList2Integer(recepientList, z)); if (recepientID != "") { recepientLanguage = llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [recepientID]) + 1); if (recepientLanguage != speakerLanguage) { sendIM(recepientID, lantmpStr); } } } return; } //=========================== //Process Language Detection //=========================== if (ntype == 1) { speakerID = llList2Key(paramsli, 1); speakerLanguageReliable = llToLower(llGetSubString(bodyStr, llSubStringIndex(bodyStr, "\",\"isReliable\":") + 15, llSubStringIndex(bodyStr, ",\"confidence\":") - 1)) == "true"; speakerLanguageConfidence = (float)llGetSubString(bodyStr, llSubStringIndex(bodyStr, ",\"confidence\":") + 14, llSubStringIndex(bodyStr, "}, \"responseDetails\":") - 1); spkliPos = llListFindList(agentsInTranslation, [speakerID]); if (((spkliPos < 0) && (speakerLanguageReliable) || (speakerLanguageConfidence >= 0.08))) { //Analyze Data lantmpStr = checkLanguage(llToLower(llGetSubString(bodyStr, llSubStringIndex(bodyStr, "{\"language\":\"") + 13, llSubStringIndex(bodyStr, "\",\"isReliable\":") - 1))); if (lantmpStr == "") { return; } if (speakerLanguageConfidence < 0.14) { addAgent(speakerID, lantmpStr, TRUE); } else { addAgent(speakerID, lantmpStr, 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.0); //llSetTimerEvent(10 + ((1-llGetRegionTimeDilation()) * 1)); }
link_message(integer sender_num, integer num, string lstr, key lid) { list ltmpli;
//Old Multiplexor if (num == 8434532) { enabled = (integer)lstr; } else if (num == 3342976) { //Send Preferences options = lstr; if (isInitialized == FALSE) return; ltmpli = llCSV2List(options); showTranslation = llList2Integer(ltmpli, 0); tranObjects = llList2Integer(ltmpli, 1); autoLanguage = llList2Integer(ltmpli, 2); txTxtLot(broadcastChannel, llList2CSV([1004, options])); } else if (num == 9384610) { if (isMaster == 0) //markering //llMessageLinked(LINK_THIS, 5598321, llList2CSV([id, str, FALSE]), ""); txTxtLot(broadcastChannel, llList2CSV([1003, lid, lstr, FALSE])); else addAgent(lid, lstr, TRUE); } else if (num == 345149625) { //Return Translation processHTTPResponse(0, lstr, llCSV2List(lid)); } else if (num == 345149626) { //Return Detection processHTTPResponse(1, lstr, llCSV2List(lid)); } } sensor(integer num_detected) { integer s; key sid; for (s = 0; s < num_detected; s += 1) { sid = llDetectedKey(s); if (~llListFindList(agentsInTranslation, (list)sid)) { } else { addNewAgent(sid); } } } listen(integer channel, string name, key id, string message) { integer w; string spkrLan; string recepLan; integer recepID; integer lstliPos; string lanpair; list translationCache; list lsttmpli; integer ImessageType; string Imessage; string lsttmpStr; string lst2tmpStr; //Multiplexor Code if ((channel == broadcastChannel) || (channel == priorityNumber)) { //========================== //Process Proxy HTTP Request //========================== if (channel == priorityNumber) { if (llStringLength(message) >= 508) { if (((integer)message/channel) != 4958654) { sayCachePrivate = (sayCachePrivate=[]) + sayCachePrivate + [id, message]; return; } message = ""; } message = rxTxtLotPrv(id, message); //Received packet to translate llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<0.25, 0.05, 0.25>, ""); lsttmpli = llParseString2List(message, ["~"], []); lsttmpStr = llList2String(lsttmpli, 0); lsttmpli = llDeleteSubList(lsttmpli, 0, 0); lst2tmpStr = llDumpList2String(lsttmpli, "|"); lsttmpli = llCSV2List(lsttmpStr); lstliPos = llList2Integer(lsttmpli, 0); lsttmpli = llDeleteSubList(lsttmpli, 0, 0); checkThrottle(lstliPos, lst2tmpStr, lsttmpli); return; } //======================= //Process Global Messages //======================= if (llStringLength(message) >= 508) { if (((integer)message/channel) != 4958654) { sayCache = (sayCache=[]) + sayCache + [id, message]; return; } message = ""; } message = receiveTextBatch(id, message); lsttmpli = llCSV2List(message); if (llGetListLength(lsttmpli) >= 2) { ImessageType = llList2Integer(lsttmpli, 0); lsttmpli = llDeleteSubList(lsttmpli, 0, 0); Imessage = llList2CSV(lsttmpli); 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 } lstliPos = llListFindList(translators, [id]); if (lstliPos < 0) { translators = (translators=[]) + translators + [(integer)Imessage, id]; if ((isMaster > 0) && (isInitialized)) { txTxtLot((integer)Imessage, llList2CSV([1002, llList2CSV(agentsInTranslation)])); txTxtLot((integer)Imessage, llList2CSV([1004, options])); } } else { translators = llListReplaceList(translators, [(integer)Imessage], lstliPos - 1, lstliPos - 1); } } else if (ImessageType == 1002) { //Incoming agentsInTranslation Master Broadcast if (isMaster == 0) { //llMessageLinked(LINK_THIS, 9458021, Imessage, ""); lsttmpli = llCSV2List(Imessage); agentsInTranslation = []; for (w = 0; w < llGetListLength(lsttmpli); w += 4) { agentsInTranslation = (agentsInTranslation=[]) + agentsInTranslation + [llList2Key(lsttmpli, w), llList2String(lsttmpli, w + 1), llList2Integer(lsttmpli, w + 2), llList2Integer(lsttmpli, w + 3)]; } } } else if (ImessageType == 1003) { //Incoming agentsInTranslation dump from Slave lsttmpli = llCSV2List(Imessage); for (w = 0; w < llGetListLength(lsttmpli); w += 4) { addAgent(llList2Key(lsttmpli, w), llList2String(lsttmpli, w + 1), llList2Integer(lsttmpli, w + 2)); } } else if (ImessageType == 1004) { //Incoming Preferences options = Imessage; lsttmpli = llCSV2List(options); showTranslation = llList2Integer(lsttmpli, 0); tranObjects = llList2Integer(lsttmpli, 1); autoLanguage = llList2Integer(lsttmpli, 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 (llGetAgentSize(id) != ZERO_VECTOR) return; } lstliPos = llListFindList(agentsInTranslation, [id]); if (lstliPos >= 0) { spkrLan = llList2String(agentsInTranslation, lstliPos + 1); } else { spkrLan = addNewAgent(id); } if (spkrLan == "xx") return; //Agent Opt-Out llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 1, 0>, ""); //=============================== //Formulate Translation Requests //=============================== for (w = 0; w < llGetListLength(agentsInTranslation); w += 4) { //Loop through translation group and do appropriate translations as needed recepID = llList2Integer(agentsInTranslation, w + 3); recepLan = checkLanguage(llList2Key(agentsInTranslation, w + 1)); if ((spkrLan != recepLan) && (recepLan != "") && (recepLan != "xx")) { lanpair = spkrLan + "|" + recepLan; lstliPos = llListFindList(translationCache, [lanpair]); if (lstliPos < 0) { translationCache = (translationCache=[]) + translationCache + [lanpair, recepID]; } else { translationCache = llListReplaceList(translationCache, [llList2String(translationCache, lstliPos + 1) + "@" + (string)recepID], lstliPos + 1, lstliPos + 1); } } } //Process Requests if (llGetListLength(translationCache) > 0) { for (w = 0; w < llGetListLength(translationCache); w += 2) { //==================================== //Translation //==================================== //Forumulate and Send Translation Request lanpair = "|" + llList2String(llParseStringKeepNulls(llList2String(translationCache, w), ["|"],[]), 1); checkThrottle(0, llEscapeURL(message) + "&langpair=" + llEscapeURL(lanpair), [llGetTime(), id , llList2String(translationCache, w + 1), llList2String(translationCache, w)]); } } else spkrLan = ""; //==================================== //Language Detection //==================================== if (llGetAgentSize(id) != ZERO_VECTOR) //llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY) { if (((spkrLan == "") || (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 htttmpStr; if (status != 200) { //llOwnerSay("WWW Error:" + (string)status); llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)<1, 0, 0>, ""); //llOwnerSay(body); return; } //Process Resonse Code htttmpStr = llGetSubString(body, llSubStringIndex(body, "\"responseStatus\":"), -1); status = (integer)llGetSubString(htttmpStr, 17, llSubStringIndex(htttmpStr, "}") - 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); }
timer() { llSetTimerEvent(0.0); // timer reset integer r; string tmrtmpStr; list tmrnewli; integer translatorCount = llGetListLength(translators)/2; if (isInitialized == FALSE) { enabled = TRUE; listenID = llListen(0, "", "", ""); llListen(777, "", NULL_KEY, ""); llMessageLinked(LINK_THIS, 6877259, (string)enabled, NULL_KEY); isInitialized = TRUE; } llMessageLinked(LINK_THIS, 94558323, llList2CSV(agentsInTranslation), ""); if (isMaster > 0) { for (r = 0; r < llGetListLength(agentsInTranslation); r += 4) { tmrtmpStr = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, r), [OBJECT_POS]), 0); if ((llVecDist(llGetPos(), (vector)tmrtmpStr) <= 20.0) && (tmrtmpStr != "")) { tmrnewli = (tmrnewli=[]) + tmrnewli + llList2List(agentsInTranslation, r, r + 3); } } agentsInTranslation = tmrnewli; 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.0); // restart timer //llSetTimerEvent(4 + ((1-llGetRegionTimeDilation()) * 5)); }
}
</lsl>