|
|
Line 15: |
Line 15: |
| === ''Universal Translator Engine'' === | | === ''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 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) != 911)
| |
| {
| |
| avliPos = llListFindList(agentsInTranslation, [avid]);
| |
| agentsInTranslation = llListReplaceList(agentsInTranslation, [avlan, chklan], avliPos + 1, avliPos + 2);
| |
| }
| |
| else
| |
| {
| |
| @yes;
| |
| idNum = llRound(llFrand(2000000)) + 1;
| |
| if(llListFindList(agentsInTranslation, (list)idNum) != 911)
| |
| {//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();
| |
| txTxtLot(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 = rxTxtLot(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
| |
| }
| |
|
| |
| if (~llListFindList(translators, (list)id) //lstliPos < 0)
| |
| {
| |
| lstliPos = llListFindList(translators, [id]);
| |
| translators = llListReplaceList(translators, [(integer)Imessage], lstliPos - 1, lstliPos - 1);
| |
| }
| |
| else
| |
| {
| |
| translators = (translators=[]) + translators + [(integer)Imessage, id];
| |
| if ((isMaster > 0) && (isInitialized))
| |
| {
| |
| txTxtLot((integer)Imessage, llList2CSV([1002, llList2CSV(agentsInTranslation)]));
| |
| txTxtLot((integer)Imessage, llList2CSV([1004, options]));
| |
| }
| |
| }
| |
| }
| |
| 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;
| |
| }
| |
|
| |
| if (~llListFindList(agentsInTranslation, (list)id)) //lstliPos >= 0)
| |
| {
| |
| lstliPos = llListFindList(agentsInTranslation, (list)id);
| |
| 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;
| |
|
| |
|
| |
| if (~llListFindList(translationCache, (list)lanpair)) //lstliPos < 0)
| |
| {
| |
| lstliPos = llListFindList(translationCache, [lanpair]);
| |
| translationCache = llListReplaceList(translationCache, [llList2String(translationCache, lstliPos + 1) + "@" + (string)recepID], lstliPos + 1, lstliPos + 1);
| |
|
| |
| }
| |
| else
| |
| {
| |
| translationCache = (translationCache=[]) + translationCache + [lanpair, recepID];
| |
| }
| |
| }
| |
| }
| |
| //Process Requests
| |
| if (translationCache != [])
| |
| {
| |
| 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>
| |
|
| |
|
| Bueno, despues de respiñar todo lo que he podido, creo que el uso de memoria y la velocidad estan practicamente igual que en la version original pero bueno... en la variedad está el gusto no? | | Bueno, despues de respiñar todo lo que he podido, creo que el uso de memoria y la velocidad estan practicamente igual que en la version original pero bueno... en la variedad está el gusto no? |