From 47a324f720bf42bb0b6d90ef4b0e64091f6f8bc7 Mon Sep 17 00:00:00 2001 From: Griatch Date: Tue, 2 Jul 2013 13:38:38 +0200 Subject: [PATCH] Made cmdhandler merge same-prio cmdsets in groups. Before this fix one could face the following situation: Two exits "allcom" and "test". Both have exit cmdsets with prio 9. If "test" merges first, it contains no "allcom" command to overload the "allcom" in the Player cmdset (prio -5). But the merged set now has a priority of 9 thanks to merging the "test" set. So when merging the "allcom" exit-command, it merges with a same-prio set. And since exit-cmdsets have the duplicate-flag set, there will be two allcom commands in the final set. The problem does not show up if "allcom" happened to be merged first, making this effect non-consistent and buggy. Merging the same-prio exit-sets first, then merging onto the lower-prio sets resolves this issue. --- src/commands/cmdhandler.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/commands/cmdhandler.py b/src/commands/cmdhandler.py index 9be05a915e..bbb93b7b5d 100644 --- a/src/commands/cmdhandler.py +++ b/src/commands/cmdhandler.py @@ -139,14 +139,25 @@ def get_and_merge_cmdsets(caller): cmdsets = yield [caller_cmdset] + [player_cmdset] + [channel_cmdset] + local_objects_cmdsets # weed out all non-found sets - cmdsets = yield [cmdset for cmdset in cmdsets if cmdset] + cmdsets = yield [cmdset for cmdset in cmdsets if cmdset and cmdset.key!="Empty"] # report cmdset errors to user (these should already have been logged) yield [caller.msg(cmdset.message) for cmdset in cmdsets if cmdset.key == "_CMDSET_ERROR"] - # sort cmdsets after reverse priority (highest prio are merged in last) - yield cmdsets.sort(key=lambda x: x.priority) - #cmdsets = yield sorted(cmdsets, key=lambda x: x.priority) if cmdsets: + # we group and merge all same-prio cmdsets separately (this avoids order-dependent + # clashes in certain cases, such as when duplicates=True) + tempmergers = {} + for cmdset in cmdsets: + prio = cmdset.priority + if prio in tempmergers: + # merge same-prio cmdset together separately + tempmergers[prio] = yield cmdset + tempmergers[prio] + else: + tempmergers[prio] = cmdset + + # sort cmdsets after reverse priority (highest prio are merged in last) + cmdsets = yield sorted(tempmergers.values(), key=lambda x: x.priority) + # Merge all command sets into one, beginning with the lowest-prio one cmdset = cmdsets.pop(0) for merging_cmdset in cmdsets: