Browse Source

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

master
jcao219 13 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 @@ -14,6 +14,8 @@ DAY_TIME_LIMIT_CHANGE = 120 # After DAY_TIME_LIMIT_WARN has passed
START_WITH_DAY = False
KILL_IDLE_TIME = 300
WARN_IDLE_TIME = 180
PART_GRACE_TIME = 10
KILL_GRACE_TIME = 30
LOG_FILENAME = ""
BARE_LOG_FILENAME = "barelog.txt"

192
wolfgame.py

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

Loading…
Cancel
Save