From 0eb5d2956024a32144c306705217e509c6a14bc3 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 11 Dec 2010 13:37:26 +0000 Subject: [PATCH] Cleaned up the webclient and changed how it handles sessions and identifies with the server. Fixed some reported bugs caused by the changed layout of sessionhandler. --- src/commands/default/admin.py | 10 +-- src/commands/default/general.py | 60 +++++++------- src/commands/default/system.py | 12 ++- src/comms/models.py | 4 +- src/players/models.py | 4 +- src/scripts/scripts.py | 4 +- src/server/server.py | 6 +- src/server/session.py | 8 +- src/server/sessionhandler.py | 15 ++++ src/server/webclient.py | 65 ++++++++++------ src/settings_default.py | 2 +- src/utils/reloads.py | 8 +- src/utils/text2html.py | 4 +- src/utils/utils.py | 13 +++- src/web/media/javascript/evennia_webclient.js | 78 ++++++++++++++----- src/web/webclient/views.py | 5 +- 16 files changed, 191 insertions(+), 107 deletions(-) diff --git a/src/commands/default/admin.py b/src/commands/default/admin.py index bcde88fe6d..8149e788e8 100644 --- a/src/commands/default/admin.py +++ b/src/commands/default/admin.py @@ -7,7 +7,7 @@ Admin commands from django.conf import settings from django.contrib.auth.models import User from src.players.models import PlayerDB -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS from src.permissions.permissions import has_perm, has_perm_string from src.permissions.models import PermissionGroup from src.utils import utils @@ -48,7 +48,7 @@ class CmdBoot(MuxCommand): if 'port' in self.switches: # Boot a particular port. - sessions = sessionhandler.get_session_list(True) + sessions = SESSIONS.get_session_list(True) for sess in sessions: # Find the session with the matching port number. if sess.getClientAddress()[1] == int(args): @@ -66,7 +66,7 @@ class CmdBoot(MuxCommand): pobj.msg(string) return # we have a bootable object with a connected user - matches = sessionhandler.sessions_from_object(pobj) + matches = SESSIONS.sessions_from_object(pobj) for match in matches: boot_list.append(match) else: @@ -90,7 +90,7 @@ class CmdBoot(MuxCommand): if feedback: session.msg(feedback) session.disconnectClient() - sessionhandler.remove_session(session) + SESSIONS.remove_session(session) caller.msg("You booted %s." % name) @@ -479,4 +479,4 @@ class CmdWall(MuxCommand): self.caller.msg("Usage: @wall ") return message = "%s shouts \"%s\"" % (self.caller.name, self.args) - sessionhandler.announce_all(message) + SESSIONS.announce_all(message) diff --git a/src/commands/default/general.py b/src/commands/default/general.py index 9d9a89e649..29cc65f048 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -4,7 +4,7 @@ now. """ import time from django.conf import settings -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS from src.permissions.models import PermissionGroup from src.permissions.permissions import has_perm, has_perm_string from src.objects.models import HANDLE_SEARCH_ERRORS @@ -342,7 +342,7 @@ class CmdWho(MuxCommand): """ caller = self.caller - session_list = sessionhandler.get_sessions() + session_list = SESSIONS.get_sessions() if self.cmdstring == "doing": show_session_data = False @@ -350,44 +350,44 @@ class CmdWho(MuxCommand): show_session_data = has_perm_string(caller, "Immortals,Wizards") if show_session_data: - retval = "Player Name On For Idle Room Cmds Host\n\r" + table = [["Player Name"], ["On for"], ["Idle"], ["Room"], ["Cmds"], ["Host"]] else: - retval = "Player Name On For Idle\n\r" - + table = [["Player Name"], ["On for"], ["Idle"]] + for session in session_list: if not session.logged_in: continue delta_cmd = time.time() - session.cmd_last_visible delta_conn = time.time() - session.conn_time plr_pobject = session.get_character() - if show_session_data: - retval += '%-31s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n' % \ - (plr_pobject.name[:25], \ - # On-time - utils.time_format(delta_conn,0), \ - # Idle time - utils.time_format(delta_cmd,1), \ - # Flags - '', \ - # Location - plr_pobject.location.id, \ - session.cmd_total, \ - # More flags? - '', \ - session.address[0]) + table[0].append(plr_pobject.name[:25]) + table[1].append(utils.time_format(delta_conn,0)) + table[2].append(utils.time_format(delta_cmd,1)) + table[3].append(plr_pobject.location.id) + table[4].append(session.cmd_total) + table[5].append(session.address[0]) else: - retval += '%-31s%9s %4s%-3s\r\n' % \ - (plr_pobject.name[:25], \ - # On-time - utils.time_format(delta_conn,0), \ - # Idle time - utils.time_format(delta_cmd,1), \ - # Flags - '') - retval += '%d Players logged in.' % (len(session_list),) + table[0].append(plr_pobject.name[:25]) + table[1].append(utils.time_format(delta_conn,0)) + table[2].append(utils.time_format(delta_cmd,1)) + stable = [] + for row in table: # prettify values + stable.append([str(val).strip() for val in row]) + ftable = utils.format_table(stable, 5) + string = "" + for ir, row in enumerate(ftable): + if ir == 0: + string += "\n" + "{w%s{n" % ("".join(row)) + else: + string += "\n" + "".join(row) + nplayers = (SESSIONS.player_count()) + if nplayers == 1: + string += '\nOne player logged in.' + else: + string += '\n%d players logged in.' % nplayers - caller.msg(retval) + caller.msg(string) class CmdSay(MuxCommand): """ diff --git a/src/commands/default/system.py b/src/commands/default/system.py index e83fc17ebd..cc2f90ea46 100644 --- a/src/commands/default/system.py +++ b/src/commands/default/system.py @@ -9,13 +9,15 @@ import os, datetime import django, twisted from django.contrib.auth.models import User -from src.server import sessionhandler +from src.server.server import EVENNIA +from src.server.sessionhandler import SESSIONS from src.scripts.models import ScriptDB from src.objects.models import ObjectDB from src.config.models import ConfigValue from src.utils import reloads, create, logger, utils, gametime from src.commands.default.muxcommand import MuxCommand + class CmdReload(MuxCommand): """ Reload the system @@ -429,13 +431,9 @@ class CmdShutdown(MuxCommand): announcement = "\nServer is being SHUT DOWN!\n" if self.args: announcement += "%s\n" % self.args - - sessionhandler.announce_all(announcement) logger.log_infomsg('Server shutdown by %s.' % self.caller.name) - - # access server through session so we don't call server directly - # (importing it directly would restart it...) - session.server.shutdown() + SESSIONS.announce_all(announcement) + EVENNIA.shutdown() class CmdVersion(MuxCommand): """ diff --git a/src/comms/models.py b/src/comms/models.py index 18ad861491..8b13e9fbe1 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -17,7 +17,7 @@ be able to delete connections on the fly). from django.db import models from src.utils.idmapper.models import SharedMemoryModel from src.players.models import PlayerDB -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS from src.comms import managers from src.permissions.permissions import has_perm from src.utils.utils import is_iter @@ -509,7 +509,7 @@ class Channel(SharedMemoryModel): # send message to all connected players for conn in conns: for session in \ - sessionhandler.SESSIONS.sessions_from_player(conn.player): + SESSIONS.sessions_from_player(conn.player): session.msg(msg) return True diff --git a/src/players/models.py b/src/players/models.py index 407ab0f7db..4dc52bc073 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -44,7 +44,7 @@ from django.conf import settings from django.db import models from django.contrib.auth.models import User from django.utils.encoding import smart_str -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS from src.players import manager from src.typeclasses.models import Attribute, TypedObject from src.permissions import permissions @@ -220,7 +220,7 @@ class PlayerDB(TypedObject): #@property def sessions_get(self): "Getter. Retrieve sessions related to this player/user" - return sessionhandler.SESSIONS.sessions_from_player(self) + return SESSIONS.sessions_from_player(self) #@sessions.setter def sessions_set(self, value): "Setter. Protects the sessions property from adding things" diff --git a/src/scripts/scripts.py b/src/scripts/scripts.py index 280d27d87a..af5a205889 100644 --- a/src/scripts/scripts.py +++ b/src/scripts/scripts.py @@ -7,7 +7,7 @@ It also defines a few common scripts. from time import time from twisted.internet import task -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS from src.typeclasses.typeclass import TypeClass from src.scripts.models import ScriptDB from src.comms import channelhandler @@ -234,7 +234,7 @@ class CheckSessions(Script): "called every 60 seconds" #print "session check!" #print "ValidateSessions run" - sessionhandler.validate_sessions() + SESSIONS.validate_sessions() class ValidateScripts(Script): "Check script validation regularly" diff --git a/src/server/server.py b/src/server/server.py index d5b69fc964..d90bb2099f 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -22,7 +22,7 @@ from django.db import connection from django.conf import settings from src.utils import reloads from src.config.models import ConfigValue -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS from src.server import initial_setup from src.utils.utils import get_evennia_version @@ -77,7 +77,7 @@ class Evennia(object): self.run_initial_setup() # we have to null this here. - sessionhandler.SESSIONS.session_count(0) + SESSIONS.session_count(0) self.start_time = time.time() @@ -152,7 +152,7 @@ class Evennia(object): """ if not message: message = 'The server has been shutdown. Please check back soon.' - sessionhandler.SESSIONS.disconnect_all_sessions(reason=message) + SESSIONS.disconnect_all_sessions(reason=message) reactor.callLater(0, reactor.stop) diff --git a/src/server/session.py b/src/server/session.py index 392b2cd5be..75d8923904 100644 --- a/src/server/session.py +++ b/src/server/session.py @@ -12,7 +12,7 @@ from django.conf import settings from src.comms.models import Channel from src.utils import logger, reloads from src.commands import cmdhandler -from src.server import sessionhandler +from src.server.sessionhandler import SESSIONS IDLE_TIMEOUT = settings.IDLE_TIMEOUT IDLE_COMMAND = settings.IDLE_COMMAND @@ -75,7 +75,7 @@ class SessionBase(object): # Total number of commands issued. self.cmd_total = 0 #self.channels_subscribed = {} - sessionhandler.SESSIONS.add_unloggedin_session(self) + SESSIONS.add_unloggedin_session(self) # call hook method self.at_connect() @@ -101,7 +101,7 @@ class SessionBase(object): reloads.reload_scripts(obj=self.player.character, init_mode=True) #add session to connected list - sessionhandler.SESSIONS.add_loggedin_session(self) + SESSIONS.add_loggedin_session(self) #call hook self.at_login() @@ -123,7 +123,7 @@ class SessionBase(object): uaccount.last_login = datetime.now() uaccount.save() self.logged_in = False - sessionhandler.SESSIONS.remove_session(self) + SESSIONS.remove_session(self) def session_validate(self): """ diff --git a/src/server/sessionhandler.py b/src/server/sessionhandler.py index 9e26c12f3b..4f4a56c0c2 100644 --- a/src/server/sessionhandler.py +++ b/src/server/sessionhandler.py @@ -151,6 +151,14 @@ class SessionHandler(object): num = max(0, num + add) ConfigValue.objects.conf('nr_sessions', str(num)) + def player_count(self): + """ + Get the number of connected players (not sessions since a player + may have more than one session connected if ALLOW_MULTISESSION is True) + Only logged-in players are counted here. + """ + return len(set(sess.uid for sess in self.get_sessions())) + def sessions_from_player(self, player): """ Given a player, return any matching sessions. @@ -179,6 +187,13 @@ class SessionHandler(object): """ return [sess for sess in self.get_sessions(include_unloggedin=True) if sess.suid and sess.suid == suid] + def announce_all(self, message): + """ + Send message to all connected sessions + """ + for sess in self.get_sessions(include_unloggedin=True): + sess.msg(message) + SESSIONS = SessionHandler() diff --git a/src/server/webclient.py b/src/server/webclient.py index 1f3a049707..c48e6e9c65 100644 --- a/src/server/webclient.py +++ b/src/server/webclient.py @@ -16,6 +16,8 @@ found on http://localhost:8020/webclient.) handle these requests and act as a gateway to sessions connected over the webclient. """ +import time +from hashlib import md5 from twisted.web import server, resource from twisted.internet import defer @@ -27,7 +29,8 @@ from django.conf import settings from src.utils import utils from src.utils.text2html import parse_html from src.config.models import ConnectScreen -from src.server import session, sessionhandler +from src.server import session +from src.server.sessionhandler import SESSIONS SERVERNAME = settings.SERVERNAME ENCODINGS = settings.ENCODINGS @@ -94,8 +97,8 @@ class WebClient(resource.Resource): self.databuffer[suid] = dataentries def disconnect(self, suid): - "Disconnect session" - sess = sessionhandler.SESSIONS.session_from_suid(suid) + "Disconnect session with given suid." + sess = SESSIONS.session_from_suid(suid) if sess: sess[0].session_disconnect() if self.requests.has_key(suid): @@ -110,32 +113,35 @@ class WebClient(resource.Resource): This is called by render_POST when the client requests an init mode operation (at startup) """ - csess = request.getSession() # obs, this is a cookie, not an evennia session! + #csess = request.getSession() # obs, this is a cookie, not an evennia session! #csees.expireCallbacks.append(lambda : ) - suid = csess.uid + suid = request.args.get('suid', ['0'])[0] + remote_addr = request.getClientIP() host_string = "%s (%s:%s)" % (SERVERNAME, request.getHost().host, request.getHost().port) - self.requests[suid] = [] - self.databuffer[suid] = [] + if suid == '0': + # creating a unique id hash string + suid = md5(str(time.time())).hexdigest() + self.requests[suid] = [] + self.databuffer[suid] = [] - sess = sessionhandler.SESSIONS.session_from_suid(suid) - if not sess: sess = WebClientSession() - sess.client = self - sess.session_connect(remote_addr, suid) - sessionhandler.SESSIONS.add_unloggedin_session(sess) - return jsonify({'msg':host_string}) + sess.client = self + sess.session_connect(remote_addr, suid) + return jsonify({'msg':host_string, 'suid':suid}) def mode_input(self, request): """ This is called by render_POST when the client is sending data to the server. """ - string = request.args.get('msg', [''])[0] - data = request.args.get('data', [None])[0] - suid = request.getSession().uid - sess = sessionhandler.SESSIONS.session_from_suid(suid) + suid = request.args.get('suid', ['0'])[0] + if suid == '0': + return '' + sess = SESSIONS.session_from_suid(suid) if sess: + string = request.args.get('msg', [''])[0] + data = request.args.get('data', [None])[0] sess[0].at_data_in(string, data) return '' @@ -147,16 +153,29 @@ class WebClient(resource.Resource): mechanism: the server will wait to reply until data is available. """ - suid = request.getSession().uid + suid = request.args.get('suid', ['0'])[0] + if suid == '0': + return '' + dataentries = self.databuffer.get(suid, []) if dataentries: - return dataentries.pop(0) + return dataentries.pop(0) reqlist = self.requests.get(suid, []) request.notifyFinish().addErrback(self._responseFailed, suid, request) reqlist.append(request) self.requests[suid] = reqlist return server.NOT_DONE_YET + def mode_close(self, request): + """ + This is called by render_POST when the client is signalling + that it is about to be closed. + """ + suid = request.args.get('suid', ['0'])[0] + if suid == '0': + self.disconnect(suid) + return '' + def render_POST(self, request): """ This function is what Twisted calls with POST requests coming @@ -176,6 +195,9 @@ class WebClient(resource.Resource): elif dmode == 'receive': # the client is waiting to receive data. return self.mode_receive(request) + elif dmode == 'close': + # the client is closing + return self.mode_close(request) else: # this should not happen if client sends valid data. return '' @@ -234,8 +256,7 @@ class WebClientSession(session.Session): # string handling is similar to telnet if self.encoding: try: - string = utils.to_str(string, encoding=self.encoding) - #self.client.lineSend(self.suid, ansi.parse_ansi(string, strip_ansi=True)) + string = utils.to_str(string, encoding=self.encoding) self.client.lineSend(self.suid, parse_html(string)) return except Exception: @@ -256,7 +277,7 @@ class WebClientSession(session.Session): self.client.lineSend(self.suid, parse_html(string)) def at_data_in(self, string, data=None): """ - Input from Player -> Evennia (called by client). + Input from Player -> Evennia (called by client protocol). Use of 'data' is up to the client - server implementation. """ diff --git a/src/settings_default.py b/src/settings_default.py index 7e45a9b179..aad2a1f4b9 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -33,7 +33,7 @@ TELNET_PORTS = [4000] # in the section 'Config for Django web features') WEBSERVER_ENABLED = True # A list of ports the Evennia webserver listens on -WEBSERVER_PORTS = [8020] +WEBSERVER_PORTS = [8000] # Start the evennia ajax client on /webclient # (the webserver must also be running) WEBCLIENT_ENABLED = True diff --git a/src/utils/reloads.py b/src/utils/reloads.py index 2643be9f60..ff94dbc11b 100644 --- a/src/utils/reloads.py +++ b/src/utils/reloads.py @@ -28,8 +28,10 @@ def reload_modules(): # We protect e.g. src/ from reload since reloading it in a running # server can create unexpected results (and besides, non-evennia devs # should never need to do that anyway). Updating src requires a server - # reboot. + # reboot. Modules in except_dirs are considered ok to reload despite being + # inside src/ protected_dirs = ('src.',) + except_dirs = ('src.commands.default.') # flag 'dangerous' typeclasses (those which retain a memory # reference, notably Scripts with a timer component) for @@ -43,8 +45,8 @@ def reload_modules(): unsafe_modules = list(set(unsafe_modules)) def safe_dir_to_reload(modpath): - "Check so modpath is not a subdir of a protected dir" - return not any(modpath.startswith(pdir) for pdir in protected_dirs) + "Check so modpath is not a subdir of a protected dir, and not an ok exception" + return not any(modpath.startswith(pdir) and not any(modpath.startswith(pdir) for pdir in except_dirs) for pdir in protected_dirs) def safe_mod_to_reload(modpath): "Check so modpath is not in an unsafe module" return not any(mpath.startswith(modpath) for mpath in unsafe_modules) diff --git a/src/utils/text2html.py b/src/utils/text2html.py index 355bc2ca48..559b8fe594 100644 --- a/src/utils/text2html.py +++ b/src/utils/text2html.py @@ -37,7 +37,7 @@ class TextToHTMLparser(object): normalcode = '\033[0m' tabstop = 4 - re_string = re.compile(r'(?P[<&>])|(?P^[ \t]+)|(?P\r\n|\r|\n)|(?P(^|\s)((http|ftp)://.*?))(\s|$)', + re_string = re.compile(r'(?P[<&>])|(?P^[ \t]+)|(?P\r\n|\r|\n)|(?P(^|\s)((http|ftp)://.*?))(\s|$)', re.S|re.M|re.I) def re_color(self, text): @@ -95,7 +95,7 @@ class TextToHTMLparser(object): elif c['space'] == '\t': return ' '*self.tabstop else: - url = m.group('protocal') + url = m.group('protocol') if url.startswith(' '): prefix = ' ' url = url[1:] diff --git a/src/utils/utils.py b/src/utils/utils.py index 54d5688bf7..8df856a8c6 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -320,12 +320,21 @@ def format_table(table, extra_space=1): collumns must have the same number of rows (some positions may be empty though). - The function formats the columns to be as wide as the wides member + The function formats the columns to be as wide as the widest member of each column. extra_space defines how much extra padding should minimum be left between collumns. - first_row_ansi defines an evential colour string for the first row. + + print the resulting list e.g. with + + for ir, row in enumarate(ftable): + if ir == 0: + # make first row white + string += "\n{w" + ""join(row) + "{n" + else: + string += "\n" + "".join(row) + print string """ if not table: diff --git a/src/web/media/javascript/evennia_webclient.js b/src/web/media/javascript/evennia_webclient.js index aff7152ac1..5ae007f61b 100644 --- a/src/web/media/javascript/evennia_webclient.js +++ b/src/web/media/javascript/evennia_webclient.js @@ -28,15 +28,18 @@ contain the 'mode' of the request to be handled by the protocol: should happen at this point. The server returns a data object with the 'msg' property containing the server address. + mode 'close' - closes the connection. The server closes the session and does + cleanup at this point. */ - // jQuery must be imported by the calling html page before this script // (it comes with Evennia, in media/javascript/jquery-.js) // There are plenty of help on using the jQuery library on http://jquery.com/ // Server communications +var CLIENT_HASH = '0'; // variable holding the client id + function webclient_receive(){ // This starts an asynchronous long-polling request. It will either timeout // or receive data from the 'receivedata' url. In both cases a new request will @@ -49,7 +52,7 @@ function webclient_receive(){ cache: false, // Forces browser reload independent of cache timeout:30000, // Timeout in ms. After this time a new long-poll will be started. dataType:"json", - data: {mode:'receive'}, + data: {mode:'receive', 'suid':CLIENT_HASH}, // callback methods @@ -66,7 +69,7 @@ function webclient_receive(){ function webclient_input(){ // Send an input from the player to the server - var outmsg = $("#inputfield").val() // get data from form + var outmsg = $("#inputfield").val(); // get data from form $.ajax({ type: "POST", @@ -74,7 +77,7 @@ function webclient_input(){ async: true, cache: false, timeout: 30000, - data: {mode:'input', msg:outmsg, data:'NoData'}, + data: {mode:'input', msg:outmsg, data:'NoData', 'suid':CLIENT_HASH}, //callback methods @@ -82,7 +85,7 @@ function webclient_input(){ //if (outmsg.length > 0 ) msg_display("inp", outmsg) // echo input on command line history_add(outmsg); HISTORY_POS = 0; - $('#inputform')[0].reset() // clear input field + $('#inputform')[0].reset(); // clear input field }, error: function(XMLHttpRequest, textStatus, errorThrown){ msg_display("err", "Error: Server returned an error or timed out. Try resending."); @@ -100,19 +103,20 @@ function webclient_init(){ cache: false, timeout: 50000, dataType:"json", - data: {mode:'init'}, + data: {mode:'init', 'suid':CLIENT_HASH}, // callback methods success: function(data){ // called when request to initdata completes $("#connecting").remove() // remove the "connecting ..." message. + CLIENT_HASH = data.suid // unique id hash given from server setTimeout(function () { // a small timeout to stop 'loading' indicator in Chrome $("#playercount").fadeOut('slow'); }, 10000); // Report success - msg_display('sys',"Connected to " + data.msg + ".") + msg_display('sys',"Connected to " + data.msg + "."); // Wait for input webclient_receive(); @@ -124,6 +128,29 @@ function webclient_init(){ }); } +function webclient_close(){ + // Kill the connection and do house cleaning on the server. + $.ajax({ + type: "POST", + url: "/webclientdata", + async: false, + cache: false, + timeout: 50000, + dataType: "json", + data: {mode: 'close', 'suid': CLIENT_HASH}, + + success: function(data){ + CLIENT_HASH = '0'; + alert("Mud client connection was closed cleanly."); + }, + error: function(XMLHttpRequest, textStatus, errorThrown){ + CLIENT_HASH = '0'; + alert("There was an error disconnecting from the mud server."); + } + + }); +} + // Display messages function msg_display(type, msg){ @@ -156,17 +183,17 @@ function history_add(input) { // add an entry to history if (input != HISTORY[HISTORY.length-1]) { if (HISTORY.length >= HISTORY_MAX_LENGTH) { - HISTORY.shift() // kill oldest history entry + HISTORY.shift(); // kill oldest history entry } - HISTORY[HISTORY.length-1] = input - HISTORY[HISTORY.length] = '' + HISTORY[HISTORY.length-1] = input; + HISTORY[HISTORY.length] = ''; } } // Catching keyboard shortcuts $(document).keypress( function(event) { - var code = event.keyCode ? event.keyCode : event.which + var code = event.keyCode ? event.keyCode : event.which; // always focus input field $("#inputfield")[0].focus(); @@ -192,21 +219,34 @@ $(document).keypress( function(event) { // handler to avoid double-clicks until the ajax request finishes $("#inputsend").one("click", webclient_input) -// Callback function - called when page has finished loading (gets things going) -$(document).ready(function(){ - - // remove the "no javascript" warning, since we obviously have javascript - $('#noscript').remove() - - // set sizes of elements and reposition them +function webclient_set_sizes() { + // Sets the size of the message window var win_h = $(document).height(); var win_w = $('#wrapper').width(); var inp_h = $('#inputform').height(); var inp_w = $('#inputsend').width() $("#messagewindow").css({'height':win_h-inp_h - 20}); $("#inputfield").css({'width':win_w-inp_w - 20}); +} - setTimeout(function () { // a small timeout to stop 'loading' indicator in Chrome +// Callback function - called when page has finished loading (gets things going) +$(document).ready(function(){ + // remove the "no javascript" warning, since we obviously have javascript + $('#noscript').remove(); + // set sizes of elements and reposition them + webclient_set_sizes(); + // a small timeout to stop 'loading' indicator in Chrome + setTimeout(function () { webclient_init(); }, 500); +}); + +// Callback function - called when the browser window resizes +$(window).resize(function() { + webclient_set_sizes(); +}); + +// Callback function - called when page is closed or moved away from. +$(window).unload(function() { + webclient_close(); }); \ No newline at end of file diff --git a/src/web/webclient/views.py b/src/web/webclient/views.py index c233867393..e9ac9910a3 100644 --- a/src/web/webclient/views.py +++ b/src/web/webclient/views.py @@ -8,8 +8,7 @@ page and serve it eventual static content. from django.shortcuts import render_to_response from django.template import RequestContext from django.conf import settings -from src.server import sessionhandler -from src.config.models import ConfigValue +from src.server.sessionhandler import SESSIONS def webclient(request): """ @@ -17,7 +16,7 @@ def webclient(request): """ # as an example we send the number of connected players to the template - pagevars = {'num_players_connected': ConfigValue.objects.conf('nr_sessions')} + pagevars = {'num_players_connected': SESSIONS.player_count()} context_instance = RequestContext(request) return render_to_response('webclient.html', pagevars, context_instance)