Core: Handle integer arguments in player names gracefully (#4151)

This commit is contained in:
Richard Snider
2025-04-04 19:36:20 -06:00
committed by GitHub
parent b5bf9ed1d7
commit 507e051a5a

View File

@@ -279,22 +279,30 @@ def get_choice(option, root, value=None) -> Any:
raise RuntimeError(f"All options specified in \"{option}\" are weighted as zero.") raise RuntimeError(f"All options specified in \"{option}\" are weighted as zero.")
class SafeDict(dict): class SafeFormatter(string.Formatter):
def __missing__(self, key): def get_value(self, key, args, kwargs):
return '{' + key + '}' if isinstance(key, int):
if key < len(args):
return args[key]
else:
return "{" + str(key) + "}"
else:
return kwargs.get(key, "{" + key + "}")
def handle_name(name: str, player: int, name_counter: Counter): def handle_name(name: str, player: int, name_counter: Counter):
name_counter[name.lower()] += 1 name_counter[name.lower()] += 1
number = name_counter[name.lower()] number = name_counter[name.lower()]
new_name = "%".join([x.replace("%number%", "{number}").replace("%player%", "{player}") for x in name.split("%%")]) new_name = "%".join([x.replace("%number%", "{number}").replace("%player%", "{player}") for x in name.split("%%")])
new_name = string.Formatter().vformat(new_name, (), SafeDict(number=number,
NUMBER=(number if number > 1 else ''), new_name = SafeFormatter().vformat(new_name, (), {"number": number,
player=player, "NUMBER": (number if number > 1 else ''),
PLAYER=(player if player > 1 else ''))) "player": player,
"PLAYER": (player if player > 1 else '')})
# Run .strip twice for edge case where after the initial .slice new_name has a leading whitespace. # Run .strip twice for edge case where after the initial .slice new_name has a leading whitespace.
# Could cause issues for some clients that cannot handle the additional whitespace. # Could cause issues for some clients that cannot handle the additional whitespace.
new_name = new_name.strip()[:16].strip() new_name = new_name.strip()[:16].strip()
if new_name == "Archipelago": if new_name == "Archipelago":
raise Exception(f"You cannot name yourself \"{new_name}\"") raise Exception(f"You cannot name yourself \"{new_name}\"")
return new_name return new_name