Made a rudimentary gui for the webclient. Some data is going through to webclient, but currently html conversion is not working.

This commit is contained in:
Griatch 2016-02-11 21:55:44 +01:00
parent 33b73c7430
commit 66641b54ab
4 changed files with 230 additions and 90 deletions

View file

@ -52,6 +52,7 @@ An "emitter" object must have a function
var Evennia = {
debug: true,
initialized: false,
// Initialize.
// startup Evennia emitter and connection.
@ -68,13 +69,19 @@ An "emitter" object must have a function
// Evennia.emit to return data to Client.
//
init: function(opts) {
if (this.initialized) {
// make it safe to call multiple times.
return;
}
this.initialized = true;
opts = opts || {};
this.emitter = opts.emitter || new DefaultEmitter();
if (opts.connection) {
this.connection = opts.connection;
}
else if (window.WebSocket) {
else if (window.WebSocket && wsactive) {
this.connection = new WebsocketConnection();
if (!this.connection) {
this.connection = new AjaxCometConnection();
@ -82,7 +89,7 @@ An "emitter" object must have a function
} else {
this.connection = new AjaxCometConnection();
}
// this.connection = opts.connection || window.WebSocket ? new WebsocketConnection() : new AjaxCometConnection();
log('Evennia initialized.')
},
// Client -> Evennia.
@ -115,16 +122,17 @@ An "emitter" object must have a function
//
// Args:
// event (event): Event received from Evennia
// data (obj):
// args (array): Arguments to listener
// kwargs (obj): keyword-args to listener
//
emit: function (cmdname, data) {
log('emit called with args: + ' + cmdname + ',' + data);
if (data.cmdid) {
cmdmap[data.cmdid].apply(this, [data]);
delete cmdmap[cmddata.cmdid];
emit: function (cmdname, args, kwargs) {
log('emit called with args: ' + cmdname + ',' + args + ',' + kwargs);
if (kwargs.cmdid) {
cmdmap[kwargs.cmdid].apply(this, [args, kwargs]);
delete cmdmap[kwargs.cmdid];
}
else {
this.emitter.emit(cmdname, data);
this.emitter.emit(cmdname, args, kwargs);
}
},
@ -135,7 +143,7 @@ An "emitter" object must have a function
// the Server. An alternative can be overridden in Evennia.init.
//
var DefaultEmitter = function () {
var cmdmap = {};
var listeners = {};
// Emit data to all listeners tied to a given cmdname
//
// Args:
@ -144,11 +152,11 @@ An "emitter" object must have a function
// called as function(kwargs).
// kwargs (obj): Argument to the listener.
//
var emit = function (cmdname, kwargs) {
log('emit', cmdname, kwargs);
var emit = function (cmdname, args, kwargs) {
log('emit', cmdname, args, kwargs);
if (cmdmap[cmdname]) {
cmdmap[cmdname].apply(this, kwargs);
if (listeners[cmdname]) {
listeners[cmdname].apply(this, [args, kwargs]);
};
};
@ -161,7 +169,7 @@ An "emitter" object must have a function
//
var on = function (cmdname, listener) {
if (typeof(listener === 'function')) {
cmdmap[cmdname] = listener;
listeners[cmdname] = listener;
};
};
@ -171,7 +179,7 @@ An "emitter" object must have a function
// cmdname (str): Name of event to handle
//
var off = function (cmdname) {
delete cmdmap[cmdname]
delete listeners[cmdname]
};
return {emit:emit, on:on, off:off}
};
@ -184,17 +192,21 @@ An "emitter" object must have a function
// Handle Websocket open event
websocket.onopen = function (event) {
log('Websocket connection openened. ', event);
Evennia.emit('socket:open', event);
Evennia.emit('socket:open', [], event);
};
// Handle Websocket close event
websocket.onclose = function (event) {
log('WebSocket connection closed.');
Evennia.emit('socket:close', event);
Evennia.emit('socket:close', [], event);
};
// Handle websocket errors
websocket.onerror = function (event) {
log("Websocket error to ", wsurl, event);
Evennia.emit('socket:error', event.data);
Evennia.emit('socket:error', [], event);
if (websocket.readyState === websocket.CLOSED) {
log("Websocket failed. Falling back to Ajax...");
Evennia.connection = AjaxCometConnection();
}
};
// Handle incoming websocket data [cmdname, kwargs]
websocket.onmessage = function (event) {
@ -203,13 +215,14 @@ An "emitter" object must have a function
return;
}
// Parse the incoming data, send to emitter
// Incoming data is on the form [cmdname, kwargs]
// Incoming data is on the form [cmdname, args, kwargs]
data = JSON.parse(data);
log("incoming " + data);
Evennia.emit(data[0], data[1]);
Evennia.emit(data[0], data[1], data[2]);
};
websocket.msg = function(data) {
websocket.send(JSON.stringify(data));
websocket.msg = function(cmdname, args, kwargs) {
// send
websocket.send(JSON.stringify([cmdname, args, kwargs]));
};
return websocket;
@ -221,11 +234,11 @@ An "emitter" object must have a function
log("Trying ajax ...");
var client_hash = '0';
// Send Client -> Evennia. Called by Evennia.send.
var msg = function(data) {
var msg = function(cmdname, args, kwargs) {
$.ajax({type: "POST", url: "/webclientdata",
async: true, cache: false, timeout: 30000,
dataType: "json",
data: {mode:'input', msg: data, 'suid': client_hash},
data: {mode:'input', msg: [cmdname, args, kwargs], 'suid': client_hash},
success: function(data) {},
error: function(req, stat, err) {
log("COMET: Server returned error. " + err);
@ -243,7 +256,7 @@ An "emitter" object must have a function
dataType: "json",
data: {mode: 'receive', 'suid': client_hash},
success: function(data) {
Evennia.emit(data[0], data[1])
Evennia.emit(data[0], data[1], data[2])
},
error: function() {
poll() // timeout; immediately re-poll
@ -284,16 +297,10 @@ function log(msg) {
}
// Called when page has finished loading (kicks the client into gear)
$(document).ready(function(){
// a small timeout to stop 'loading' indicator in Chrome
setTimeout(function () {
log('Evennia initialized...')
Evennia.init()
}, 500);
// set an idle timer to avoid proxy servers to time out on us (every 3 minutes)
setInterval(function() {
log('Idle tick.');
}, 60000*3);
$(document).ready(function() {
setTimeout( function () {
Evennia.init()
},
500
);
});

View file

@ -13,16 +13,152 @@
*/
//
// GUI Helpers
// GUI Elements
//
//
// Manage history for input line
//
var inputlog = function() {
var history_max = 21;
var history = new Array();
var history_pos = 0;
history[0] = ''; // the very latest input is empty for new entry.
function history_back() {
// step backwards in history stack
history_pos = Math.min(++history_pos, history.length - 1);
return history[history.length - 1 - history_pos];
}
function history_fwd() {
// step forwards in history stack
history_pos = Math.max(--history_pos, 0);
return history[history.length -1 - history_pos];
}
function history_add(input) {
// add a new entry to history, don't repeat latest
if (input != history[history.length-1]) {
if (history.length >= history_max) {
history.shift(); // kill oldest entry
}
history[history.length-1] = input;
history[history.length] = '';
}
}
return {back: history_back,
fwd: history_fwd,
add: history_add}
};
$.fn.appendCaret = function() {
/* jQuery extension that will forward the caret to the end of the input, and
won't harm other elements (although calling this on multiple inputs might
not have the expected consequences).
Thanks to
http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
for the good starting point. */
return this.each(function() {
var range,
// Index at where to place the caret.
end,
self = this;
if (self.setSelectionRange) {
// other browsers
end = self.value.length;
self.focus();
// NOTE: Need to delay the caret movement until after the callstack.
setTimeout(function() {
self.setSelectionRange(end, end);
}, 0);
}
else if (self.createTextRange) {
// IE
end = self.value.length - 1;
range = self.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', end);
// NOTE: I haven't tested to see if IE has the same problem as
// W3C browsers seem to have in this context (needing to fire
// select after callstack).
range.select();
}
});
};
// GUI Event Handlers
$(document).keydown( function(event) {
// catch all keyboard input, handle special chars
var code = event.which;
inputfield = $("#inputfield");
inputfield.focus();
if (code === 13) { // Enter key sends text
outtext = inputfield.val()
inputlog.add(outtext)
Evennia.msg("text", [outtext], {});
event.prevetDefault()
}
else if (code === 38) { // Arrow up
inputfield.val(inputlog.back()).appendCaret();
}
else if (code === 40) { // Arrow down
inputfield.val(inputlog.fwd()).appendCaret();
}
});
// client size setter
function set_window_size() {
var winh = $(document).height();
var formh = $('#inputform').outerHeight(true);
$("#messagewindow").css({'height': winh - formh - 1});
}
// Event - called when window resizes
$(window).resize(set_window_size);
//
// Listeners
//
function doText(args, kwargs) {
// append message to previous ones
$("#messagewindow").append(
"<div class='msg out>" + args[0] + "</div>");
// scroll message window to bottom
$("#messagewindow").animate({scrollTop: $('#messageindow')[0].scrollHeight});
}
function doPrompt(args, kwargs) {
// show prompt
$('prompt').replaceWith(
"<div id='prompt' class='msg out'>" + args[0] + "</div>");
}
$(document).ready(function() {
// a small timeout to stop 'loading' indicator in Chrome
Evennia.init()
// register listeners
Evennia.emitter.on("text", doText);
Evennia.emitter.on("prompt", doPrompt);
set_window_size();
// set an idle timer to avoid proxy servers to time out on us (every 3 minutes)
setInterval(function() {
log('Idle tick.');
Evennia.msg("text", ["idle"], {});
},
60000*3
);
});
//
// Senders
//

View file

@ -14,60 +14,66 @@ JQuery available.
<meta name="author" content="Evennia" />
<meta name="generator" content="Evennia" />
<link rel='stylesheet' type="text/css" media="screen" href="{% static "webclient/css/webclient.css" %}">
<link rel='stylesheet' type="text/css" media="screen" href={% static "webclient/css/webclient.css" %}>
<script src="http://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript" charset="utf-8"></script>
<!--for offline testing, download the jquery library from jquery.com-->
<!--script src="/media/javascript/jquery-1.11.1.js" type="text/javascript" charset="utf-8"></script-->
<!-- Import JQuery and warn if there is a problem -->
{% block jquery_import %}
<script src="http://code.jquery.com/jquery-2.1.1.min.js" type="text/javascript" charset="utf-8"></script>
{% endblock %}
<script type="text/javascript" charset="utf-8">
if(!window.jQuery){document.write("<div class='err'>jQuery library not found or the online version could not be reached.</div>");}
if(!window.jQuery) {
document.write("<div class='err'>jQuery library not found or the online version could not be reached.</div>");
}
</script>
<!-- Set up javascript url -->
<!-- Set up Websocket url and load the evennia.js library-->
<script language="javascript" type="text/javascript">
{% if websocket_enabled %}
var wsactive = true;
{% else %}
var wsactive = false;
{% endif %}
{% if websocket_url %}
var wsurl = "{{websocket_url}}:{{websocket_port}}";
{% else %}
var wsurl = "ws://" + this.location.hostname + ":{{websocket_port}}";
{% endif %}
document.write("\<script src=\"{% static "webclient/js/evennia.js" %}\" type=\"text/javascript\" charset=\"utf-8\"\>\</script\>")
</script>
<script src={% static "webclient/js/evennia.js" %} language="javascript" type="text/javascript" charset="utf-8"/></script>
<!-- Load gui library -->
{% block guilib_import %}
<script src={% static "webclient/js/webclient_gui.js" %} language="javascript" type="text/javascript" charset="utf-8"></script>
{% endblock %}
</head>
<body>
<div id="connecting">
{% block Connecting %}
{% block connecting %}
{% endblock %}
</div>
<div id="noscript">
<h3>Javascript Error: The Evennia MUD client requires that you have Javascript activated.</h3>
<p>Turn off eventual script blockers and/or switch to a web
browser supporting javascript.</p>
<p>For admins: The error could also be due to not being able
to access the online jQuery javascript library. If you are
testing the client without an internet connection, you have
to previously download the jQuery library from
http://code.jquery.com (it's just one file) and then edit
webclient.html to point to the local copy.</p>
<div id="noscript" class="err">
<h3>Javascript Error: The Evennia MUD client requires that you
have Javascript activated.</h3>
<p>Turn off eventual script blockers and/or switch to a
web browser supporting javascript. <p>
This error could also be due to not being able to access
the online jQuery javascript library.</p>
<!-- This is will only fire if javascript is actually active -->
<script language="javascript" type="text/javascript">
$('#noscript').remove();
</script>
</div>
<!-- This is will only fire if js is actually active -->
<script language="javascript" type="text/javascript">
$('#noscript').remove();
</script>
<!-- main client -->
<div id=clientwrapper>
{% block client %}
{% endblock %}
</div>
<!-- import this after the client -->
{% block guilib_import %}
<script src="webclient/js/webclient_gui.js" language="javascript" type="test/javascript"> </script>
{% endblock %}
</body>
</html>

View file

@ -1,30 +1,21 @@
{% extends "webclient/base.html" %}
{% block guilib_import %}
{% endblock %}
<!-- Django-template blocks available for overloading:
- connecting - custom connect messages
- jquery_import - for changing to a local jquery version
- guilib_import - for using your own gui lib
-->
{% block connecting %}
{% endblock %}
{% block client %}
<h1>Webclient!</h1>
<div id="client">
<div id="messagewindow"> mainarea </div>
<div id="inputform">
<textarea name="inputfield" type="text"> </textarea>
</div>
</div>
<form>
<input id="maininput" type="text" name="input">
<input type="button" value="Send" onClick="sendInput()">
</form>
<script language="javascript" type="text/javascript">
var sendInput = function() {
var inmsg = $("#maininput").val();
log("sendInput: " + inmsg);
Evennia.msg("echo", [inmsg], {});
};
</script>
{% endblock %}