// KeywordSearchManager // This module handles keyword searches made by the user. // A keyword search is started by calling keywordSearch() with // a paremeter equal to the key of the agent making the search. // 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 // ====================== XMLRPC request constants: ====================== \\ // Sent by the client to the server when the server polls // and the client has no data to send. integer NO_REQUESTS = 5000; // Sent by the server to the client when a poll occurs. integer SERVER_POLL = 6000; // Sent by client to server requesting that the server stop polling. integer STOP_POLLING = 6001; // Sent by the client to the server (or external entity) requesting a // piece of content: integer GET_CATEGORY = 7001; // String value: catagory requested integer GET_NOTECARD = 7002; // String value: Notecard name requested. integer GET_PREV = 7003; // String value: "" integer GET_NEXT = 7004; // String value: "" integer GET_KEYWORD_SEARCH = 7005; // String value: Keyword requested. // Sent by the server to the client, between MENU_BEGIN and MENU_END // requesting that it display text. integer SET_CATEGORY = 8001; // String value: Catagory name to display. integer SET_NOTECARD = 8002; // String value: Notecard name to display. integer SET_PREV = 8003; // String value ignored integer SET_NEXT = 8004; // String value ignored. integer SET_KEYWORD_SEARCH = 8005; // String value ignored. integer SET_TEXT = 8006; // String value: any text. // Sent by the server to the client specifying the start // and end of a menu. integer MENU_BEGIN = 9001; // String value: Menu title integer MENU_END = 9002; // ====================== /XMLRPC request constants ====================== \\ // ========== For method invocation ========== string randomStr(string chars, integer len) { integer numChars = llStringLength(chars); string ret; integer i; for (i = 0; i < len; i++) { integer randIndex = llFloor(llFrand(numChars)); ret += llGetSubString(chars, randIndex, randIndex); } return ret; } string SEPERATOR_CHARS = "`~!@#$%^&*()-_+[]{}\|'\";/?.>,<"; integer SEPERATOR_LEN = 3; string dumpList2String(list src) { // Generate a seperator not present in any of the // elements in the list. string chars = (string) src; // Squashes all elements together. string seperator; do { seperator = randomStr(SEPERATOR_CHARS, SEPERATOR_LEN); } while (llSubStringIndex(chars, seperator) != -1); return seperator + llDumpList2String(src, seperator); } list parseStringKeepNulls(string src) { // The seperator should be the first SEPERATOR_LEN // characters in the string. return llParseStringKeepNulls(llDeleteSubString(src, 0, SEPERATOR_LEN - 1), [llGetSubString(src, 0, SEPERATOR_LEN - 1)], []); } callMethod(integer callId, string methodName, list parameters) { llMessageLinked(LINK_THIS, callId, dumpList2String(parameters), methodName); } returnValue(string methodName, integer methodIdentifyer, list value) { llMessageLinked(LINK_THIS, methodIdentifyer, dumpList2String(value), methodName + "_ret"); } // ============================================= trigger_addChatHandle(string moduleName, integer channel) { callMethod(0, "addChatHandle", [moduleName, channel]); } trigger_removeChatHandle(string moduleName, integer channel) { callMethod(0, "removeChatHandle", [moduleName, channel]); } trigger_sendRpcData(integer iData, string sData) { callMethod(0, "sendRpcData", [iData, sData]); } trigger_pong(string moduleName) { callMethod(0, "pong", [moduleName]); } key searcherKey = NULL_KEY; string this; default { state_entry() { this = llGetScriptName(); } link_message(integer sender, integer num, string parameters, key methodName) { if (methodName == "keywordSearch") { list paramList = parseStringKeepNulls(parameters); // Method signature: // keywordSearch(key searcher) key searcher = (key) llList2String(paramList, 0); searcherKey = searcher; state input; } else if (methodName == "ping") { list paramList = parseStringKeepNulls(parameters); // Method signature: // ping(string moduleName) string moduleName = llList2String(paramList, 0); if (moduleName == this) trigger_pong(this); } } } state input { state_entry() { llSay(0, "Please state your search request."); trigger_addChatHandle(llGetScriptName(), 0); } link_message(integer sender_num, integer num, string parameters, key methodName) { if (methodName == "receivedChatData") { list paramList = parseStringKeepNulls(parameters); // Method signature: // receivedChatData(string moduleName, integer channel, string name, key id, string message) string moduleName = llList2String(paramList, 0); integer channel = (integer) llList2String(paramList, 1); string name = llList2String(paramList, 2); key id = (key) llList2String(paramList, 3); string message = llList2String(paramList, 4); if (moduleName == llGetScriptName()) { if (id == searcherKey) { trigger_sendRpcData(GET_KEYWORD_SEARCH, message); llSay(0, "Searching for \"" + message + "\""); state default; } } } else if (methodName == "setUser") { list paramList = parseStringKeepNulls(parameters); // Method signature: // setUser(key userId) // Since we really dont want to be here when the user // changes, switch back to default. state default; } } state_exit() { trigger_removeChatHandle(llGetScriptName(), 0); } }