/* Evennia websocket webclient (javascript component) The client is composed of two parts: src/server/portal/websocket_client.py - the portal-side component this file - the javascript component handling dynamic content messages sent to the client is one of two modes: OOB("func1",args, "func2",args, ...) - OOB command executions, this will call unique javascript functions func1(args), func2(args) etc. text - any other text is considered a normal text output in the main output window. */ // If on, allows client user to send OOB messages to server by // prepending with ##OOB{}, for example ##OOB{"echo":[1,2,3,4]} var OOB_debug = true // // Custom OOB functions // functions defined here can be called by name by the server. For // example input OOB{"echo":(args),{kwargs}} will trigger a function named // echo(args, kwargs). The commands the server understands is set by // settings.OOB_PLUGIN_MODULES function echo(args, kwargs) { // example echo function. doShow("out", "ECHO return: " + args) } function list (args, kwargs) { // show in main window doShow("out", args) } function send (args, kwargs) { // show in main window. SEND returns kwargs {name:value}. for (sendvalue in kwargs) { doShow("out", sendvalue + " = " + kwargs[sendvalue]);} } function report (args, kwargs) { // show in main window. REPORT returns kwargs // {attrfieldname:value} for (name in kwargs) { doShow("out", name + " = " + kwargs[name]) } } function repeat (args, kwargs) { // called by repeating oob funcs doShow("out", args) } function err (args, kwargs) { // display error doShow("err", args) } // // Webclient code // function webclient_init(){ // called when client is just initializing websocket = new WebSocket(wsurl); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onclose = function(evt) { onClose(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.onerror = function(evt) { onError(evt) }; } function onOpen(evt) { // called when client is first connecting $("#connecting").remove(); // remove the "connecting ..." message doShow("sys", "Using websockets - connected to " + wsurl + ".") setTimeout(function () { $("#numplayers").fadeOut('slow', doSetSizes); }, 10000); } function onClose(evt) { // called when client is closing CLIENT_HASH = 0; alert("Mud client connection was closed cleanly."); } function onMessage(evt) { // called when the Evennia is sending data to client var inmsg = evt.data if (inmsg.length > 3 && inmsg.substr(0, 3) == "OOB") { // dynamically call oob methods, if available try { var oobarray = JSON.parse(inmsg.slice(3));} // everything after OOB } catch(err) { // not JSON packed - a normal text doShow('out', inmsg); return; } if (typeof oobarray != "undefined") { for (var ind in oobarray) { try { window[oobarray[ind][0]](oobarray[ind][1], oobarray[ind][2]) } catch(err) { doShow("err", "Could not execute js OOB function '" + oobarray[ind][0] + "(" + oobarray[ind][1] + oobarray[ind][2] + ")'") } } } } else if (inmsg.length >= 6 && inmsg.substr(0, 6) == "PROMPT") { // handle prompt var game_prompt = inmsg.slice(6); doPrompt("prompt", game_prompt); } else { // normal message doShow('out', inmsg); } } function onError(evt) { // called on a server error doShow('err', "Connection error trying to access websocket on " + wsurl + ". " + "Contact the admin and/or check settings.WEBSOCKET_CLIENT_URL."); } function doSend(){ // relays data from client to Evennia. // If OOB_debug is set, allows OOB test data on the // form ##OOB{func:args} outmsg = $("#inputfield").val(); history_add(outmsg); HISTORY_POS = 0; $('#inputform')[0].reset(); // clear input field if (OOB_debug && outmsg.length > 4 && outmsg.substr(0, 5) == "##OOB") { if (outmsg == "##OOBUNITTEST") { // unittest mode doShow("out", "OOB testing mode ..."); doOOB(JSON.parse('{"ECHO":"Echo test"}')); doOOB(JSON.parse('{"LIST":"COMMANDS"}')); doOOB(JSON.parse('{"SEND":"CHARACTER_NAME"}')); doOOB(JSON.parse('{"REPORT":"TEST"}')); doOOB(JSON.parse('{"UNREPORT":"TEST"}')); doOOB(JSON.parse('{"REPEAT": 1}')); doOOB(JSON.parse('{"UNREPEAT": 1}')); doShow("out", "... OOB testing mode done."); return } // test OOB messaging try { doShow("out", "OOB input: " + outmsg.slice(5)); if (outmsg.length == 5) { doShow("err", "OOB testing syntax: ##OOB{\"cmdname:args, ...}"); } else { doOOB(JSON.parse(outmsg.slice(5))); } } catch(err) { doShow("err", err) } } else { // normal output websocket.send(outmsg); } } function doOOB(oobdict){ // Send OOB data from client to Evennia. // Takes input on form {funcname:[args], funcname: [args], ... } var oobmsg = JSON.stringify(oobdict); websocket.send("OOB" + oobmsg); } function doShow(type, msg){ // Add msg to the main output window. // type gives the class of div to use. // The default types are // "out" (normal output) or "err" (red error message) $("#messagewindow").append( "