Browse Source

major restructuring

--HG--
rename : wolfgame.py => modules/wolfgame.py
rename : var.py => settings/wolfgame.py
rename : decorators.py => tools/decorators.py
rename : wolfgamelogger.py => tools/wolfgamelogger.py
master
Jimmy Cao 13 years ago
parent
commit
38edcffdb1
  1. 0
      modules/__init__.py
  2. 132
      modules/common.py
  3. 47
      modules/sabotage.py
  4. 76
      modules/wolfgame.py
  5. 0
      settings/__init__.py
  6. 6
      settings/sabotage.py
  7. 2
      settings/wolfgame.py
  8. 0
      tools/__init__.py
  9. 0
      tools/decorators.py
  10. 22
      tools/moduleloader.py
  11. 2
      tools/wolfgamelogger.py
  12. 72
      wolfbot.py

0
modules/__init__.py

132
modules/common.py

@ -0,0 +1,132 @@
import botconfig
from tools import decorators
import logging
import tools.moduleloader as ld
def on_privmsg(cli, rawnick, chan, msg):
currmod = ld.MODULES[ld.CURRENT_MODULE]
if chan != botconfig.NICK: #not a PM
if "" in currmod.COMMANDS.keys():
for fn in currmod.COMMANDS[""]:
try:
fn(cli, rawnick, chan, msg)
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.")
# Now that is always called first.
for x in set(list(COMMANDS.keys()) + list(currmod.COMMANDS.keys())):
if x and msg.lower().startswith(botconfig.CMD_CHAR+x):
h = msg[len(x)+1:]
if not h or h[0] == " " or not x:
for fn in COMMANDS.get(x,[])+currmod.COMMANDS.get(x,[]):
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 msg.lower().startswith(botconfig.CMD_CHAR+x):
h = msg[len(x)+1:]
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,[]):
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]
if cmd in set(list(HOOKS.keys())+list(currmod.HOOKS.keys())):
largs = list(args)
for i,arg in enumerate(largs):
if isinstance(arg, bytes): largs[i] = arg.decode('ascii')
for fn in HOOKS.get(cmd, [])+currmod.HOOKS.get(cmd, []):
try:
fn(cli, prefix, *largs)
except Exception as e:
if botconfig.DEBUG_MODE:
raise e
else:
logging.error(traceback.format_exc())
cli.msg(botconfig.CHANNEL, "An error has occurred and has been logged.")
else:
logging.debug('Unhandled command {0}({1})'.format(cmd, [arg.decode('utf_8')
for arg in args
if isinstance(arg, bytes)]))
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):
def prepare_stuff(*args):
cli.join(botconfig.CHANNEL)
cli.msg("ChanServ", "op "+botconfig.CHANNEL)
cli.cap("REQ", "extended-join")
cli.cap("REQ", "account-notify")
ld.MODULES[ld.CURRENT_MODULE].connect_callback(cli)
if botconfig.JOIN_AFTER_CLOAKED:
prepare_stuff = hook("event_hosthidden", id=294)(prepare_stuff)
@hook("nicknameinuse")
def mustghost(cli, *blah):
cli.nick(botconfig.NICK+"_")
cli.ns_ghost()
cli.nick(botconfig.NICK)
prepare_stuff(cli)
@hook("unavailresource")
def mustrelease(cli, *blah):
cli.nick(botconfig.NICK+"_")
cli.ns_release()
cli.nick(botconfig.NICK)
prepare_stuff(cli)
if not botconfig.JOIN_AFTER_CLOAKED: # join immediately
prepare_stuff(cli)
@hook("ping")
def on_ping(cli, prefix, server):
cli.send('PONG', server)
@cmd("module")
def ch_module(cli, nick, chan, rest):
rest = rest.strip()
if rest in ld.MODULES.keys():
ld.CURRENT_MODULE = rest
ld.MODULES[rest].connect_callback(cli)
cli.msg(chan, "Module {0} is now active.".format(rest))
else:
cli.msg(chan, "Module {0} does not exist.".format(rest))

