Converted to Twisted from asyncore. Not positive if this is just my local machine, but it seems like this backend is a bit faster.
This commit is contained in:
parent
82f46a2b69
commit
97cf1213e6
8 changed files with 113 additions and 145 deletions
1
INSTALL
1
INSTALL
|
|
@ -1,6 +1,7 @@
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
* Python 2.5 strongly recommended, although 2.3 or 2.4 may work just fine.
|
* Python 2.5 strongly recommended, although 2.3 or 2.4 may work just fine.
|
||||||
|
* Twisted -- http://twistedmatrix.com/
|
||||||
* PySqlite2 (If you're using the default SQLite driver)
|
* PySqlite2 (If you're using the default SQLite driver)
|
||||||
* Django (Latest trunk from Subversion recommended)
|
* Django (Latest trunk from Subversion recommended)
|
||||||
* Optional: Apache2 or equivalent webserver with a Python interpreter
|
* Optional: Apache2 or equivalent webserver with a Python interpreter
|
||||||
|
|
|
||||||
10
events.py
10
events.py
|
|
@ -1,17 +1,21 @@
|
||||||
|
import time
|
||||||
|
from twisted.internet import protocol, reactor, defer
|
||||||
import session_mgr
|
import session_mgr
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Holds the events scheduled in scheduler.py.
|
Holds the events scheduled in scheduler.py.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Dictionary of events with a list in the form of: [<interval>, <lastrantime>]
|
||||||
schedule = {
|
schedule = {
|
||||||
'check_sessions': 60,
|
'check_sessions': [60, None]
|
||||||
}
|
}
|
||||||
|
|
||||||
lastrun = {}
|
|
||||||
|
|
||||||
def check_sessions():
|
def check_sessions():
|
||||||
"""
|
"""
|
||||||
Check all of the connected sessions.
|
Event: Check all of the connected sessions.
|
||||||
"""
|
"""
|
||||||
session_mgr.check_all_sessions()
|
session_mgr.check_all_sessions()
|
||||||
|
schedule['check_sessions'][1] = time.time()
|
||||||
|
reactor.callLater(schedule['check_sessions'][0], check_sessions)
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ def announce_all(message, with_ann_prefix=True, with_nl=True):
|
||||||
newline = ''
|
newline = ''
|
||||||
|
|
||||||
for session in session_mgr.get_session_list():
|
for session in session_mgr.get_session_list():
|
||||||
session.msg_no_nl('%s %s%s' % (prefix, message,newline,))
|
session.msg('%s %s%s' % (prefix, message,newline,))
|
||||||
|
|
||||||
def word_wrap(text, width=78):
|
def word_wrap(text, width=78):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
22
scheduler.py
22
scheduler.py
|
|
@ -1,5 +1,5 @@
|
||||||
import time
|
|
||||||
import events
|
import events
|
||||||
|
from twisted.internet import protocol, reactor, defer
|
||||||
"""
|
"""
|
||||||
A really simple scheduler. We can probably get a lot fancier with this
|
A really simple scheduler. We can probably get a lot fancier with this
|
||||||
in the future, but it'll do for now.
|
in the future, but it'll do for now.
|
||||||
|
|
@ -11,24 +11,12 @@ ADDING AN EVENT:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# The timer method to be triggered by the main server loop.
|
# The timer method to be triggered by the main server loop.
|
||||||
def heartbeat():
|
def start_events():
|
||||||
"""
|
"""
|
||||||
Handle one tic/heartbeat.
|
Handle one tic/heartbeat.
|
||||||
"""
|
"""
|
||||||
tictime = time.time()
|
|
||||||
for event in events.schedule:
|
for event in events.schedule:
|
||||||
try:
|
event_func = getattr(events, event)
|
||||||
events.lastrun[event]
|
|
||||||
except:
|
|
||||||
events.lastrun[event] = time.time()
|
|
||||||
|
|
||||||
diff = tictime - events.lastrun[event]
|
|
||||||
|
|
||||||
if diff >= events.schedule[event]:
|
if callable(event_func):
|
||||||
event_func = getattr(events, event)
|
reactor.callLater(events.schedule[event][0], event_func)
|
||||||
|
|
||||||
if callable(event_func):
|
|
||||||
event_func()
|
|
||||||
|
|
||||||
# We'll get a new reading for time for accuracy.
|
|
||||||
events.lastrun[event] = time.time()
|
|
||||||
|
|
|
||||||
90
server.py
90
server.py
|
|
@ -1,12 +1,15 @@
|
||||||
from traceback import format_exc
|
from traceback import format_exc
|
||||||
from asyncore import dispatcher
|
import time
|
||||||
from asynchat import async_chat
|
import sys
|
||||||
import socket, asyncore, time
|
|
||||||
|
from twisted.application import internet, service
|
||||||
|
from twisted.internet import protocol, reactor, defer
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
||||||
from apps.config.models import CommandAlias
|
from apps.config.models import CommandAlias
|
||||||
import sys
|
from session import SessionProtocol
|
||||||
import scheduler
|
import scheduler
|
||||||
import functions_general
|
import functions_general
|
||||||
import session_mgr
|
import session_mgr
|
||||||
|
|
@ -15,22 +18,20 @@ import settings
|
||||||
import cmdtable
|
import cmdtable
|
||||||
import initial_setup
|
import initial_setup
|
||||||
|
|
||||||
class Server(dispatcher):
|
class EvenniaService(service.Service):
|
||||||
"""
|
|
||||||
The main server class from which everything branches.
|
def __init__(self, filename="blah"):
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self.cmd_alias_list = {}
|
self.cmd_alias_list = {}
|
||||||
self.game_running = True
|
self.game_running = True
|
||||||
|
|
||||||
# Database-specific startup optimizations.
|
# Database-specific startup optimizations.
|
||||||
if settings.DATABASE_ENGINE == "sqlite3":
|
if settings.DATABASE_ENGINE == "sqlite3":
|
||||||
self.sqlite3_prep()
|
self.sqlite3_prep()
|
||||||
|
|
||||||
# Wipe our temporary flags on all of the objects.
|
# Wipe our temporary flags on all of the objects.
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
cursor.execute("UPDATE objects_object SET nosave_flags=''")
|
cursor.execute("UPDATE objects_object SET nosave_flags=''")
|
||||||
|
|
||||||
print '-'*50
|
print '-'*50
|
||||||
# Load command aliases into memory for easy/quick access.
|
# Load command aliases into memory for easy/quick access.
|
||||||
self.load_cmd_aliases()
|
self.load_cmd_aliases()
|
||||||
|
|
@ -40,21 +41,15 @@ class Server(dispatcher):
|
||||||
print ' Game started for the first time, setting defaults.'
|
print ' Game started for the first time, setting defaults.'
|
||||||
initial_setup.handle_setup()
|
initial_setup.handle_setup()
|
||||||
|
|
||||||
# Start accepting connections.
|
|
||||||
dispatcher.__init__(self)
|
|
||||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.set_reuse_addr()
|
|
||||||
self.bind(('', int(self.port)))
|
|
||||||
self.listen(100)
|
|
||||||
self.start_time = time.time()
|
self.start_time = time.time()
|
||||||
|
|
||||||
print ' %s started on port %s.' % (gameconf.get_configvalue('site_name'), self.port,)
|
print ' %s started on port %s.' % (gameconf.get_configvalue('site_name'), self.port,)
|
||||||
print '-'*50
|
print '-'*50
|
||||||
|
scheduler.start_events()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
BEGIN SERVER STARTUP METHODS
|
BEGIN SERVER STARTUP METHODS
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def load_cmd_aliases(self):
|
def load_cmd_aliases(self):
|
||||||
"""
|
"""
|
||||||
Load up our command aliases.
|
Load up our command aliases.
|
||||||
|
|
@ -63,17 +58,8 @@ class Server(dispatcher):
|
||||||
for alias in alias_list:
|
for alias in alias_list:
|
||||||
self.cmd_alias_list[alias.user_input] = alias.equiv_command
|
self.cmd_alias_list[alias.user_input] = alias.equiv_command
|
||||||
print ' Command Aliases Loaded: %i' % (len(self.cmd_alias_list),)
|
print ' Command Aliases Loaded: %i' % (len(self.cmd_alias_list),)
|
||||||
|
pass
|
||||||
def handle_accept(self):
|
|
||||||
"""
|
|
||||||
What to do when we get a connection.
|
|
||||||
"""
|
|
||||||
conn, addr = self.accept()
|
|
||||||
session = session_mgr.new_session(self, conn, addr)
|
|
||||||
session.game_connect_screen(session)
|
|
||||||
print 'Connection:', str(session)
|
|
||||||
print 'Sessions active:', len(session_mgr.get_session_list())
|
|
||||||
|
|
||||||
def sqlite3_prep(self):
|
def sqlite3_prep(self):
|
||||||
"""
|
"""
|
||||||
Optimize some SQLite stuff at startup since we can't save it to the
|
Optimize some SQLite stuff at startup since we can't save it to the
|
||||||
|
|
@ -84,14 +70,14 @@ class Server(dispatcher):
|
||||||
cursor.execute("PRAGMA synchronous=OFF")
|
cursor.execute("PRAGMA synchronous=OFF")
|
||||||
cursor.execute("PRAGMA count_changes=OFF")
|
cursor.execute("PRAGMA count_changes=OFF")
|
||||||
cursor.execute("PRAGMA temp_store=2")
|
cursor.execute("PRAGMA temp_store=2")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
BEGIN GENERAL METHODS
|
BEGIN GENERAL METHODS
|
||||||
"""
|
"""
|
||||||
def shutdown(self, message='The server has been shutdown. Please check back soon.'):
|
def shutdown(self, message='The server has been shutdown. Please check back soon.'):
|
||||||
functions_general.announce_all(message)
|
functions_general.announce_all(message)
|
||||||
self.game_running = False
|
session_mgr.disconnect_all_sessions()
|
||||||
|
reactor.callLater(0, reactor.stop)
|
||||||
|
|
||||||
def command_list(self):
|
def command_list(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -112,32 +98,26 @@ class Server(dispatcher):
|
||||||
'events', 'functions_db', 'functions_general', 'functions_comsys',
|
'events', 'functions_db', 'functions_general', 'functions_comsys',
|
||||||
'functions_help', 'gameconf', 'session', 'apps.objects.models',
|
'functions_help', 'gameconf', 'session', 'apps.objects.models',
|
||||||
'apps.helpsys.models', 'apps.config.models']
|
'apps.helpsys.models', 'apps.config.models']
|
||||||
|
|
||||||
for mod in reload_list:
|
for mod in reload_list:
|
||||||
reload(sys.modules[mod])
|
reload(sys.modules[mod])
|
||||||
|
|
||||||
session.msg("Modules reloaded.")
|
session.msg("Modules reloaded.")
|
||||||
functions_general.log_infomsg("Modules reloaded by %s." % (session,))
|
functions_general.log_infomsg("Modules reloaded by %s." % (session,))
|
||||||
|
|
||||||
|
def getEvenniaServiceFactory(self):
|
||||||
|
f = protocol.ServerFactory()
|
||||||
|
f.protocol = SessionProtocol
|
||||||
|
f.server = self
|
||||||
|
return f
|
||||||
|
|
||||||
"""
|
"""
|
||||||
END Server CLASS
|
END Server CLASS
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
application = service.Application('Evennia')
|
||||||
BEGIN MAIN APPLICATION LOGIC
|
mud_service = EvenniaService('Evennia Server')
|
||||||
"""
|
|
||||||
if __name__ == '__main__':
|
|
||||||
server = Server()
|
|
||||||
|
|
||||||
try:
|
|
||||||
while server.game_running:
|
|
||||||
asyncore.loop(timeout=5, count=1)
|
|
||||||
scheduler.heartbeat()
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
server.shutdown()
|
|
||||||
print '--> Server killed by keystroke.'
|
|
||||||
|
|
||||||
except:
|
# Sheet sheet, fire ze missiles!
|
||||||
server.shutdown(message="The server has encountered a fatal error and has been shut down. Please check back soon.")
|
serviceCollection = service.IServiceCollection(application)
|
||||||
functions_general.log_errmsg("Untrapped error: %s" %
|
internet.TCPServer(4000, mud_service.getEvenniaServiceFactory()).setServiceParent(serviceCollection)
|
||||||
(format_exc()))
|
|
||||||
87
session.py
87
session.py
|
|
@ -1,7 +1,8 @@
|
||||||
from asyncore import dispatcher
|
import time, sys
|
||||||
from asynchat import async_chat
|
|
||||||
import socket, asyncore, time, sys
|
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
|
|
||||||
|
from twisted.conch.telnet import StatefulTelnetProtocol
|
||||||
|
|
||||||
import cmdhandler
|
import cmdhandler
|
||||||
from apps.objects.models import Object
|
from apps.objects.models import Object
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
@ -10,20 +11,34 @@ import functions_db
|
||||||
import functions_general
|
import functions_general
|
||||||
import session_mgr
|
import session_mgr
|
||||||
|
|
||||||
class PlayerSession(async_chat):
|
class SessionProtocol(StatefulTelnetProtocol):
|
||||||
"""
|
"""
|
||||||
This class represents a player's sesssion. From here we branch down into
|
This class represents a player's sesssion. From here we branch down into
|
||||||
other various classes, please try to keep this one tidy!
|
other various classes, please try to keep this one tidy!
|
||||||
"""
|
"""
|
||||||
def __init__(self, server, sock, addr):
|
|
||||||
async_chat.__init__(self, sock)
|
def connectionMade(self):
|
||||||
self.server = server
|
"""
|
||||||
self.address = addr
|
What to do when we get a connection.
|
||||||
self.set_terminator("\n")
|
"""
|
||||||
|
session_mgr.add_session(self)
|
||||||
|
self.game_connect_screen()
|
||||||
|
self.prep_session()
|
||||||
|
print 'Connection:', self
|
||||||
|
print 'Sessions active:', len(session_mgr.get_session_list())
|
||||||
|
|
||||||
|
def getClientAddress(self):
|
||||||
|
"""
|
||||||
|
Returns the client's address and port in a tuple. For example
|
||||||
|
('127.0.0.1', 41917)
|
||||||
|
"""
|
||||||
|
return self.transport.client
|
||||||
|
|
||||||
|
def prep_session(self):
|
||||||
|
#self.server = server
|
||||||
|
self.address = self.getClientAddress()
|
||||||
self.name = None
|
self.name = None
|
||||||
self.data = []
|
|
||||||
self.uid = None
|
self.uid = None
|
||||||
self.sock = sock
|
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
# The time the user last issued a command.
|
# The time the user last issued a command.
|
||||||
self.cmd_last = time.time()
|
self.cmd_last = time.time()
|
||||||
|
|
@ -35,6 +50,18 @@ class PlayerSession(async_chat):
|
||||||
self.conn_time = time.time()
|
self.conn_time = time.time()
|
||||||
self.channels_subscribed = {}
|
self.channels_subscribed = {}
|
||||||
|
|
||||||
|
def disconnectClient(self):
|
||||||
|
"""
|
||||||
|
Manually disconnect the client.
|
||||||
|
"""
|
||||||
|
self.transport.loseConnection()
|
||||||
|
|
||||||
|
def connectionLost(self, reason):
|
||||||
|
"""
|
||||||
|
Execute this when a client abruplty loses their connection.
|
||||||
|
"""
|
||||||
|
print "DISCONNECT:", reason.getErrorMessage()
|
||||||
|
|
||||||
def has_user_channel(self, cname, alias_search=False, return_muted=False):
|
def has_user_channel(self, cname, alias_search=False, return_muted=False):
|
||||||
"""
|
"""
|
||||||
Is this session subscribed to the named channel?
|
Is this session subscribed to the named channel?
|
||||||
|
|
@ -93,24 +120,17 @@ class PlayerSession(async_chat):
|
||||||
if chan_list:
|
if chan_list:
|
||||||
self.channels_subscribed = pickle.loads(chan_list)
|
self.channels_subscribed = pickle.loads(chan_list)
|
||||||
|
|
||||||
def collect_incoming_data(self, data):
|
def lineReceived(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
|
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.
|
the user input and pass it to our command handler.
|
||||||
"""
|
"""
|
||||||
line = (''.join(self.data))
|
line = (''.join(data))
|
||||||
line = line.strip('\r')
|
line = line.strip('\r')
|
||||||
uinput = line
|
uinput = line
|
||||||
self.data = []
|
|
||||||
|
|
||||||
# Stuff anything we need to pass in this dictionary.
|
# Stuff anything we need to pass in this dictionary.
|
||||||
cdat = {"server": self.server, "uinput": uinput, "session": self}
|
cdat = {"server": self.factory.server, "uinput": uinput, "session": self}
|
||||||
cmdhandler.handle(cdat)
|
cmdhandler.handle(cdat)
|
||||||
|
|
||||||
def handle_close(self):
|
def handle_close(self):
|
||||||
|
|
@ -122,7 +142,7 @@ class PlayerSession(async_chat):
|
||||||
pobject.set_flag("CONNECTED", False)
|
pobject.set_flag("CONNECTED", False)
|
||||||
pobject.get_location().emit_to_contents("%s has disconnected." % (pobject.get_name(show_dbref=False),), exclude=pobject)
|
pobject.get_location().emit_to_contents("%s has disconnected." % (pobject.get_name(show_dbref=False),), exclude=pobject)
|
||||||
|
|
||||||
async_chat.handle_close(self)
|
self.disconnectClient()
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
session_mgr.remove_session(self)
|
session_mgr.remove_session(self)
|
||||||
print 'Sessions active:', len(session_mgr.get_session_list())
|
print 'Sessions active:', len(session_mgr.get_session_list())
|
||||||
|
|
@ -137,7 +157,7 @@ class PlayerSession(async_chat):
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def game_connect_screen(self, session):
|
def game_connect_screen(self):
|
||||||
"""
|
"""
|
||||||
Show the banner screen.
|
Show the banner screen.
|
||||||
"""
|
"""
|
||||||
|
|
@ -148,7 +168,7 @@ class PlayerSession(async_chat):
|
||||||
connect <email> <password>\n\r
|
connect <email> <password>\n\r
|
||||||
create \"<username>\" <email> <password>\n\r"""
|
create \"<username>\" <email> <password>\n\r"""
|
||||||
buffer += '-'*50
|
buffer += '-'*50
|
||||||
session.msg(buffer)
|
self.msg(buffer)
|
||||||
|
|
||||||
def login(self, user):
|
def login(self, user):
|
||||||
"""
|
"""
|
||||||
|
|
@ -163,27 +183,19 @@ class PlayerSession(async_chat):
|
||||||
|
|
||||||
self.msg("You are now logged in as %s." % (self.name,))
|
self.msg("You are now logged in as %s." % (self.name,))
|
||||||
pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(),), exclude=pobject)
|
pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(),), exclude=pobject)
|
||||||
cdat = {"session": self, "uinput":'look', "server": self.server}
|
cdat = {"session": self, "uinput":'look', "server": self.factory.server}
|
||||||
cmdhandler.handle(cdat)
|
cmdhandler.handle(cdat)
|
||||||
functions_general.log_infomsg("Login: %s" % (self,))
|
functions_general.log_infomsg("Login: %s" % (self,))
|
||||||
pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),))
|
pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),))
|
||||||
pobject.set_attribute("Lastsite", "%s" % (self.address[0],))
|
pobject.set_attribute("Lastsite", "%s" % (self.address,))
|
||||||
self.load_user_channels()
|
self.load_user_channels()
|
||||||
|
|
||||||
def msg(self, message):
|
def msg(self, message):
|
||||||
"""
|
"""
|
||||||
Sends a message with the newline/return included. Use this instead of
|
Sends a message to the session.
|
||||||
directly calling push().
|
|
||||||
"""
|
"""
|
||||||
self.push("%s\n\r" % (message,))
|
self.sendLine("%s" % (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):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
String representation of the user session class. We use
|
String representation of the user session class. We use
|
||||||
|
|
@ -194,6 +206,3 @@ class PlayerSession(async_chat):
|
||||||
else:
|
else:
|
||||||
symbol = '?'
|
symbol = '?'
|
||||||
return "<%s> %s@%s" % (symbol, self.name, self.address,)
|
return "<%s> %s@%s" % (symbol, self.name, self.address,)
|
||||||
|
|
||||||
# def handle_error(self):
|
|
||||||
# self.handle_close()
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import time
|
import time
|
||||||
from session import PlayerSession
|
|
||||||
import gameconf
|
import gameconf
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -8,13 +7,12 @@ Session manager, handles connected players.
|
||||||
# Our list of connected sessions.
|
# Our list of connected sessions.
|
||||||
session_list = []
|
session_list = []
|
||||||
|
|
||||||
def new_session(server, conn, addr):
|
def add_session(session):
|
||||||
"""
|
"""
|
||||||
Create and return a new session.
|
Adds a session to the session list.
|
||||||
"""
|
"""
|
||||||
session = PlayerSession(server, conn, addr)
|
|
||||||
session_list.insert(0, session)
|
session_list.insert(0, session)
|
||||||
return session
|
print 'Sessions active:', len(get_session_list())
|
||||||
|
|
||||||
def get_session_list():
|
def get_session_list():
|
||||||
"""
|
"""
|
||||||
|
|
@ -22,6 +20,13 @@ def get_session_list():
|
||||||
"""
|
"""
|
||||||
return session_list
|
return session_list
|
||||||
|
|
||||||
|
def disconnect_all_sessions():
|
||||||
|
"""
|
||||||
|
Cleanly disconnect all of the connected sessions.
|
||||||
|
"""
|
||||||
|
for sess in get_session_list():
|
||||||
|
sess.handle_close()
|
||||||
|
|
||||||
def check_all_sessions():
|
def check_all_sessions():
|
||||||
"""
|
"""
|
||||||
Check all currently connected sessions and see if any are dead.
|
Check all currently connected sessions and see if any are dead.
|
||||||
|
|
@ -38,14 +43,7 @@ def check_all_sessions():
|
||||||
if (time.time() - sess.cmd_last) > idle_timeout:
|
if (time.time() - sess.cmd_last) > idle_timeout:
|
||||||
sess.msg("Idle timeout exceeded, disconnecting.")
|
sess.msg("Idle timeout exceeded, disconnecting.")
|
||||||
sess.handle_close()
|
sess.handle_close()
|
||||||
## This doesn't seem to provide an accurate indication of timed out
|
|
||||||
## sessions.
|
|
||||||
#if not sess.writable() or not sess.readable():
|
|
||||||
# print 'Problematic Session:'
|
|
||||||
# print 'Readable ', sess.readable()
|
|
||||||
# print 'Writable ', sess.writable()
|
|
||||||
|
|
||||||
|
|
||||||
def remove_session(session):
|
def remove_session(session):
|
||||||
"""
|
"""
|
||||||
Removes a session from the session list.
|
Removes a session from the session list.
|
||||||
|
|
|
||||||
22
startup.sh
22
startup.sh
|
|
@ -1,25 +1,13 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export DJANGO_SETTINGS_MODULE="settings"
|
export DJANGO_SETTINGS_MODULE="settings"
|
||||||
|
|
||||||
## Uncomment whichever python binary you'd like to use to run the game.
|
|
||||||
## Evennia is developed on 2.5 but should be compatible with 2.4.
|
|
||||||
# PYTHON_BIN="python"
|
|
||||||
# PYTHON_BIN="python2.4"
|
|
||||||
PYTHON_BIN="python2.5"
|
|
||||||
|
|
||||||
## The name of your logfile.
|
|
||||||
LOGNAME="logs/evennia.log"
|
|
||||||
## Where to put the last log file from the game's last running
|
|
||||||
## on next startup.
|
|
||||||
LOGNAME_OLD="logs/evennia.log.old"
|
|
||||||
mv $LOGNAME $LOGNAME_OLD
|
|
||||||
|
|
||||||
## There are several different ways you can run the server, read the
|
## There are several different ways you can run the server, read the
|
||||||
## description for each and uncomment the desired mode.
|
## description for each and uncomment the desired mode.
|
||||||
|
|
||||||
## Generate profile data for use with cProfile.
|
## TODO: Make this accept a command line argument to use interactive
|
||||||
# $PYTHON_BIN -m cProfile -o profiler.log -s time server.py
|
## mode instead of having to uncomment crap.
|
||||||
|
|
||||||
## Interactive mode. Good for development and debugging.
|
## Interactive mode. Good for development and debugging.
|
||||||
#$PYTHON_BIN server.py
|
#twistd -noy twistd -ny server.py
|
||||||
## Stand-alone mode. Good for running games.
|
## Stand-alone mode. Good for running games.
|
||||||
nohup $PYTHON_BIN server.py > $LOGNAME &
|
twistd -ny server.py
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue