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 @@ @@ -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 @@ @@ -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 @@ @@ -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.
from oyoyo.parse import parse_nick
import var
import settings.wolfgame as var
import botconfig
from wolfgamelogger import WolfgameLogger
import decorators
from tools.wolfgamelogger import WolfgameLogger
from tools import decorators
from datetime import datetime, timedelta
import threading
import random
@ -37,46 +37,22 @@ hook = decorators.generate(HOOKS, raw_nick=True, permissions=False) @@ -37,46 +37,22 @@ 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)
@hook("whospcrpl", id=294)
def on_whoreply(cli, server, nick, ident, cloak, user, acc):
if user in var.USERS: return # Don't add someone who is already there
if user == botconfig.NICK:
cli.nickname = user
cli.ident = ident
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("whospcrpl", id=294)
def on_whoreply(cli, server, nick, ident, cloak, user, acc):
if user in var.USERS: return # Don't add someone who is already there
if user == botconfig.NICK:
cli.nickname = user
cli.ident = ident
cli.hostmask = cloak
if acc == "0":
acc = "*"
var.USERS[user] = dict(cloak=cloak,account=acc)
@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)
@hook("endofwho", id=294)
def afterwho(*args):
decorators.unhook(HOOKS, 294)
cli.who(botconfig.CHANNEL, "%nuha")
var.LAST_PING = None # time of last ping
var.LAST_STATS = None
@ -116,9 +92,6 @@ def connect_callback(cli): @@ -116,9 +92,6 @@ def connect_callback(cli):
var.DAY_TIME_LIMIT_CHANGE = 0
var.KILL_IDLE_TIME = 0 #300
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): @@ -784,7 +757,7 @@ def chk_win(cli):
if lwolves == lpl / 2:
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 "+
"villagers. The wolves eat everyone, and win."))
village_win = False
@ -885,12 +858,7 @@ def del_player(cli, nick, forced_death = False): @@ -885,12 +858,7 @@ def del_player(cli, nick, forced_death = False):
if nick in var.WOUNDED:
var.WOUNDED.remove(nick)
chk_decision(cli)
return ret
@hook("ping")
def on_ping(cli, prefix, server):
cli.send('PONG', server)
return ret
def reaper(cli, gameid):
@ -980,8 +948,6 @@ def on_join(cli, raw_nick, chan, acc="*", rname=""): @@ -980,8 +948,6 @@ def on_join(cli, raw_nick, chan, acc="*", rname=""):
break
if nick in var.DCED_PLAYERS.keys():
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")
def goat(cli, nick, chan, rest):
@ -1107,8 +1073,6 @@ def on_nick(cli, prefix, nick): @@ -1107,8 +1073,6 @@ def on_nick(cli, prefix, nick):
cli.msg(chan, ("\02{0}\02 has returned to "+
"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=""):
nick, _, _, cloak = parse_nick(nick)

0
settings/__init__.py

6
settings/sabotage.py

@ -0,0 +1,6 @@ @@ -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 @@ -18,7 +18,7 @@ PART_GRACE_TIME = 7
QUIT_GRACE_TIME = 30
LOG_FILENAME = ""
BARE_LOG_FILENAME = "barelog.txt"
BARE_LOG_FILENAME = ""
# HIT MISS SUICIDE
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 @@ @@ -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): @@ -35,4 +35,4 @@ class WolfgameLogger(object):
bl.write(self.barelogged)
self.logged = ""
self.barelogged = ""
self.barelogged = ""

72
wolfbot.py

@ -23,77 +23,13 @@ from oyoyo.client import IRCClient @@ -23,77 +23,13 @@ from oyoyo.client import IRCClient
from oyoyo.parse import parse_nick
import logging
import botconfig
import wolfgame
import time
import traceback
import modules.common
class UTCFormatter(logging.Formatter):
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():
if not botconfig.DEBUG_MODE:
logging.basicConfig(filename='errors.log', filemode='a', level=logging.WARNING)
@ -104,14 +40,14 @@ def main(): @@ -104,14 +40,14 @@ def main():
logging.basicConfig(level=logging.DEBUG)
cli = IRCClient(
{"privmsg":on_privmsg,
"":__unhandled__},
{"privmsg":modules.common.on_privmsg,
"":modules.common.__unhandled__},
host=botconfig.HOST,
port=botconfig.PORT,
authname=botconfig.USERNAME,
password=botconfig.PASS,
nickname=botconfig.NICK,
connect_cb=wolfgame.connect_callback
connect_cb=modules.common.connect_callback
)
cli.mainLoop()

Loading…
Cancel
Save