Fix for #176 improve invalid role errors

This commit is contained in:
Fudster 2017-02-02 02:31:51 +00:00 committed by jacob1
parent 4c67a5b438
commit 0a6c6200ab
2 changed files with 66 additions and 42 deletions

View File

@ -15,7 +15,7 @@ __all__ = ["pm", "is_fake_nick", "mass_mode", "mass_privmsg", "reply",
"is_owner", "is_admin", "plural", "singular", "list_players",
"list_players_and_roles", "list_participants", "get_role", "get_roles",
"get_reveal_role", "get_templates", "role_order", "break_long_message",
"complete_match", "get_victim", "get_nick", "InvalidModeException"]
"complete_match","complete_one_match", "get_victim", "get_nick", "InvalidModeException"]
# message either privmsg or notice, depending on user settings
def pm(cli, target, message):
if is_fake_nick(target) and botconfig.DEBUG_MODE:
@ -418,18 +418,19 @@ def break_long_message(phrases, joinstr = " "):
#completes a partial nickname or string from a list
def complete_match(string, matches):
num_matches = 0
bestmatch = string
possible_matches = set()
for possible in matches:
if string == possible:
return string, 1
return [string]
if possible.startswith(string) or possible.lstrip("[{\\^_`|}]").startswith(string):
bestmatch = possible
num_matches += 1
if num_matches != 1:
return None, num_matches
else:
return bestmatch, 1
possible_matches.add(possible)
return sorted(possible_matches)
def complete_one_match(string, matches):
matches = complete_match(string,matches)
if len(matches) == 1:
return matches.pop()
return None
#wrapper around complete_match() used for roles
def get_victim(cli, nick, victim, in_chan, self_in_list=False, bot_in_list=False):
@ -444,20 +445,20 @@ def get_victim(cli, nick, victim, in_chan, self_in_list=False, bot_in_list=False
pl.append(botconfig.NICK)
pll.append(botconfig.NICK.lower())
tempvictim, num_matches = complete_match(victim.lower(), pll)
if not tempvictim:
tempvictims = complete_match(victim.lower(), pll)
if len(tempvictims) != 1:
#ensure messages about not being able to act on yourself work
if num_matches == 0 and nick.lower().startswith(victim.lower()):
if len(tempvictims) == 0 and nick.lower().startswith(victim.lower()):
return nick
reply(cli, nick, chan, messages["not_playing"].format(victim), private=True)
return
return pl[pll.index(tempvictim)] #convert back to normal casing
return pl[pll.index(tempvictims.pop())] #convert back to normal casing
# wrapper around complete_match() used for any nick on the channel
def get_nick(cli, nick):
ul = [x for x in var.USERS]
ull = [x.lower() for x in var.USERS]
lnick, num_matches = complete_match(nick.lower(), ull)
lnick = complete_match(nick.lower(), ull)
if not lnick:
return None
return ul[ull.index(lnick)]

View File

@ -2920,7 +2920,7 @@ def goat(cli, nick, chan, rest):
if not rest:
cli.notice(nick, messages["not_enough_parameters"])
victim, _ = complete_match(rest.lower(), ull)
victim = complete_one_match(rest.lower(), ull)
if not victim:
cli.notice(nick, messages["goat_target_not_in_channel"].format(rest))
return
@ -4450,7 +4450,7 @@ def consecrate(cli, nick, chan, rest):
dead = [x.nick for x in var.ALL_PLAYERS if x.nick not in alive]
deadl = [x.lower() for x in dead]
tempvictim, num_matches = complete_match(victim.lower(), deadl)
tempvictim = complete_one_match(victim.lower(), deadl)
if not tempvictim:
pm(cli, nick, messages["consecrate_fail"].format(victim))
return
@ -4539,7 +4539,7 @@ def pray(cli, nick, chan, rest):
pm(cli, nick, messages["not_enough_parameters"])
return
# complete this as a match with other roles (so "cursed" can match "cursed villager" for instance)
role, _ = complete_match(what.lower(), var.ROLE_GUIDE.keys())
role = complete_one_match(what.lower(), var.ROLE_GUIDE.keys())
if role is None:
# typo, let them fix it
pm(cli, nick, messages["specific_invalid_role"].format(what))
@ -4780,7 +4780,7 @@ def change_sides(cli, nick, chan, rest, sendmsg=True):
return
team = re.split(" +", rest)[0]
team, _ = complete_match(team, ("villagers", "wolves"))
team = complete_one_match(team, ("villagers", "wolves"))
if not team:
pm(cli, nick, messages["turncoat_error"])
return
@ -6526,17 +6526,29 @@ def listroles(cli, nick, chan, rest):
elif rest[0] and not rest[0].isdigit():
gamemode = rest[0]
if gamemode not in var.GAME_MODES.keys():
gamemode, _ = complete_match(rest[0], var.GAME_MODES.keys() - ["roles", "villagergame"] - var.DISABLED_GAMEMODES)
matches = complete_match(rest[0], var.GAME_MODES.keys() - {"roles", "villagergame"} - var.DISABLED_GAMEMODES)
if len(matches) > 1:
reply(cli, nick, chan, nick + " " + messages["invalid_mode"].format(rest[0], ", ".join(matches)))
rest = []
roleindex = {}
return
if len(matches) == 0:
reply(cli, nick, chan, nick + " " + messages["invalid_mode_no_list"].format(rest[0], ", ".join(matches)))
rest = []
roleindex = {}
return
else:
gamemode = matches[0]
validMode = gamemode in var.GAME_MODES.keys() and gamemode != "roles" and gamemode != "villagergame" and gamemode not in var.DISABLED_GAMEMODES
if validMode and hasattr(var.GAME_MODES[gamemode][0](), "ROLE_GUIDE"):
mode = var.GAME_MODES[gamemode][0]()
if hasattr(mode, "ROLE_INDEX") and hasattr(mode, "ROLE_GUIDE"):
roleindex = mode.ROLE_INDEX
roleguide = mode.ROLE_GUIDE
elif gamemode == "default" and "ROLE_INDEX" in var.ORIGINAL_SETTINGS and "ROLE_GUIDE" in var.ORIGINAL_SETTINGS:
roleindex = var.ORIGINAL_SETTINGS["ROLE_INDEX"]
roleguide = var.ORIGINAL_SETTINGS["ROLE_GUIDE"]
rest.pop(0)
if hasattr(mode, "ROLE_INDEX") and hasattr(mode, "ROLE_GUIDE"):
roleindex = mode.ROLE_INDEX
roleguide = mode.ROLE_GUIDE
elif gamemode == "default" and "ROLE_INDEX" in var.ORIGINAL_SETTINGS and "ROLE_GUIDE" in var.ORIGINAL_SETTINGS:
roleindex = var.ORIGINAL_SETTINGS["ROLE_INDEX"]
roleguide = var.ORIGINAL_SETTINGS["ROLE_GUIDE"]
else:
if validMode and not hasattr(var.GAME_MODES[gamemode][0](), "ROLE_GUIDE"):
msg.append("{0}: {1}roles is disabled for the {2} game mode.".format(nick, botconfig.CMD_CHAR, gamemode))
@ -6721,10 +6733,15 @@ def game_stats(cli, nick, chan, rest):
if len(rest) and not rest[0].isdigit():
gamemode = rest[0]
if gamemode != "all" and gamemode not in var.GAME_MODES.keys():
gamemode, _ = complete_match(gamemode, var.GAME_MODES.keys())
if not gamemode:
cli.notice(nick, messages["invalid_mode_no_list"].format(rest[0]))
return
matches = complete_match(gamemode, var.GAME_MODES.keys())
if len(matches) == 1:
gamemode = matches[0]
if not matches:
cli.notice(nick, messages["invalid_mode_no_list"].format(rest[0]))
return
if len(matches) > 1:
cli.notice(nick, messages["invalid_mode"].format(rest[0], ", ".join(matches)))
return
rest.pop(0)
# Check for invalid input
if len(rest) and rest[0].isdigit():
@ -6791,11 +6808,14 @@ def player_stats(cli, nick, chan, rest):
else:
role = " ".join(params[1:])
if role not in var.ROLE_GUIDE.keys():
match, _ = complete_match(role, var.ROLE_GUIDE.keys() | ["lover"])
if not match:
matches = complete_match(role, var.ROLE_GUIDE.keys() | {"lover"})
if not matches:
reply(cli, nick, chan, messages["no_such_role"].format(role))
return
role = match
if len(matches) > 1:
reply(cli, nick, chan,nick, messages["invalid_mode"].format(role, ", ".join(matches)))
return
role = matches
# Attempt to find the player's stats
reply(cli, nick, chan, db.get_player_stats(acc, hostmask, role))
@ -6813,13 +6833,16 @@ def vote_gamemode(var, wrapper, gamemode, doreply):
return
if gamemode not in var.GAME_MODES.keys():
match, _ = complete_match(gamemode, var.GAME_MODES.keys() - ["roles", "villagergame"] - var.DISABLED_GAMEMODES)
if not match:
if doreply:
wrapper.pm(messages["invalid_mode_no_list"].format(gamemode))
matches = complete_match(gamemode, var.GAME_MODES.keys() - {"roles", "villagergame"} - var.DISABLED_GAMEMODES)
if not matches:
wrapper.pm(messages["invalid_mode_no_list"].format(gamemode))
return
gamemode = match
if len(matches) > 1:
wrapper.pm(messages["invalid_mode"].format(gamemode, ", ".join(matches)))
return
if len(matches) == 1:
gamemode = matches[0]
if gamemode != "roles" and gamemode != "villagergame" and gamemode not in var.DISABLED_GAMEMODES:
if var.GAMEMODE_VOTES.get(wrapper.source.nick) == gamemode:
wrapper.pm(messages["already_voted_game"].format(gamemode))
@ -7167,9 +7190,9 @@ if botconfig.DEBUG_MODE or botconfig.ALLOWED_NORMAL_MODE_COMMANDS:
if gamemode not in var.GAME_MODES.keys() - var.DISABLED_GAMEMODES:
gamemode = gamemode.split()[0]
gamemode, _ = complete_match(gamemode, var.GAME_MODES.keys() - var.DISABLED_GAMEMODES)
gamemode = complete_one_match(gamemode, var.GAME_MODES.keys() - var.DISABLED_GAMEMODES)
if not gamemode:
cli.notice(nick, messages["invalid_mode_no_list"].format(rest))
cli.notice(nick, messages["invalid_mode_no_list"].format(rest.split()[0]))
return
parts[0] = gamemode