Make PEP8 cleanup of line spaces and character distances as well as indents
This commit is contained in:
parent
7ff783fea1
commit
b278337172
189 changed files with 2039 additions and 1583 deletions
|
|
@ -19,4 +19,6 @@ class ServerConfigAdmin(admin.ModelAdmin):
|
|||
save_as = True
|
||||
save_on_top = True
|
||||
list_select_related = True
|
||||
|
||||
|
||||
admin.site.register(ServerConfig, ServerConfigAdmin)
|
||||
|
|
|
|||
|
|
@ -319,8 +319,12 @@ class FunctionCall(amp.Command):
|
|||
|
||||
# Helper functions for pickling.
|
||||
|
||||
dumps = lambda data: to_str(pickle.dumps(to_str(data), pickle.HIGHEST_PROTOCOL))
|
||||
loads = lambda data: pickle.loads(to_str(data))
|
||||
def dumps(data):
|
||||
return to_str(pickle.dumps(to_str(data), pickle.HIGHEST_PROTOCOL))
|
||||
|
||||
|
||||
def loads(data):
|
||||
return pickle.loads(to_str(data))
|
||||
|
||||
|
||||
# -------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ checks for.
|
|||
These all print to the terminal.
|
||||
"""
|
||||
|
||||
|
||||
def check_errors(settings):
|
||||
"""
|
||||
Check for deprecations that are critical errors and should stop
|
||||
|
|
@ -52,10 +53,10 @@ def check_errors(settings):
|
|||
raise DeprecationWarning(deprstring % "CHANNEL_TYPECLASS_PATHS")
|
||||
if hasattr(settings, "SEARCH_MULTIMATCH_SEPARATOR"):
|
||||
raise DeprecationWarning(
|
||||
"settings.SEARCH_MULTIMATCH_SEPARATOR was replaced by "
|
||||
"SEARCH_MULTIMATCH_REGEX and SEARCH_MULTIMATCH_TEMPLATE. "
|
||||
"Update your settings file (see evennia/settings_default.py "
|
||||
"for more info).")
|
||||
"settings.SEARCH_MULTIMATCH_SEPARATOR was replaced by "
|
||||
"SEARCH_MULTIMATCH_REGEX and SEARCH_MULTIMATCH_TEMPLATE. "
|
||||
"Update your settings file (see evennia/settings_default.py "
|
||||
"for more info).")
|
||||
|
||||
gametime_deprecation = ("The settings TIME_SEC_PER_MIN, TIME_MIN_PER_HOUR,"
|
||||
"TIME_HOUR_PER_DAY, TIME_DAY_PER_WEEK, \n"
|
||||
|
|
@ -65,8 +66,8 @@ def check_errors(settings):
|
|||
"and manipulate these time units, the tools from utils.gametime "
|
||||
"are now found in contrib/convert_gametime.py instead.")
|
||||
if any(hasattr(settings, value) for value in ("TIME_SEC_PER_MIN", "TIME_MIN_PER_HOUR",
|
||||
"TIME_HOUR_PER_DAY", "TIME_DAY_PER_WEEK", "TIME_WEEK_PER_MONTH",
|
||||
"TIME_MONTH_PER_YEAR")):
|
||||
"TIME_HOUR_PER_DAY", "TIME_DAY_PER_WEEK", "TIME_WEEK_PER_MONTH",
|
||||
"TIME_MONTH_PER_YEAR")):
|
||||
raise DeprecationWarning(gametime_deprecation)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import django
|
|||
|
||||
# Signal processing
|
||||
SIG = signal.SIGINT
|
||||
CTRL_C_EVENT = 0 # Windows SIGINT-like signal
|
||||
CTRL_C_EVENT = 0 # Windows SIGINT-like signal
|
||||
|
||||
# Set up the main python paths to Evennia
|
||||
EVENNIA_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
|
@ -101,7 +101,7 @@ CREATED_NEW_GAMEDIR = \
|
|||
"""
|
||||
|
||||
ERROR_INPUT = \
|
||||
"""
|
||||
"""
|
||||
Command
|
||||
{args} {kwargs}
|
||||
raised an error: '{traceback}'.
|
||||
|
|
@ -419,6 +419,7 @@ def evennia_version():
|
|||
pass
|
||||
return version
|
||||
|
||||
|
||||
EVENNIA_VERSION = evennia_version()
|
||||
|
||||
|
||||
|
|
@ -434,7 +435,7 @@ def check_main_evennia_dependencies():
|
|||
error = False
|
||||
|
||||
# Python
|
||||
pversion = ".".join(str(num) for num in sys.version_info if type(num) == int)
|
||||
pversion = ".".join(str(num) for num in sys.version_info if isinstance(num, int))
|
||||
if LooseVersion(pversion) < LooseVersion(PYTHON_MIN):
|
||||
print(ERROR_PYTHON_VERSION.format(pversion=pversion, python_min=PYTHON_MIN))
|
||||
error = True
|
||||
|
|
@ -451,7 +452,7 @@ def check_main_evennia_dependencies():
|
|||
error = True
|
||||
# Django
|
||||
try:
|
||||
dversion = ".".join(str(num) for num in django.VERSION if type(num) == int)
|
||||
dversion = ".".join(str(num) for num in django.VERSION if isinstance(num, int))
|
||||
# only the main version (1.5, not 1.5.4.0)
|
||||
dversion_main = ".".join(dversion.split(".")[:2])
|
||||
if LooseVersion(dversion) < LooseVersion(DJANGO_MIN):
|
||||
|
|
@ -502,8 +503,8 @@ def create_secret_key():
|
|||
import random
|
||||
import string
|
||||
secret_key = list((string.letters +
|
||||
string.digits + string.punctuation).replace("\\", "")\
|
||||
.replace("'", '"').replace("{","_").replace("}","-"))
|
||||
string.digits + string.punctuation).replace("\\", "")
|
||||
.replace("'", '"').replace("{", "_").replace("}", "-"))
|
||||
random.shuffle(secret_key)
|
||||
secret_key = "".join(secret_key[:40])
|
||||
return secret_key
|
||||
|
|
@ -600,7 +601,7 @@ def check_database():
|
|||
# Check so a database exists and is accessible
|
||||
from django.db import connection
|
||||
tables = connection.introspection.get_table_list(connection.cursor())
|
||||
if not tables or not isinstance(tables[0], basestring): # django 1.8+
|
||||
if not tables or not isinstance(tables[0], basestring): # django 1.8+
|
||||
tables = [tableinfo.name for tableinfo in tables]
|
||||
if tables and u'accounts_accountdb' in tables:
|
||||
# database exists and seems set up. Initialize evennia.
|
||||
|
|
@ -741,8 +742,8 @@ def kill(pidfile, killsignal=SIG, succmsg="", errmsg="",
|
|||
os.kill(int(pid), killsignal)
|
||||
|
||||
except OSError:
|
||||
print("Process %(pid)s cannot be stopped. "\
|
||||
"The PID file 'server/%(pidfile)s' seems stale. "\
|
||||
print("Process %(pid)s cannot be stopped. "
|
||||
"The PID file 'server/%(pidfile)s' seems stale. "
|
||||
"Try removing it." % {'pid': pid, 'pidfile': pidfile})
|
||||
return
|
||||
print("Evennia:", succmsg)
|
||||
|
|
@ -782,6 +783,7 @@ def error_check_python_modules():
|
|||
"""
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
def _imp(path, split=True):
|
||||
"helper method"
|
||||
mod, fromlist = path, "None"
|
||||
|
|
@ -821,6 +823,7 @@ def error_check_python_modules():
|
|||
_imp(settings.BASE_EXIT_TYPECLASS)
|
||||
_imp(settings.BASE_SCRIPT_TYPECLASS)
|
||||
|
||||
|
||||
def init_game_directory(path, check_db=True):
|
||||
"""
|
||||
Try to analyze the given path to find settings.py - this defines
|
||||
|
|
@ -888,10 +891,10 @@ def init_game_directory(path, check_db=True):
|
|||
# verify existence of log file dir (this can be missing e.g.
|
||||
# if the game dir itself was cloned since log files are in .gitignore)
|
||||
logdirs = [logfile.rsplit(os.path.sep, 1)
|
||||
for logfile in (SERVER_LOGFILE, PORTAL_LOGFILE, HTTP_LOGFILE)]
|
||||
for logfile in (SERVER_LOGFILE, PORTAL_LOGFILE, HTTP_LOGFILE)]
|
||||
if not all(os.path.isdir(pathtup[0]) for pathtup in logdirs):
|
||||
errstr = "\n ".join("%s (log file %s)" % (pathtup[0], pathtup[1]) for pathtup in logdirs
|
||||
if not os.path.isdir(pathtup[0]))
|
||||
if not os.path.isdir(pathtup[0]))
|
||||
print(ERROR_LOGDIR_MISSING.format(logfiles=errstr))
|
||||
sys.exit()
|
||||
|
||||
|
|
@ -985,7 +988,7 @@ def list_settings(keys):
|
|||
table = evtable.EvTable()
|
||||
confs = [key for key in sorted(evsettings.__dict__) if key.isupper()]
|
||||
for i in range(0, len(confs), 4):
|
||||
table.add_row(*confs[i:i+4])
|
||||
table.add_row(*confs[i:i + 4])
|
||||
else:
|
||||
# a specific key
|
||||
table = evtable.EvTable(width=131)
|
||||
|
|
@ -1165,8 +1168,8 @@ def server_operation(mode, service, interactive, profiler, logserver=False, doex
|
|||
elif mode == 'stop':
|
||||
if os.name == "nt":
|
||||
print (
|
||||
"(Obs: You can use a single Ctrl-C to skip "
|
||||
"Windows' annoying 'Terminate batch job (Y/N)?' prompts.)")
|
||||
"(Obs: You can use a single Ctrl-C to skip "
|
||||
"Windows' annoying 'Terminate batch job (Y/N)?' prompts.)")
|
||||
# stop processes, avoiding reload
|
||||
if service == 'server':
|
||||
kill(SERVER_PIDFILE, SIG,
|
||||
|
|
@ -1237,7 +1240,7 @@ def main():
|
|||
help=("Which component to operate on: "
|
||||
"'server', 'portal' or 'all' (default if not set)."))
|
||||
parser.epilog = (
|
||||
"Common usage: evennia start|stop|reload. Django-admin database commands:"
|
||||
"Common usage: evennia start|stop|reload. Django-admin database commands:"
|
||||
"evennia migration|flush|shell|dbshell (see the django documentation for more django-admin commands.)")
|
||||
|
||||
args, unknown_args = parser.parse_known_args()
|
||||
|
|
@ -1275,7 +1278,6 @@ def main():
|
|||
print("Using settings file '%s' (%s)." % (
|
||||
SETTINGSFILE, SETTINGS_DOTPATH))
|
||||
|
||||
|
||||
if args.initsettings:
|
||||
# create new settings file
|
||||
global GAMEDIR
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ import os
|
|||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from subprocess import Popen
|
||||
import Queue, thread
|
||||
import Queue
|
||||
import thread
|
||||
import evennia
|
||||
|
||||
try:
|
||||
|
|
@ -35,7 +36,7 @@ EVENNIA_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||
EVENNIA_BIN = os.path.join(EVENNIA_ROOT, "bin")
|
||||
EVENNIA_LIB = os.path.dirname(evennia.__file__)
|
||||
|
||||
SERVER_PY_FILE = os.path.join(EVENNIA_LIB,'server', 'server.py')
|
||||
SERVER_PY_FILE = os.path.join(EVENNIA_LIB, 'server', 'server.py')
|
||||
PORTAL_PY_FILE = os.path.join(EVENNIA_LIB, 'server', 'portal', 'portal.py')
|
||||
|
||||
GAMEDIR = None
|
||||
|
|
@ -79,6 +80,7 @@ PROCESS_DOEXIT = "Deferring to external runner."
|
|||
|
||||
# Functions
|
||||
|
||||
|
||||
def set_restart_mode(restart_file, flag="reload"):
|
||||
"""
|
||||
This sets a flag file for the restart mode.
|
||||
|
|
@ -203,14 +205,14 @@ def start_services(server_argv, portal_argv, doexit=False):
|
|||
|
||||
# restart only if process stopped cleanly
|
||||
if (message == "server_stopped" and int(rc) == 0 and
|
||||
get_restart_mode(SERVER_RESTART) in ("True", "reload", "reset")):
|
||||
get_restart_mode(SERVER_RESTART) in ("True", "reload", "reset")):
|
||||
print(PROCESS_RESTART.format(component="Server"))
|
||||
SERVER = thread.start_new_thread(server_waiter, (processes, ))
|
||||
continue
|
||||
|
||||
# normally the portal is not reloaded since it's run as a daemon.
|
||||
if (message == "portal_stopped" and int(rc) == 0 and
|
||||
get_restart_mode(PORTAL_RESTART) == "True"):
|
||||
get_restart_mode(PORTAL_RESTART) == "True"):
|
||||
print(PROCESS_RESTART.format(component="Portal"))
|
||||
PORTAL = thread.start_new_thread(portal_waiter, (processes, ))
|
||||
continue
|
||||
|
|
@ -296,8 +298,8 @@ def main():
|
|||
|
||||
pid = get_pid(SERVER_PIDFILE)
|
||||
if pid and not args.noserver:
|
||||
print("\nEvennia Server is already running as process %(pid)s. Not restarted." % {'pid': pid})
|
||||
args.noserver = True
|
||||
print("\nEvennia Server is already running as process %(pid)s. Not restarted." % {'pid': pid})
|
||||
args.noserver = True
|
||||
if args.noserver:
|
||||
server_argv = None
|
||||
else:
|
||||
|
|
@ -350,5 +352,6 @@ def main():
|
|||
# Start processes
|
||||
start_services(server_argv, portal_argv, doexit=args.doexit)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -35,7 +35,11 @@ _IDLE_COMMAND = settings.IDLE_COMMAND
|
|||
_IDLE_COMMAND = (_IDLE_COMMAND, ) if _IDLE_COMMAND == "idle" else (_IDLE_COMMAND, "idle")
|
||||
_GA = object.__getattribute__
|
||||
_SA = object.__setattr__
|
||||
_NA = lambda o: "N/A"
|
||||
|
||||
|
||||
def _NA(o):
|
||||
return "N/A"
|
||||
|
||||
|
||||
_ERROR_INPUT = "Inputfunc {name}({session}): Wrong/unrecognized input: {inp}"
|
||||
|
||||
|
|
@ -58,8 +62,8 @@ def text(session, *args, **kwargs):
|
|||
|
||||
txt = args[0] if args else None
|
||||
|
||||
#explicitly check for None since text can be an empty string, which is
|
||||
#also valid
|
||||
# explicitly check for None since text can be an empty string, which is
|
||||
# also valid
|
||||
if txt is None:
|
||||
return
|
||||
# this is treated as a command input
|
||||
|
|
@ -72,10 +76,10 @@ def text(session, *args, **kwargs):
|
|||
puppet = session.puppet
|
||||
if puppet:
|
||||
txt = puppet.nicks.nickreplace(txt,
|
||||
categories=("inputline", "channel"), include_account=True)
|
||||
categories=("inputline", "channel"), include_account=True)
|
||||
else:
|
||||
txt = session.account.nicks.nickreplace(txt,
|
||||
categories=("inputline", "channel"), include_account=False)
|
||||
categories=("inputline", "channel"), include_account=False)
|
||||
kwargs.pop("options", None)
|
||||
cmdhandler(session, txt, callertype="session", session=session, **kwargs)
|
||||
session.update_session_counters()
|
||||
|
|
@ -123,11 +127,11 @@ def default(session, cmdname, *args, **kwargs):
|
|||
|
||||
"""
|
||||
err = "Session {sessid}: Input command not recognized:\n" \
|
||||
" name: '{cmdname}'\n" \
|
||||
" args, kwargs: {args}, {kwargs}".format(sessid=session.sessid,
|
||||
cmdname=cmdname,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
" name: '{cmdname}'\n" \
|
||||
" args, kwargs: {args}, {kwargs}".format(sessid=session.sessid,
|
||||
cmdname=cmdname,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
if session.protocol_flags.get("INPUTDEBUG", False):
|
||||
session.msg(err)
|
||||
log_err(err)
|
||||
|
|
@ -153,15 +157,12 @@ def browser_sessid(session, *args, **kwargs):
|
|||
uid = browsersession.get("logged_in", None)
|
||||
if uid:
|
||||
try:
|
||||
account = AccountDB.objects.get(pk=uid)
|
||||
account = AccountDB.objects.get(pk=uid)
|
||||
except Exception:
|
||||
return
|
||||
session.sessionhandler.login(session, account)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def client_options(session, *args, **kwargs):
|
||||
"""
|
||||
This allows the client an OOB way to inform us about its name and capabilities.
|
||||
|
|
@ -189,12 +190,12 @@ def client_options(session, *args, **kwargs):
|
|||
if not kwargs or kwargs.get("get", False):
|
||||
# return current settings
|
||||
options = dict((key, flags[key]) for key in flags
|
||||
if key.upper() in ("ANSI", "XTERM256", "MXP",
|
||||
"UTF-8", "SCREENREADER", "ENCODING",
|
||||
"MCCP", "SCREENHEIGHT",
|
||||
"SCREENWIDTH", "INPUTDEBUG",
|
||||
"RAW", "NOCOLOR",
|
||||
"NOGOAHEAD"))
|
||||
if key.upper() in ("ANSI", "XTERM256", "MXP",
|
||||
"UTF-8", "SCREENREADER", "ENCODING",
|
||||
"MCCP", "SCREENHEIGHT",
|
||||
"SCREENWIDTH", "INPUTDEBUG",
|
||||
"RAW", "NOCOLOR",
|
||||
"NOGOAHEAD"))
|
||||
session.msg(client_options=options)
|
||||
return
|
||||
|
||||
|
|
@ -248,17 +249,18 @@ def client_options(session, *args, **kwargs):
|
|||
elif key == "nogoahead":
|
||||
flags["NOGOAHEAD"] = validate_bool(value)
|
||||
elif key in ('Char 1', 'Char.Skills 1', 'Char.Items 1',
|
||||
'Room 1', 'IRE.Rift 1', 'IRE.Composer 1'):
|
||||
'Room 1', 'IRE.Rift 1', 'IRE.Composer 1'):
|
||||
# ignore mudlet's default send (aimed at IRE games)
|
||||
pass
|
||||
elif not key in ("options", "cmdid"):
|
||||
elif key not in ("options", "cmdid"):
|
||||
err = _ERROR_INPUT.format(
|
||||
name="client_settings", session=session, inp=key)
|
||||
name="client_settings", session=session, inp=key)
|
||||
session.msg(text=err)
|
||||
session.protocol_flags = flags
|
||||
# we must update the portal as well
|
||||
session.sessionhandler.session_portal_sync(session)
|
||||
|
||||
|
||||
# GMCP alias
|
||||
hello = client_options
|
||||
supports_set = client_options
|
||||
|
|
@ -298,6 +300,7 @@ def login(session, *args, **kwargs):
|
|||
if account:
|
||||
session.sessionhandler.login(session, account)
|
||||
|
||||
|
||||
_gettable = {
|
||||
"name": lambda obj: obj.key,
|
||||
"key": lambda obj: obj.key,
|
||||
|
|
@ -305,6 +308,7 @@ _gettable = {
|
|||
"servername": lambda obj: settings.SERVERNAME
|
||||
}
|
||||
|
||||
|
||||
def get_value(session, *args, **kwargs):
|
||||
"""
|
||||
Return the value of a given attribute or db_property on the
|
||||
|
|
@ -335,7 +339,7 @@ def _testrepeat(**kwargs):
|
|||
|
||||
|
||||
_repeatable = {"test1": _testrepeat, # example only
|
||||
"test2": _testrepeat} # "
|
||||
"test2": _testrepeat} # "
|
||||
|
||||
|
||||
def repeat(session, *args, **kwargs):
|
||||
|
|
@ -368,7 +372,6 @@ def repeat(session, *args, **kwargs):
|
|||
session.msg("Allowed repeating functions are: %s" % (", ".join(_repeatable)))
|
||||
|
||||
|
||||
|
||||
def unrepeat(session, *args, **kwargs):
|
||||
"Wrapper for OOB use"
|
||||
kwargs["stop"] = True
|
||||
|
|
@ -415,7 +418,7 @@ def monitor(session, *args, **kwargs):
|
|||
else:
|
||||
# the handler will add fieldname and obj to the kwargs automatically
|
||||
MONITOR_HANDLER.add(obj, field_name, _on_monitor_change, idstring=session.sessid,
|
||||
persistent=False, name=name, session=session)
|
||||
persistent=False, name=name, session=session)
|
||||
|
||||
|
||||
def unmonitor(session, *args, **kwargs):
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class ServerConfigManager(models.Manager):
|
|||
the server at run-time.
|
||||
|
||||
"""
|
||||
|
||||
def conf(self, key=None, value=None, delete=False, default=None):
|
||||
"""
|
||||
Add, retrieve and manipulate config values.
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ IRC_COLOR_MAP = dict([
|
|||
(r'|[c', IRC_COLOR + IRC_NORMAL + "," + IRC_DCYAN),
|
||||
(r'|[w', IRC_COLOR + IRC_NORMAL + "," + IRC_GRAY), # light grey background
|
||||
(r'|[x', IRC_COLOR + IRC_NORMAL + "," + IRC_BLACK) # pure black background
|
||||
])
|
||||
])
|
||||
RE_IRC_COLOR = re.compile(r"|".join([re.escape(key) for key in viewkeys(IRC_COLOR_MAP)]), re.DOTALL)
|
||||
RE_MXP = re.compile(r'\|lc(.*?)\|lt(.*?)\|le', re.DOTALL)
|
||||
RE_ANSI_ESCAPES = re.compile(r"(%s)" % "|".join(("{{", "%%", "\\\\")), re.DOTALL)
|
||||
|
|
|
|||
|
|
@ -22,12 +22,14 @@ MSSP_VAL = chr(2)
|
|||
# try to get the customized mssp info, if it exists.
|
||||
MSSPTable_CUSTOM = utils.variable_from_module(settings.MSSP_META_MODULE, "MSSPTable", default={})
|
||||
|
||||
|
||||
class Mssp(object):
|
||||
"""
|
||||
Implements the MSSP protocol. Add this to a variable on the telnet
|
||||
protocol to set it up.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, protocol):
|
||||
"""
|
||||
initialize MSSP by storing protocol on ourselves and calling
|
||||
|
|
@ -80,108 +82,108 @@ class Mssp(object):
|
|||
|
||||
"""
|
||||
|
||||
self.mssp_table = {
|
||||
self.mssp_table = {
|
||||
|
||||
# Required fields
|
||||
# Required fields
|
||||
|
||||
"NAME": "Evennia",
|
||||
"PLAYERS": self.get_player_count,
|
||||
"UPTIME" : self.get_uptime,
|
||||
"NAME": "Evennia",
|
||||
"PLAYERS": self.get_player_count,
|
||||
"UPTIME": self.get_uptime,
|
||||
|
||||
# Generic
|
||||
# Generic
|
||||
|
||||
"CRAWL DELAY": "-1",
|
||||
"CRAWL DELAY": "-1",
|
||||
|
||||
"HOSTNAME": "", # current or new hostname
|
||||
"PORT": ["4000"], # most important port should be last in list
|
||||
"CODEBASE": "Evennia",
|
||||
"CONTACT": "", # email for contacting the mud
|
||||
"CREATED": "", # year MUD was created
|
||||
"ICON": "", # url to icon 32x32 or larger; <32kb.
|
||||
"IP": "", # current or new IP address
|
||||
"LANGUAGE": "", # name of language used, e.g. English
|
||||
"LOCATION": "", # full English name of server country
|
||||
"MINIMUM AGE": "0", # set to 0 if not applicable
|
||||
"WEBSITE": "www.evennia.com",
|
||||
"HOSTNAME": "", # current or new hostname
|
||||
"PORT": ["4000"], # most important port should be last in list
|
||||
"CODEBASE": "Evennia",
|
||||
"CONTACT": "", # email for contacting the mud
|
||||
"CREATED": "", # year MUD was created
|
||||
"ICON": "", # url to icon 32x32 or larger; <32kb.
|
||||
"IP": "", # current or new IP address
|
||||
"LANGUAGE": "", # name of language used, e.g. English
|
||||
"LOCATION": "", # full English name of server country
|
||||
"MINIMUM AGE": "0", # set to 0 if not applicable
|
||||
"WEBSITE": "www.evennia.com",
|
||||
|
||||
# Categorisation
|
||||
# Categorisation
|
||||
|
||||
"FAMILY": "Custom", # evennia goes under 'Custom'
|
||||
"GENRE": "None", # Adult, Fantasy, Historical, Horror, Modern, None, or Science Fiction
|
||||
"GAMEPLAY": "None", # Adventure, Educational, Hack and Slash, None,
|
||||
# Player versus Player, Player versus Environment,
|
||||
# Roleplaying, Simulation, Social or Strategy
|
||||
"STATUS": "Open Beta", # Alpha, Closed Beta, Open Beta, Live
|
||||
"GAMESYSTEM": "Custom", # D&D, d20 System, World of Darkness, etc. Use Custom if homebrew
|
||||
"SUBGENRE": "None", # LASG, Medieval Fantasy, World War II, Frankenstein,
|
||||
# Cyberpunk, Dragonlance, etc. Or None if not available.
|
||||
"FAMILY": "Custom", # evennia goes under 'Custom'
|
||||
"GENRE": "None", # Adult, Fantasy, Historical, Horror, Modern, None, or Science Fiction
|
||||
"GAMEPLAY": "None", # Adventure, Educational, Hack and Slash, None,
|
||||
# Player versus Player, Player versus Environment,
|
||||
# Roleplaying, Simulation, Social or Strategy
|
||||
"STATUS": "Open Beta", # Alpha, Closed Beta, Open Beta, Live
|
||||
"GAMESYSTEM": "Custom", # D&D, d20 System, World of Darkness, etc. Use Custom if homebrew
|
||||
"SUBGENRE": "None", # LASG, Medieval Fantasy, World War II, Frankenstein,
|
||||
# Cyberpunk, Dragonlance, etc. Or None if not available.
|
||||
|
||||
# World
|
||||
# World
|
||||
|
||||
"AREAS": "0",
|
||||
"HELPFILES": "0",
|
||||
"MOBILES": "0",
|
||||
"OBJECTS": "0",
|
||||
"ROOMS": "0", # use 0 if room-less
|
||||
"CLASSES": "0", # use 0 if class-less
|
||||
"LEVELS": "0", # use 0 if level-less
|
||||
"RACES": "0", # use 0 if race-less
|
||||
"SKILLS": "0", # use 0 if skill-less
|
||||
"AREAS": "0",
|
||||
"HELPFILES": "0",
|
||||
"MOBILES": "0",
|
||||
"OBJECTS": "0",
|
||||
"ROOMS": "0", # use 0 if room-less
|
||||
"CLASSES": "0", # use 0 if class-less
|
||||
"LEVELS": "0", # use 0 if level-less
|
||||
"RACES": "0", # use 0 if race-less
|
||||
"SKILLS": "0", # use 0 if skill-less
|
||||
|
||||
# Protocols set to 1 or 0)
|
||||
# Protocols set to 1 or 0)
|
||||
|
||||
"ANSI": "1",
|
||||
"GMCP": "0",
|
||||
"ATCP": "0",
|
||||
"MCCP": "0",
|
||||
"MCP": "0",
|
||||
"MSDP": "0",
|
||||
"MSP": "0",
|
||||
"MXP": "0",
|
||||
"PUEBLO": "0",
|
||||
"SSL": "1",
|
||||
"UTF-8": "1",
|
||||
"ZMP": "0",
|
||||
"VT100": "0",
|
||||
"XTERM 256 COLORS": "0",
|
||||
"ANSI": "1",
|
||||
"GMCP": "0",
|
||||
"ATCP": "0",
|
||||
"MCCP": "0",
|
||||
"MCP": "0",
|
||||
"MSDP": "0",
|
||||
"MSP": "0",
|
||||
"MXP": "0",
|
||||
"PUEBLO": "0",
|
||||
"SSL": "1",
|
||||
"UTF-8": "1",
|
||||
"ZMP": "0",
|
||||
"VT100": "0",
|
||||
"XTERM 256 COLORS": "0",
|
||||
|
||||
# Commercial set to 1 or 0)
|
||||
# Commercial set to 1 or 0)
|
||||
|
||||
"PAY TO PLAY": "0",
|
||||
"PAY FOR PERKS": "0",
|
||||
"PAY TO PLAY": "0",
|
||||
"PAY FOR PERKS": "0",
|
||||
|
||||
# Hiring set to 1 or 0)
|
||||
# Hiring set to 1 or 0)
|
||||
|
||||
"HIRING BUILDERS": "0",
|
||||
"HIRING CODERS": "0",
|
||||
"HIRING BUILDERS": "0",
|
||||
"HIRING CODERS": "0",
|
||||
|
||||
# Extended variables
|
||||
# Extended variables
|
||||
|
||||
# World
|
||||
# World
|
||||
|
||||
"DBSIZE": "0",
|
||||
"EXITS": "0",
|
||||
"EXTRA DESCRIPTIONS": "0",
|
||||
"MUDPROGS": "0",
|
||||
"MUDTRIGS": "0",
|
||||
"RESETS": "0",
|
||||
"DBSIZE": "0",
|
||||
"EXITS": "0",
|
||||
"EXTRA DESCRIPTIONS": "0",
|
||||
"MUDPROGS": "0",
|
||||
"MUDTRIGS": "0",
|
||||
"RESETS": "0",
|
||||
|
||||
# Game (set to 1, 0 or one of the given alternatives)
|
||||
# Game (set to 1, 0 or one of the given alternatives)
|
||||
|
||||
"ADULT MATERIAL": "0",
|
||||
"MULTICLASSING": "0",
|
||||
"NEWBIE FRIENDLY": "0",
|
||||
"PLAYER CITIES": "0",
|
||||
"PLAYER CLANS": "0",
|
||||
"PLAYER CRAFTING": "0",
|
||||
"PLAYER GUILDS": "0",
|
||||
"EQUIPMENT SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"MULTIPLAYING": "None", # "None", "Restricted", "Full"
|
||||
"PLAYERKILLING": "None", # "None", "Restricted", "Full"
|
||||
"QUEST SYSTEM": "None", # "None", "Immortal Run", "Automated", "Integrated"
|
||||
"ROLEPLAYING": "None", # "None", "Accepted", "Encouraged", "Enforced"
|
||||
"TRAINING SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"WORLD ORIGINALITY": "None", # "All Stock", "Mostly Stock", "Mostly Original", "All Original"
|
||||
"ADULT MATERIAL": "0",
|
||||
"MULTICLASSING": "0",
|
||||
"NEWBIE FRIENDLY": "0",
|
||||
"PLAYER CITIES": "0",
|
||||
"PLAYER CLANS": "0",
|
||||
"PLAYER CRAFTING": "0",
|
||||
"PLAYER GUILDS": "0",
|
||||
"EQUIPMENT SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"MULTIPLAYING": "None", # "None", "Restricted", "Full"
|
||||
"PLAYERKILLING": "None", # "None", "Restricted", "Full"
|
||||
"QUEST SYSTEM": "None", # "None", "Immortal Run", "Automated", "Integrated"
|
||||
"ROLEPLAYING": "None", # "None", "Accepted", "Encouraged", "Enforced"
|
||||
"TRAINING SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"WORLD ORIGINALITY": "None", # "All Stock", "Mostly Stock", "Mostly Original", "All Original"
|
||||
}
|
||||
|
||||
# update the static table with the custom one
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ LINKS_SUB = re.compile(r'\|lc(.*?)\|lt(.*?)\|le', re.DOTALL)
|
|||
MXP = chr(91)
|
||||
MXP_TEMPSECURE = "\x1B[4z"
|
||||
MXP_SEND = MXP_TEMPSECURE + \
|
||||
"<SEND HREF=\"\\1\">" + \
|
||||
"\\2" + \
|
||||
MXP_TEMPSECURE + \
|
||||
"</SEND>"
|
||||
"<SEND HREF=\"\\1\">" + \
|
||||
"\\2" + \
|
||||
MXP_TEMPSECURE + \
|
||||
"</SEND>"
|
||||
|
||||
|
||||
def mxp_parse(text):
|
||||
"""
|
||||
|
|
@ -44,6 +45,7 @@ def mxp_parse(text):
|
|||
text = LINKS_SUB.sub(MXP_SEND, text)
|
||||
return text
|
||||
|
||||
|
||||
class Mxp(object):
|
||||
"""
|
||||
Implements the MXP protocol.
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ DEFAULT_HEIGHT = settings.CLIENT_DEFAULT_HEIGHT
|
|||
|
||||
# try to get the customized mssp info, if it exists.
|
||||
|
||||
|
||||
class Naws(object):
|
||||
"""
|
||||
Implements the NAWS protocol. Add this to a variable on the telnet
|
||||
protocol to set it up.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, protocol):
|
||||
"""
|
||||
initialize NAWS by storing protocol on ourselves and calling
|
||||
|
|
@ -37,8 +39,8 @@ class Naws(object):
|
|||
"""
|
||||
self.naws_step = 0
|
||||
self.protocol = protocol
|
||||
self.protocol.protocol_flags['SCREENWIDTH'] = {0: DEFAULT_WIDTH} # windowID (0 is root):width
|
||||
self.protocol.protocol_flags['SCREENHEIGHT'] = {0: DEFAULT_HEIGHT} # windowID:width
|
||||
self.protocol.protocol_flags['SCREENWIDTH'] = {0: DEFAULT_WIDTH} # windowID (0 is root):width
|
||||
self.protocol.protocol_flags['SCREENHEIGHT'] = {0: DEFAULT_HEIGHT} # windowID:width
|
||||
self.protocol.negotiationMap[NAWS] = self.negotiate_sizes
|
||||
self.protocol.do(NAWS).addCallbacks(self.do_naws, self.no_naws)
|
||||
|
||||
|
|
@ -72,9 +74,8 @@ class Naws(object):
|
|||
|
||||
"""
|
||||
if len(options) == 4:
|
||||
# NAWS is negotiated with 16bit words
|
||||
width = options[0] + options[1]
|
||||
self.protocol.protocol_flags['SCREENWIDTH'][0] = int(width.encode('hex'), 16)
|
||||
height = options[2] + options[3]
|
||||
self.protocol.protocol_flags['SCREENHEIGHT'][0] = int(height.encode('hex'), 16)
|
||||
|
||||
# NAWS is negotiated with 16bit words
|
||||
width = options[0] + options[1]
|
||||
self.protocol.protocol_flags['SCREENWIDTH'][0] = int(width.encode('hex'), 16)
|
||||
height = options[2] + options[3]
|
||||
self.protocol.protocol_flags['SCREENHEIGHT'][0] = int(height.encode('hex'), 16)
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ def _portal_maintenance():
|
|||
session.disconnect(reason=reason)
|
||||
PORTAL_SESSIONS.disconnect(session)
|
||||
|
||||
|
||||
if _IDLE_TIMEOUT > 0:
|
||||
# only start the maintenance task if we care about idling.
|
||||
_maintenance_task = LoopingCall(_portal_maintenance)
|
||||
|
|
@ -188,6 +189,7 @@ class Portal(object):
|
|||
#
|
||||
# -------------------------------------------------------------
|
||||
|
||||
|
||||
# twistd requires us to define the variable 'application' so it knows
|
||||
# what to execute from.
|
||||
application = service.Application('Portal')
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from collections import deque, namedtuple
|
|||
from twisted.internet import reactor
|
||||
from django.conf import settings
|
||||
from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, \
|
||||
PCONNSYNC, PDISCONNALL
|
||||
PCONNSYNC, PDISCONNALL
|
||||
from evennia.utils.logger import log_trace
|
||||
|
||||
# module import
|
||||
|
|
@ -97,7 +97,7 @@ class PortalSessionHandler(SessionHandler):
|
|||
if len(_CONNECTION_QUEUE) > 1:
|
||||
session.data_out(text=[["%s DoS protection is active. You are queued to connect in %g seconds ..." % (
|
||||
settings.SERVERNAME,
|
||||
len(_CONNECTION_QUEUE)*_MIN_TIME_BETWEEN_CONNECTS)], {}])
|
||||
len(_CONNECTION_QUEUE) * _MIN_TIME_BETWEEN_CONNECTS)], {}])
|
||||
now = time.time()
|
||||
if (now - self.connection_last < _MIN_TIME_BETWEEN_CONNECTS) or not self.portal.amp_protocol:
|
||||
if not session or not self.connection_task:
|
||||
|
|
@ -428,4 +428,5 @@ class PortalSessionHandler(SessionHandler):
|
|||
except Exception:
|
||||
log_trace()
|
||||
|
||||
|
||||
PORTAL_SESSIONS = PortalSessionHandler()
|
||||
|
|
|
|||
|
|
@ -21,11 +21,13 @@ if RSS_ENABLED:
|
|||
except ImportError:
|
||||
raise ImportError("RSS requires python-feedparser to be installed. Install or set RSS_ENABLED=False.")
|
||||
|
||||
|
||||
class RSSReader(Session):
|
||||
"""
|
||||
A simple RSS reader using the feedparser module.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, factory, url, rate):
|
||||
"""
|
||||
Initialize the reader.
|
||||
|
|
@ -112,6 +114,7 @@ class RSSReader(Session):
|
|||
"""
|
||||
return threads.deferToThread(self.get_new).addCallback(self._callback, init).addErrback(self._errback)
|
||||
|
||||
|
||||
class RSSBotFactory(object):
|
||||
"""
|
||||
Initializes new bots.
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class SshProtocol(Manhole, session.Session):
|
|||
here.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, starttuple):
|
||||
"""
|
||||
For setting up the account. If account is not None then we'll
|
||||
|
|
@ -310,7 +311,7 @@ class ExtraInfoAuthServer(SSHUserAuthServer):
|
|||
c = credentials.UsernamePassword(self.user, password)
|
||||
c.transport = self.transport
|
||||
return self.portal.login(c, None, IConchUser).addErrback(
|
||||
self._ebPassword)
|
||||
self._ebPassword)
|
||||
|
||||
|
||||
class AccountDBPasswordChecker(object):
|
||||
|
|
@ -375,6 +376,7 @@ class TerminalSessionTransport_getPeer(object):
|
|||
provide getPeer to the transport. This one does.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, proto, chainedProtocol, avatar, width, height):
|
||||
self.proto = proto
|
||||
self.avatar = avatar
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class SSLProtocol(TelnetProtocol):
|
|||
Communication is the same as telnet, except data transfer
|
||||
is done with encryption.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SSLProtocol, self).__init__(*args, **kwargs)
|
||||
self.protocol_name = "ssl"
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ SUPPRESS_GA = chr(3)
|
|||
|
||||
# try to get the customized mssp info, if it exists.
|
||||
|
||||
|
||||
class SuppressGA(object):
|
||||
"""
|
||||
Implements the SUPRESS-GO-AHEAD protocol. Add this to a variable on the telnet
|
||||
protocol to set it up.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, protocol):
|
||||
"""
|
||||
Initialize suppression of GO-AHEADs.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
clients) gets a telnet protocol instance assigned to them. All
|
||||
communication between game and player goes through here.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.protocol_name = "telnet"
|
||||
super(TelnetProtocol, self).__init__(*args, **kwargs)
|
||||
|
|
@ -146,7 +147,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
"""
|
||||
return (option == MCCP or
|
||||
option == ECHO or
|
||||
option == suppress_ga.SUPPRESS_GA)
|
||||
option == suppress_ga.SUPPRESS_GA)
|
||||
|
||||
def disableLocal(self, option):
|
||||
"""
|
||||
|
|
@ -332,11 +333,11 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
# by telling the client that WE WON'T echo, the client knows
|
||||
# that IT should echo. This is the expected behavior from
|
||||
# our perspective.
|
||||
self.transport.write(mccp_compress(self, IAC+WONT+ECHO))
|
||||
self.transport.write(mccp_compress(self, IAC + WONT + ECHO))
|
||||
else:
|
||||
# by telling the client that WE WILL echo, the client can
|
||||
# safely turn OFF its OWN echo.
|
||||
self.transport.write(mccp_compress(self, IAC+WILL+ECHO))
|
||||
self.transport.write(mccp_compress(self, IAC + WILL + ECHO))
|
||||
if raw:
|
||||
# no processing
|
||||
self.sendLine(text)
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class TelnetOOB(object):
|
|||
|
||||
"""
|
||||
msdp_cmdname = "{msdp_var}{msdp_cmdname}{msdp_val}".format(
|
||||
msdp_var=MSDP_VAR, msdp_cmdname=cmdname, msdp_val=MSDP_VAL)
|
||||
msdp_var=MSDP_VAR, msdp_cmdname=cmdname, msdp_val=MSDP_VAL)
|
||||
|
||||
if not (args or kwargs):
|
||||
return msdp_cmdname
|
||||
|
|
@ -191,11 +191,11 @@ class TelnetOOB(object):
|
|||
msdp_args += "{msdp_array_open}" \
|
||||
"{msdp_args}" \
|
||||
"{msdp_array_close}".format(
|
||||
msdp_array_open=MSDP_ARRAY_OPEN,
|
||||
msdp_array_close=MSDP_ARRAY_CLOSE,
|
||||
msdp_args="".join("%s%s"
|
||||
% (MSDP_VAL, json.dumps(val))
|
||||
for val in args))
|
||||
msdp_array_open=MSDP_ARRAY_OPEN,
|
||||
msdp_array_close=MSDP_ARRAY_CLOSE,
|
||||
msdp_args="".join("%s%s"
|
||||
% (MSDP_VAL, json.dumps(val))
|
||||
for val in args))
|
||||
|
||||
msdp_kwargs = ""
|
||||
if kwargs:
|
||||
|
|
@ -203,12 +203,12 @@ class TelnetOOB(object):
|
|||
msdp_kwargs += "{msdp_table_open}" \
|
||||
"{msdp_kwargs}" \
|
||||
"{msdp_table_close}".format(
|
||||
msdp_table_open=MSDP_TABLE_OPEN,
|
||||
msdp_table_close=MSDP_TABLE_CLOSE,
|
||||
msdp_kwargs="".join("%s%s%s%s"
|
||||
% (MSDP_VAR, key, MSDP_VAL,
|
||||
json.dumps(val))
|
||||
for key, val in kwargs.iteritems()))
|
||||
msdp_table_open=MSDP_TABLE_OPEN,
|
||||
msdp_table_close=MSDP_TABLE_CLOSE,
|
||||
msdp_kwargs="".join("%s%s%s%s"
|
||||
% (MSDP_VAR, key, MSDP_VAL,
|
||||
json.dumps(val))
|
||||
for key, val in kwargs.iteritems()))
|
||||
|
||||
msdp_string = msdp_args + msdp_kwargs
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class Ttype(object):
|
|||
telnet protocol.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, protocol):
|
||||
"""
|
||||
Initialize ttype by storing protocol on ourselves and calling
|
||||
|
|
@ -132,8 +133,8 @@ class Ttype(object):
|
|||
term = option
|
||||
tupper = term.upper()
|
||||
# identify xterm256 based on flag
|
||||
xterm256 = (tupper.endswith("-256COLOR") # Apple Terminal, old Tintin
|
||||
or tupper.endswith("XTERM") and # old Tintin, Putty
|
||||
xterm256 = (tupper.endswith("-256COLOR") # Apple Terminal, old Tintin or
|
||||
tupper.endswith("XTERM") and # old Tintin, Putty
|
||||
not tupper.endswith("-COLOR"))
|
||||
if xterm256:
|
||||
self.protocol.protocol_flags['ANSI'] = True
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class WebSocketClient(Protocol, Session):
|
|||
"""
|
||||
cmdarray = json.loads(string)
|
||||
if cmdarray:
|
||||
self.data_in(**{cmdarray[0]:[cmdarray[1], cmdarray[2]]})
|
||||
self.data_in(**{cmdarray[0]: [cmdarray[1], cmdarray[2]]})
|
||||
|
||||
def sendLine(self, line):
|
||||
"""
|
||||
|
|
@ -199,7 +199,6 @@ class WebSocketClient(Protocol, Session):
|
|||
# send to client on required form [cmdname, args, kwargs]
|
||||
self.sendLine(json.dumps([cmd, args, kwargs]))
|
||||
|
||||
|
||||
def send_prompt(self, *args, **kwargs):
|
||||
kwargs["options"].update({"send_prompt": True})
|
||||
self.send_text(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ _KEEPALIVE = 30 # how often to check keepalive
|
|||
# extend this if one wants to send more
|
||||
# complex database objects too.
|
||||
|
||||
|
||||
class LazyEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if isinstance(obj, Promise):
|
||||
|
|
@ -86,7 +87,7 @@ class WebClient(resource.Resource):
|
|||
now = time.time()
|
||||
to_remove = []
|
||||
keep_alives = ((csessid, remove) for csessid, (t, remove)
|
||||
in self.last_alive.iteritems() if now - t > _KEEPALIVE)
|
||||
in self.last_alive.iteritems() if now - t > _KEEPALIVE)
|
||||
for csessid, remove in keep_alives:
|
||||
if remove:
|
||||
# keepalive timeout. Line is dead.
|
||||
|
|
@ -203,7 +204,7 @@ class WebClient(resource.Resource):
|
|||
if sess:
|
||||
sess = sess[0]
|
||||
cmdarray = json.loads(request.args.get('data')[0])
|
||||
sess.sessionhandler.data_in(sess, **{cmdarray[0]:[cmdarray[1], cmdarray[2]]})
|
||||
sess.sessionhandler.data_in(sess, **{cmdarray[0]: [cmdarray[1], cmdarray[2]]})
|
||||
return '""'
|
||||
|
||||
def mode_receive(self, request):
|
||||
|
|
@ -381,5 +382,5 @@ class WebClientSession(session.Session):
|
|||
|
||||
"""
|
||||
if not cmdname == "options":
|
||||
#print "ajax.send_default", cmdname, args, kwargs
|
||||
# print "ajax.send_default", cmdname, args, kwargs
|
||||
self.client.lineSend(self.csessid, [cmdname, args, kwargs])
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ from evennia.utils import mod_import, time_format
|
|||
DUMMYRUNNER_SETTINGS = mod_import(settings.DUMMYRUNNER_SETTINGS_MODULE)
|
||||
if not DUMMYRUNNER_SETTINGS:
|
||||
raise IOError("Error: Dummyrunner could not find settings file at %s" %
|
||||
settings.DUMMYRUNNER_SETTINGS_MODULE)
|
||||
settings.DUMMYRUNNER_SETTINGS_MODULE)
|
||||
|
||||
DATESTRING = "%Y%m%d%H%M%S"
|
||||
|
||||
|
|
@ -177,6 +177,8 @@ until you see the initial login slows things too much.
|
|||
|
||||
|
||||
ICOUNT = 0
|
||||
|
||||
|
||||
def idcounter():
|
||||
"""
|
||||
Makes unique ids.
|
||||
|
|
@ -191,6 +193,8 @@ def idcounter():
|
|||
|
||||
|
||||
GCOUNT = 0
|
||||
|
||||
|
||||
def gidcounter():
|
||||
"""
|
||||
Makes globally unique ids.
|
||||
|
|
@ -220,6 +224,7 @@ def makeiter(obj):
|
|||
# Client classes
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class DummyClient(telnet.StatefulTelnetProtocol):
|
||||
"""
|
||||
Handles connection to a running Evennia server,
|
||||
|
|
@ -238,14 +243,14 @@ class DummyClient(telnet.StatefulTelnetProtocol):
|
|||
self.key = "Dummy-%s" % self.cid
|
||||
self.gid = "%s-%s" % (time.strftime(DATESTRING), self.cid)
|
||||
self.istep = 0
|
||||
self.exits = [] # exit names created
|
||||
self.objs = [] # obj names created
|
||||
self.exits = [] # exit names created
|
||||
self.objs = [] # obj names created
|
||||
|
||||
self._connected = False
|
||||
self._loggedin = False
|
||||
self._logging_out = False
|
||||
self._report = ""
|
||||
self._cmdlist = [] # already stepping in a cmd definition
|
||||
self._cmdlist = [] # already stepping in a cmd definition
|
||||
self._login = self.factory.actions[0]
|
||||
self._logout = self.factory.actions[1]
|
||||
self._actions = self.factory.actions[2:]
|
||||
|
|
@ -268,7 +273,7 @@ class DummyClient(telnet.StatefulTelnetProtocol):
|
|||
# start client tick
|
||||
d = LoopingCall(self.step)
|
||||
# dissipate exact step by up to +/- 0.5 second
|
||||
timestep = TIMESTEP + (-0.5 + (random.random()*1.0))
|
||||
timestep = TIMESTEP + (-0.5 + (random.random() * 1.0))
|
||||
d.start(timestep, now=True).addErrback(self.error)
|
||||
|
||||
def connectionLost(self, reason):
|
||||
|
|
@ -329,7 +334,7 @@ class DummyClient(telnet.StatefulTelnetProtocol):
|
|||
if rand < CHANCE_OF_LOGIN:
|
||||
# get the login commands
|
||||
self._cmdlist = list(makeiter(self._login(self)))
|
||||
NLOGGED_IN += 1 # this is for book-keeping
|
||||
NLOGGED_IN += 1 # this is for book-keeping
|
||||
print("connecting client %s (%i/%i)..." % (self.key, NLOGGED_IN, NCLIENTS))
|
||||
self._loggedin = True
|
||||
else:
|
||||
|
|
@ -350,6 +355,7 @@ class DummyClient(telnet.StatefulTelnetProtocol):
|
|||
|
||||
class DummyFactory(protocol.ClientFactory):
|
||||
protocol = DummyClient
|
||||
|
||||
def __init__(self, actions):
|
||||
"Setup the factory base (shared by all clients)"
|
||||
self.actions = actions
|
||||
|
|
@ -359,6 +365,7 @@ class DummyFactory(protocol.ClientFactory):
|
|||
# Starts clients and connects them to a running server.
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
def start_all_dummy_clients(nclients):
|
||||
"""
|
||||
Initialize all clients, connect them and start to step them
|
||||
|
|
@ -379,7 +386,7 @@ def start_all_dummy_clients(nclients):
|
|||
pratio = 1.0 / sum(tup[0] for tup in actions[2:])
|
||||
flogin, flogout, probs, cfuncs = actions[0], actions[1], [tup[0] * pratio for tup in actions[2:]], [tup[1] for tup in actions[2:]]
|
||||
# create cumulative probabilies for the random actions
|
||||
cprobs = [sum(v for i,v in enumerate(probs) if i<=k) for k in range(len(probs))]
|
||||
cprobs = [sum(v for i, v in enumerate(probs) if i <= k) for k in range(len(probs))]
|
||||
# rebuild a new, optimized action structure
|
||||
actions = (flogin, flogout) + tuple(zip(cprobs, cfuncs))
|
||||
|
||||
|
|
@ -394,6 +401,7 @@ def start_all_dummy_clients(nclients):
|
|||
# Command line interface
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -103,13 +103,14 @@ def c_login(client):
|
|||
client.exits.extend([exitname1, exitname2])
|
||||
|
||||
cmds = ('create %s %s' % (cname, cpwd),
|
||||
'connect %s %s' % (cname, cpwd),
|
||||
'@dig %s' % START_ROOM % client.gid,
|
||||
'@teleport %s' % START_ROOM % client.gid,
|
||||
'@dig %s = %s, %s' % (roomname, exitname1, exitname2)
|
||||
)
|
||||
'connect %s %s' % (cname, cpwd),
|
||||
'@dig %s' % START_ROOM % client.gid,
|
||||
'@teleport %s' % START_ROOM % client.gid,
|
||||
'@dig %s = %s, %s' % (roomname, exitname1, exitname2)
|
||||
)
|
||||
return cmds
|
||||
|
||||
|
||||
def c_login_nodig(client):
|
||||
"logins, don't dig its own room"
|
||||
cname = DUMMY_NAME % client.gid
|
||||
|
|
@ -119,12 +120,14 @@ def c_login_nodig(client):
|
|||
'connect %s %s' % (cname, cpwd))
|
||||
return cmds
|
||||
|
||||
|
||||
def c_logout(client):
|
||||
"logouts of the game"
|
||||
return "@quit"
|
||||
|
||||
# random commands
|
||||
|
||||
|
||||
def c_looks(client):
|
||||
"looks at various objects"
|
||||
cmds = ["look %s" % obj for obj in client.objs]
|
||||
|
|
@ -134,6 +137,7 @@ def c_looks(client):
|
|||
cmds = "look"
|
||||
return cmds
|
||||
|
||||
|
||||
def c_examines(client):
|
||||
"examines various objects"
|
||||
cmds = ["examine %s" % obj for obj in client.objs]
|
||||
|
|
@ -143,20 +147,23 @@ def c_examines(client):
|
|||
cmds = "examine me"
|
||||
return cmds
|
||||
|
||||
|
||||
def c_idles(client):
|
||||
"idles"
|
||||
cmds = ('idle','idle')
|
||||
cmds = ('idle', 'idle')
|
||||
return cmds
|
||||
|
||||
|
||||
def c_help(client):
|
||||
"reads help files"
|
||||
cmds = ('help',
|
||||
'help @teleport',
|
||||
'help look',
|
||||
'help @tunnel',
|
||||
'help @dig')
|
||||
'help @teleport',
|
||||
'help look',
|
||||
'help @tunnel',
|
||||
'help @dig')
|
||||
return cmds
|
||||
|
||||
|
||||
def c_digs(client):
|
||||
"digs a new room, storing exit names on client"
|
||||
roomname = ROOM_TEMPLATE % client.counter()
|
||||
|
|
@ -165,42 +172,48 @@ def c_digs(client):
|
|||
client.exits.extend([exitname1, exitname2])
|
||||
return '@dig/tel %s = %s, %s' % (roomname, exitname1, exitname2)
|
||||
|
||||
|
||||
def c_creates_obj(client):
|
||||
"creates normal objects, storing their name on client"
|
||||
objname = OBJ_TEMPLATE % client.counter()
|
||||
client.objs.append(objname)
|
||||
cmds = ('@create %s' % objname,
|
||||
'@desc %s = "this is a test object' % objname,
|
||||
'@set %s/testattr = this is a test attribute value.' % objname,
|
||||
'@set %s/testattr2 = this is a second test attribute.' % objname)
|
||||
'@desc %s = "this is a test object' % objname,
|
||||
'@set %s/testattr = this is a test attribute value.' % objname,
|
||||
'@set %s/testattr2 = this is a second test attribute.' % objname)
|
||||
return cmds
|
||||
|
||||
|
||||
def c_creates_button(client):
|
||||
"creates example button, storing name on client"
|
||||
objname = TOBJ_TEMPLATE % client.counter()
|
||||
client.objs.append(objname)
|
||||
cmds = ('@create %s:%s' % (objname, TOBJ_TYPECLASS),
|
||||
'@desc %s = test red button!' % objname)
|
||||
'@desc %s = test red button!' % objname)
|
||||
return cmds
|
||||
|
||||
|
||||
def c_socialize(client):
|
||||
"socializechats on channel"
|
||||
cmds = ('ooc Hello!',
|
||||
'ooc Testing ...',
|
||||
'ooc Testing ... times 2',
|
||||
'say Yo!',
|
||||
'emote stands looking around.')
|
||||
'ooc Testing ...',
|
||||
'ooc Testing ... times 2',
|
||||
'say Yo!',
|
||||
'emote stands looking around.')
|
||||
return cmds
|
||||
|
||||
|
||||
def c_moves(client):
|
||||
"moves to a previously created room, using the stored exits"
|
||||
cmds = client.exits # try all exits - finally one will work
|
||||
cmds = client.exits # try all exits - finally one will work
|
||||
return "look" if not cmds else cmds
|
||||
|
||||
|
||||
def c_moves_n(client):
|
||||
"move through north exit if available"
|
||||
return "north"
|
||||
|
||||
|
||||
def c_moves_s(client):
|
||||
"move through south exit if available"
|
||||
return "south"
|
||||
|
|
@ -215,8 +228,9 @@ def c_moves_s(client):
|
|||
# otherwise the system will normalize them.
|
||||
#
|
||||
|
||||
## "normal builder" definitionj
|
||||
#ACTIONS = ( c_login,
|
||||
|
||||
# "normal builder" definitionj
|
||||
# ACTIONS = ( c_login,
|
||||
# c_logout,
|
||||
# (0.5, c_looks),
|
||||
# (0.08, c_examines),
|
||||
|
|
@ -224,8 +238,8 @@ def c_moves_s(client):
|
|||
# (0.01, c_digs),
|
||||
# (0.01, c_creates_obj),
|
||||
# (0.3, c_moves))
|
||||
## "heavy" builder definition
|
||||
#ACTIONS = ( c_login,
|
||||
# "heavy" builder definition
|
||||
# ACTIONS = ( c_login,
|
||||
# c_logout,
|
||||
# (0.2, c_looks),
|
||||
# (0.1, c_examines),
|
||||
|
|
@ -234,8 +248,8 @@ def c_moves_s(client):
|
|||
# (0.1, c_creates_obj),
|
||||
# #(0.01, c_creates_button),
|
||||
# (0.2, c_moves))
|
||||
## "passive account" definition
|
||||
#ACTIONS = ( c_login,
|
||||
# "passive account" definition
|
||||
# ACTIONS = ( c_login,
|
||||
# c_logout,
|
||||
# (0.7, c_looks),
|
||||
# #(0.1, c_examines),
|
||||
|
|
@ -245,24 +259,24 @@ def c_moves_s(client):
|
|||
# #(0.1, c_creates_button),
|
||||
# #(0.4, c_moves))
|
||||
# "inactive account" definition
|
||||
#ACTIONS = (c_login_nodig,
|
||||
# ACTIONS = (c_login_nodig,
|
||||
# c_logout,
|
||||
# (1.0, c_idles))
|
||||
## "normal account" definition
|
||||
ACTIONS = ( c_login,
|
||||
c_logout,
|
||||
(0.01, c_digs),
|
||||
(0.39, c_looks),
|
||||
(0.2, c_help),
|
||||
(0.4, c_moves))
|
||||
# "normal account" definition
|
||||
ACTIONS = (c_login,
|
||||
c_logout,
|
||||
(0.01, c_digs),
|
||||
(0.39, c_looks),
|
||||
(0.2, c_help),
|
||||
(0.4, c_moves))
|
||||
# walking tester. This requires a pre-made
|
||||
# "loop" of multiple rooms that ties back
|
||||
# to limbo (using @tunnel and @open)
|
||||
#ACTIONS = (c_login_nodig,
|
||||
# ACTIONS = (c_login_nodig,
|
||||
# c_logout,
|
||||
# (1.0, c_moves_n))
|
||||
## "socializing heavy builder" definition
|
||||
#ACTIONS = (c_login,
|
||||
# "socializing heavy builder" definition
|
||||
# ACTIONS = (c_login,
|
||||
# c_logout,
|
||||
# (0.1, c_socialize),
|
||||
# (0.1, c_looks),
|
||||
|
|
@ -270,7 +284,7 @@ ACTIONS = ( c_login,
|
|||
# (0.1, c_creates_obj),
|
||||
# (0.2, c_digs),
|
||||
# (0.3, c_moves))
|
||||
## "heavy digger memory tester" definition
|
||||
#ACTIONS = (c_login,
|
||||
# "heavy digger memory tester" definition
|
||||
# ACTIONS = (c_login,
|
||||
# c_logout,
|
||||
# (1.0, c_digs))
|
||||
|
|
|
|||
|
|
@ -7,22 +7,25 @@ the script will append to this file if it already exists.
|
|||
Call this module directly to plot the log (requires matplotlib and numpy).
|
||||
"""
|
||||
from __future__ import division
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
#TODO!
|
||||
# TODO!
|
||||
#sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
#os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings'
|
||||
import ev
|
||||
from evennia.utils.idmapper import base as _idmapper
|
||||
|
||||
LOGFILE = "logs/memoryusage.log"
|
||||
INTERVAL = 30 # log every 30 seconds
|
||||
INTERVAL = 30 # log every 30 seconds
|
||||
|
||||
|
||||
class Memplot(ev.Script):
|
||||
"""
|
||||
Describes a memory plotting action.
|
||||
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"Called at script creation"
|
||||
self.key = "memplot"
|
||||
|
|
@ -38,11 +41,12 @@ class Memplot(ev.Script):
|
|||
rmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "rss")).read()) / 1000.0 # resident memory
|
||||
vmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "vsz")).read()) / 1000.0 # virtual memory
|
||||
total_num, cachedict = _idmapper.cache_size()
|
||||
t0 = (time.time() - self.db.starttime) / 60.0 # save in minutes
|
||||
t0 = (time.time() - self.db.starttime) / 60.0 # save in minutes
|
||||
|
||||
with open(LOGFILE, "a") as f:
|
||||
f.write("%s, %s, %s, %s\n" % (t0, rmem, vmem, int(total_num)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# plot output from the file
|
||||
|
|
@ -51,10 +55,10 @@ if __name__ == "__main__":
|
|||
import numpy
|
||||
|
||||
data = numpy.genfromtxt("../../../game/" + LOGFILE, delimiter=",")
|
||||
secs = data[:,0]
|
||||
rmem = data[:,1]
|
||||
vmem = data[:,2]
|
||||
nobj = data[:,3]
|
||||
secs = data[:, 0]
|
||||
rmem = data[:, 1]
|
||||
vmem = data[:, 2]
|
||||
nobj = data[:, 3]
|
||||
|
||||
# calculate derivative of obj creation
|
||||
#oderiv = (0.5*(nobj[2:] - nobj[:-2]) / (secs[2:] - secs[:-2])).copy()
|
||||
|
|
@ -76,7 +80,7 @@ if __name__ == "__main__":
|
|||
ax2.set_ylabel("Number of objects")
|
||||
ax2.legend(loc="lower right")
|
||||
ax2.annotate("First 500 bots\nconnecting", xy=(10, 4000))
|
||||
ax2.annotate("Next 500 bots\nconnecting", xy=(350,10000))
|
||||
ax2.annotate("Next 500 bots\nconnecting", xy=(350, 10000))
|
||||
#ax2.annotate("@reload", xy=(185,600))
|
||||
|
||||
# # plot mem vs cachesize
|
||||
|
|
@ -91,8 +95,8 @@ if __name__ == "__main__":
|
|||
# ax1.plot(nobj, vmem, "b", label="VMEM", lw=2)
|
||||
#
|
||||
|
||||
## # empirical estimate of memory usage: rmem = 35.0 + 0.0157 * Ncache
|
||||
## # Ncache = int((rmem - 35.0) / 0.0157) (rmem in MB)
|
||||
# empirical estimate of memory usage: rmem = 35.0 + 0.0157 * Ncache
|
||||
# Ncache = int((rmem - 35.0) / 0.0157) (rmem in MB)
|
||||
#
|
||||
# rderiv_aver = 0.0157
|
||||
# fig = pp.figure()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ DUMMYRUNNER_MIXIN = True
|
|||
# account creations. The default one is safer but deliberately
|
||||
# very slow to make cracking harder.
|
||||
PASSWORD_HASHERS = (
|
||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||
)
|
||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||
)
|
||||
# make dummy clients able to test all commands
|
||||
PERMISSION_ACCOUNT_DEFAULT = "Developer"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ query as well as count them for optimization testing.
|
|||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import sys, os
|
||||
import sys
|
||||
import os
|
||||
#sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
#os.environ["DJANGO_SETTINGS_MODULE"] = "game.settings"
|
||||
from django.db import connection
|
||||
|
|
@ -26,17 +27,18 @@ def count_queries(exec_string, setup_string):
|
|||
print(query["time"], query["sql"])
|
||||
print("Number of queries: %s" % nqueries)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# setup tests here
|
||||
|
||||
setup_string = \
|
||||
"""
|
||||
"""
|
||||
from evennia.objects.models import ObjectDB
|
||||
g = ObjectDB.objects.get(db_key="Griatch")
|
||||
"""
|
||||
exec_string = \
|
||||
"""
|
||||
"""
|
||||
g.tags.all()
|
||||
"""
|
||||
count_queries(exec_string, setup_string)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Trace a message through the messaging system
|
|||
from __future__ import print_function
|
||||
import time
|
||||
|
||||
|
||||
def timetrace(message, idstring, tracemessage="TEST_MESSAGE", final=False):
|
||||
"""
|
||||
Trace a message with time stamps.
|
||||
|
|
@ -30,10 +31,10 @@ def timetrace(message, idstring, tracemessage="TEST_MESSAGE", final=False):
|
|||
else:
|
||||
t1 = time.time()
|
||||
# print to log (important!)
|
||||
print("** timetrace (%s): dT=%fs, total=%fs." % (idstring, t1-tlast, t1-t0))
|
||||
print("** timetrace (%s): dT=%fs, total=%fs." % (idstring, t1 - tlast, t1 - t0))
|
||||
|
||||
if final:
|
||||
message = " **** %s (total %f) **** " % (tracemessage, t1-t0)
|
||||
message = " **** %s (total %f) **** " % (tracemessage, t1 - t0)
|
||||
else:
|
||||
message = "%s %f %f" % (tracemessage, t1, t0)
|
||||
return message
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ _FLUSH_CACHE = None
|
|||
_IDMAPPER_CACHE_MAXSIZE = settings.IDMAPPER_CACHE_MAXSIZE
|
||||
_GAMETIME_MODULE = None
|
||||
|
||||
|
||||
def _server_maintenance():
|
||||
"""
|
||||
This maintenance function handles repeated checks and updates that
|
||||
|
|
@ -122,17 +123,20 @@ def _server_maintenance():
|
|||
if _MAINTENANCE_COUNT % 3700 == 0:
|
||||
# validate channels off-sync with scripts
|
||||
evennia.CHANNEL_HANDLER.update()
|
||||
## Commenting this out, it is probably not needed
|
||||
## with CONN_MAX_AGE set. Keeping it as a reminder
|
||||
## if database-gone-away errors appears again /Griatch
|
||||
#if _MAINTENANCE_COUNT % 18000 == 0:
|
||||
|
||||
# Commenting this out, it is probably not needed
|
||||
# with CONN_MAX_AGE set. Keeping it as a reminder
|
||||
# if database-gone-away errors appears again /Griatch
|
||||
# if _MAINTENANCE_COUNT % 18000 == 0:
|
||||
# connection.close()
|
||||
maintenance_task = LoopingCall(_server_maintenance)
|
||||
maintenance_task.start(60, now=True) # call every minute
|
||||
maintenance_task.start(60, now=True) # call every minute
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Evennia Main Server object
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class Evennia(object):
|
||||
|
||||
"""
|
||||
|
|
@ -195,10 +199,10 @@ class Evennia(object):
|
|||
Optimize some SQLite stuff at startup since we
|
||||
can't save it to the database.
|
||||
"""
|
||||
if ((".".join(str(i) for i in django.VERSION) < "1.2" and settings.DATABASES.get('default', {}).get('ENGINE') == "sqlite3")
|
||||
or (hasattr(settings, 'DATABASES')
|
||||
and settings.DATABASES.get("default", {}).get('ENGINE', None)
|
||||
== 'django.db.backends.sqlite3')):
|
||||
if ((".".join(str(i) for i in django.VERSION) < "1.2" and settings.DATABASES.get('default', {}).get('ENGINE') == "sqlite3") or
|
||||
(hasattr(settings, 'DATABASES') and
|
||||
settings.DATABASES.get("default", {}).get('ENGINE', None) ==
|
||||
'django.db.backends.sqlite3')):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("PRAGMA cache_size=10000")
|
||||
cursor.execute("PRAGMA synchronous=OFF")
|
||||
|
|
@ -253,7 +257,7 @@ class Evennia(object):
|
|||
# if this is the first start we might not have a "previous"
|
||||
# setup saved. Store it now.
|
||||
[ServerConfig.objects.conf(settings_names[i], tup[1])
|
||||
for i, tup in enumerate(settings_compare) if not tup[0]]
|
||||
for i, tup in enumerate(settings_compare) if not tup[0]]
|
||||
|
||||
def run_initial_setup(self):
|
||||
"""
|
||||
|
|
@ -273,8 +277,8 @@ class Evennia(object):
|
|||
# modules and setup will resume from this step, retrying
|
||||
# the last failed module. When all are finished, the step
|
||||
# is set to -1 to show it does not need to be run again.
|
||||
print(' Resuming initial setup from step %(last)s.' % \
|
||||
{'last': last_initial_setup_step})
|
||||
print(' Resuming initial setup from step %(last)s.' %
|
||||
{'last': last_initial_setup_step})
|
||||
initial_setup.handle_setup(int(last_initial_setup_step))
|
||||
print('-' * 50)
|
||||
|
||||
|
|
@ -285,7 +289,7 @@ class Evennia(object):
|
|||
from evennia.objects.models import ObjectDB
|
||||
#from evennia.accounts.models import AccountDB
|
||||
|
||||
#update eventual changed defaults
|
||||
# update eventual changed defaults
|
||||
self.update_defaults()
|
||||
|
||||
[o.at_init() for o in ObjectDB.get_all_cached_instances()]
|
||||
|
|
@ -382,7 +386,7 @@ class Evennia(object):
|
|||
yield [_SA(p, "is_connected", False) for p in AccountDB.get_all_cached_instances()]
|
||||
yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()]
|
||||
yield [(p.unpuppet_all(), p.at_server_shutdown())
|
||||
for p in AccountDB.get_all_cached_instances()]
|
||||
for p in AccountDB.get_all_cached_instances()]
|
||||
yield ObjectDB.objects.clear_all_sessids()
|
||||
yield [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
|
||||
ServerConfig.objects.conf("server_restart_mode", "reset")
|
||||
|
|
@ -399,7 +403,7 @@ class Evennia(object):
|
|||
# for Windows we need to remove pid files manually
|
||||
os.remove(SERVER_PIDFILE)
|
||||
|
||||
if hasattr(self, "web_root"): # not set very first start
|
||||
if hasattr(self, "web_root"): # not set very first start
|
||||
yield self.web_root.empty_threadpool()
|
||||
|
||||
if not _reactor_stopping:
|
||||
|
|
@ -420,7 +424,6 @@ class Evennia(object):
|
|||
if SERVER_STARTSTOP_MODULE:
|
||||
SERVER_STARTSTOP_MODULE.at_server_start()
|
||||
|
||||
|
||||
def at_server_stop(self):
|
||||
"""
|
||||
This is called just before a server is shut down, regardless
|
||||
|
|
@ -429,7 +432,6 @@ class Evennia(object):
|
|||
if SERVER_STARTSTOP_MODULE:
|
||||
SERVER_STARTSTOP_MODULE.at_server_stop()
|
||||
|
||||
|
||||
def at_server_reload_start(self):
|
||||
"""
|
||||
This is called only when server starts back up after a reload.
|
||||
|
|
@ -470,7 +472,6 @@ class Evennia(object):
|
|||
if SERVER_STARTSTOP_MODULE:
|
||||
SERVER_STARTSTOP_MODULE.at_server_reload_stop()
|
||||
|
||||
|
||||
def at_server_cold_start(self):
|
||||
"""
|
||||
This is called only when the server starts "cold", i.e. after a
|
||||
|
|
@ -489,7 +490,8 @@ class Evennia(object):
|
|||
if GUEST_ENABLED:
|
||||
for guest in AccountDB.objects.all().filter(db_typeclass_path=settings.BASE_GUEST_TYPECLASS):
|
||||
for character in guest.db._playable_characters:
|
||||
if character: character.delete()
|
||||
if character:
|
||||
character.delete()
|
||||
guest.delete()
|
||||
if SERVER_STARTSTOP_MODULE:
|
||||
SERVER_STARTSTOP_MODULE.at_server_cold_start()
|
||||
|
|
@ -507,6 +509,7 @@ class Evennia(object):
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
# Tell the system the server is starting up; some things are not available yet
|
||||
ServerConfig.objects.conf("server_starting_mode", True)
|
||||
|
||||
|
|
@ -549,7 +552,7 @@ if WEBSERVER_ENABLED:
|
|||
# start a thread pool and define the root url (/) as a wsgi resource
|
||||
# recognized by Django
|
||||
threads = LockableThreadPool(minthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[0]),
|
||||
maxthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[1]))
|
||||
maxthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[1]))
|
||||
|
||||
web_root = DjangoWebRoot(threads)
|
||||
# point our media resources to url /media
|
||||
|
|
@ -597,4 +600,3 @@ if os.name == 'nt':
|
|||
# Windows only: Set PID file manually
|
||||
with open(SERVER_PIDFILE, 'w') as f:
|
||||
f.write(str(os.getpid()))
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ from django.utils.translation import ugettext as _
|
|||
|
||||
class NDbHolder(object):
|
||||
"""Holder for allowing property access of attributes"""
|
||||
|
||||
def __init__(self, obj, name, manager_name='attributes'):
|
||||
_SA(self, name, _GA(obj, manager_name))
|
||||
_SA(self, 'name', name)
|
||||
|
|
@ -65,6 +66,7 @@ class NAttributeHandler(object):
|
|||
by the `.ndb` handler in the same way as `.db` does
|
||||
for the `AttributeHandler`.
|
||||
"""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Initialized on the object
|
||||
|
|
@ -160,6 +162,7 @@ class ServerSession(Session):
|
|||
through their session.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initiate to avoid AttributeErrors down the line"""
|
||||
self.puppet = None
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class Session(object):
|
|||
self.cmd_total = 0
|
||||
|
||||
self.protocol_flags = {"ENCODING": "utf-8",
|
||||
"SCREENREADER":False,
|
||||
"SCREENREADER": False,
|
||||
"INPUTDEBUG": False,
|
||||
"RAW": False,
|
||||
"NOCOLOR": False}
|
||||
|
|
@ -106,7 +106,7 @@ class Session(object):
|
|||
|
||||
"""
|
||||
return dict((key, value) for key, value in self.__dict__.items()
|
||||
if key in self._attrs_to_sync)
|
||||
if key in self._attrs_to_sync)
|
||||
|
||||
def load_sync_data(self, sessdata):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -39,8 +39,11 @@ _ServerConfig = None
|
|||
_ScriptDB = None
|
||||
_OOB_HANDLER = None
|
||||
|
||||
|
||||
class DummySession(object):
|
||||
sessid = 0
|
||||
|
||||
|
||||
DUMMYSESSION = DummySession()
|
||||
|
||||
# AMP signals
|
||||
|
|
@ -54,7 +57,7 @@ SSHUTD = chr(7) # server shutdown
|
|||
SSYNC = chr(8) # server session sync
|
||||
SCONN = chr(11) # server portal connection (for bots)
|
||||
PCONNSYNC = chr(12) # portal post-syncing session
|
||||
PDISCONNALL = chr(13) # portal session discnnect all
|
||||
PDISCONNALL = chr(13) # portal session discnnect all
|
||||
|
||||
# i18n
|
||||
from django.utils.translation import ugettext as _
|
||||
|
|
@ -72,6 +75,7 @@ _INPUT_FUNCS = {}
|
|||
for modname in make_iter(settings.INPUT_FUNC_MODULES):
|
||||
_INPUT_FUNCS.update(callables_from_module(modname))
|
||||
|
||||
|
||||
def delayed_import():
|
||||
"""
|
||||
Helper method for delayed import of all needed entities.
|
||||
|
|
@ -222,9 +226,9 @@ class SessionHandler(dict):
|
|||
# we don't allow sending text = None, this must mean
|
||||
# that the text command is not to be used.
|
||||
continue
|
||||
rkwargs[key] = [ [], {} ]
|
||||
rkwargs[key] = [[], {}]
|
||||
elif isinstance(data, dict):
|
||||
rkwargs[key] = [ [], _validate(data) ]
|
||||
rkwargs[key] = [[], _validate(data)]
|
||||
elif hasattr(data, "__iter__"):
|
||||
if isinstance(data[-1], dict):
|
||||
if len(data) == 2:
|
||||
|
|
@ -233,11 +237,11 @@ class SessionHandler(dict):
|
|||
else:
|
||||
rkwargs[key] = [[_validate(data[0])], _validate(data[1])]
|
||||
else:
|
||||
rkwargs[key] = [ _validate(data[:-1]), _validate(data[-1]) ]
|
||||
rkwargs[key] = [_validate(data[:-1]), _validate(data[-1])]
|
||||
else:
|
||||
rkwargs[key] = [ _validate(data), {} ]
|
||||
rkwargs[key] = [_validate(data), {}]
|
||||
else:
|
||||
rkwargs[key] = [ [_validate(data)], {} ]
|
||||
rkwargs[key] = [[_validate(data)], {}]
|
||||
rkwargs[key][1]["options"] = options
|
||||
return rkwargs
|
||||
|
||||
|
|
@ -306,7 +310,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
sess.uid = None
|
||||
|
||||
# show the first login command
|
||||
self.data_in(sess, text=[[CMD_LOGINSTART],{}])
|
||||
self.data_in(sess, text=[[CMD_LOGINSTART], {}])
|
||||
|
||||
def portal_session_sync(self, portalsessiondata):
|
||||
"""
|
||||
|
|
@ -362,7 +366,6 @@ class ServerSessionHandler(SessionHandler):
|
|||
# announce the reconnection
|
||||
self.announce_all(_(" ... Server restarted."))
|
||||
|
||||
|
||||
def portal_disconnect(self, session):
|
||||
"""
|
||||
Called from Portal when Portal session closed from the portal
|
||||
|
|
@ -415,7 +418,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
"""
|
||||
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=SCONN,
|
||||
protocol_path=protocol_path, config=configdict)
|
||||
protocol_path=protocol_path, config=configdict)
|
||||
|
||||
def portal_shutdown(self):
|
||||
"""
|
||||
|
|
@ -466,14 +469,14 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
nsess = len(self.sessions_from_account(account))
|
||||
string = "Logged in: {account} {address} ({nsessions} session(s) total)"
|
||||
string = string.format(account=account,address=session.address, nsessions=nsess)
|
||||
string = string.format(account=account, address=session.address, nsessions=nsess)
|
||||
session.log(string)
|
||||
session.logged_in = True
|
||||
# sync the portal to the session
|
||||
if not testmode:
|
||||
self.server.amp_protocol.send_AdminServer2Portal(session,
|
||||
operation=SLOGIN,
|
||||
sessiondata={"logged_in": True})
|
||||
operation=SLOGIN,
|
||||
sessiondata={"logged_in": True})
|
||||
account.at_post_login(session=session)
|
||||
|
||||
def disconnect(self, session, reason="", sync_portal=True):
|
||||
|
|
@ -518,8 +521,8 @@ class ServerSessionHandler(SessionHandler):
|
|||
"""
|
||||
sessdata = self.get_all_sync_data()
|
||||
return self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION,
|
||||
operation=SSYNC,
|
||||
sessiondata=sessdata)
|
||||
operation=SSYNC,
|
||||
sessiondata=sessdata)
|
||||
|
||||
def session_portal_sync(self, session):
|
||||
"""
|
||||
|
|
@ -550,7 +553,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
reason=reason)
|
||||
|
||||
def disconnect_duplicate_sessions(self, curr_session,
|
||||
reason=_("Logged in from elsewhere. Disconnecting.")):
|
||||
reason=_("Logged in from elsewhere. Disconnecting.")):
|
||||
"""
|
||||
Disconnects any existing sessions with the same user.
|
||||
|
||||
|
|
@ -561,9 +564,9 @@ class ServerSessionHandler(SessionHandler):
|
|||
"""
|
||||
uid = curr_session.uid
|
||||
doublet_sessions = [sess for sess in self.values()
|
||||
if sess.logged_in
|
||||
and sess.uid == uid
|
||||
and sess != curr_session]
|
||||
if sess.logged_in and
|
||||
sess.uid == uid and
|
||||
sess != curr_session]
|
||||
for session in doublet_sessions:
|
||||
self.disconnect(session, reason)
|
||||
|
||||
|
|
@ -576,8 +579,8 @@ class ServerSessionHandler(SessionHandler):
|
|||
tcurr = time.time()
|
||||
reason = _("Idle timeout exceeded, disconnecting.")
|
||||
for session in (session for session in self.values()
|
||||
if session.logged_in and _IDLE_TIMEOUT > 0
|
||||
and (tcurr - session.cmd_last) > _IDLE_TIMEOUT):
|
||||
if session.logged_in and _IDLE_TIMEOUT > 0 and
|
||||
(tcurr - session.cmd_last) > _IDLE_TIMEOUT):
|
||||
self.disconnect(session, reason=reason)
|
||||
|
||||
def account_count(self):
|
||||
|
|
@ -757,10 +760,11 @@ class ServerSessionHandler(SessionHandler):
|
|||
_INPUT_FUNCS[cname](session, *cmdargs, **cmdkwargs)
|
||||
else:
|
||||
_INPUT_FUNCS["default"](session, cname, *cmdargs, **cmdkwargs)
|
||||
except Exception, err:
|
||||
except Exception as err:
|
||||
if input_debug:
|
||||
session.msg(err)
|
||||
log_trace()
|
||||
|
||||
|
||||
SESSION_HANDLER = ServerSessionHandler()
|
||||
SESSIONS = SESSION_HANDLER # legacy
|
||||
SESSIONS = SESSION_HANDLER # legacy
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class EvenniaTestSuiteRunner(DiscoverRunner):
|
|||
This test runner only runs tests on the apps specified in evennia/
|
||||
avoid running the large number of tests defined by Django
|
||||
"""
|
||||
|
||||
def build_suite(self, test_labels, extra_tests=None, **kwargs):
|
||||
"""
|
||||
Build a test suite for Evennia. test_labels is a list of apps to test.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class LockableThreadPool(threadpool.ThreadPool):
|
|||
"""
|
||||
Threadpool that can be locked from accepting new requests.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._accept_new = True
|
||||
threadpool.ThreadPool.__init__(self, *args, **kwargs)
|
||||
|
|
@ -60,6 +61,7 @@ class HTTPChannelWithXForwardedFor(http.HTTPChannel):
|
|||
HTTP xforward class
|
||||
|
||||
"""
|
||||
|
||||
def allHeadersReceived(self):
|
||||
"""
|
||||
Check to see if this is a reverse proxied connection.
|
||||
|
|
@ -227,6 +229,7 @@ class WSGIWebServer(internet.TCPServer):
|
|||
call with WSGIWebServer(threadpool, port, wsgi_resource)
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, pool, *args, **kwargs):
|
||||
"""
|
||||
This just stores the threadpool.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue