diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d346f6c60..53ddf0767f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - [Fix][pull3853]: Properly handle multimatch separations with native dashes, like 't-shirt-1' (count-infinity) - [Fix][pull3733]: Allow `CmdSetAttribute` to use categery, view dicts by key (InspectorCaracal) +- [Fix][issue3858]: Fix parsing issues in dice contrib (Griatch) - [Doc][pull3801]: Move Evennia doc build system to latest Sphinx/myST (PowershellNinja, also honorary mention to electroglyph) - [Doc][pull3800]: Describe support for Telnet SSH in HAProxy documentation (holl0wstar) @@ -53,6 +54,7 @@ [pull3853]: https://github.com/evennia/evennia/pull/3853 [pull3854]: https://github.com/evennia/evennia/pull/3853 [pull3733]: https://github.com/evennia/evennia/pull/3853 +[issue3858]: https://github.com/evennia/evennia/issues/3858 ## Evennia 5.0.1 diff --git a/evennia/contrib/rpg/dice/dice.py b/evennia/contrib/rpg/dice/dice.py index 5eec8df025..b9c2f0e93b 100644 --- a/evennia/contrib/rpg/dice/dice.py +++ b/evennia/contrib/rpg/dice/dice.py @@ -253,8 +253,10 @@ class CmdDice(default_cmds.MuxCommand): def func(self): """Mostly parsing for calling the dice roller function""" + helptxt = "Usage: @dice d [modifier] [conditional]" + if not self.args: - self.caller.msg("Usage: @dice d [modifier] [conditional]") + self.caller.msg(helptxt) return argstring = "".join(str(arg) for arg in self.args) @@ -264,36 +266,48 @@ class CmdDice(default_cmds.MuxCommand): conditional = None if len_parts < 3 or parts[1] != "d": - self.caller.msg( - "You must specify the die roll(s) as d." - " For example, 2d6 means rolling a 6-sided die 2 times." - ) + self.caller.msg(f"Malformed input. {helptxt}") return # Limit the number of dice and sides a character can roll to prevent server slow down and crashes ndicelimit = 10000 # Maximum number of dice nsidelimit = 10000 # Maximum number of sides - if int(parts[0]) > ndicelimit or int(parts[2]) > nsidelimit: - self.caller.msg("The maximum roll allowed is %sd%s." % (ndicelimit, nsidelimit)) + try: + if int(parts[0]) > ndicelimit or int(parts[2]) > nsidelimit: + self.caller.msg("The maximum roll allowed is %sd%s." % (ndicelimit, nsidelimit)) + return + except ValueError: + self.caller.msg(f"Malformed input. {helptxt}") return - ndice, nsides = parts[0], parts[2] if len_parts == 3: # just something like 1d6 + ndice, nsides = parts[0], parts[2] pass elif len_parts == 5: # either e.g. 1d6 + 3 or something like 1d6 > 3 + ndice, nsides = parts[0], parts[2] if parts[3] in ("+", "-", "*", "/"): modifier = (parts[3], parts[4]) - else: # assume it is a conditional + elif parts[3] in ("<", ">", "<=", ">=", "!=", "=="): conditional = (parts[3], parts[4]) + else: + self.caller.msg(f"Malformed input. {helptxt}") + return elif len_parts == 7: # the whole sequence, e.g. 1d6 + 3 > 5 - modifier = (parts[3], parts[4]) - conditional = (parts[5], parts[6]) + ndice, nsides = parts[0], parts[2] + err = parts[3] not in ("+", "-", "*", "/") + err = err or parts[5] not in ("<", ">", "<=", ">=", "!=", "==") + if err: + self.caller.msg(f"Malformed input. {helptxt}") + return + else: + modifier = (parts[3], parts[4]) + conditional = (parts[5], parts[6]) else: # error - self.caller.msg("You must specify a valid die roll") + self.caller.msg(f"Malformed input. {helptxt}") return # do the roll try: diff --git a/evennia/contrib/rpg/dice/tests.py b/evennia/contrib/rpg/dice/tests.py index ba5621b409..ad704c5759 100644 --- a/evennia/contrib/rpg/dice/tests.py +++ b/evennia/contrib/rpg/dice/tests.py @@ -35,3 +35,12 @@ class TestDice(BaseEvenniaCommandTest): dice.roll(11, 1001, max_dicenum=10, max_dicetype=1000) with self.assertRaises(TypeError): dice.roll(10, 1001, max_dicenum=10, max_dicetype=1000) + + def test_malformed_inputs(self, mocked_randint): + self.call(dice.CmdDice(), "d6", "Malformed input.") + self.call(dice.CmdDice(), "3d", "Malformed input.") + self.call(dice.CmdDice(), "3d6 +", "Malformed input.") + self.call(dice.CmdDice(), "3d6 -", "Malformed input.") + self.call(dice.CmdDice(), "foo 3d6 + 2", "Malformed input.") + self.call(dice.CmdDice(), "3d6 + 2 + 2", "Malformed input.") + self.call(dice.CmdDice(), "3d6 foo 2", "Malformed input.")