47
modules/sabotage.py

@ -0,0 +1,47 @@
from tools import decorators
import settings.sabotage as var
import time
from datetime import datetime, timedelta
import botconfig
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):
var.PHASE = "none"
var.PLAYERS = []
@cmd("join")
def join(cli, nick, chan, rest):
"""Either starts a new game of Werewolf or joins an existing game that has not started yet."""
if var.PHASE == "none":
cli.mode(chan, "+v", nick, nick+"!*@*")
var.PLAYERS.append(nick)
var.PHASE = "join"
var.WAITED = 0
var.GAME_ID = time.time()
var.CAN_START_TIME = datetime.now() + timedelta(seconds=var.MINIMUM_WAIT)
cli.msg(chan, ('\u0002{0}\u0002 has started a game of Sabotage. '+
'Type "{1}join" to join. Type "{1}start" to start the game. '+
'Type "{1}wait" to increase join wait time.').format(nick, botconfig.CMD_CHAR))
elif nick in var.PLAYERS:
cli.notice(nick, "You're already playing!")
elif len(pl) >= var.MAX_PLAYERS:
cli.notice(nick, "Too many players! Try again next time.")
elif var.PHASE != "join":
cli.notice(nick, "Sorry but the game is already running. Try again next time.")
else:
cli.mode(chan, "+v", nick, nick+"!*@*")
var.PLAYERS.append(nick)
cli.msg(chan, '\u0002{0}\u0002 has joined the game.'.format(nick))
var.LAST_STATS = None # reset

76
wolfgame.py → modules/wolfgame.py

