Browse Source

full threading for the reaper function

master
jcao219 14 years ago
parent
commit
5336a4b795
  1. 1
      decorators.py
  2. 13
      oyoyo/client.py
  3. 4
      oyoyo/ircevents.py
  4. 2
      oyoyo/parse.py
  5. 4
      var.py
  6. 62
      wolfgame.py

1
decorators.py

@ -35,7 +35,6 @@ def generate(fdict, **kwargs):
if (fn.owner_only != owner_only or if (fn.owner_only != owner_only or
fn.admin_only != admin_only): fn.admin_only != admin_only):
raise Exception("Command: "+x+" has non-matching protection levels!") raise Exception("Command: "+x+" has non-matching protection levels!")
fdict[x].append(innerf) fdict[x].append(innerf)
innerf.owner_only = owner_only innerf.owner_only = owner_only
innerf.raw_nick = raw_nick innerf.raw_nick = raw_nick

13
oyoyo/client.py

@ -1,4 +1,4 @@
# Copyright (c) 2008 Duncan Fordyce # Copyright (c) 2011 Duncan Fordyce, Jimmy Cao
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights # in the Software without restriction, including without limitation the rights
@ -18,11 +18,11 @@
import logging import logging
import socket import socket
import time import time
import threading
import traceback
from oyoyo.parse import parse_raw_irc_command from oyoyo.parse import parse_raw_irc_command
class IRCClientError(Exception):
pass
# Adapted from http://code.activestate.com/recipes/511490-implementation-of-the-token-bucket-algorithm/ # Adapted from http://code.activestate.com/recipes/511490-implementation-of-the-token-bucket-algorithm/
@ -107,6 +107,7 @@ class IRCClient(object):
self.port = None self.port = None
self.connect_cb = None self.connect_cb = None
self.blocking = True self.blocking = True
self.lock = threading.RLock()
self.tokenbucket = TokenBucket(3, 1.63) self.tokenbucket = TokenBucket(3, 1.63)
self.__dict__.update(kwargs) self.__dict__.update(kwargs)
@ -128,6 +129,7 @@ class IRCClient(object):
str they will be converted to bytes with the encoding specified by the str they will be converted to bytes with the encoding specified by the
'encoding' keyword argument (default 'utf8'). 'encoding' keyword argument (default 'utf8').
""" """
with self.lock:
# Convert all args to bytes if not already # Convert all args to bytes if not already
encoding = kwargs.get('encoding') or 'utf_8' encoding = kwargs.get('encoding') or 'utf_8'
bargs = [] bargs = []
@ -214,9 +216,8 @@ class IRCClient(object):
self.command_handler[command](self, prefix,*largs) self.command_handler[command](self, prefix,*largs)
elif "" in self.command_handler: elif "" in self.command_handler:
self.command_handler[""](self, prefix, command, *largs) self.command_handler[""](self, prefix, command, *largs)
finally: except Exception as e:
# error will of already been logged by the handler traceback.print_exc()
pass
yield True yield True
finally: finally:

4
oyoyo/ircevents.py

@ -1,4 +1,4 @@
# Copyright (c) 2008 Duncan Fordyce # Copyright (c) 2011 Duncan Fordyce, Jimmy Cao
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights # in the Software without restriction, including without limitation the rights
@ -15,8 +15,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
# taken from python irclib.. who took it from...
# Numeric table mostly stolen from the Perl IRC module (Net::IRC).
numeric_events = { numeric_events = {
b"001": "welcome", b"001": "welcome",
b"002": "yourhost", b"002": "yourhost",

2
oyoyo/parse.py

@ -1,4 +1,4 @@
# Copyright (c) 2008 Duncan Fordyce # Copyright (c) 2011 Duncan Fordyce, Jimmy Cao
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights # in the Software without restriction, including without limitation the rights

4
var.py

@ -8,8 +8,8 @@ DRUNK_SHOTS_MULTIPLIER = 3
NIGHT_TIME_LIMIT = 90 NIGHT_TIME_LIMIT = 90
DAY_TIME_LIMIT = 333 DAY_TIME_LIMIT = 333
START_WITH_DAY = False START_WITH_DAY = False
KILL_IDLE_TIME = 0 #300 KILL_IDLE_TIME = 300
WARN_IDLE_TIME = 0 #180 WARN_IDLE_TIME = 180
GAME_COMMAND_ADMIN_ONLY = True GAME_COMMAND_ADMIN_ONLY = True
# HIT MISS SUICIDE # HIT MISS SUICIDE

62
wolfgame.py

@ -69,8 +69,7 @@ def connect_callback(cli):
var.LAST_SAID_TIME = {} var.LAST_SAID_TIME = {}
var.GAME_START_TIME = datetime.now() # for idle checker only var.GAME_START_TIME = datetime.now() # for idle checker only
var.GRAVEYARD = [] var.GRAVEYARD_LOCK = threading.RLock()
var.GRAVEYARD_LOCK = threading.Lock()
prepare_stuff() prepare_stuff()
@ -111,6 +110,7 @@ def reset(cli):
if var.TIMERS[1]: if var.TIMERS[1]:
var.TIMERS[1].cancel() var.TIMERS[1].cancel()
var.TIMERS[1] = None var.TIMERS[1] = None
var.GAME_ID = 0
cli.mode(chan, "-m") cli.mode(chan, "-m")
cmodes = [] cmodes = []
@ -565,7 +565,11 @@ def del_player(cli, nick, forced_death = False):
Returns: False if one side won. Returns: False if one side won.
arg: forced_death = True when lynched. arg: forced_death = True when lynched.
""" """
t = timetime() # time
with var.GRAVEYARD_LOCK:
if not var.GAME_ID or var.GAME_ID > t:
# either game ended, or a new game has started.
return False
cmode = [] cmode = []
cmode.append(("-v", nick)) cmode.append(("-v", nick))
var.del_player(nick) var.del_player(nick)
@ -609,19 +613,20 @@ def del_player(cli, nick, forced_death = False):
@hook("ping") @hook("ping")
def on_ping(cli, prefix, server): def on_ping(cli, prefix, server):
cli.send('PONG', server) cli.send('PONG', server)
check_graveyard(cli)
def reaper(cli):
def reaper(cli, gameid):
# check to see if idlers need to be killed. # check to see if idlers need to be killed.
var.IDLE_KILLED = []
var.IDLE_WARNED = [] var.IDLE_WARNED = []
if not var.WARN_IDLE_TIME or not var.KILL_IDLE_TIME: if not var.WARN_IDLE_TIME or not var.KILL_IDLE_TIME:
return return
while var.PHASE != "none": while gameid == var.GAME_ID:
with var.GRAVEYARD_LOCK:
to_warn = [] to_warn = []
to_kill = []
for nick in var.list_players(): for nick in var.list_players():
lst = var.LAST_SAID_TIME.get(nick, var.GAME_START_TIME) lst = var.LAST_SAID_TIME.get(nick, var.GAME_START_TIME)
tdiff = datetime.now() - lst tdiff = datetime.now() - lst
@ -630,45 +635,37 @@ def reaper(cli):
to_warn.append(nick) to_warn.append(nick)
var.IDLE_WARNED.append(nick) var.IDLE_WARNED.append(nick)
var.LAST_SAID_TIME[nick] = (datetime.now() - var.LAST_SAID_TIME[nick] = (datetime.now() -
timedelta(seconds=var.KILL_IDLE_TIME)) # Give him a chance timedelta(seconds=var.WARN_IDLE_TIME)) # Give him a chance
elif (tdiff > timedelta(seconds=var.KILL_IDLE_TIME) and elif (tdiff > timedelta(seconds=var.KILL_IDLE_TIME) and
nick not in var.IDLE_KILLED): nick in var.IDLE_WARNED):
with var.GRAVEYARD_LOCK: to_kill.append(nick)
var.GRAVEYARD.append(("kill",nick)) print("WILL KILL "+nick)
var.IDLE_KILLED.append(nick) elif (tdiff < timedelta(seconds=var.WARN_IDLE_TIME) and
if to_warn: nick in var.IDLE_WARNED):
with var.GRAVEYARD_LOCK: var.IDLE_WARNED.remove(nick) # he saved himself from death
var.GRAVEYARD.append(("warn", to_warn))
sleep(10)
def check_graveyard(cli):
if not var.GRAVEYARD: return
chan = botconfig.CHANNEL chan = botconfig.CHANNEL
with var.GRAVEYARD_LOCK: for nck in to_kill:
for action, x in var.GRAVEYARD: if nck not in var.list_players():
if action=="kill":
if x not in var.list_players():
continue continue
cli.msg(chan, ("\u0002{0}\u0002 didn't get out of bed "+ cli.msg(chan, ("\u0002{0}\u0002 didn't get out of bed "+
"for a very long time. S/He is declared dead. Appears "+ "for a very long time. S/He is declared dead. Appears "+
"(s)he was a \u0002{1}\u0002").format(x, var.get_role(x))) "(s)he was a \u0002{1}\u0002").format(nck, var.get_role(nck)))
del_player(cli, x) if not del_player(cli, nck):
elif action=="warn": return
pl = var.list_players() pl = var.list_players()
x = [a for a in x if a in pl] x = [a for a in to_warn if a in pl]
if x:
cli.msg(chan, ("{0}: \u0002You have been idling for a while. "+ cli.msg(chan, ("{0}: \u0002You have been idling for a while. "+
"Please remember to say something soon or you "+ "Please remember to say something soon or you "+
"might be declared dead.\u0002").format(", ".join(x))) "might be declared dead.\u0002").format(", ".join(x)))
var.GRAVEYARD = [] sleep(10)
@cmd("") # update last said @cmd("") # update last said
def update_last_said(cli, nick, *rest): def update_last_said(cli, nick, *rest):
if var.PHASE not in ("join", "none"): if var.PHASE not in ("join", "none"):
var.LAST_SAID_TIME[nick] = datetime.now() var.LAST_SAID_TIME[nick] = datetime.now()
check_graveyard(cli)
@ -1647,7 +1644,8 @@ def start(cli, nick, chan, rest):
transition_day(cli) transition_day(cli)
# DEATH TO IDLERS! # DEATH TO IDLERS!
reapertimer = threading.Thread(None, reaper, args=(cli,)) var.GAME_ID = timetime()
reapertimer = threading.Thread(None, reaper, args=(cli,var.GAME_ID))
reapertimer.daemon = True reapertimer.daemon = True
reapertimer.start() reapertimer.start()

Loading…
Cancel
Save