Browse Source

fixed non-privmsg-nickserv authentication, added rate limiting for !stats, !votes, !admins, detectives now have a more complete PM message

master
jcao219 13 years ago
parent
commit
3e56a66c37
  1. 1
      botconfig.py.example
  2. 5
      oyoyo/client.py
  3. 3
      var.py
  4. 1
      wolfbot.py
  5. 50
      wolfgame.py

1
botconfig.py.example

@ -2,6 +2,7 @@ PASS = "my_nickserv_pass" @@ -2,6 +2,7 @@ PASS = "my_nickserv_pass"
CHANNEL = "#mywolfgame"
HOST = "irc.freenode.net"
PORT = 6667 # SSL not supported yet
USERNAME = "" # for authentication, can be left blank if same as NICK
NICK = "mywolfbot"
OWNERS = ("unaffiliated/wolfbot_admin1",) # the comma is required at the end if there is one owner
ADMINS = ("unaffiliated/wolfbot_admin2", "unaffiliated/wolfbot_admin3")

5
oyoyo/client.py

@ -100,6 +100,7 @@ class IRCClient(object): @@ -100,6 +100,7 @@ class IRCClient(object):
self.host = None
self.port = None
self.password = ""
self.authname = ""
self.connect_cb = None
self.blocking = True
self.lock = threading.RLock()
@ -175,9 +176,11 @@ class IRCClient(object): @@ -175,9 +176,11 @@ class IRCClient(object):
if not self.blocking:
self.socket.setblocking(0)
self.send("PASS {0}:{1}".format(self.authname if self.authname else self.nickname,
self.password if self.password else "NOPASS"))
self.nick(self.nickname)
self.user(self.nickname, self.real_name)
self.send("PASS :{0}\r\n".format(self.password if self.password else "NOPASS"))
if self.connect_cb:
self.connect_cb(self)

3
var.py

@ -2,6 +2,9 @@ PING_WAIT = 300 # Seconds @@ -2,6 +2,9 @@ PING_WAIT = 300 # Seconds
MINIMUM_WAIT = 60
EXTRA_WAIT = 20
MAXIMUM_WAITED = 2 # limit for amount of !wait's
STATS_RATE_LIMIT = 60
VOTES_RATE_LIMIT = 60
ADMINS_RATE_LIMIT = 300
SHOTS_MULTIPLIER = .12 # ceil(shots_multiplier * len_players) = bullets given
MAX_PLAYERS = 30
DRUNK_SHOTS_MULTIPLIER = 3

1
wolfbot.py

@ -87,6 +87,7 @@ def main(): @@ -87,6 +87,7 @@ def main():
"":__unhandled__},
host=botconfig.HOST,
port=botconfig.PORT,
authname=botconfig.USERNAME,
password=botconfig.PASS,
nickname=botconfig.NICK,
connect_cb=wolfgame.connect_callback

50
wolfgame.py