@ -8,10 +8,10 @@
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from oyoyo.parse import parse_nick from oyoyo.parse import parse_nick
import var import settings.wolfgame as var
import botconfig import botconfig
from wolfgamelogger import WolfgameLogger from tools.wolfgamelogger import WolfgameLogger
import decorators from tools import decorators
from datetime import datetime, timedelta from datetime import datetime, timedelta
import threading import threading
import random import random
@ -37,46 +37,22 @@ hook = decorators.generate(HOOKS, raw_nick=True, permissions=False)
def connect_callback(cli): def connect_callback(cli):
def prepare_stuff(*args): @hook("whospcrpl", id=294)
cli.join(botconfig.CHANNEL) def on_whoreply(cli, server, nick, ident, cloak, user, acc):
cli.msg("ChanServ", "op "+botconfig.CHANNEL) if user in var.USERS: return # Don't add someone who is already there
if user == botconfig.NICK:
@hook("whospcrpl", id=294) cli.nickname = user
def on_whoreply(cli, server, nick, ident, cloak, user, acc): cli.ident = ident
if user in var.USERS: return # Don't add someone who is already there cli.hostmask = cloak
if user == botconfig.NICK: if acc == "0":
cli.nickname = user acc = "*"
cli.ident = ident var.USERS[user] = dict(cloak=cloak,account=acc)
cli.hostmask = cloak
if acc == "0":
acc = "*"
var.USERS[user] = dict(cloak=cloak,account=acc)
@hook("endofwho", id=294)
def afterwho(*args):
decorators.unhook(HOOKS, 294)
cli.cap("REQ", "extended-join")
cli.cap("REQ", "account-notify")
cli.who(botconfig.CHANNEL, "%nuha")
if botconfig.JOIN_AFTER_CLOAKED:
prepare_stuff = hook("event_hosthidden", id=294)(prepare_stuff)
@hook("endofwho", id=294)
@hook("nicknameinuse") def afterwho(*args):
def mustghost(cli, *blah): decorators.unhook(HOOKS, 294)
cli.nick(botconfig.NICK+"_")
cli.ns_ghost() cli.who(botconfig.CHANNEL, "%nuha")
cli.nick(botconfig.NICK)
prepare_stuff(cli)
@hook("unavailresource")
def mustrelease(cli, *blah):
cli.nick(botconfig.NICK+"_")
cli.ns_release()
cli.nick(botconfig.NICK)
prepare_stuff(cli)
var.LAST_PING = None # time of last ping var.LAST_PING = None # time of last ping
var.LAST_STATS = None var.LAST_STATS = None
@ -116,9 +92,6 @@ def connect_callback(cli):
var.DAY_TIME_LIMIT_CHANGE = 0 var.DAY_TIME_LIMIT_CHANGE = 0
var.KILL_IDLE_TIME = 0 #300 var.KILL_IDLE_TIME = 0 #300
var.WARN_IDLE_TIME = 0 #180 var.WARN_IDLE_TIME = 0 #180
if not botconfig.JOIN_AFTER_CLOAKED: # join immediately
prepare_stuff(cli)
@ -784,7 +757,7 @@ def chk_win(cli):
if lwolves == lpl / 2: if lwolves == lpl / 2:
cli.msg(chan, ("Game over! There are the same number of wolves as "+ cli.msg(chan, ("Game over! There are the same number of wolves as "+
"villagers. The wolves eat everyone, and win.")) "villagers. The wolves eat everyone and win."))
var.LOGGER.logMessage(("Game over! There are the same number of wolves as "+ var.LOGGER.logMessage(("Game over! There are the same number of wolves as "+
"villagers. The wolves eat everyone, and win.")) "villagers. The wolves eat everyone, and win."))
village_win = False village_win = False
@ -885,12 +858,7 @@ def del_player(cli, nick, forced_death = False):
if nick in var.WOUNDED: if nick in var.WOUNDED:
var.WOUNDED.remove(nick) var.WOUNDED.remove(nick)
chk_decision(cli) chk_decision(cli)
return ret return ret
@hook("ping")
def on_ping(cli, prefix, server):
cli.send('PONG', server)
def reaper(cli, gameid): def reaper(cli, gameid):
@ -980,8 +948,6 @@ def on_join(cli, raw_nick, chan, acc="*", rname=""):
break break
if nick in var.DCED_PLAYERS.keys(): if nick in var.DCED_PLAYERS.keys():
var.PLAYERS[nick] = var.DCED_PLAYERS.pop(nick) var.PLAYERS[nick] = var.DCED_PLAYERS.pop(nick)
with open("returned.log", "a") as logf:
logf.write(time.strftime("%d/%b/%Y %H:%M:%S ", time.gmtime())+nick+"\n")
@cmd("goat") @cmd("goat")
def goat(cli, nick, chan, rest): def goat(cli, nick, chan, rest):
@ -1107,8 +1073,6 @@ def on_nick(cli, prefix, nick):
cli.msg(chan, ("\02{0}\02 has returned to "+ cli.msg(chan, ("\02{0}\02 has returned to "+
"the village.").format(nick)) "the village.").format(nick))
with open("returned.log", "a") as logf:
logf.write(time.strftime("%d/%b/%Y %H:%M:%S ", time.gmtime())+nick+"\n")
def leave(cli, what, nick, why=""): def leave(cli, what, nick, why=""):
nick, _, _, cloak = parse_nick(nick) nick, _, _, cloak = parse_nick(nick)

0
settings/__init__.py

6
settings/sabotage.py

@ -0,0 +1,6 @@
MINIMUM_WAIT = 60 # seconds before game can be started
EXTRA_WAIT = 20
MAXIMUM_WAITED = 2 # number of times !wait can be used
MAX_PLAYERS = 5
MIN_PLAYERS = 5

2
var.py → settings/wolfgame.py

@ -18,7 +18,7 @@ PART_GRACE_TIME = 7
QUIT_GRACE_TIME = 30 QUIT_GRACE_TIME = 30
LOG_FILENAME = "" LOG_FILENAME = ""
BARE_LOG_FILENAME = "barelog.txt" BARE_LOG_FILENAME = ""
# HIT MISS SUICIDE # HIT MISS SUICIDE
GUN_CHANCES = ( 5/7 , 1/7 , 1/7 ) GUN_CHANCES = ( 5/7 , 1/7 , 1/7 )

