Huge overhaul to the decorators + small changes.
- Merge channel and PM commands in a single decorator. - Add many parameters for the decorators, reducing commands cluster. - Added back the admin_only check for some commands; special-cased '<console>'. - Moved the checking for which roles are seen wolf in the settings; same for seen as default. - Added a variable to pick if one is seen as the default role or as a villager where applicable (default: True). - Fixed seer/oracle seeing through amnesiac. - Some fixes to the totem chances that I forgot to add in the previous commit. - Removed some useless module imports. - Moved some functions to settings. - Changed all single-quotes to double-quotes in commands for consistency. - Renamed 'cmd' variable in both force and rforce commands to avoid confusion. - Probably a bunch of other things. Don't consider this commit description to be 100% complete.
This commit is contained in:
parent
53cf4970ca
commit
df26d8d25e
@ -7,6 +7,7 @@ import tools.moduleloader as ld
|
||||
import traceback
|
||||
from settings import common as var
|
||||
from base64 import b64encode
|
||||
from oyoyo.parse import parse_nick
|
||||
import imp
|
||||
|
||||
def on_privmsg(cli, rawnick, chan, msg, notice = False):
|
||||
@ -19,50 +20,39 @@ def on_privmsg(cli, rawnick, chan, msg, notice = False):
|
||||
(chan == botconfig.NICK and not botconfig.ALLOW_PRIVATE_NOTICE_COMMANDS))):
|
||||
return # not allowed in settings
|
||||
|
||||
if chan != botconfig.NICK: #not a PM
|
||||
if currmod and "" in currmod.COMMANDS.keys():
|
||||
for fn in currmod.COMMANDS[""]:
|
||||
if chan == botconfig.NICK:
|
||||
chan = parse_nick(rawnick)[0]
|
||||
|
||||
if currmod and "" in currmod.COMMANDS.keys():
|
||||
for fn in currmod.COMMANDS[""]:
|
||||
try:
|
||||
fn(cli, rawnick, chan, msg)
|
||||
except:
|
||||
if botconfig.DEBUG_MODE:
|
||||
raise
|
||||
else:
|
||||
logging.error(traceback.format_exc())
|
||||
cli.msg(chan, "An error has occurred and has been logged.")
|
||||
|
||||
for x in set(list(COMMANDS.keys()) + (list(currmod.COMMANDS.keys()) if currmod else list())):
|
||||
if chan != parse_nick(rawnick)[0] and not msg.lower().startswith(botconfig.CMD_CHAR):
|
||||
break # channel message but no prefix; ignore
|
||||
if msg.lower().startswith(botconfig.CMD_CHAR+x):
|
||||
h = msg[len(x)+len(botconfig.CMD_CHAR):]
|
||||
elif not x or msg.lower().startswith(x):
|
||||
h = msg[len(x):]
|
||||
else:
|
||||
continue
|
||||
if not h or h[0] == " ":
|
||||
for fn in COMMANDS.get(x, []) + (currmod.COMMANDS.get(x, []) if currmod else []):
|
||||
try:
|
||||
fn(cli, rawnick, chan, msg)
|
||||
except Exception as e:
|
||||
fn(cli, rawnick, chan, h.lstrip())
|
||||
except:
|
||||
if botconfig.DEBUG_MODE:
|
||||
raise e
|
||||
raise
|
||||
else:
|
||||
logging.error(traceback.format_exc())
|
||||
cli.msg(chan, "An error has occurred and has been logged.")
|
||||
# Now that is always called first.
|
||||
for x in set(list(COMMANDS.keys()) + (list(currmod.COMMANDS.keys()) if currmod else list())):
|
||||
if x and msg.lower().startswith(botconfig.CMD_CHAR+x):
|
||||
h = msg[len(x)+len(botconfig.CMD_CHAR):]
|
||||
if not h or h[0] == " " or not x:
|
||||
for fn in COMMANDS.get(x,[])+(currmod.COMMANDS.get(x,[]) if currmod else []):
|
||||
try:
|
||||
fn(cli, rawnick, chan, h.lstrip())
|
||||
except Exception as e:
|
||||
if botconfig.DEBUG_MODE:
|
||||
raise e
|
||||
else:
|
||||
logging.error(traceback.format_exc())
|
||||
cli.msg(chan, "An error has occurred and has been logged.")
|
||||
|
||||
else:
|
||||
for x in set(list(PM_COMMANDS.keys()) + (list(currmod.PM_COMMANDS.keys()) if currmod else list())):
|
||||
if msg.lower().startswith(botconfig.CMD_CHAR+x):
|
||||
h = msg[len(x)+len(botconfig.CMD_CHAR):]
|
||||
elif not x or msg.lower().startswith(x):
|
||||
h = msg[len(x):]
|
||||
else:
|
||||
continue
|
||||
if not h or h[0] == " " or not x:
|
||||
for fn in PM_COMMANDS.get(x, [])+(currmod.PM_COMMANDS.get(x,[]) if currmod else []):
|
||||
try:
|
||||
fn(cli, rawnick, h.lstrip())
|
||||
except Exception as e:
|
||||
if botconfig.DEBUG_MODE:
|
||||
raise e
|
||||
else:
|
||||
logging.error(traceback.format_exc())
|
||||
cli.msg(chan, "An error has occurred and has been logged.")
|
||||
|
||||
def __unhandled__(cli, prefix, cmd, *args):
|
||||
currmod = ld.MODULES[ld.CURRENT_MODULE]
|
||||
@ -87,11 +77,9 @@ def __unhandled__(cli, prefix, cmd, *args):
|
||||
|
||||
|
||||
COMMANDS = {}
|
||||
PM_COMMANDS = {}
|
||||
HOOKS = {}
|
||||
|
||||
cmd = decorators.generate(COMMANDS)
|
||||
pmcmd = decorators.generate(PM_COMMANDS)
|
||||
hook = decorators.generate(HOOKS, raw_nick=True, permissions=False)
|
||||
|
||||
def connect_callback(cli):
|
||||
|
1097
modules/wolfgame.py
1097
modules/wolfgame.py
File diff suppressed because it is too large
Load Diff
@ -66,6 +66,7 @@ START_WITH_DAY = False
|
||||
WOLF_STEALS_GUN = True # at night, the wolf can steal steal the victim's bullets
|
||||
ROLE_REVEAL = True
|
||||
LOVER_WINS_WITH_FOOL = False # if fool is lynched, does their lover win with them?
|
||||
DEFAULT_SEEN_AS_VILL = True # non-wolves are seen as villager regardless of the default role
|
||||
|
||||
# Minimum number of players needed for mad scientist to skip over dead people when determining who is next to them
|
||||
# Set to 0 to always skip over dead players. Note this is number of players that !joined, NOT number of players currently alive
|
||||
@ -180,13 +181,17 @@ ROLE_GUIDE = {# village roles
|
||||
# If every wolf role dies, and there are no remaining traitors, the game ends and villagers win (monster may steal win)
|
||||
WOLF_ROLES = ["wolf", "alpha wolf", "werecrow", "wolf cub"]
|
||||
# Access to wolfchat, and counted towards the # of wolves vs villagers when determining if a side has won
|
||||
WOLFCHAT_ROLES = ["wolf", "alpha wolf", "werecrow", "wolf cub", "traitor", "hag", "sorcerer"]
|
||||
WOLFCHAT_ROLES = WOLF_ROLES + ["traitor", "hag", "sorcerer"]
|
||||
# Wins with the wolves, even if the roles are not necessarily wolves themselves
|
||||
WOLFTEAM_ROLES = ["wolf", "alpha wolf", "werecrow", "wolf cub", "traitor", "hag", "sorcerer", "minion", "cultist"]
|
||||
WOLFTEAM_ROLES = WOLFCHAT_ROLES + ["minion", "cultist"]
|
||||
# These roles never win as a team, only ever individually (either instead of or in addition to the regular winners)
|
||||
TRUE_NEUTRAL_ROLES = ["crazed shaman", "fool", "jester", "monster", "clone"]
|
||||
# These are the roles that will NOT be used for when amnesiac turns, everything else is fair game! (var.DEFAULT_ROLE is also appended if not in this list)
|
||||
AMNESIAC_BLACKLIST = ["monster", "amnesiac", "minion", "matchmaker", "clone", "doctor", "villager", "cultist"]
|
||||
# These roles are seen as wolf by the seer/oracle
|
||||
SEEN_WOLF = WOLF_ROLES + ["monster", "mad scientist"]
|
||||
# These are seen as the default role (or villager) when seen by seer
|
||||
SEEN_DEFAULT = ["traitor", "hag", "sorcerer", "village elder", "time lord", "villager", "cultist", "minion", "vengeful ghost", "lycan", "clone", "fool", "jester"]
|
||||
|
||||
# The roles in here are considered templates and will be applied on TOP of other roles. The restrictions are a list of roles that they CANNOT be applied to
|
||||
# NB: if you want a template to apply to everyone, list it here but make the restrictions an empty list. Templates not listed here are considered full roles instead
|
||||
@ -223,7 +228,7 @@ QUIT_MESSAGES_NO_REVEAL = ("\u0002{0}\u0002 suddenly falls over dead before the
|
||||
"\u0002{0}\u0002 fell off the roof of their house and is now dead.",
|
||||
"\u0002{0}\u0002 is crushed to death by a falling tree. The villagers desperately try to save them, but it is too late.")
|
||||
|
||||
import botconfig, fnmatch
|
||||
import botconfig, fnmatch, sys, time, re
|
||||
|
||||
RULES = (botconfig.CHANNEL + " channel rules: http://wolf.xnrand.com/rules")
|
||||
DENY = {}
|
||||
@ -240,6 +245,32 @@ PING_IN_ACCS = [] # accounts of people who have opted in for ping
|
||||
|
||||
is_role = lambda plyr, rol: rol in ROLES and plyr in ROLES[rol]
|
||||
|
||||
def pm(cli, target, message): # message either privmsg or notice, depending on user settings
|
||||
if is_fake_nick(target) and botconfig.DEBUG_MODE:
|
||||
print("[{0}] Would send message to fake nick {1}: {2}".format(
|
||||
time.strftime("%d/%b/%Y %H:%M:%S"),
|
||||
target,
|
||||
message), file=sys.stderr)
|
||||
|
||||
return
|
||||
|
||||
if is_user_notice(target):
|
||||
cli.notice(target, message)
|
||||
return
|
||||
|
||||
cli.msg(target, message)
|
||||
|
||||
def is_user_notice(nick):
|
||||
if nick in USERS and USERS[nick]["account"] and USERS[nick]["account"] != "*":
|
||||
if USERS[nick]["account"] in PREFER_NOTICE_ACCS:
|
||||
return True
|
||||
if nick in USERS and USERS[nick]["cloak"] in PREFER_NOTICE and not ACCOUNTS_ONLY:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_fake_nick(who):
|
||||
return re.match("[0-9]+", who)
|
||||
|
||||
def is_admin(nick):
|
||||
if nick not in USERS.keys():
|
||||
return False
|
||||
|
@ -15,7 +15,8 @@ import settings.wolfgame as var
|
||||
|
||||
def generate(fdict, permissions=True, **kwargs):
|
||||
"""Generates a decorator generator. Always use this"""
|
||||
def cmd(*s, raw_nick=False, admin_only=False, owner_only=False, hookid=-1):
|
||||
def cmd(*s, raw_nick=False, admin_only=False, owner_only=False, chan=True, pm=False,
|
||||
game=False, join=False, none=False, playing=False, roles=(), hookid=-1):
|
||||
def dec(f):
|
||||
def innerf(*args):
|
||||
largs = list(args)
|
||||
@ -29,13 +30,15 @@ def generate(fdict, permissions=True, **kwargs):
|
||||
else:
|
||||
nick = ""
|
||||
cloak = ""
|
||||
if len(largs) > 3 and largs[2] and largs[2][0] == "#":
|
||||
chan = largs[2]
|
||||
else:
|
||||
chan = ""
|
||||
if not raw_nick and len(largs) > 1 and largs[1]:
|
||||
largs[1] = nick
|
||||
if chan and not chan == botconfig.CHANNEL and not admin_only and not owner_only:
|
||||
if nick == "<console>":
|
||||
return f(*largs) # special case; no questions
|
||||
if not pm and largs[2] == nick: # PM command
|
||||
return
|
||||
if not chan and largs[2] != nick: # channel command
|
||||
return
|
||||
if largs[2].startswith("#") and largs[2] != botconfig.CHANNEL and not admin_only and not owner_only:
|
||||
if "" in s:
|
||||
return # Don't have empty commands triggering in other channels
|
||||
allowed = False
|
||||
@ -51,6 +54,33 @@ def generate(fdict, permissions=True, **kwargs):
|
||||
acc = None
|
||||
if "" in s:
|
||||
return f(*largs)
|
||||
if game and var.PHASE not in ("day", "night") + (("join",) if join else ()):
|
||||
largs[0].notice(nick, "No game is currently running.")
|
||||
return
|
||||
if ((join and none and var.PHASE not in ("join", "none"))
|
||||
or (none and not join and var.PHASE != "none")):
|
||||
largs[0].notice(nick, "Sorry, but the game is already running. Try again next time.")
|
||||
return
|
||||
if join and not none:
|
||||
if var.PHASE == "none":
|
||||
largs[0].notice(nick, "No game is currently running.")
|
||||
return
|
||||
if var.PHASE != "join" and not game:
|
||||
largs[0].notice(nick, "Werewolf is already in play.")
|
||||
return
|
||||
if playing and nick not in var.list_players() or nick in var.DISCONNECTED.keys():
|
||||
cli.notice(nick, "You're not currently playing.")
|
||||
return
|
||||
if roles:
|
||||
for role in roles:
|
||||
if nick in var.ROLES[role]:
|
||||
break
|
||||
else:
|
||||
if len(roles) == 1:
|
||||
var.pm(largs[0], nick, "Only a{0} {1} may use this command.".format("n" if roles[0][0] in "aeiou" else "", roles[0]))
|
||||
else:
|
||||
var.pm(largs[0], nick, "Only a{0} {1} or {2} may use this command.".format("n" if roles[0][0] in "aeiou" else "", ", ".join(roles[:-1]), roles[-1]))
|
||||
return
|
||||
if acc:
|
||||
for pattern in var.DENY_ACCOUNTS.keys():
|
||||
if fnmatch.fnmatch(acc.lower(), pattern.lower()):
|
||||
@ -105,6 +135,13 @@ def generate(fdict, permissions=True, **kwargs):
|
||||
innerf.owner_only = owner_only
|
||||
innerf.raw_nick = raw_nick
|
||||
innerf.admin_only = admin_only
|
||||
innerf.chan = chan
|
||||
innerf.pm = pm
|
||||
innerf.none = none
|
||||
innerf.join = join
|
||||
innerf.game = game
|
||||
innerf.playing = playing
|
||||
innerf.roles = roles
|
||||
innerf.hookid = hookid
|
||||
innerf.__doc__ = f.__doc__
|
||||
return innerf
|
||||
|
Loading…
x
Reference in New Issue
Block a user