summaryrefslogtreecommitdiffstats
path: root/main.py
diff options
context:
space:
mode:
authorZaran <zaran.krleza@gmail.com>2011-11-27 01:57:06 -0800
committerZaran <zaran.krleza@gmail.com>2011-11-27 01:57:06 -0800
commit18e333a8c3f401e97489ffc712adab27a4a2e0c4 (patch)
tree3f4153b4c513467926394f5d7033970fb963e2d7 /main.py
downloadpickupbot-18e333a8c3f401e97489ffc712adab27a4a2e0c4.tar.gz
Initial commit
Diffstat (limited to 'main.py')
-rw-r--r--main.py186
1 files changed, 186 insertions, 0 deletions
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..1994135
--- /dev/null
+++ b/main.py
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Author: Zaran <zaran.krleza@gmail.com>
+
+import irclib
+import sys
+
+class MatchState:
+ gametypes = { 'duel':2,
+ 'ctf':8,
+ 'ictf':8,
+ 'ca':8 }
+
+ def __init__(self):
+ state = {}
+ for gt in MatchState.gametypes:
+ state[gt] = set()
+ self._state = state
+
+ def __str__(self):
+ matchlist = [ "{}: {}/{}".format(k, len(v), self.__class__.gametypes[k])
+ for k,v in self._state.items() ]
+ return "|".join(matchlist)
+
+ def _remove_from_gametype(self, nickname, gametype):
+ if gametype in self._state:
+ self._state[gametype].discard(nickname)
+
+ def _add_to_gametype(self, nickname, gametype):
+ """Internal: add a nickname to a given gametype"""
+ if gametype in self._state:
+ self._state[gametype].add(nickname)
+
+ def add(self,nickname,gametypes=None):
+ """Add a nickname to a list of gametypes or to all gametypes
+ if the list is not specified"""
+ if (gametypes is None) or (len(gametypes) == 0):
+ for gt in self._state:
+ self._add_to_gametype(nickname,gt)
+ else:
+ for gt in gametypes:
+ self._add_to_gametype(nickname,gt)
+
+ def remove(self,nickname,gametypes=None):
+ if (gametypes is None) or (len(gametypes) == 0):
+ for gt in self._state:
+ self._remove_from_gametype(nickname,gt)
+ else:
+ for gt in gametypes:
+ self._remove_from_gametype(nickname,gt)
+
+ def rename(self, oldnick, newnick):
+ for pl in self._state.values():
+ if oldnick in pl:
+ pl.remove(oldnick)
+ pl.add(newnick)
+
+ def player_list(self,gametypes=None):
+ result = {}
+ if (gametypes is None) or (len(gametypes) == 0):
+ for gt in self._state:
+ result[gt] = list(self._state[gt])
+ else:
+ for gt in gametypes:
+ if gt in self._state[gt]:
+ result[gt] = list(self._state[gt])
+ return result
+
+ def check_match_begin(self):
+ gametype = None
+ player_list = None
+ for gt in self._state:
+ if len(self._state[gt]) == self.__class__.gametypes[gt]:
+ player_list = list(self._state[gt])
+ gametype = gt
+ self._state[gt] = set()
+ for player in player_list:
+ self.remove(player)
+ break
+ return gametype, player_list
+
+class IRCMatchBot(irclib.SimpleIRCClient):
+
+ def __init__(self, target):
+ irclib.SimpleIRCClient.__init__(self)
+ self.target = target
+ self.matchState = MatchState()
+
+ def update_topic(self):
+ """Set the channel topic to the match state"""
+ self.connection.topic(self.target, str(self.matchState))
+
+ def on_welcome(self, connection, event):
+ connection.join(self.target)
+
+ def on_join(self, connection, event):
+ pass
+
+ def on_mode(self, connection, event):
+ if connection.get_nickname() in event.arguments():
+ self.update_topic()
+
+ def on_pubmsg(self, connection, event):
+ nick = irclib.nm_to_n(event.source())
+ words = event.arguments()[0].split(None,1)
+ command = words[0]
+ if command[0] == '!':
+ command = command[1:]
+ if (len(words) > 1) and (len(words[1]) > 0):
+ args = words[1]
+ else:
+ args = None
+ self.do_command(connection,nick,command,args)
+
+ def do_command(self, c, nick, command, args):
+ if command == "help":
+ c.privmsg(nick, "Je suis le bot de Pickup de #warsow.fr")
+ c.privmsg(nick, "")
+ elif (command == "add") or (command == "remove") or (command == "list"):
+ if args is None:
+ gtlist = None
+ else:
+ gtlist = [gt.strip() for gt in args.split(',')]
+ if command == "add":
+ self.matchState.add(nick, gtlist)
+ gametype, player_list = self.matchState.check_match_begin()
+ if gametype is not None:
+ c.privmsg( self.target,
+ "Un {} est sur le point de commencer. Liste des joueurs : {}"
+ .format( gametype, ", ".join(player_list) ) )
+ self.update_topic()
+ elif command == "remove":
+ self.matchState.remove(nick, gtlist)
+ self.update_topic()
+ elif command == "list":
+ result = self.matchState.player_list(gtlist)
+ for gt in result:
+ if len(result[gt]) > 0:
+ c.privmsg(nick, "{}: {}".format(gt, ", ".join(result[gt])))
+ else:
+ c.privmsg(nick, "Cette commande n'existe pas, tape !help pour obtenir de l'aide")
+
+ def on_part(self, c, e):
+ nick = irclib.nm_to_n(e.source())
+ self.matchState.remove(nick, None)
+ self.update_topic()
+
+ def on_quit(self, c, e):
+ self.on_part(c,e)
+
+ def on_disconnect(self, connection, event):
+ sys.exit(0)
+
+ def on_nick(self,c,e):
+ old_nick = irclib.nm_to_n(e.source())
+ new_nick = e.target()
+ self.matchState.rename(old_nick, new_nick)
+
+def main():
+ if len(sys.argv) != 4:
+ print "Usage: " + sys.argv[0] + " <server[:port]> <nickname> <channel>"
+ sys.exit(1)
+
+ s = sys.argv[1].split(":", 1)
+ server = s[0]
+ if len(s) == 2:
+ try:
+ port = int(s[1])
+ except ValueError:
+ print "Error: Erroneous port."
+ sys.exit(1)
+ else:
+ port = 6667
+ nickname = sys.argv[2]
+ channel = sys.argv[3]
+
+ c = IRCMatchBot(channel)
+ try:
+ c.connect(server, port, nickname)
+ except irclib.ServerConnectionError, x:
+ print x
+ sys.exit(1)
+ c.start()
+
+if __name__ == "__main__":
+ main()