0
tools/__init__.py

0
decorators.py → tools/decorators.py

22
tools/moduleloader.py

@ -0,0 +1,22 @@
import os
import botconfig
MODULES = {}
for modfile in os.listdir("modules"):
if modfile == "common.py":
continue # no need to load this one
if modfile.startswith("__"):
continue
if not modfile.endswith(".py"):
continue # not a module
if not os.path.isfile("modules/"+modfile):
continue # not a file
modfile = modfile[:-3]
MODULES[modfile] = getattr(__import__("modules."+modfile), modfile)
if botconfig.DEFAULT_MODULE in MODULES.keys():
CURRENT_MODULE = botconfig.DEFAULT_MODULE.lower()
else:
CURRENT_MODULE = "wolfgame"

2
wolfgamelogger.py → tools/wolfgamelogger.py

@ -35,4 +35,4 @@ class WolfgameLogger(object):
bl.write(self.barelogged) bl.write(self.barelogged)
self.logged = "" self.logged = ""
self.barelogged = "" self.barelogged = ""

72
wolfbot.py

@ -23,77 +23,13 @@ from oyoyo.client import IRCClient
from oyoyo.parse import parse_nick from oyoyo.parse import parse_nick
import logging import logging
import botconfig import botconfig
import wolfgame
import time import time
import traceback import traceback
import modules.common
class UTCFormatter(logging.Formatter): class UTCFormatter(logging.Formatter):
converter = time.gmtime converter = time.gmtime
def on_privmsg(cli, rawnick, chan, msg):
if chan != botconfig.NICK: #not a PM
if "" in wolfgame.COMMANDS.keys():
for fn in wolfgame.COMMANDS[""]:
try:
fn(cli, rawnick, chan, msg)
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.")
# Now that is always called first.
for x in wolfgame.COMMANDS.keys():
if x and msg.lower().startswith(botconfig.CMD_CHAR+x):
h = msg[len(x)+1:]
if not h or h[0] == " " or not x:
for fn in wolfgame.COMMANDS[x]:
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 wolfgame.PM_COMMANDS.keys():
if msg.lower().startswith(botconfig.CMD_CHAR+x):
h = msg[len(x)+1:]
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 wolfgame.PM_COMMANDS[x]:
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):
if cmd in wolfgame.HOOKS.keys():
largs = list(args)
for i,arg in enumerate(largs):
if isinstance(arg, bytes): largs[i] = arg.decode('ascii')
for fn in wolfgame.HOOKS[cmd]:
try:
fn(cli, prefix, *largs)
except Exception as e:
if botconfig.DEBUG_MODE:
raise e
else:
logging.error(traceback.format_exc())
cli.msg(botconfig.CHANNEL, "An error has occurred and has been logged.")
else:
logging.debug('Unhandled command {0}({1})'.format(cmd, [arg.decode('utf_8')
for arg in args
if isinstance(arg, bytes)]))
def main(): def main():
if not botconfig.DEBUG_MODE: if not botconfig.DEBUG_MODE:
logging.basicConfig(filename='errors.log', filemode='a', level=logging.WARNING) logging.basicConfig(filename='errors.log', filemode='a', level=logging.WARNING)
@ -104,14 +40,14 @@ def main():
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
cli = IRCClient( cli = IRCClient(
{"privmsg":on_privmsg, {"privmsg":modules.common.on_privmsg,
"":__unhandled__}, "":modules.common.__unhandled__},
host=botconfig.HOST, host=botconfig.HOST,
port=botconfig.PORT, port=botconfig.PORT,
authname=botconfig.USERNAME, authname=botconfig.USERNAME,
password=botconfig.PASS, password=botconfig.PASS,
nickname=botconfig.NICK, nickname=botconfig.NICK,
connect_cb=wolfgame.connect_callback connect_cb=modules.common.connect_callback
) )
cli.mainLoop() cli.mainLoop()

Loading…
Cancel
Save