// Provides an interface for communicating with the inventory repository. // Copyright (C) 2005-2006 Francisco V. Saldana // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // Francisco V. Saldana can be contacted using his email account // username: dressedinblue, at domain: gmail.com // and in Second Life by IMming Christopher Omega integer REPOSITORY_CHANNEL = 19283; // ========== For method invocation ========== string randomSeperator(integer len) { integer firstChar = (integer)llFrand(60) + 20; // Range of printable chars = 0x20 to 0x7E if (len <= 1) return llUnescapeURL("%"+(string)firstChar); integer lastChar; do { // Last char must not equal first char. lastChar = (integer)llFrand(60) + 20; } while (lastChar == firstChar); string ret = llUnescapeURL("%"+(string)firstChar); for (len -= 2; len > 0; --len) ret += llUnescapeURL("%" + (string)((integer)llFrand(60) + 20)); return ret + llUnescapeURL("%"+(string)lastChar); } string listToString(list src) { string chars = (string) src; // Squashes all elements together. string seperator; do { // Find a seperator that's not in the list's string form seperator = randomSeperator(3); // so we dont kill data. } while (llSubStringIndex(chars, seperator) != -1); return seperator + llDumpList2String(src, seperator); } list stringToList(string src) { // First 3 chars is seperator. return llParseStringKeepNulls(llDeleteSubString(src, 0, 2), [llGetSubString(src, 0, 2)], []); } callMethod(integer identifyer, string methodName, list parameters) { llMessageLinked(LINK_THIS, identifyer, // ID only necessary for return value. listToString(parameters), methodName); } returnValue(integer identifyer, string methodName, list value) { callMethod(identifyer, methodName + "_ret", value); } // ============================================= trigger_pong(string moduleName) { integer callId = (integer) llFrand(127239); callMethod(callId, "pong", [moduleName]); } integer connectToRemoteReceiverReturnVal; trigger_connectToRemoteReceiver(key uuid) { integer callId = (integer) llFrand(182374); connectToRemoteReceiverReturnVal = callId; callMethod(callId, "connectToRemoteReceiver", [uuid]); } integer callRemoteMethodReturnVal; trigger_callRemoteMethod(key receiver, integer returnsValue, integer methodCallId, string methodName, list paramList) { integer callId = (integer) llFrand(182435); callRemoteMethodReturnVal = callId; callMethod(callId, "callRemoteMethod", [receiver, returnsValue, methodCallId, methodName, listToString(paramList)]); } trigger_displayStatusMessage(string msg) { callMethod(0, "displayStatusMessage", [msg]); } integer INFO = 0; integer WARNING = 1; integer ERROR = 2; trigger_log(integer type, string message) { callMethod(0, "log", [type, message]); } integer requestContentReturnVal; remote_requestContent(key destination, integer id) { requestContentReturnVal = (integer) llFrand(182341); trigger_callRemoteMethod(repositoryUuid, TRUE, requestContentReturnVal, "requestContent", [destination, id]); } string REPOSITORY_NAME = "SLPL_REPOSITORY"; key repositoryUuid; integer repositoryConnected = FALSE; string this; default { state_entry() { this = llGetScriptName(); llSensorRepeat(REPOSITORY_NAME, NULL_KEY, ACTIVE|PASSIVE, 96, TWO_PI, 5); trigger_log(INFO, "Searching for repository..."); llSetTimerEvent(30); llResetTime(); } sensor(integer det) { repositoryUuid = llDetectedKey(0); trigger_connectToRemoteReceiver(repositoryUuid); llSensorRemove(); } link_message(integer sender, integer callId, string parameters, key methodName) { if (methodName == "connectToRemoteReceiver_ret" && callId == connectToRemoteReceiverReturnVal) { list paramList = stringToList(parameters); // Method signature: // connectToRemoteReceiver_ret(integer connected) integer connected = (integer) llList2String(paramList, 0); if (connected) { trigger_log(INFO, "Connected to repository " + (string) repositoryUuid); } repositoryConnected = connected; state main; } else if (methodName == "moduleReset") { list paramList = stringToList(parameters); string moduleName = llList2String(paramList, 0); if (moduleName == "OutboundRMI") { trigger_connectToRemoteReceiver(repositoryUuid); } } } timer() { integer elapsed = (integer) llGetTime(); if (elapsed > 300) { trigger_log(ERROR, "Repository not located after " + (string) elapsed + " seconds, aborting search."); state unconnected; } else { trigger_log(WARNING, "Repository not located after " + (string) elapsed + " seconds."); } } } state unconnected { link_message(integer sender, integer callId, string parameters, key methodName) { if (methodName == "sendRepositoryContent") { list paramList = stringToList(parameters); // Method signature: // sendRepositoryContent(key destination, integer id) key destination = (key) llList2String(paramList, 0); integer id = (integer) llList2String(paramList, 1); trigger_log(ERROR, "Can't retrieve content #" + (string)id + " from repository. Repository not found."); state default; } } } state main { link_message(integer sender, integer callId, string parameters, key methodName) { if (methodName == "sendRepositoryContent") { list paramList = stringToList(parameters); // Method signature: // sendRepositoryContent(key destination, integer id) key destination = (key) llList2String(paramList, 0); integer id = (integer) llList2String(paramList, 1); remote_requestContent(destination, id); trigger_log(INFO, "Requesting content#" + (string)id + " from repository..."); } else if (methodName == "requestContent_ret" && callId == requestContentReturnVal) { list paramList = stringToList(parameters); // Method sig: // requestContent_ret(integer successful) integer successful = (integer) llList2String(paramList, 0); if (successful) { trigger_log(INFO, "Request for content successful."); } else { trigger_log(ERROR, "Request for content failed."); } } else if (methodName == "moduleReady") { list paramList = stringToList(parameters); string module = llList2String(paramList, 0); if (module == this) returnValue(callId, methodName, [TRUE]); } } }