@ -36,15 +36,11 @@ hook = decorators.generate(HOOKS, raw_nick=True) @@ -36,15 +36,11 @@ hook = decorators.generate(HOOKS, raw_nick=True)
# Game Logic Begins:
def connect_callback(cli):
cli.ns_identify(botconfig.PASS)
def prepare_stuff(*args):
cli.join(botconfig.CHANNEL)
cli.msg("ChanServ", "op "+botconfig.CHANNEL)
var.USERS = []
var.CLOAKS = []
@hook("whoreply", id=294)
def on_whoreply(cli, server, dunno, chan, dunno1,
cloak, dunno3, user, status, dunno4):
@ -65,7 +61,6 @@ def connect_callback(cli): @@ -65,7 +61,6 @@ def connect_callback(cli):
@hook("nicknameinuse")
def mustghost(cli, *blah):
cli.nick(botconfig.NICK+"_")
cli.ns_identify(botconfig.PASS)
cli.ns_ghost()
cli.nick(botconfig.NICK)
prepare_stuff()
@ -73,12 +68,18 @@ def connect_callback(cli): @@ -73,12 +68,18 @@ def connect_callback(cli):
@hook("unavailresource")
def mustrelease(cli, *blah):
cli.nick(botconfig.NICK+"_")
cli.ns_identify(botconfig.PASS)
cli.ns_release()
cli.nick(botconfig.NICK)
prepare_stuff()
var.LAST_PING = 0 # time of last ping
var.LAST_PING = None # time of last ping
var.LAST_STATS = None
var.LAST_VOTES = None
var.LAST_ADMINS = None
var.USERS = []
var.CLOAKS = []
var.PINGING = False
var.ADMIN_PINGING = False
var.ROLES = {"person" : []}
@ -214,7 +215,7 @@ def restart_program(cli, nick, *rest): @@ -214,7 +215,7 @@ def restart_program(cli, nick, *rest):
def pinger(cli, nick, chan, rest):
"""Pings the channel to get people's attention. Rate-Limited."""
if (var.LAST_PING and
var.LAST_PING + timedelta(seconds=300) > datetime.now()):
var.LAST_PING + timedelta(seconds=var.PING_WAIT) > datetime.now()):
cli.notice(nick, ("This command is ratelimited. " +
"Please wait a while before using it again."))
return
@ -395,6 +396,14 @@ def stats(cli, nick, chan, rest): @@ -395,6 +396,14 @@ def stats(cli, nick, chan, rest):
cli.notice(nick, "No game is currently running.")
return
if (var.LAST_STATS and
var.LAST_STATS + timedelta(seconds=var.STATS_RATE_LIMIT) > datetime.now()):
cli.msg(chan, (nick+": This command is ratelimited. " +
"Please wait a while before using it again."))
return
var.LAST_STATS = datetime.now()
pl = var.list_players()
pl.sort(key=lambda x: x.lower())
if len(pl) > 1:
@ -531,13 +540,23 @@ def chk_decision(cli): @@ -531,13 +540,23 @@ def chk_decision(cli):
@cmd("votes")
def show_votes(cli, nick, chan, rest):
"""Displays the voting statistics."""
if var.PHASE in ("none", "join"):
cli.notice(nick, "No game is currently running.")
return
if var.PHASE != "day":
cli.notice(nick, "Voting is only during the day.")
return
elif not var.VOTES.values():
if (var.LAST_VOTES and
var.LAST_VOTES + timedelta(seconds=var.VOTES_RATE_LIMIT) > datetime.now()):
cli.msg(chan, (nick+": This command is ratelimited. " +
"Please wait a while before using it again."))
return
var.LAST_VOTES = datetime.now()
if not var.VOTES.values():
cli.msg(chan, nick+": No votes yet.")
else:
votelist = ["{0}: {1} ({2})".format(votee,
@ -1727,7 +1746,10 @@ def transition_night(cli): @@ -1727,7 +1746,10 @@ def transition_night(cli):
cli.msg(dttv, ("You are a \u0002detective\u0002.\n"+
"It is your job to determine all the wolves and traitors. "+
"Your job is during the day, and you can see the true "+
"identity of all users, even traitors."))
"identity of all users, even traitors.\n"+
"But, each time you use your ability, you risk a 2/5 "+
"chance of having your identity revealed to the wolves. So be "+
"careful. Use \"!id\" to identify any player during the day."))
for d in var.ROLES["village drunk"]:
cli.msg(d, 'You have been drinking too much! You are the \u0002village drunk\u0002.')
@ -2096,6 +2118,14 @@ def show_admins(cli, nick, chan, rest): @@ -2096,6 +2118,14 @@ def show_admins(cli, nick, chan, rest):
"""Pings the admins that are available."""
admins = []
if (var.LAST_ADMINS and
var.LAST_ADMINS + timedelta(seconds=var.ADMINS_RATE_LIMIT) > datetime.now()):
cli.msg(chan, (nick+": This command is ratelimited. " +
"Please wait a while before using it again."))
return
var.LAST_ADMINS = datetime.now()
if var.ADMIN_PINGING:
return
var.ADMIN_PINGING = True

Loading…
Cancel
Save