Kill proxy with fire

It's not needed since we can import at function scope. Also make
chk_nightdone implicit for role commands executed during night, so we
can remove tons of redundant calls.
This commit is contained in:
skizzerz 2017-12-29 16:49:09 -06:00
parent b677400ce4
commit e8408214f5
17 changed files with 36 additions and 169 deletions

View File

@ -278,7 +278,8 @@ class command:
return # commands not allowed in alt channels
if "" in self.commands:
return self.func(var, dispatcher, rest)
self.func(var, dispatcher, rest)
return
if self.phases and var.PHASE not in self.phases:
return
@ -298,12 +299,18 @@ class command:
return
if self.roles or (self.users is not None and user in self.users):
return self.func(var, dispatcher, rest) # don't check restrictions for role commands
self.func(var, dispatcher, rest) # don't check restrictions for role commands
# Role commands might end the night if it's nighttime
if var.PHASE == "night":
from src.wolfgame import chk_nightdone
chk_nightdone(cli)
return
if self.owner_only:
if user.is_owner():
adminlog(chan, rawnick, self.name, rest)
return self.func(var, dispatcher, rest)
self.func(var, dispatcher, rest)
return
dispatcher.pm(messages["not_owner"])
return
@ -325,12 +332,13 @@ class command:
if self.flag:
if self.flag in flags:
adminlog(chan, rawnick, self.name, rest)
return self.func(var, dispatcher, rest)
self.func(var, dispatcher, rest)
return
dispatcher.pm(messages["not_an_admin"])
return
return self.func(var, dispatcher, rest)
self.func(var, dispatcher, rest)
class cmd:
def __init__(self, *cmds, raw_nick=False, flag=None, owner_only=False,
@ -425,7 +433,8 @@ class cmd:
hostmask = nick + "!" + ident + "@" + host
if "" in self.cmds:
return self.func(*largs)
self.func(*largs)
return
if self.phases and var.PHASE not in self.phases:
return
@ -448,7 +457,12 @@ class cmd:
return
if self.roles or (self.nicks is not None and nick in self.nicks):
return self.func(*largs) # don't check restrictions for role commands
self.func(*largs) # don't check restrictions for role commands
# Role commands might end the night if it's nighttime
if var.PHASE == "night":
from src.wolfgame import chk_nightdone
chk_nightdone(cli)
return
forced_owner_only = False
if hasattr(botconfig, "OWNERS_ONLY_COMMANDS"):
@ -461,7 +475,8 @@ class cmd:
if self.owner_only or forced_owner_only:
if owner:
adminlog(chan, rawnick, self.name, rest)
return self.func(*largs)
self.func(*largs)
return
if chan == nick:
pm(cli, nick, messages["not_owner"])
@ -473,7 +488,8 @@ class cmd:
admin = is_admin(nick, ident, host)
if self.flag and (admin or owner):
adminlog(chan, rawnick, self.name, rest)
return self.func(*largs)
self.func(*largs)
return
denied_cmds = var.DENY[hostmask] | var.DENY_ACCS[acc]
for command in self.cmds:
@ -487,14 +503,15 @@ class cmd:
if self.flag:
if self.flag in flags:
adminlog(chan, rawnick, self.name, rest)
return self.func(*largs)
self.func(*largs)
return
elif chan == nick:
pm(cli, nick, messages["not_an_admin"])
else:
cli.notice(nick, messages["not_an_admin"])
return
return self.func(*largs)
self.func(*largs)
class hook:
def __init__(self, name, hookid=-1):

View File

@ -985,7 +985,6 @@ class SleepyMode(GameMode):
if "correct" in self.on_path:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_wake"])
self.having_nightmare = None
chk_nightdone(cli)
elif "fake1" in self.on_path:
pm(cli, self.having_nightmare, messages["sleepy_nightmare_fake_1"])
self.step = 0
@ -1452,10 +1451,13 @@ class MudkipMode(GameMode):
self.recursion_guard = True
gameid = var.GAME_ID
last = tovote[-1]
from src.wolfgame import chk_decision
for p in tovote:
deadlist = tovote[:]
deadlist.remove(p)
chk_decision(cli, force=p, deadlist=deadlist, end_game=p is last)
self.recursion_guard = False
# gameid changes if game stops due to us voting someone
if var.GAME_ID == gameid:

View File

@ -1,97 +0,0 @@
""" This module introduces two decorators - @proxy.stub and @proxy.impl
@proxy.stub is used to decorate a stub method that should be filled in
with an implementation in some other module. Calling the stub method
calls the implementation method in the other module instead of the stub
method itself (or raises a NotImplementedError if no such
implementation exists)
@proxy.impl is used to define a previously-declared stub with an actual
implementation to call -- the signature for the implementation must
exactly match the signature for the stub (enforced for Python 3.3+).
Attempting to implement a non-existent stub is an error, as is trying
to re-implement a stub that is already implemented.
Example:
(foo.py)
@proxy.stub
def my_method(foo, bar=10):
pass
(bar.py)
@proxy.impl
def my_method(foo, bar=10):
return foo * bar
"""
import inspect
IMPLS = {}
SIGS = {}
def stub(f):
def inner(*args, **kwargs):
_ignore_locals_ = True
if f.__name__ not in IMPLS:
raise NotImplementedError(("This proxy stub has not yet been "
"implemented in another module"))
return IMPLS[f.__name__](*args, **kwargs)
if f.__name__ in SIGS:
_sigmatch(f)
SIGS[f.__name__] = inspect.signature(f)
return inner
def impl(f):
if f.__name__ not in SIGS:
raise NameError(("Attempting to implement a proxy stub {0} that does "
"not exist").format(f.__name__))
if f.__name__ in IMPLS:
raise SyntaxError(("Attempting to implement a proxy stub {0} that "
"already has an implementation").format(f.__name__))
_sigmatch(f)
# Always wrap proxy implementations in an error handler
# proxy needs to be a top level (no dependencies) module, so can't import this
# up top or else we get loops
from src.decorators import handle_error
IMPLS[f.__name__] = handle_error(f)
# allows this method to be called directly in our module rather
# than forcing use of the stub's module
return handle_error(f)
def _sigmatch(f):
rs = inspect.signature(f)
ts = SIGS[f.__name__]
if len(rs.parameters) != len(ts.parameters):
raise TypeError(
("Arity does not match existing stub, "
"expected {0} parameters but got {1}.").format(
len(ts.parameters), len(rs.parameters)))
opl = list(rs.parameters.values())
tpl = list(ts.parameters.values())
for i in range(len(rs.parameters)):
op = opl[i]
tp = tpl[i]
if op.name != tp.name:
raise TypeError(
("Parameter name does not match existing stub, "
"expected {0} but got {1}.").format(tp.name, op.name))
if op.default != tp.default:
raise TypeError(
("Default value of parameter does not match existing stub "
"for parameter {0}, expected {1} but got {2}.").format(
op.name,
("no default" if tp.default is inspect.Parameter.empty
else repr(tp.default)),
("no default" if op.default is inspect.Parameter.empty
else repr(op.default))))
if op.kind != tp.kind:
raise TypeError(
("Parameter type does not match existing stub for "
"parameter {0}, expected {1} but got {2}.").format(
op.name, str(tp.kind), str(op.kind)))
# vim: set sw=4 expandtab:

View File

@ -47,7 +47,6 @@ def guard(cli, nick, chan, rest):
pm(cli, nick, messages["protecting_target"].format(GUARDED[nick]))
pm(cli, victim, messages["target_protected"])
debuglog("{0} ({1}) GUARD: {2} ({3})".format(nick, role, victim, get_role(victim)))
chk_nightdone(cli)
@cmd("pass", chan=False, pm=True, playing=True, phases=("night",), roles=("bodyguard", "guardian angel"))
def pass_cmd(cli, nick, chan, rest):
@ -58,7 +57,6 @@ def pass_cmd(cli, nick, chan, rest):
PASSED.add(nick)
pm(cli, nick, messages["guardian_no_protect"])
debuglog("{0} ({1}) PASS".format(nick, get_role(nick)))
chk_nightdone(cli)
@event_listener("rename_player")
def on_rename(evt, cli, var, prefix, nick):

View File

@ -50,7 +50,6 @@ def see(cli, nick, chan, rest):
relay_wolfchat_command(cli, nick, messages["doomsayer_wolfchat"].format(nick, victim), ("doomsayer",), is_wolf_command=True)
SEEN.add(nick)
chk_nightdone(cli)
@event_listener("rename_player")
def on_rename(evt, cli, var, prefix, nick):

View File

@ -38,8 +38,6 @@ def dullahan_kill(var, wrapper, message):
debuglog("{0} (dullahan) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
chk_nightdone(wrapper.client)
@command("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("dullahan",))
def dullahan_retract(var, wrapper, message):
"""Removes a dullahan's kill selection."""

View File

@ -44,7 +44,6 @@ def hvisit(var, wrapper, message):
revt.dispatch(var, wrapper.source, target)
debuglog("{0} (harlot) VISIT: {1} ({2})".format(wrapper.source, target, vrole))
chk_nightdone(wrapper.client)
@command("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("harlot",))
def pass_cmd(var, wrapper, message):
@ -55,7 +54,6 @@ def pass_cmd(var, wrapper, message):
PASSED.add(wrapper.source)
wrapper.pm(messages["no_visit"])
debuglog("{0} (harlot) PASS".format(wrapper.source))
chk_nightdone(wrapper.client)
@event_listener("bite")
def on_bite(evt, var, alpha, target):

View File

@ -39,7 +39,6 @@ def hunter_kill(var, wrapper, message):
wrapper.pm(messages["player_kill"].format(orig))
debuglog("{0} (hunter) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
chk_nightdone(wrapper.client)
@command("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("hunter",))
def hunter_retract(var, wrapper, message):
@ -63,7 +62,6 @@ def hunter_pass(var, wrapper, message):
wrapper.pm(messages["hunter_pass"])
debuglog("{0} (hunter) PASS".format(wrapper.source))
chk_nightdone(wrapper.client)
@event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):

View File

@ -81,8 +81,6 @@ def charm(var, wrapper, message):
debuglog("{0} (piper) CHARM {1} ({2})".format(wrapper.source, target1, get_main_role(target1)))
wrapper.send(messages["charm_success"].format(orig1))
chk_nightdone(wrapper.client)
@event_listener("chk_win", priority=2)
def on_chk_win(evt, cli, var, rolemap, mainroles, lpl, lwolves, lrealwolves):
# lpl doesn't included wounded/sick people or consecrating priests

View File

@ -73,7 +73,6 @@ def see(cli, nick, chan, rest):
debuglog("{0} ({1}) SEE: {2} ({3}) as {4} ({5} aura)".format(nick, role, victim, vrole, victimrole, aura))
SEEN.add(nick)
chk_nightdone(cli)
@event_listener("rename_player")
def on_rename(evt, cli, var, prefix, nick):

View File

@ -87,7 +87,6 @@ def totem(cli, nick, chan, rest, prefix="You"): # XXX: The transition_day_begin
relay_wolfchat_command(cli, nick, messages["shaman_wolfchat"].format(nick, original_victim), ("wolf shaman",), is_wolf_command=True)
SHAMANS[nick] = (victim, original_victim)
debuglog("{0} ({1}) TOTEM: {2} ({3})".format(nick, role, victim, TOTEMS[nick]))
chk_nightdone(cli)
@event_listener("rename_player")
def on_rename(evt, cli, var, prefix, nick):

View File

@ -50,7 +50,6 @@ def vg_kill(var, wrapper, message):
wrapper.pm(messages["player_kill"].format(orig))
debuglog("{0} (vengeful ghost) KILL: {1} ({2})".format(wrapper.source.nick, target, get_main_role(target)))
chk_nightdone(wrapper.source.client)
@command("retract", "r", chan=False, pm=True, playing=False, phases=("night",))
def vg_retract(var, wrapper, message):

View File

@ -33,8 +33,6 @@ def vigilante_kill(var, wrapper, message):
debuglog("{0} (vigilante) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
chk_nightdone(wrapper.client)
@command("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("vigilante",))
def vigilante_retract(var, wrapper, message):
"""Removes a vigilante's kill selection."""
@ -53,7 +51,6 @@ def vigilante_pass(var, wrapper, message):
wrapper.send(messages["hunter_pass"])
debuglog("{0} (vigilante) PASS".format(wrapper.source))
chk_nightdone(wrapper.client)
@event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):

View File

@ -33,7 +33,6 @@ def choose_idol(cli, nick, chan, rest):
pm(cli, nick, messages["wild_child_success"].format(victim))
debuglog("{0} (wild child) IDOLIZE: {1} ({2})".format(nick, victim, get_role(victim)))
chk_nightdone(cli)
@event_listener("see")
def on_see(evt, cli, var, seer, victim):

View File

@ -93,7 +93,6 @@ def wolf_kill(cli, nick, chan, rest):
if in_wolflist(nick, nick):
relay_wolfchat_command(cli, nick, msg, var.WOLF_ROLES, is_wolf_command=True, is_kill_command=True)
chk_nightdone(cli)
@cmd("retract", "r", chan=False, pm=True, playing=True, phases=("night",))
def wolf_retract(cli, nick, chan, rest):

View File

@ -4,18 +4,16 @@ import re
import botconfig
import src.settings as var
from src import proxy, debuglog
from src import debuglog
from src.events import Event
from src.messages import messages
__all__ = ["pm", "is_fake_nick", "mass_mode", "mass_privmsg", "reply",
"is_user_simple", "is_user_notice", "in_wolflist",
"relay_wolfchat_command", "chk_nightdone", "chk_decision",
"chk_win", "irc_lower", "irc_equals", "match_hostmask",
"relay_wolfchat_command", "irc_lower", "irc_equals", "match_hostmask",
"is_owner", "is_admin", "plural", "singular", "list_players",
"list_players_and_roles", "get_role", "get_roles",
"get_reveal_role", "change_role", "role_order", "break_long_message",
"complete_match","complete_one_match", "get_victim", "get_nick", "InvalidModeException"]
"get_role", "get_roles", "get_reveal_role", "change_role", "role_order", "break_long_message",
"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:
@ -175,18 +173,6 @@ def relay_wolfchat_command(cli, nick, message, roles, is_wolf_command=False, is_
if var.SPECTATING_WOLFCHAT:
player.send_messages()
@proxy.stub
def chk_nightdone(cli):
pass
@proxy.stub
def chk_decision(cli, force="", end_game=True, deadlist=[]):
pass
@proxy.stub
def chk_win(cli, end_game=True, winner=None):
pass
def irc_lower(nick):
if nick is None:
return None
@ -314,11 +300,6 @@ def list_players(roles=None, *, mainroles=None):
from src.functions import get_players
return [p.nick for p in get_players(roles, mainroles=mainroles)]
def list_players_and_roles():
# TODO DEPRECATED: replace with iterating over var.MAIN_ROLES directly
# (and working with user objects instead of nicks)
return {u.nick: r for u, r in var.MAIN_ROLES.items()}
def get_role(p):
# TODO DEPRECATED: replace with get_main_role(user)
from src import users

View File

@ -47,7 +47,7 @@ import botconfig
import src
import src.settings as var
from src.utilities import *
from src import db, events, dispatcher, channels, users, hooks, logger, proxy, debuglog, errlog, plog
from src import db, events, dispatcher, channels, users, hooks, logger, debuglog, errlog, plog
from src.decorators import command, cmd, hook, handle_error, event_listener, COMMANDS
from src.functions import get_players, get_all_players, get_participants, get_main_role, get_all_roles
from src.messages import messages
@ -1796,7 +1796,6 @@ def fday(cli, nick, chan, rest):
transition_day(cli)
# Specify force = "nick" to force nick to be lynched
@proxy.impl
def chk_decision(cli, force="", end_game=True, deadlist=[]):
with var.GRAVEYARD_LOCK:
if var.PHASE != "day":
@ -2245,7 +2244,6 @@ def stop_game(winner="", abort=False, additional_winners=None, log=True):
return True
@proxy.impl
def chk_win(cli, end_game=True, winner=None):
""" Returns True if someone won """
chan = botconfig.CHANNEL
@ -3751,7 +3749,6 @@ def on_transition_day_resolve_end(evt, var, victims):
if evt.data["novictmsg"] and len(evt.data["dead"]) == 0:
evt.data["message"].append(random.choice(messages["no_victims"]) + messages["no_victims_append"])
@proxy.impl
def chk_nightdone(cli):
if var.PHASE != "night":
return
@ -4369,7 +4366,6 @@ def observe(cli, nick, chan, rest):
relay_wolfchat_command(cli, nick, messages["sorcerer_success_wolfchat"].format(nick, victim), ("sorcerer"))
debuglog("{0} ({1}) OBSERVE: {2} ({3})".format(nick, role, victim, get_role(victim)))
chk_nightdone(cli)
@cmd("pray", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("prophet",))
def pray(cli, nick, chan, rest):
@ -4412,7 +4408,6 @@ def pray(cli, nick, chan, rest):
pm(cli, nick, messages["vision_only_role_self"].format(role))
var.PRAYED[nick][0] = 2
debuglog("{0} ({1}) PRAY {2} - ONLY".format(nick, get_role(nick), role))
chk_nightdone(cli)
return
# select someone with the role that we haven't looked at before for this particular role
prevlist = (p for p, rl in var.PRAYED[nick][3].items() if role in rl)
@ -4422,7 +4417,6 @@ def pray(cli, nick, chan, rest):
pm(cli, nick, messages["vision_no_more_role"].format(plural(role)))
var.PRAYED[nick][0] = 2
debuglog("{0} ({1}) PRAY {2} - NO OTHER".format(nick, get_role(nick), role))
chk_nightdone(cli)
return
target = random.choice(list(people))
var.PRAYED[nick][0] = 1
@ -4475,8 +4469,6 @@ def pray(cli, nick, chan, rest):
pm(cli, target, messages["vision_prophet"].format(nick))
debuglog("{0} ({1}) PRAY REVEAL".format(nick, get_role(nick)))
chk_nightdone(cli)
@cmd("give", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("doctor",))
@cmd("immunize", "immunise", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("doctor",))
def immunize(cli, nick, chan, rest):
@ -4548,7 +4540,6 @@ def bite_cmd(cli, nick, chan, rest):
pm(cli, nick, messages["alpha_bite_target"].format(victim))
relay_wolfchat_command(cli, nick, messages["alpha_bite_wolfchat"].format(nick, victim), ("alpha wolf",), is_wolf_command=True)
debuglog("{0} ({1}) BITE: {2} ({3})".format(nick, get_role(nick), actual, get_role(actual)))
chk_nightdone(cli)
@cmd("pass", chan=False, pm=True, playing=True, phases=("night",),
roles=("turncoat", "warlock"))
@ -4585,7 +4576,6 @@ def pass_cmd(cli, nick, chan, rest):
var.PASSED.add(nick)
debuglog("{0} ({1}) PASS".format(nick, get_role(nick)))
chk_nightdone(cli)
@cmd("side", chan=False, pm=True, playing=True, phases=("night",), roles=("turncoat",))
def change_sides(cli, nick, chan, rest, sendmsg=True):
@ -4602,7 +4592,6 @@ def change_sides(cli, nick, chan, rest, sendmsg=True):
pm(cli, nick, messages["turncoat_success"].format(team))
var.TURNCOATS[nick] = (team, var.NIGHT_COUNT)
debuglog("{0} ({1}) SIDE {2}".format(nick, get_role(nick), team))
chk_nightdone(cli)
@cmd("choose", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
@cmd("match", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
@ -4666,7 +4655,6 @@ def choose(cli, nick, chan, rest, sendmsg=True): # XXX: transition_day also need
pm(cli, victim2, messages["matchmaker_target_notify_simple"].format(victim))
debuglog("{0} ({1}) MATCH: {2} ({3}) + {4} ({5})".format(nick, get_role(nick), victim, get_role(victim), victim2, get_role(victim2)))
chk_nightdone(cli)
@cmd("target", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("assassin",))
def target(cli, nick, chan, rest):
@ -4692,7 +4680,6 @@ def target(cli, nick, chan, rest):
pm(cli, nick, messages["assassin_target_success"].format(victim))
debuglog("{0} (assassin) TARGET: {1} ({2})".format(nick, victim, get_role(victim)))
chk_nightdone(cli)
@cmd("hex", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("hag",))
def hex_target(cli, nick, chan, rest):
@ -4735,7 +4722,6 @@ def hex_target(cli, nick, chan, rest):
relay_wolfchat_command(cli, nick, messages["hex_success_wolfchat"].format(nick, victim), ("hag",))
debuglog("{0} ({1}) HEX: {2} ({3})".format(nick, get_role(nick), victim, get_role(victim)))
chk_nightdone(cli)
@cmd("curse", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("warlock",))
def curse(cli, nick, chan, rest):
@ -4780,7 +4766,6 @@ def curse(cli, nick, chan, rest):
relay_wolfchat_command(cli, nick, messages["curse_success_wolfchat"].format(nick, victim), ("warlock",))
debuglog("{0} ({1}) CURSE: {2} ({3})".format(nick, get_role(nick), victim, vrole))
chk_nightdone(cli)
@cmd("clone", chan=False, pm=True, playing=True, phases=("night",), roles=("clone",))
def clone(cli, nick, chan, rest):
@ -4819,7 +4804,6 @@ def clone(cli, nick, chan, rest):
pm(cli, nick, messages["clone_target_success"].format(victim))
debuglog("{0} ({1}) CLONE: {2} ({3})".format(nick, get_role(nick), victim, get_role(victim)))
chk_nightdone(cli)
var.ROLE_COMMAND_EXCEPTIONS.add("clone")
@ -5249,7 +5233,6 @@ def transition_night(cli):
# If there are no nightroles that can act, immediately turn it to daytime
chk_nightdone(cli)
def cgamemode(cli, arg):
chan = botconfig.CHANNEL
if var.ORIGINAL_SETTINGS: # needs reset