mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Mayor first overhaul of the evennia.py launcher. Not tested yet.
This commit is contained in:
parent
84483b7842
commit
2846e64833
1 changed files with 360 additions and 270 deletions
630
game/evennia.py
630
game/evennia.py
|
|
@ -8,71 +8,70 @@ Sets the appropriate environmental variables and launches the server
|
|||
and portal through the runner. Run without arguments to get a
|
||||
menu. Run the script with the -h flag to see usage information.
|
||||
|
||||
Usage:
|
||||
|
||||
evennia init <path> - creates a new game location, sets up a custom
|
||||
settings file and copies all templates to <path>
|
||||
evennia [settings][options] - handles server start/stop/restart if called
|
||||
from the game folder. Can be called outside
|
||||
the game folder if called with the path
|
||||
to the settings file.
|
||||
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
from optparse import OptionParser
|
||||
from subprocess import Popen
|
||||
import shutil
|
||||
import importlib
|
||||
import django
|
||||
|
||||
# Set the Python path up so we can get to settings.py from here.
|
||||
from argparse import ArgumentParser
|
||||
from subprocess import Popen
|
||||
from django.core import management
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
# Signal processing
|
||||
SIG = signal.SIGINT
|
||||
|
||||
# Check/Create settings
|
||||
# Set up the main python paths to Evennia
|
||||
EVENNIA_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
EVENNIA_BIN = os.path.join(EVENNIA_ROOT, "bin")
|
||||
EVENNIA_LIB = os.path.join(EVENNIA_ROOT, "lib")
|
||||
EVENNIA_RUNNER = os.path.join(EVENNIA_BIN, "runner.py")
|
||||
EVENNIA_TEMPLATE = os.path.join(EVENNIA_ROOT, "game_template")
|
||||
|
||||
_CREATED_SETTINGS = False
|
||||
if not os.path.exists('settings.py'):
|
||||
# If settings.py doesn't already exist, create it and populate it with some
|
||||
# basic stuff.
|
||||
EVENNIA_VERSION = "Unknown"
|
||||
TWISTED_BINARY = "twistd"
|
||||
|
||||
# make random secret_key.
|
||||
import random
|
||||
import string
|
||||
secret_key = list((string.letters +
|
||||
string.digits + string.punctuation).replace("\\", "").replace("'", '"'))
|
||||
random.shuffle(secret_key)
|
||||
secret_key = "".join(secret_key[:40])
|
||||
# Game directory structure
|
||||
SETTINGFILE = "settings.py"
|
||||
SERVERDIR = "server"
|
||||
CONFDIR = os.path.join(SERVERDIR, "conf")
|
||||
SETTINGS_PATH = os.path.join(CONFDIR, SETTINGFILE)
|
||||
SETTINGS_DOTPATH = "server.conf.settings"
|
||||
CURRENT_DIR = os.getcwd()
|
||||
GAMEDIR = CURRENT_DIR
|
||||
|
||||
settings_file = open('settings.py', 'w')
|
||||
_CREATED_SETTINGS = True
|
||||
# Operational setup
|
||||
SERVER_LOGFILE = None
|
||||
PORTAL_LOGFILE = None
|
||||
SERVER_PIDFILE = None
|
||||
PORTAL_PIDFILE = None
|
||||
SERVER_RESTART = None
|
||||
PORTAL_RESTART = None
|
||||
SERVER_PY_FILE = None
|
||||
PORTAL_PY_FILE = None
|
||||
|
||||
string = \
|
||||
# add Evennia root and bin dir to PYTHONPATH
|
||||
sys.path.insert(0, EVENNIA_ROOT)
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# Messages
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
WELCOME_MESSAGE = \
|
||||
"""
|
||||
######################################################################
|
||||
# Evennia MU* server configuration file
|
||||
#
|
||||
# You may customize your setup by copy&pasting the variables you want
|
||||
# to change from the master config file src/settings_default.py to
|
||||
# this file. Try to *only* copy over things you really need to customize
|
||||
# and do *not* make any changes to src/settings_default.py directly.
|
||||
# This way you'll always have a sane default to fall back on
|
||||
# (also, the master config file may change with server updates).
|
||||
#
|
||||
######################################################################
|
||||
|
||||
from src.settings_default import *
|
||||
|
||||
######################################################################
|
||||
# Custom settings
|
||||
######################################################################
|
||||
|
||||
|
||||
######################################################################
|
||||
# SECRET_KEY was randomly seeded when settings.py was first created.
|
||||
# Don't share this with anybody. It is used by Evennia to handle
|
||||
# cryptographic hashing for things like cookies on the web side.
|
||||
######################################################################
|
||||
SECRET_KEY = '%s'
|
||||
|
||||
""" % secret_key
|
||||
|
||||
settings_file.write(string)
|
||||
settings_file.close()
|
||||
|
||||
print """
|
||||
Welcome to Evennia!
|
||||
|
||||
No previous setting file was found so we created a fresh
|
||||
|
|
@ -87,81 +86,101 @@ SECRET_KEY = '%s'
|
|||
Make sure to create a superuser when asked. The superuser's
|
||||
email-address does not have to exist.
|
||||
"""
|
||||
sys.exit()
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Test the import of the settings file
|
||||
#------------------------------------------------------------
|
||||
try:
|
||||
from game import settings
|
||||
except Exception:
|
||||
import traceback
|
||||
string = "\n" + traceback.format_exc()
|
||||
WARNING_RUNSERVER = \
|
||||
"""
|
||||
WARNING: There is no need to run the Django development
|
||||
webserver to test out Evennia web features (the web client
|
||||
will in fact not work since the Django test server knows
|
||||
nothing about MUDs). Instead, just start Evennia with the
|
||||
webserver component active (this is the default).
|
||||
"""
|
||||
|
||||
# note - if this fails, ugettext will also fail, so we cannot translate this string.
|
||||
|
||||
string += """\n
|
||||
Error: Couldn't import the file 'settings.py' in the directory containing %(file)r.
|
||||
ERROR_SETTINGS = \
|
||||
"""
|
||||
ERROR: Could not import the file {settingsfile} from {settingspath}.
|
||||
There are usually two reasons for this:
|
||||
1) The settings module contains errors. Review the traceback above to resolve the
|
||||
problem, then try again.
|
||||
2) If you get errors on finding DJANGO_SETTINGS_MODULE you might have set up django
|
||||
wrong in some way. If you run a virtual machine, it might be worth to restart it
|
||||
to see if this resolves the issue. Evennia should not require you to define any
|
||||
environment variables manually.
|
||||
""" % {'file': __file__}
|
||||
print string
|
||||
sys.exit(1)
|
||||
1) The settings file is a normal Python module. It may contain a syntax error.
|
||||
Resolve the problem and try again.
|
||||
2) Django is not correctly installed. This usually shows by errors involving
|
||||
'DJANGO_SETTINGS_MODULE'. If you run a virtual machine, it might be worth to restart it
|
||||
to see if this resolves the issue.
|
||||
""".format(settingsfile=SETTINGFILE, settingspath=SETTINGS_PATH)
|
||||
|
||||
# set the settings location
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings'
|
||||
ERROR_DATABASE = \
|
||||
"""
|
||||
Your database does not seem to be set up correctly.
|
||||
(error was '{traceback}')
|
||||
|
||||
# required since django1.7.
|
||||
django.setup()
|
||||
Try to run
|
||||
|
||||
# signal processing
|
||||
SIG = signal.SIGINT
|
||||
python evennia.py
|
||||
|
||||
to initialize the database according to your settings.
|
||||
"""
|
||||
|
||||
ERROR_WINDOWS_WIN32API = \
|
||||
"""
|
||||
ERROR: Unable to import win32api, which Twisted requires to run.
|
||||
You may download it from:
|
||||
|
||||
http://sourceforge.net/projects/pywin32
|
||||
or
|
||||
http://starship.python.net/crew/mhammond/win32/Downloads.html
|
||||
"""
|
||||
|
||||
INFO_WINDOWS_BATFILE = \
|
||||
"""
|
||||
INFO: Since you are running Windows, a file 'twistd.bat' was
|
||||
created for you. This is a simple batch file that tries to call
|
||||
the twisted executable. Evennia determined this to be:
|
||||
|
||||
%(twistd_path)s
|
||||
|
||||
If you run into errors at startup you might need to edit
|
||||
twistd.bat to point to the actual location of the Twisted
|
||||
executable (usually called twistd.py) on your machine.
|
||||
|
||||
This procedure is only done once. Run evennia.py again when you
|
||||
are ready to start the server.
|
||||
"""
|
||||
|
||||
CMDLINE_HELP = \
|
||||
"""
|
||||
Main Evennia launcher. When starting in interactive (-i) mode, only
|
||||
the Server will do so since this is the most commonly useful setup. To
|
||||
activate interactive mode also for the Portal, use the menu or launch
|
||||
the two services one after the other as two separate calls to this
|
||||
program.
|
||||
"""
|
||||
"""
|
||||
Main Evennia launcher. When starting in interactive (-i) mode, only
|
||||
the Server will do so since this is the most commonly useful setup. To
|
||||
activate interactive mode also for the Portal, use the menu or launch
|
||||
the two services one after the other as two separate calls to this
|
||||
program.
|
||||
"""
|
||||
|
||||
|
||||
VERSION_INFO = \
|
||||
"""
|
||||
Evennia {version}
|
||||
{about}
|
||||
OS: {os}
|
||||
Python: {python}
|
||||
Twisted: {twisted}
|
||||
Django: {django}
|
||||
{south}
|
||||
"""
|
||||
"""
|
||||
Evennia {version}
|
||||
{about}
|
||||
OS: {os}
|
||||
Python: {python}
|
||||
Twisted: {twisted}
|
||||
Django: {django}
|
||||
"""
|
||||
|
||||
ABOUT_INFO= \
|
||||
"""
|
||||
MUD/MUX/MU* development system
|
||||
"""
|
||||
Evennia MUD/MUX/MU* development system
|
||||
|
||||
Licence: BSD 3-Clause Licence
|
||||
Web: http://www.evennia.com
|
||||
Irc: #evennia on FreeNode
|
||||
Forum: http://www.evennia.com/discussions
|
||||
Maintainer (2010-): Griatch (griatch AT gmail DOT com)
|
||||
Maintainer (2006-10): Greg Taylor
|
||||
"""
|
||||
Licence: BSD 3-Clause Licence
|
||||
Web: http://www.evennia.com
|
||||
Irc: #evennia on FreeNode
|
||||
Forum: http://www.evennia.com/discussions
|
||||
Maintainer (2010-): Griatch (griatch AT gmail DOT com)
|
||||
Maintainer (2006-10): Greg Taylor
|
||||
"""
|
||||
|
||||
HELP_ENTRY = \
|
||||
"""
|
||||
(version %s)
|
||||
|
||||
All launcher functionality can be accessed directly from the command
|
||||
line. See python evennia.py -h for options.
|
||||
See python evennia.py -h for controlling Evennia directly from
|
||||
the command line.
|
||||
|
||||
Evennia has two parts that both must run:
|
||||
|
||||
|
|
@ -212,89 +231,185 @@ MENU = \
|
|||
"""
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# System Configuration and setup
|
||||
# Functions
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
SERVER_PIDFILE = "server.pid"
|
||||
PORTAL_PIDFILE = "portal.pid"
|
||||
|
||||
SERVER_RESTART = "server.restart"
|
||||
PORTAL_RESTART = "portal.restart"
|
||||
|
||||
# Get the settings
|
||||
from django.conf import settings
|
||||
|
||||
from src.utils.utils import get_evennia_version
|
||||
EVENNIA_VERSION = get_evennia_version()
|
||||
|
||||
# Setup access of the evennia server itself
|
||||
SERVER_PY_FILE = os.path.join(settings.SRC_DIR, 'server/server.py')
|
||||
PORTAL_PY_FILE = os.path.join(settings.SRC_DIR, 'server/portal.py')
|
||||
|
||||
# Get logfile names
|
||||
SERVER_LOGFILE = settings.SERVER_LOG_FILE
|
||||
PORTAL_LOGFILE = settings.PORTAL_LOG_FILE
|
||||
|
||||
# Add this to the environmental variable for the 'twistd' command.
|
||||
currpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if 'PYTHONPATH' in os.environ:
|
||||
os.environ['PYTHONPATH'] += (":%s" % currpath)
|
||||
else:
|
||||
os.environ['PYTHONPATH'] = currpath
|
||||
|
||||
TWISTED_BINARY = 'twistd'
|
||||
if os.name == 'nt':
|
||||
# Windows needs more work to get the correct binary
|
||||
def evennia_version():
|
||||
"""
|
||||
Get the Evennia version info from the main package.
|
||||
"""
|
||||
version = "Unknown"
|
||||
with open(os.path.join(EVENNIA_ROOT, "VERSION.txt"), 'r') as f:
|
||||
version = f.read().strip()
|
||||
try:
|
||||
# Test for for win32api
|
||||
import win32api
|
||||
except ImportError:
|
||||
print """
|
||||
ERROR: Unable to import win32api, which Twisted requires to run.
|
||||
You may download it from:
|
||||
version = "%s(GIT %s)" % (version, os.popen("git rev-parse --short HEAD").read().strip())
|
||||
except IOError:
|
||||
pass
|
||||
return version
|
||||
|
||||
http://sourceforge.net/projects/pywin32
|
||||
or
|
||||
http://starship.python.net/crew/mhammond/win32/Downloads.html"""
|
||||
|
||||
def init_game_directory(path):
|
||||
"""
|
||||
Try to analyze the given path to find settings.py - this defines
|
||||
the game directory and also sets PYTHONPATH as well as the
|
||||
django path.
|
||||
"""
|
||||
global GAMEDIR
|
||||
if os.path.exists(os.path.join(path, SETTINGFILE)):
|
||||
# path given to server/conf/
|
||||
GAMEDIR = os.path.dirname(os.path.dirname(os.path.dirname(path)))
|
||||
elif os.path.exists(SETTINGS_PATH):
|
||||
# path given to somewhere else in gamedir
|
||||
GAMEDIR = os.path.dirname(os.path.dirname(path))
|
||||
else:
|
||||
# Assume path given to root game dir
|
||||
GAMEDIR = path
|
||||
|
||||
# set pythonpath to gamedir
|
||||
sys.path.insert(0, GAMEDIR)
|
||||
# set the settings location
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = SETTINGS_DOTPATH
|
||||
# required since django1.7.
|
||||
django.setup()
|
||||
|
||||
# check all dependencies
|
||||
from evennia.utils.utils import check_evennia_dependencies
|
||||
if not check_evennia_
|
||||
|
||||
|
||||
|
||||
# test existence of settings module
|
||||
try:
|
||||
settings = importlib.import_module(SETTINGS_DOTPATH)
|
||||
except Exception:
|
||||
import traceback
|
||||
print "\n" + traceback.format_exc()
|
||||
print ERROR_SETTINGS
|
||||
sys.exit()
|
||||
|
||||
if not os.path.exists('twistd.bat'):
|
||||
# Test for executable twisted batch file. This calls the twistd.py
|
||||
# executable that is usually not found on the path in Windows.
|
||||
# It's not enough to locate scripts.twistd, what we want is the
|
||||
# executable script C:\PythonXX/Scripts/twistd.py. Alas we cannot
|
||||
# hardcode this location since we don't know if user has Python
|
||||
# in a non-standard location, so we try to figure it out.
|
||||
from twisted.scripts import twistd
|
||||
twistd_path = os.path.abspath(
|
||||
os.path.join(os.path.dirname(twistd.__file__),
|
||||
os.pardir, os.pardir, os.pardir, os.pardir,
|
||||
'scripts', 'twistd.py'))
|
||||
bat_file = open('twistd.bat', 'w')
|
||||
bat_file.write("@\"%s\" \"%s\" %%*" % (sys.executable, twistd_path))
|
||||
bat_file.close()
|
||||
print """
|
||||
INFO: Since you are running Windows, a file 'twistd.bat' was
|
||||
created for you. This is a simple batch file that tries to call
|
||||
the twisted executable. Evennia determined this to be:
|
||||
# set up the Evennia executables and log file locations
|
||||
global SERVER_PY_FILE, PORTAL_PY_FILE
|
||||
global SERVER_LOGFILE, PORTAL_LOGFILE
|
||||
global SERVER_PIDFILE, PORTAL_PIDFILE
|
||||
global SERVER_RESTART, PORTAL_RESTART
|
||||
global EVENNIA_VERSION
|
||||
|
||||
%(twistd_path)s
|
||||
SERVER_PY_FILE = os.path.join(settings.LIB_DIR, "server/server.py")
|
||||
PORTAL_PY_FILE = os.path.join(settings.LIB_DIR, "portal/server.py")
|
||||
|
||||
If you run into errors at startup you might need to edit
|
||||
twistd.bat to point to the actual location of the Twisted
|
||||
executable (usually called twistd.py) on your machine.
|
||||
SERVER_PIDFILE = os.path.join(GAMEDIR, SERVERDIR, "server.pid")
|
||||
PORTAL_PIDFILE = os.path.join(GAMEDIR, SERVERDIR, "portal.pid")
|
||||
|
||||
This procedure is only done once. Run evennia.py again when you
|
||||
are ready to start the server.
|
||||
""" % {'twistd_path': twistd_path}
|
||||
sys.exit()
|
||||
SERVER_RESTART = os.path.join(GAMEDIR, SERVERDIR, "server.restart")
|
||||
PORTAL_RESTART = os.path.join(GAMEDIR, SERVERDIR, "portal.restart")
|
||||
|
||||
TWISTED_BINARY = 'twistd.bat'
|
||||
SERVER_LOGFILE = settings.SERVER_LOG_FILE
|
||||
PORTAL_LOGFILE = settings.PORTAL_LOG_FILE
|
||||
|
||||
# This also tests the library access
|
||||
from evennia.utils.utils import get_evennia_version
|
||||
EVENNIA_VERSION = get_evennia_version()
|
||||
|
||||
# set up twisted
|
||||
if os.name == 'nt':
|
||||
# We need to handle Windows twisted separately. We create a
|
||||
# batchfile in game/server, linking to the actual binary
|
||||
|
||||
global TWISTED_BINARY
|
||||
TWISTED_BINARY = "twistd.bat"
|
||||
|
||||
# add path so system can find the batfile
|
||||
sys.path.insert(0, os.path.join(GAMEDIR, SERVERDIR))
|
||||
|
||||
try:
|
||||
importlib.import_module("win32api")
|
||||
except ImportError:
|
||||
print ERROR_WINDOWS_WIN32API
|
||||
sys.exit()
|
||||
|
||||
if not os.path.exists(os.path.join(EVENNIA_BIN, TWISTED_BINARY)):
|
||||
# Test for executable twisted batch file. This calls the
|
||||
# twistd.py executable that is usually not found on the
|
||||
# path in Windows. It's not enough to locate
|
||||
# scripts.twistd, what we want is the executable script
|
||||
# C:\PythonXX/Scripts/twistd.py. Alas we cannot hardcode
|
||||
# this location since we don't know if user has Python in
|
||||
# a non-standard location. So we try to figure it out.
|
||||
twistd = importlib.import_module("twisted.scripts.twistd")
|
||||
twistd_dir = os.path.dirname(twistd.__file__)
|
||||
|
||||
# note that we hope the twistd package won't change here, since we
|
||||
# try to get to the executable by relative path.
|
||||
twistd_path = os.path.abspath(os.path.join(twistd_dir,
|
||||
os.pardir, os.pardir, os.pardir, os.pardir,
|
||||
'scripts', 'twistd.py'))
|
||||
|
||||
with open('twistd.bat', 'w') as bat_file:
|
||||
# build a custom bat file for windows
|
||||
bat_file.write("@\"%s\" \"%s\" %%*" % (sys.executable, twistd_path))
|
||||
|
||||
print INFO_WINDOWS_BATFILE.format(twistd_path=twistd_path)
|
||||
|
||||
|
||||
#
|
||||
# Check/Create settings
|
||||
#
|
||||
|
||||
def create_secret_key():
|
||||
"""
|
||||
Randomly create the secret key for the settings file
|
||||
"""
|
||||
import random
|
||||
import string
|
||||
secret_key = list((string.letters +
|
||||
string.digits + string.punctuation).replace("\\", "").replace("'", '"'))
|
||||
random.shuffle(secret_key)
|
||||
secret_key = "".join(secret_key[:40])
|
||||
return secret_key
|
||||
|
||||
|
||||
def create_settings_file():
|
||||
"""
|
||||
Uses the template settings file to build a working
|
||||
settings file.
|
||||
"""
|
||||
settings_path = os.path.join(GAMEDIR, "server", "conf", "settings.py")
|
||||
with open(settings_path, 'r') as f:
|
||||
settings_string = f.read()
|
||||
|
||||
# tweak the settings
|
||||
setting_dict = {"servername":"Evennia",
|
||||
"secret_key":create_secret_key}
|
||||
|
||||
# modify the settings
|
||||
settings_string.format(**setting_dict)
|
||||
|
||||
with open(settings_path, 'w') as f:
|
||||
f.write(settingsj_string)
|
||||
|
||||
|
||||
# Functions
|
||||
|
||||
def create_game_directory(dirname):
|
||||
"""
|
||||
Initialize a new game directory named dirname
|
||||
at the current path. This means copying the
|
||||
template directory from evennia's root.
|
||||
"""
|
||||
global GAMEDIR
|
||||
GAMEDIR = os.abspath(os.path.join(CURRENT_DIR, dirname))
|
||||
if os.path.exists(GAMEDIR):
|
||||
print "Cannot create new Evennia game dir: '%s' already exists." % dirname
|
||||
sys.exit()
|
||||
# copy template directory
|
||||
shutil.copytree(EVENNIA_TEMPLATE, GAMEDIR)
|
||||
# pre-build settings file in the new GAMEDIR
|
||||
create_settings_file()
|
||||
|
||||
|
||||
def get_pid(pidfile):
|
||||
"""
|
||||
Get the PID (Process ID) by trying to access
|
||||
|
|
@ -351,25 +466,19 @@ def show_version_info(about=False):
|
|||
import os, sys
|
||||
import twisted
|
||||
import django
|
||||
try:
|
||||
import south
|
||||
sversion = "South %s" % south.__version__
|
||||
except ImportError:
|
||||
sversion = "South <not installed>"
|
||||
|
||||
return VERSION_INFO.format(version=EVENNIA_VERSION,
|
||||
about=ABOUT_INFO if about else "",
|
||||
os=os.name, python=sys.version.split()[0],
|
||||
twisted=twisted.version.short(),
|
||||
django=django.get_version(),
|
||||
south=sversion)
|
||||
django=django.get_version())
|
||||
|
||||
def run_menu():
|
||||
"""
|
||||
This launches an interactive menu.
|
||||
"""
|
||||
|
||||
cmdstr = [sys.executable, "runner.py"]
|
||||
cmdstr = [sys.executable, EVENNIA_RUNNER]
|
||||
|
||||
while True:
|
||||
# menu loop
|
||||
|
|
@ -405,7 +514,10 @@ def run_menu():
|
|||
cmdstr.extend(['--iportal'])
|
||||
elif inp == 4:
|
||||
cmdstr.extend(['--iserver', '--iportal'])
|
||||
return cmdstr
|
||||
# start server
|
||||
cmdstr.append("start")
|
||||
Popen(cmdstr)
|
||||
return
|
||||
elif inp < 10:
|
||||
if inp == 5:
|
||||
if os.name == 'nt':
|
||||
|
|
@ -427,20 +539,18 @@ def run_menu():
|
|||
return
|
||||
else:
|
||||
print "Not a valid option."
|
||||
return None
|
||||
|
||||
|
||||
def handle_args(options, mode, service):
|
||||
def server_operation(mode, service, interactive):
|
||||
"""
|
||||
Handle argument options given on the command line.
|
||||
|
||||
options - parsed object for command line
|
||||
mode - str; start/stop etc
|
||||
service - str; server, portal or all
|
||||
interactive - bool; use interactive mode or daemon
|
||||
"""
|
||||
|
||||
inter = options.interactive
|
||||
cmdstr = [sys.executable, "runner.py"]
|
||||
cmdstr = [sys.executable, EVENNIA_RUNNER]
|
||||
errmsg = "The %s does not seem to be running."
|
||||
|
||||
if mode == 'start':
|
||||
|
|
@ -450,21 +560,23 @@ def handle_args(options, mode, service):
|
|||
|
||||
# starting one or many services
|
||||
if service == 'server':
|
||||
if inter:
|
||||
if interactive:
|
||||
cmdstr.append('--iserver')
|
||||
cmdstr.append('--noportal')
|
||||
elif service == 'portal':
|
||||
if inter:
|
||||
if interactive:
|
||||
cmdstr.append('--iportal')
|
||||
cmdstr.append('--noserver')
|
||||
management.call_command('collectstatic', verbosity=1, interactive=False)
|
||||
else: # all
|
||||
# for convenience we don't start logging of
|
||||
# portal, only of server with this command.
|
||||
if inter:
|
||||
if interactive:
|
||||
cmdstr.extend(['--iserver'])
|
||||
management.call_command('collectstatic', verbosity=1, interactive=False)
|
||||
return cmdstr
|
||||
# start the server
|
||||
cmdstr.append("start")
|
||||
Popen(cmdstr)
|
||||
|
||||
elif mode == 'reload':
|
||||
# restarting services
|
||||
|
|
@ -493,7 +605,6 @@ def handle_args(options, mode, service):
|
|||
else:
|
||||
kill(PORTAL_PIDFILE, SIG, "Portal stopped.", errmsg % 'Portal', PORTAL_RESTART, restart=False)
|
||||
kill(SERVER_PIDFILE, SIG, "Server stopped.", errmsg % 'Server', restart="shutdown")
|
||||
return None
|
||||
|
||||
|
||||
def error_check_python_modules():
|
||||
|
|
@ -504,20 +615,16 @@ def error_check_python_modules():
|
|||
the python source files themselves). Best they fail already here
|
||||
before we get any further.
|
||||
"""
|
||||
def imp(path, split=True):
|
||||
mod, fromlist = path, "None"
|
||||
if split:
|
||||
mod, fromlist = path.rsplit('.', 1)
|
||||
__import__(mod, fromlist=[fromlist])
|
||||
from django.conf import settings
|
||||
|
||||
# core modules
|
||||
imp(settings.COMMAND_PARSER)
|
||||
imp(settings.SEARCH_AT_RESULT)
|
||||
imp(settings.SEARCH_AT_MULTIMATCH_INPUT)
|
||||
imp(settings.CONNECTION_SCREEN_MODULE, split=False)
|
||||
importlib.import_module(settings.COMMAND_PARSER)
|
||||
importlib.import_module(settings.SEARCH_AT_RESULT)
|
||||
importlib.import_module(settings.SEARCH_AT_MULTIMATCH_INPUT)
|
||||
importlib.import_module(settings.CONNECTION_SCREEN_MODULE, split=False)
|
||||
#imp(settings.AT_INITIAL_SETUP_HOOK_MODULE, split=False)
|
||||
for path in settings.LOCK_FUNC_MODULES:
|
||||
imp(path, split=False)
|
||||
importlib.import_module(path, split=False)
|
||||
# cmdsets
|
||||
|
||||
deprstring = "settings.%s should be renamed to %s. If defaults are used, " \
|
||||
|
|
@ -541,12 +648,13 @@ def error_check_python_modules():
|
|||
if not cmdsethandler.import_cmdset(settings.CMDSET_CHARACTER, None): print "Warning: CMDSET_CHARACTER failed to load"
|
||||
if not cmdsethandler.import_cmdset(settings.CMDSET_PLAYER, None): print "Warning: CMDSET_PLAYER failed to load"
|
||||
# typeclasses
|
||||
imp(settings.BASE_PLAYER_TYPECLASS)
|
||||
imp(settings.BASE_OBJECT_TYPECLASS)
|
||||
imp(settings.BASE_CHARACTER_TYPECLASS)
|
||||
imp(settings.BASE_ROOM_TYPECLASS)
|
||||
imp(settings.BASE_EXIT_TYPECLASS)
|
||||
imp(settings.BASE_SCRIPT_TYPECLASS)
|
||||
importlib.import_module(settings.BASE_PLAYER_TYPECLASS)
|
||||
importlib.import_module(settings.BASE_OBJECT_TYPECLASS)
|
||||
importlib.import_module(settings.BASE_CHARACTER_TYPECLASS)
|
||||
importlib.import_module(settings.BASE_ROOM_TYPECLASS)
|
||||
importlib.import_module(settings.BASE_EXIT_TYPECLASS)
|
||||
importlib.import_module(settings.BASE_SCRIPT_TYPECLASS)
|
||||
|
||||
|
||||
def create_database():
|
||||
from django.core.management import call_command
|
||||
|
|
@ -554,32 +662,25 @@ def create_database():
|
|||
call_command("migrate", interactive=False)
|
||||
print "\n ... database initialized.\n"
|
||||
|
||||
|
||||
def create_superuser():
|
||||
from django.core.management import call_command
|
||||
print "\nCreate a superuser below. The superuser is Player #1, the 'owner' account of the server.\n"
|
||||
call_command("createsuperuser", interactive=True)
|
||||
|
||||
|
||||
def check_database(automigrate=False):
|
||||
# Check so a database exists and is accessible
|
||||
from django.db import DatabaseError
|
||||
from src.players.models import PlayerDB
|
||||
try:
|
||||
superuser = PlayerDB.objects.get(id=1)
|
||||
PlayerDB.objects.get(id=1)
|
||||
except DatabaseError, e:
|
||||
if automigrate:
|
||||
create_database()
|
||||
create_superuser()
|
||||
else:
|
||||
print """
|
||||
Your database does not seem to be set up correctly.
|
||||
(error was '%s')
|
||||
|
||||
Try to run
|
||||
|
||||
python evennia.py
|
||||
|
||||
to initialize the database according to your settings.
|
||||
""" % e
|
||||
print ERROR_DATABASE.format(traceback=e)
|
||||
sys.exit()
|
||||
except PlayerDB.DoesNotExist:
|
||||
# no superuser yet. We need to create it.
|
||||
|
|
@ -587,71 +688,60 @@ def check_database(automigrate=False):
|
|||
|
||||
def main():
|
||||
"""
|
||||
This handles command line input.
|
||||
Run the evennia main program.
|
||||
"""
|
||||
|
||||
parser = OptionParser(usage="%prog [-i] start|stop|reload|menu [server|portal]|manager args",
|
||||
# set up argument parser
|
||||
|
||||
parser = ArgumentParser(#usage="%prog [-i] start|stop|reload|menu [server|portal]|manager args",
|
||||
description=CMDLINE_HELP)
|
||||
parser.add_option('-i', '--interactive', action='store_true',
|
||||
parser.add_argument('-i', '--interactive', action='store_true',
|
||||
dest='interactive', default=False,
|
||||
help="Start given processes in interactive mode.")
|
||||
parser.add_option('-v', '--version', action='store_true',
|
||||
parser.add_argument('-v', '--version', action='store_true',
|
||||
dest='show_version', default=False,
|
||||
help="Show version info.")
|
||||
parser.add_argument('--init', action='store', dest="init", metavar="dirname")
|
||||
parser.add_argument('-c', '--config', action='store', dest="config", default=None)
|
||||
parser.add_argument("mode", default="menu")
|
||||
parser.add_argument("service", choices=["all", "server", "portal"], default="all")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args:
|
||||
if options.show_version:
|
||||
print show_version_info()
|
||||
return
|
||||
mode = "menu"
|
||||
service = 'all'
|
||||
if args:
|
||||
mode = args[0]
|
||||
service = "all"
|
||||
if len(args) > 1:
|
||||
service = args[1]
|
||||
# handle arguments
|
||||
|
||||
if mode in ["start", "menu"]:
|
||||
check_database(True)
|
||||
elif mode not in ["stop"]:
|
||||
check_database(False)
|
||||
if args.show_version:
|
||||
print show_version_info()
|
||||
|
||||
if mode not in ['menu', 'start', 'reload', 'stop']:
|
||||
from django.core.management import call_command
|
||||
call_command(mode)
|
||||
sys.exit()
|
||||
if service not in ['server', 'portal', 'all']:
|
||||
print "service should be none, 'server', 'portal' or 'all'."
|
||||
mode, service = args.mode, args.service
|
||||
|
||||
if args.init:
|
||||
create_game_directory(args.init)
|
||||
sys.exit()
|
||||
|
||||
# this must be done first - it sets up all the global properties
|
||||
# and initializes django for the game directory
|
||||
init_game_directory(CURRENT_DIR)
|
||||
|
||||
if mode == 'menu':
|
||||
# launch menu
|
||||
cmdstr = run_menu()
|
||||
# launch menu for operation
|
||||
check_database(True)
|
||||
run_menu()
|
||||
elif mode in ('start', 'reload', 'stop'):
|
||||
# operate the server directly
|
||||
if mode != "stop":
|
||||
check_database(False)
|
||||
server_operation(mode, service, args.interactive)
|
||||
else:
|
||||
# handle command-line arguments
|
||||
cmdstr = handle_args(options, mode, service)
|
||||
if cmdstr:
|
||||
# call the runner.
|
||||
cmdstr.append('start')
|
||||
Popen(cmdstr)
|
||||
# pass-through to django manager
|
||||
from django.core.management import call_command
|
||||
call_command(mode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# start Evennia
|
||||
# start Evennia from the command line
|
||||
|
||||
if _CREATED_SETTINGS:
|
||||
# if settings were created, info has already been printed.
|
||||
sys.exit()
|
||||
|
||||
from src.utils.utils import check_evennia_dependencies
|
||||
if check_evennia_dependencies():
|
||||
if len(sys.argv) > 1 and sys.argv[1] in ('runserver', 'testserver'):
|
||||
print """
|
||||
WARNING: There is no need to run the Django development
|
||||
webserver to test out Evennia web features (the web client
|
||||
will in fact not work since the Django test server knows
|
||||
nothing about MUDs). Instead, just start Evennia with the
|
||||
webserver component active (this is the default).
|
||||
"""
|
||||
print WARNING_RUNSERVER
|
||||
main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue