Browse Source

allow players that quit/part during the game to rejoin within a certain period of time after their disconnection

master
jcao219 14 years ago
parent
commit
c81d98dfbb
  1. 2
      var.py
  2. 192
      wolfgame.py

2
var.py

@ -14,6 +14,8 @@ DAY_TIME_LIMIT_CHANGE = 120 # After DAY_TIME_LIMIT_WARN has passed
START_WITH_DAY = False START_WITH_DAY = False
KILL_IDLE_TIME = 300 KILL_IDLE_TIME = 300
WARN_IDLE_TIME = 180 WARN_IDLE_TIME = 180
PART_GRACE_TIME = 10
KILL_GRACE_TIME = 30
LOG_FILENAME = "" LOG_FILENAME = ""
BARE_LOG_FILENAME = "barelog.txt" BARE_LOG_FILENAME = "barelog.txt"

192
wolfgame.py

@ -105,6 +105,8 @@ def connect_callback(cli):
var.GRAVEYARD_LOCK = threading.RLock() var.GRAVEYARD_LOCK = threading.RLock()
var.GAME_ID = 0 var.GAME_ID = 0
var.DISCONNECTED = {} # players who got disconnected
var.LOGGER = WolfgameLogger(var.LOG_FILENAME, var.BARE_LOG_FILENAME) var.LOGGER = WolfgameLogger(var.LOG_FILENAME, var.BARE_LOG_FILENAME)
if botconfig.DEBUG_MODE: if botconfig.DEBUG_MODE:
@ -855,53 +857,64 @@ 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)
def reaper(cli, gameid): def reaper(cli, gameid):
# check to see if idlers need to be killed. # check to see if idlers need to be killed.
var.IDLE_WARNED = [] var.IDLE_WARNED = []
chan = botconfig.CHANNEL
if not var.WARN_IDLE_TIME and not var.KILL_IDLE_TIME:
return
while gameid == var.GAME_ID: while gameid == var.GAME_ID:
with var.GRAVEYARD_LOCK: with var.GRAVEYARD_LOCK:
to_warn = [] if var.WARN_IDLE_TIME or var.KILL_IDLE_TIME: # only if enabled
to_kill = [] to_warn = []
for nick in var.list_players(): to_kill = []
lst = var.LAST_SAID_TIME.get(nick, var.GAME_START_TIME) for nick in var.list_players():
tdiff = datetime.now() - lst lst = var.LAST_SAID_TIME.get(nick, var.GAME_START_TIME)
if (tdiff > timedelta(seconds=var.WARN_IDLE_TIME) and tdiff = datetime.now() - lst
nick not in var.IDLE_WARNED): if (tdiff > timedelta(seconds=var.WARN_IDLE_TIME) and
if var.WARN_IDLE_TIME: nick not in var.IDLE_WARNED):
to_warn.append(nick) if var.WARN_IDLE_TIME:
var.IDLE_WARNED.append(nick) to_warn.append(nick)
var.LAST_SAID_TIME[nick] = (datetime.now() - var.IDLE_WARNED.append(nick)
timedelta(seconds=var.WARN_IDLE_TIME)) # Give him a chance var.LAST_SAID_TIME[nick] = (datetime.now() -
elif (tdiff > timedelta(seconds=var.KILL_IDLE_TIME) and timedelta(seconds=var.WARN_IDLE_TIME)) # Give him a chance
nick in var.IDLE_WARNED): elif (tdiff > timedelta(seconds=var.KILL_IDLE_TIME) and
if var.KILL_IDLE_TIME: nick in var.IDLE_WARNED):
to_kill.append(nick) if var.KILL_IDLE_TIME:
elif (tdiff < timedelta(seconds=var.WARN_IDLE_TIME) and to_kill.append(nick)
nick in var.IDLE_WARNED): elif (tdiff < timedelta(seconds=var.WARN_IDLE_TIME) and
var.IDLE_WARNED.remove(nick) # he saved himself from death nick in var.IDLE_WARNED):
chan = botconfig.CHANNEL var.IDLE_WARNED.remove(nick) # he saved himself from death
for nck in to_kill: for nck in to_kill:
if nck not in var.list_players(): if nck 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(nck, var.get_role(nck))) "(s)he was a \u0002{1}\u0002.").format(nck, var.get_role(nck)))
if not del_player(cli, nck): if not del_player(cli, nck):
return return
pl = var.list_players() pl = var.list_players()
x = [a for a in to_warn if a in pl] x = [a for a in to_warn if a in pl]
if x: 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 say something soon or you "+ "Please say something soon or you "+
"might be declared dead.\u0002").format(", ".join(x))) "might be declared dead.\u0002").format(", ".join(x)))
for dcedplayer in list(var.DISCONNECTED.keys()):
_, timeofdc, what = var.DISCONNECTED[dcedplayer]
if what == "quit" and (datetime.now() - timeofdc) > timedelta(seconds=var.QUIT_GRACE_TIME):
cli.msg(chan, ("\02{0}\02 died due to a fatal attack by wild animals. Appears (s)he "+
"was a \02{1}\02.").format(dcedplayer, var.get_role(dcedplayer)))
del var.DISCONNECTED[dcedplayer]
if not del_player(cli, dcedplayer):
return
elif what == "part" and (datetime.now() - timeofdc) > timedelta(seconds=var.PART_GRACE_TIME):
cli.msg(chan, ("\02{0}\02 died due to eating poisonous berries. Appears (s)he was "+
"a \02{1}\02.").format(dcedplayer, var.get_role(dcedplayer)))
del var.DISCONNECTED[dcedplayer]
if not del_player(cli, dcedplayer):
return
sleep(10) sleep(10)
@ -922,8 +935,14 @@ def on_join(cli, raw_nick, chan):
if nick not in var.USERS and nick != botconfig.NICK: if nick not in var.USERS and nick != botconfig.NICK:
var.USERS.append(nick) var.USERS.append(nick)
var.CLOAKS.append(cloak) var.CLOAKS.append(cloak)
#if nick in var.list_players(): with var.GRAVEYARD_LOCK:
# cli.mode(chan, "+v", nick, nick+"!*@*") needed? if nick in var.DISCONNECTED.keys():
clk = var.DISCONNECTED[nick][0]
if cloak == clk:
cli.mode(chan, "+v", nick, nick+"!*@*")
del var.DISCONNECTED[nick]
cli.msg(chan, "\02{0}\02 has returned to the village.".format(nick))
@cmd("goat") @cmd("goat")
def goat(cli, nick, chan, rest): def goat(cli, nick, chan, rest):
@ -969,6 +988,7 @@ def goat(cli, nick, chan, rest):
@hook("nick") @hook("nick")
def on_nick(cli, prefix, nick): def on_nick(cli, prefix, nick):
prefix,u,m,cloak = parse_nick(prefix) prefix,u,m,cloak = parse_nick(prefix)
chan = botconfig.CHANNEL
if prefix in var.USERS: if prefix in var.USERS:
var.USERS.remove(prefix) var.USERS.remove(prefix)
@ -1038,54 +1058,80 @@ def on_nick(cli, prefix, nick):
v.remove(prefix) v.remove(prefix)
v.append(nick) v.append(nick)
# Check if he was DC'ed
if var.PHASE in ("night", "day"):
with var.GRAVEYARD_LOCK:
if nick in var.DISCONNECTED.keys():
clk = var.DISCONNECTED[nick][0]
if cloak == clk:
cli.mode(chan, "+v", nick, nick+"!*@*")
del var.DISCONNECTED[nick]
cli.msg(chan, ("\02{0}\02 has returned to "+
"the village.").format(nick))
def leave(cli, what, nick, why=""): def leave(cli, what, nick, why=""):
"""Exit the game.""" nick, _, _, cloak = parse_nick(nick)
if not what.startswith(botconfig.CMD_CHAR) and nick in var.USERS:
if nick in var.USERS:
i = var.USERS.index(nick) i = var.USERS.index(nick)
var.USERS.remove(nick) var.USERS.remove(nick)
var.CLOAKS.pop(i) var.CLOAKS.pop(i)
if why and why == botconfig.CHANGING_HOST_QUIT_MESSAGE: if why and why == botconfig.CHANGING_HOST_QUIT_MESSAGE:
return return
if var.PHASE == "none" and what.startswith(botconfig.CMD_CHAR): if var.PHASE == "none":
cli.notice(nick, "No game is currently running.")
return
elif var.PHASE == "none":
return
if nick not in var.list_players() and what.startswith(botconfig.CMD_CHAR): # not playing
cli.notice(nick, "You're not currently playing.")
return return
elif nick not in var.list_players(): if nick not in var.list_players():
return return
# the player who just quit was in the game
if nick in var.USERS: if nick in var.USERS:
var.DEAD_USERS[nick] = var.CLOAKS[var.USERS.index(nick)] var.DEAD_USERS[nick] = var.CLOAKS[var.USERS.index(nick)]
# for gstats, just in case # for gstats, just in case
msg = "" killhim = True
if what in (botconfig.CMD_CHAR+"quit", botconfig.CMD_CHAR+"leave"): if what == "part" and (not var.PART_GRACE_TIME or var.PHASE == "join"):
msg = ("\u0002{0}\u0002 died of an unknown disease. "+ msg = ("\02{0}\02 died due to eating poisonous berries. Appears "+
"S/He was a \u0002{1}\u0002.") "(s)he was a \02{1}\02.").format(nick, var.get_role(nick))
elif what == "part": elif what == "quit" and (not var.QUIT_GRACE_TIME or var.PHASE == "join"):
msg = ("\u0002{0}\u0002 died due to eating poisonous berries. "+ msg = ("\02{0}\02 died due to a fatal attack by wild animals. Appears "+
"Appears (s)he was a \u0002{1}\u0002.") "(s)he was a \02{1}\02.").format(nick, var.get_role(nick))
elif what == "quit": elif what != "kick":
msg = ("\u0002{0}\u0002 died due to a fatal attack by wild animals. "+ msg = "\u0002{0}\u0002 has gone missing.".format(nick)
"Appears (s)he was a \u0002{1}\u0002.") killhim = False
elif what == "kick": else:
msg = ("\u0002{0}\u0002 died due to falling off a cliff. "+ msg = ("\02{0}\02 died due to falling off a cliff. Appears "+
"Appears (s)he was a \u0002{1}\u0002.") "(s)he was a \02{1}\02.").format(nick, var.get_role(nick))
msg = msg.format(nick, var.get_role(nick))
cli.msg(botconfig.CHANNEL, msg) cli.msg(botconfig.CHANNEL, msg)
var.LOGGER.logMessage(msg.replace("\02", "")) var.LOGGER.logMessage(msg.replace("\02", ""))
del_player(cli, nick) if killhim:
del_player(cli, nick)
else:
var.DISCONNECTED[nick] = (cloak, datetime.now(), what)
_ = cmd("quit", "leave")(lambda cli, nick, chan, rest: leave(cli, botconfig.CMD_CHAR+"quit", nick, ""))
_.__doc__ = "Quits the game"
#Functions decorated with hook do not parse the nick by default #Functions decorated with hook do not parse the nick by default
hook("part")(lambda cli, nick, *rest: leave(cli, "part", parse_nick(nick)[0])) hook("part")(lambda cli, nick, *rest: leave(cli, "part", nick))
hook("quit")(lambda cli, nick, *rest: leave(cli, "quit", parse_nick(nick)[0], rest[0])) hook("quit")(lambda cli, nick, *rest: leave(cli, "quit", nick, rest[0]))
hook("kick")(lambda cli, nick, *rest: leave(cli, "kick", parse_nick(rest[1])[0])) hook("kick")(lambda cli, nick, *rest: leave(cli, "kick", rest[1]))
@cmd("quit", "leave")
def leave_game(cli, nick, chan, rest):
"""Quits the game."""
if var.PHASE == "none":
cli.notice(nick, "No game is currently running.")
return
if nick not in var.list_players(): # not playing
cli.notice(nick, "You're not currently playing.")
return
if nick in var.USERS:
var.DEAD_USERS[nick] = var.CLOAKS[var.USERS.index(nick)]
cli.msg(chan, ("\02{0}\02 died of an unknown disease. "+
"S/He was a \02{1}\02.").format(nick, var.get_role(nick)))
var.LOGGER.logMessage(("{0} died of an unknown disease. "+
"S/He was a {1}.").format(nick, var.get_role(nick)))
del_player(cli, nick)
@ -2124,6 +2170,8 @@ def start(cli, nick, chan, rest):
var.DAY_START_TIME = None var.DAY_START_TIME = None
var.NIGHT_START_TIME = None var.NIGHT_START_TIME = None
dict.clear(var.DISCONNECTED)
var.LOGGER.log("Game Start") var.LOGGER.log("Game Start")
var.LOGGER.logBare("GAME", "BEGIN", nick) var.LOGGER.logBare("GAME", "BEGIN", nick)
var.LOGGER.logBare(str(len(pl)), "PLAYERCOUNT") var.LOGGER.logBare(str(len(pl)), "PLAYERCOUNT")

Loading…
Cancel
Save