From 5c6ee440390b989e31c85bfb361c6b34bb86b536 Mon Sep 17 00:00:00 2001 From: Griatch Date: Mon, 3 Sep 2012 19:21:04 +0200 Subject: [PATCH] Modified contrib/evlang to optionally make use of ProcPool multiprocessing. --- contrib/dice.py | 6 +++--- contrib/evlang/evlang.py | 27 +++++++++++++++++++-------- src/settings_default.py | 5 +++-- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/contrib/dice.py b/contrib/dice.py index db276c428c..fb728b871d 100644 --- a/contrib/dice.py +++ b/contrib/dice.py @@ -4,7 +4,7 @@ Dice - rolls dice for roleplaying, in-game gambling or GM:ing Evennia contribution - Griatch 2012 -This module implements a full-fledge dice-roller and a 'dice' command to +This module implements a full-fledged dice-roller and a 'dice' command to go with it. It uses standard RPG 'd'-syntax (e.g. 2d6 to roll two six-sided die) and also supports modifiers such as 3d6 + 5. @@ -21,7 +21,7 @@ Installation: To use in your code, just import the roll_dice function from this module. To use the dice/roll command, just import this module in your custom -cmdset module and add the following line to the end of OOCCmdSet's +cmdset module and add the following line to the end of DefaultCmdSet's at_cmdset_creation(): self.add(dice.CmdDice()) @@ -93,7 +93,7 @@ RE_COND = re.compile(r"(<|>|<=|>=|!=|==)") class CmdDice(default_cmds.MuxCommand): """ - roll a dice + roll dice Usage: dice[/switch] d [modifier] [success condition] diff --git a/contrib/evlang/evlang.py b/contrib/evlang/evlang.py index 330075cf31..20eec82b5f 100644 --- a/contrib/evlang/evlang.py +++ b/contrib/evlang/evlang.py @@ -84,7 +84,8 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspa from django.core.management import setup_environ from game import settings setup_environ(settings) -from ev import logger +from src.utils.utils import run_async +_LOGGER = None #------------------------------------------------------------ # Evennia-specific blocks @@ -308,9 +309,12 @@ class Evlang(object): """ def alarm(codestring): "store the code of too-long-running scripts" + global _LOGGER + if not _LOGGER: + from src.utils import logger as _LOGGER self.timedout_codestrings.append(codestring) err = "Evlang code '%s' exceeded allowed execution time (>%ss)." % (codestring, timeout) - logger.log_errmsg("EVLANG time exceeded: caller: %s, scripter: %s, code: %s" % (caller, scripter, codestring)) + _LOGGER.log_errmsg("EVLANG time exceeded: caller: %s, scripter: %s, code: %s" % (caller, scripter, codestring)) if not self.msg(err, scripter, caller): raise EvlangError(err) def errback(f): @@ -702,10 +706,10 @@ class LimitedExecVisitor(object): def visitPower(self, node, *args): "Make sure power-of operations don't get too big" - if node.left.value > 1000000 or node.right.value > 10000: + if node.left.value > 1000000 or node.right.value > 10: lineno = get_node_lineno(node) self.errors.append(LimitedExecAttrError( \ - "power law index too big - restricted", lineno)) + "power law solution too big - restricted", lineno)) def ok(self, node, *args): "Default callback for 'harmless' AST nodes." @@ -802,7 +806,7 @@ def validate_code(codestring): raise LimitedExecCodeException(codestring, checker.errors) return True -def limited_exec(code, context = {}, timeout_secs = 2): +def limited_exec(code, context = {}, timeout_secs = 2, retobj=None): """ Validate source code and make sure it contains no unauthorized expression/statements as configured via 'UNALLOWED_AST_NODES' and @@ -824,9 +828,16 @@ def limited_exec(code, context = {}, timeout_secs = 2): if code did not execute within the given timelimit = LimitedExecTimeoutException """ - # run code only after validation has completed - if validate_context(context) and validate_code(code): - exec code in context + if retobj: + callback = lambda r: retobj.msg(r) + errback = lambda e: retobj.msg(e) + # run code only after validation has completed + if validate_context(context) and validate_code(code): + run_async(code, *context, at_return=callback, at_err=errback) + else: + # run code only after validation has completed + if validate_context(context) and validate_code(code): + run_async(code, *context) diff --git a/src/settings_default.py b/src/settings_default.py index 37fe268fa0..33fdf94eb5 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -222,9 +222,10 @@ BASE_OBJECT_TYPECLASS = "src.objects.objects.Object" BASE_CHARACTER_TYPECLASS = "src.objects.objects.Character" # Typeclass for rooms (fallback) BASE_ROOM_TYPECLASS = "src.objects.objects.Room" -# Typeclass for Exit objects (fallback) +# Typeclass for Exit objects (fallback). BASE_EXIT_TYPECLASS = "src.objects.objects.Exit" -# Typeclass for Scripts (fallback) +# Typeclass for Scripts (fallback). You usually don't need to change this +# but create custom variations of scripts on a per-case basis instead. BASE_SCRIPT_TYPECLASS = "src.scripts.scripts.DoNothing" # The home location for new characters. This must be a unique # dbref (default is Limbo #2). If you want more advanced control over