Modified contrib/evlang to optionally make use of ProcPool multiprocessing.
This commit is contained in:
parent
ffcf4b3c2f
commit
5c6ee44039
3 changed files with 25 additions and 13 deletions
|
|
@ -4,7 +4,7 @@ Dice - rolls dice for roleplaying, in-game gambling or GM:ing
|
||||||
Evennia contribution - Griatch 2012
|
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
|
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.
|
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 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
|
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():
|
at_cmdset_creation():
|
||||||
|
|
||||||
self.add(dice.CmdDice())
|
self.add(dice.CmdDice())
|
||||||
|
|
@ -93,7 +93,7 @@ RE_COND = re.compile(r"(<|>|<=|>=|!=|==)")
|
||||||
|
|
||||||
class CmdDice(default_cmds.MuxCommand):
|
class CmdDice(default_cmds.MuxCommand):
|
||||||
"""
|
"""
|
||||||
roll a dice
|
roll dice
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
dice[/switch] <nr>d<sides> [modifier] [success condition]
|
dice[/switch] <nr>d<sides> [modifier] [success condition]
|
||||||
|
|
|
||||||
|
|
@ -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 django.core.management import setup_environ
|
||||||
from game import settings
|
from game import settings
|
||||||
setup_environ(settings)
|
setup_environ(settings)
|
||||||
from ev import logger
|
from src.utils.utils import run_async
|
||||||
|
_LOGGER = None
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Evennia-specific blocks
|
# Evennia-specific blocks
|
||||||
|
|
@ -308,9 +309,12 @@ class Evlang(object):
|
||||||
"""
|
"""
|
||||||
def alarm(codestring):
|
def alarm(codestring):
|
||||||
"store the code of too-long-running scripts"
|
"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)
|
self.timedout_codestrings.append(codestring)
|
||||||
err = "Evlang code '%s' exceeded allowed execution time (>%ss)." % (codestring, timeout)
|
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):
|
if not self.msg(err, scripter, caller):
|
||||||
raise EvlangError(err)
|
raise EvlangError(err)
|
||||||
def errback(f):
|
def errback(f):
|
||||||
|
|
@ -702,10 +706,10 @@ class LimitedExecVisitor(object):
|
||||||
|
|
||||||
def visitPower(self, node, *args):
|
def visitPower(self, node, *args):
|
||||||
"Make sure power-of operations don't get too big"
|
"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)
|
lineno = get_node_lineno(node)
|
||||||
self.errors.append(LimitedExecAttrError( \
|
self.errors.append(LimitedExecAttrError( \
|
||||||
"power law index too big - restricted", lineno))
|
"power law solution too big - restricted", lineno))
|
||||||
|
|
||||||
def ok(self, node, *args):
|
def ok(self, node, *args):
|
||||||
"Default callback for 'harmless' AST nodes."
|
"Default callback for 'harmless' AST nodes."
|
||||||
|
|
@ -802,7 +806,7 @@ def validate_code(codestring):
|
||||||
raise LimitedExecCodeException(codestring, checker.errors)
|
raise LimitedExecCodeException(codestring, checker.errors)
|
||||||
return True
|
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
|
Validate source code and make sure it contains no unauthorized
|
||||||
expression/statements as configured via 'UNALLOWED_AST_NODES' and
|
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 =
|
if code did not execute within the given timelimit =
|
||||||
LimitedExecTimeoutException
|
LimitedExecTimeoutException
|
||||||
"""
|
"""
|
||||||
|
if retobj:
|
||||||
|
callback = lambda r: retobj.msg(r)
|
||||||
|
errback = lambda e: retobj.msg(e)
|
||||||
# run code only after validation has completed
|
# run code only after validation has completed
|
||||||
if validate_context(context) and validate_code(code):
|
if validate_context(context) and validate_code(code):
|
||||||
exec code in context
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -222,9 +222,10 @@ BASE_OBJECT_TYPECLASS = "src.objects.objects.Object"
|
||||||
BASE_CHARACTER_TYPECLASS = "src.objects.objects.Character"
|
BASE_CHARACTER_TYPECLASS = "src.objects.objects.Character"
|
||||||
# Typeclass for rooms (fallback)
|
# Typeclass for rooms (fallback)
|
||||||
BASE_ROOM_TYPECLASS = "src.objects.objects.Room"
|
BASE_ROOM_TYPECLASS = "src.objects.objects.Room"
|
||||||
# Typeclass for Exit objects (fallback)
|
# Typeclass for Exit objects (fallback).
|
||||||
BASE_EXIT_TYPECLASS = "src.objects.objects.Exit"
|
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"
|
BASE_SCRIPT_TYPECLASS = "src.scripts.scripts.DoNothing"
|
||||||
# The home location for new characters. This must be a unique
|
# The home location for new characters. This must be a unique
|
||||||
# dbref (default is Limbo #2). If you want more advanced control over
|
# dbref (default is Limbo #2). If you want more advanced control over
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue