From df393d4bf0ab88e039d6fed6a407c20e79d51d85 Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Fri, 22 Dec 2006 06:17:17 +0000 Subject: [PATCH] Converted the game configuration stuff to its own module. --- evennia/trunk/TODO | 3 +- evennia/trunk/events.py | 15 +++++ evennia/trunk/gameconf.py | 10 +++ evennia/trunk/scheduler.py | 33 +++------- evennia/trunk/server.py | 46 ++----------- evennia/trunk/sessions.py | 129 +++++++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 65 deletions(-) create mode 100644 evennia/trunk/events.py create mode 100644 evennia/trunk/gameconf.py create mode 100644 evennia/trunk/sessions.py diff --git a/evennia/trunk/TODO b/evennia/trunk/TODO index 4b41dc848d..29d7893b98 100644 --- a/evennia/trunk/TODO +++ b/evennia/trunk/TODO @@ -1 +1,2 @@ -* Since we now have support for GARBAGE, we need to handle creating over a garbage object gracefully. +Add any things that need work here: +* We're going to need a delayed event queue in addition to the scheduler. diff --git a/evennia/trunk/events.py b/evennia/trunk/events.py new file mode 100644 index 0000000000..644cb721aa --- /dev/null +++ b/evennia/trunk/events.py @@ -0,0 +1,15 @@ +""" +Holds the events scheduled in scheduler.py. +""" + +schedule = { + 'event_example': 60, + } + +lastrun = {} + +def event_example(): + """ + This is where the example event would be placed. + """ + pass diff --git a/evennia/trunk/gameconf.py b/evennia/trunk/gameconf.py new file mode 100644 index 0000000000..b21627be6c --- /dev/null +++ b/evennia/trunk/gameconf.py @@ -0,0 +1,10 @@ +from apps.config.models import ConfigValue +""" +Handle the setting/retrieving of server config directives. +""" + +def get_configvalue(configname): + """ + Retrieve a configuration value. + """ + return ConfigValue.objects.get(conf_key=configname).conf_value diff --git a/evennia/trunk/scheduler.py b/evennia/trunk/scheduler.py index 9ef277215d..efcb72be95 100644 --- a/evennia/trunk/scheduler.py +++ b/evennia/trunk/scheduler.py @@ -1,4 +1,5 @@ import time +import events """ A really simple scheduler. We can probably get a lot fancier with this in the future, but it'll do for now. @@ -8,24 +9,6 @@ ADDING AN EVENT: * Add the proper event_ function here. * Profit. """ - -schedule = { - 'event_example': 60, - } - -lastrun = {} - -""" -BEGIN EVENTS -""" -def event_example(): - """ - This is where the example event would be placed. - """ - pass -""" -END EVENTS -""" # The timer method to be triggered by the main server loop. def heartbeat(): @@ -33,19 +16,19 @@ def heartbeat(): Handle one tic/heartbeat. """ tictime = time.time() - for event in schedule: + for event in events.schedule: try: - lastrun[event] + events.lastrun[event] except: - lastrun[event] = time.time() + events.lastrun[event] = time.time() - diff = tictime - lastrun[event] + diff = tictime - events.lastrun[event] - if diff >= schedule[event]: - event_func = getattr(self, event) + if diff >= events.schedule[event]: + event_func = getattr(events, event) if callable(event_func): event_func() # We'll get a new reading for time for accuracy. - lastrun[event] = time.time() + events.lastrun[event] = time.time() diff --git a/evennia/trunk/server.py b/evennia/trunk/server.py index c682ff3b68..e1fbfc1435 100755 --- a/evennia/trunk/server.py +++ b/evennia/trunk/server.py @@ -4,12 +4,13 @@ import socket, asyncore, time, sys from django.db import models from django.db import connection -from apps.config.models import ConfigValue, CommandAlias +from apps.config.models import CommandAlias import scheduler import functions_db import functions_general import global_defines import session_mgr +import gameconf class Server(dispatcher): """ @@ -17,7 +18,6 @@ class Server(dispatcher): """ def __init__(self): self.cmd_alias_list = {} - self.configvalue = {} self.game_running = True # Wipe our temporary flags on all of the objects. @@ -26,35 +26,24 @@ class Server(dispatcher): print '-'*50 # Load stuff up into memory for easy/quick access. - self.load_configvalues() self.load_cmd_aliases() + self.port = gameconf.get_configvalue('site_port') # Start accepting connections. dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() - self.bind(('', int(self.configvalue['site_port']))) + self.bind(('', int(self.port))) self.listen(100) self.start_time = time.time() - print ' %s started on port %s.' % (self.configvalue['site_name'], self.configvalue['site_port'],) + print ' %s started on port %s.' % (gameconf.get_configvalue('site_name'), self.port,) print '-'*50 """ BEGIN SERVER STARTUP METHODS """ - def load_configvalues(self): - """ - Loads our site's configuration up for easy access. - """ - configs = ConfigValue.objects.all() - - for conf in configs: - self.configvalue[conf.conf_key] = conf.conf_value - - print ' Configuration Loaded.' - def load_cmd_aliases(self): """ Load up our command aliases. @@ -62,7 +51,7 @@ class Server(dispatcher): alias_list = CommandAlias.objects.all() for alias in alias_list: self.cmd_alias_list[alias.user_input] = alias.equiv_command - print ' Aliases Loaded: %i' % (len(self.cmd_alias_list),) + print ' Command Aliases Loaded: %i' % (len(self.cmd_alias_list),) def handle_accept(self): """ @@ -76,28 +65,7 @@ class Server(dispatcher): """ BEGIN GENERAL METHODS - """ - def add_object_to_cache(self, object): - """ - Adds an object to the cached object list. - """ - self.object_list[object.id] = object - - def remove_object_from_cache(self, object): - """ - Removes an object from the cache. - """ - if self.object_list.has_key(object.id): - del self.object_list[object.id] - else: - print 'ERROR: Trying to remove non-cached object: %s' % (object,) - - def get_configvalue(self, configname): - """ - Retrieve a configuration value. - """ - return self.configvalue[configname] - + """ def shutdown(self, message='The server has been shutdown. Please check back soon.'): functions_general.announce_all(message) self.game_running = False diff --git a/evennia/trunk/sessions.py b/evennia/trunk/sessions.py new file mode 100644 index 0000000000..4290d9f03f --- /dev/null +++ b/evennia/trunk/sessions.py @@ -0,0 +1,129 @@ +from asyncore import dispatcher +from asynchat import async_chat +import socket, asyncore, time, sys +import cmdhandler +from apps.objects.models import Object +from django.contrib.auth.models import User +import commands_general +import functions_db +import session_mgr + +class PlayerSession(async_chat): + """ + This class represents a player's sesssion. From here we branch down into + other various classes, please try to keep this one tidy! + """ + def __init__(self, server, sock, addr): + async_chat.__init__(self, sock) + self.server = server + self.address = addr + self.set_terminator("\n") + self.name = None + self.data = [] + self.uid = None + self.sock = sock + self.logged_in = False + # The time the user last issued a command. + self.cmd_last = time.time() + # Total number of commands issued. + self.cmd_total = 0 + # The time when the user connected. + self.conn_time = time.time() + + def collect_incoming_data(self, data): + """ + Stuff any incoming data into our buffer, self.data + """ + self.data.append(data) + + def found_terminator(self): + """ + Any line return indicates a command for the purpose of a MUD. So we take + the user input and pass it to our command handler. + """ + line = (''.join(self.data)) + line = line.strip('\r') + uinput = line + self.data = [] + + # Increment our user's command counter. + self.cmd_total += 1 + # Store the timestamp of the user's last command. + self.cmd_last = time.time() + # Stuff anything we need to pass in this dictionary. + cdat = {"server": self.server, "uinput": uinput, "session": self} + cmdhandler.handle(cdat) + + def handle_close(self): + """ + Break the connection and do some accounting. + """ + self.get_pobject().set_flag("CONNECTED", False) + async_chat.handle_close(self) + self.logged_in = False + session_mgr.remove_session(self) + print 'Sessions active:', len(session_mgr.get_session_list()) + + def get_pobject(self): + """ + Returns the object associated with a session. + """ + result = Object.objects.get(id=self.uid) + #print 'RES', result + return result + + def game_connect_screen(self, session): + """ + Show our banner screen. + """ + buffer = '-'*50 + buffer += ' \n\rWelcome to Evennia!\n\r' + buffer += '-'*50 + '\n\r' + buffer += """Please type one of the following to begin:\n\r + connect \n\r + create \n\r""" + buffer += '-'*50 + session.msg(buffer) + + def login(self, user): + """ + After the user has authenticated, handle logging him in. + """ + self.uid = user.id + self.name = user.username + self.logged_in = True + self.conn_time = time.time() + self.get_pobject().set_flag("CONNECTED", True) + + self.msg("You are now logged in as %s." % (self.name,)) + cdat = {"session": self, "uinput":'look', "server": self.server} + cmdhandler.handle(cdat) + print "Login: %s" % (self,) + + def msg(self, message): + """ + Sends a message with the newline/return included. Use this instead of + directly calling push(). + """ + self.push("%s\n\r" % (message,)) + + def msg_no_nl(self, message): + """ + Sends a message without the newline/return included. Use this instead of + directly calling push(). + """ + self.push("%s" % (message,)) + + def __str__(self): + """ + String representation of the user session class. We use + this a lot in the server logs and stuff. + """ + if self.logged_in: + symbol = '#' + else: + symbol = '?' + return "<%s> %s@%s" % (symbol, self.name, self.address,) + +# def handle_error(self): +# self.handle_close()