!#/usr/bin/python from twisted.internet import reactor, protocol import random from conf import * # a client protocol class UnoBot(protocol.Protocol): def connectionMade(self): print "Connected" self.rawsend("NICK %s \n" % (nick)) self.rawsend("USER %s * * :%s\n" % (ident, realname)) self.logf = open("raw.txt", "a") self.game = {} self.game["going"] = False self.game["playing"] = False self.game["starter"] = "" def on_GAME_STOP(self, info) : self.game = {} self.game["going"] = False self.game["playing"] = False self.game["starter"] = "" self.ircsend(channel, "The game has ended") def dataReceived(self, data): print data self.logf.write(data) error = 0 lines = data.replace("\r", "").split("\n") if data.split(" ")[0] == "PING" : self.rawsend("PONG %s\n" % (data.split(" ")[1])) for line in lines : if line != "" : try : info = {} info["raw"] = line info["words"] = line[1:].split(" ") if info["words"][1] == "001" : if bpass != "" : self.ircsend("NickServ", "IDENTIFY %s %s" % (nick, bpass)) self.rawsend("JOIN %s \n" % (channel)) info["whois"] = info["words"][0] info["sender"] = info["whois"].split("!")[0] except : print "Ok" try : info["hostname"] = info["whois"].split("@")[1] except : info["hostname"] = "Unknown" try : info["mode"] = info["words"][1] except : info["mode"] = "Unknown" try : if info["words"][2] == nick : info["channel"] = info["sender"] else : info["channel"] = info["words"][2].replace(":", "") except : info["channel"] = "Unknown" try : if info["mode"] == "PRIVMSG" or info["mode"] == "TOPIC" : if ":" in info["words"][3] : info["message"] = " ".join(info["words"][3:])[1:] else : info["message"] = " ".join(info["words"][3:]) else : info["message"] = "Unknown" except : error = 1 #if error != 1 : self.prettify(info) self.command_parser(info) def on_GAME_START(self, info) : if not self.game["going"] : self.shuffle_deck() self.ircsend(info["channel"], "Who is going to play? Up to four players may join.") self.game["players"] = {} self.game["order"] = [] self.game["going"] = True self.game["starter"] = info["sender"] else : self.ircsend(info["channel"], "%s: We are already playing a game!" % (info["sender"])) def on_PLAYER_JOIN(self, info) : if len(self.game["order"]) <= 3 and self.game["going"] and not self.game["playing"] and info["sender"] not in self.game["order"]: self.game["order"].append(info["sender"]) self.game["players"][info["sender"]] = {} self.game["players"][info["sender"]]["cards"] = [] self.ircsend(channel, "%s has just joined the game!" % (info["sender"])) elif not self.game["going"] : self.ircsend(info["channel"], "We are not playing yet!") elif len(self.game["order"]) == 4 : self.ircsend(info["channel"], "Sorry, but there are already 4 players") elif self.game["playing"] : self.ircsend(info["channel"], "We are already playing a game!") elif info["sender"] in self.game["order"] : self.ircsend(info["channel"], "%s: You have already joined!" % (info["sender"])) def shuffle_deck(self) : self.game["deck"] = [] for color in ["r", "y", "b", "g"] : for action in ["skip", "+2", "rev"] : self.game["deck"].append("%s_%s" % (color, action)) for num in range(1, 10) : self.game["deck"].append("%s_%s" % (color, num)) self.game["deck"] = self.game["deck"] + self.game["deck"] for card in range(4) : self.game["deck"].append("w_*") self.game["deck"].append("w_+4") for color in ["r", "y", "b", "g"] : self.game["deck"].append("%s_0" % (color)) random.shuffle(self.game["deck"]) def connectionLost(self, reason): print "connection lost" self.logf.close() def on_GO(self, info) : if self.game["going"] : for player in self.game["order"] : self.game["players"][player]["r"] = [] self.game["players"][player]["g"] = [] self.game["players"][player]["b"] = [] self.game["players"][player]["y"] = [] self.game["players"][player]["w"] = [] for count in range(10) : self.game["players"][player][str(count)] = [] self.game["players"][player]["skip"] = [] self.game["players"][player]["+2"] = [] self.game["players"][player]["rev"] = [] self.game["players"][player]["*"] = [] self.game["players"][player]["+4"] = [] for card in range(7) : self.game["players"][player]["cards"].append(self.game["deck"][0]) self.game["players"][player][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][player][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][player]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(player, "Your hand: %s" % (msg)) self.ircsend(channel, "Let the game begin! %s goes first. Also, the current card is [%s]" % (self.game["order"][0], self.game["deck"][0])) self.game["nextup"] = 1 self.game["up"] = 0 self.game["currentcard"] = self.game["deck"][0] self.game["deck"].pop(0) self.game["reversed"] = False if self.game["currentcard"][0] == "w" : self.game["chooser"] = self.game["order"][0] self.ircsend(channel, "%s needs to choose a color with the choose command" % (self.game["chooser"])) else : self.game["chooser"] = "" self.game["safe"] = [] else : self.ircsend(channel, "We are not playing a game right now!") self.game["playing"] = True def on_TURN_DONE(self, info) : if self.game["reversed"] : if self.game["up"] == 0 : self.game["up"] = len(self.game["order"]) - 1 self.game["nextup"] = len(self.game["order"]) - 2 else : self.game["up"] -= 1 if self.game["nextup"] == 0 : self.game["nextup"] == len(self.game["order"]) - 1 else : self.game["nextup"] -= 1 else : if self.game["up"] == len(self.game["order"]) - 1 : self.game["up"] = 0 self.game["nextup"] = 1 else : self.game["up"] += 1 if self.game["nextup"] == len(self.game["order"]) - 1 : self.game["nextup"] = 0 else : self.game["nextup"] += 1 msg = "" for card in self.game["players"][info["sender"]]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(info["sender"], "Your hand: %s" % (msg)) self.ircsend(channel, "%s now has %s card(s) left in his/her hand" % (info["sender"], len(self.game["players"][info["sender"]]["cards"]))) self.ircsend(channel, "It is now %s's turn" % (self.game["order"][self.game["up"]])) self.ircsend(channel, "The current card is now [%s]" % (self.game["currentcard"])) def eval_card(self, info) : if self.game["currentcard"].split("_")[1] not in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] : if self.game["currentcard"].split("_")[1] == "rev" : if not self.game["reversed"] : self.game["reversed"] = True else : self.game["reversed"] = False self.ircsend(channel, "The turn order has been reversed!") self.on_TURN_DONE(info) elif self.game["currentcard"].split("_")[1] == "skip" : self.on_SKIP(info) self.on_TURN_DONE(info) elif self.game["currentcard"].split("_")[1] == "+2" : for card in range(2) : self.game["players"][self.game["order"][self.game["nextup"]]]["cards"].append(self.game["deck"][0]) self.game["players"][self.game["order"][self.game["nextup"]]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][self.game["order"][self.game["nextup"]]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][self.game["order"][self.game["nextup"]]]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(self.game["order"][self.game["nextup"]], "Your hand: %s" % (msg)) self.ircsend(channel, "%s has %s card(s) left in his/her hand" % (self.game["order"][self.game["nextup"]], len(self.game["players"][self.game["order"][self.game["nextup"]]]["cards"]))) self.on_TURN_DONE(info) elif self.game["currentcard"] == "w_*" : self.game["chooser"] = info["sender"] self.ircsend(channel, "%s needs to choose a color with the choose command" % (self.game["order"][self.game["up"]])) elif self.game["currentcard"] == "w_+4" : self.game["chooser"] = info["sender"] for card in range(4) : self.game["players"][self.game["order"][self.game["nextup"]]]["cards"].append(self.game["deck"][0]) self.game["players"][self.game["order"][self.game["nextup"]]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][self.game["order"][self.game["nextup"]]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][self.game["order"][self.game["nextup"]]]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(self.game["order"][self.game["nextup"]], "Your hand: %s" % (msg)) self.ircsend(channel, "%s now has %s card(s) left in his/her hand" % (self.game["order"][self.game["nextup"]], len(self.game["players"][self.game["order"][self.game["nextup"]]]["cards"]))) self.ircsend(channel, "%s needs to choose a color with the choose command" % (self.game["order"][self.game["up"]])) else : self.on_TURN_DONE(info) def on_SKIP(self, info) : if self.game["reversed"] : if self.game["up"] == 0 : self.game["up"] = len(self.game["order"]) - 1 self.game["nextup"] = len(self.game["order"]) - 2 else : self.game["up"] -= 1 if self.game["nextup"] == 0 : self.game["nextup"] == len(self.game["order"]) - 1 else : self.game["nextup"] -= 1 else : if self.game["up"] == len(self.game["order"]) - 1 : self.game["up"] = 0 self.game["nextup"] = 1 else : self.game["up"] += 1 if self.game["nextup"] == len(self.game["order"]) - 1 : self.game["nextup"] = 0 else : self.game["nextup"] += 1 def on_PLAY(self, info, args) : if info["sender"] == self.game["order"][self.game["up"]] : if len(args) == 2 : if args[1] in self.game["players"][info["sender"]]["cards"] : if args[1].split("_")[0] == self.game["currentcard"].split("_")[0] or args[1].split("_")[1] == self.game["currentcard"].split("_")[1] or args[1][0] == "w" : if len(self.game["players"][info["sender"]]["cards"]) > 1 and info["sender"] in self.game["safe"] : self.game["safe"].remove(info["sender"]) self.game["currentcard"] = args[1] self.game["players"][info["sender"]]["cards"].remove(args[1]) self.game["players"][info["sender"]][args[1].split("_")[0]].remove(args[1].split("_")[1]) self.game["players"][info["sender"]][args[1].split("_")[1]].remove(args[1].split("_")[0]) self.eval_card(info) if len(self.game["players"][info["sender"]]["cards"]) == 0 : self.ircsend(channel, "%s wins the game!" % (info["sender"])) self.on_GAME_STOP(info) else : self.ircsend(channel, "%s: You cannot play that card right now!" % (info["sender"])) else : self.ircsend(channel, "%s: You do not have that card!" % (info["sender"])) else : self.ircsend(channel, "%s: It is not your turn!" % (info["sender"])) def on_CHOOSE(self, info, args) : if self.game["playing"] : if info["sender"] == self.game["chooser"] and args[1] in ["red", "yellow", "blue", "green"] : self.game["currentcard"] = "%s_*" % (args[1][0]) self.game["chooser"] = "" self.ircsend(channel, "%s is now the current color" % (args[1])) self.on_TURN_DONE(info) else : self.ircsend(channel, "%s: You either did not play a wild card or that color is invalid" % (info["sender"])) else : self.ircsend(channel, "We are not playing a game right now!") def on_DRAW(self, info) : if self.game["playing"] : if self.game["players"][info["sender"]][self.game["currentcard"].split("_")[0]] == [] and self.game["players"][info["sender"]][self.game["currentcard"].split("_")[1]] == [] and "w_*" not in self.game["players"][info["sender"]]["cards"] and "w_+4" not in self.game["players"][info["sender"]]["cards"] : self.game["players"][info["sender"]]["cards"].append(self.game["deck"][0]) self.game["players"][info["sender"]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][info["sender"]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][info["sender"]]["cards"] : msg = msg + "[%s] " % (card) self.on_TURN_DONE(info) else : self.ircsend(channel, "%s: You have a card that you can play!" % (info["sender"])) else : self.ircsend(channel, "We are not playing a game right now!") def on_UNO(self, info) : if self.game["playing"] : if len(self.game["players"][info["sender"]]["cards"]) == 1 : self.game["safe"].append(info["sender"]) self.ircsend(channel, "Uno! Approved") else : self.ircsend(channel, "%s: You have more than one card. Try counting next time!" % (info["sender"])) for card in range(2) : self.game["players"][info["sender"]]["cards"].append(self.game["deck"][0]) self.game["players"][info["sender"]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][info["sender"]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][info["sender"]]["cards"] : msg += "[%s] " % (card) self.ircsend(info["sender"], "Your hand: %s" % (msg)) self.ircsend(channel, "%s now has %s card(s) left in his/her hand" % (info["sender"], len(self.game["players"][info["sender"]]["cards"]))) else : self.ircsend(channel, "We are not playing a game right now!") def on_CATCH(self, info, args) : if self.game["playing"] : if args[1] in self.game["order"] : if args[1] not in self.game["safe"] and len(self.game["players"][args[1]]["cards"]) == 1 : for card in range(2) : self.game["players"][args[1]]["cards"].append(self.game["deck"][0]) self.game["players"][args[1]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][args[1]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][args[1]]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(args[1], "Your hand: %s" % (msg)) self.ircsend(channel, "%s now has %s card(s) left in his/her hand" % (args[1], len(self.game["players"][args[1]]["cards"]))) elif args[1] in self.game["safe"] : self.ircsend(channel, "Wrong! That person already said Uno!") for card in range(2) : self.game["players"][info["sender"]]["cards"].append(self.game["deck"][0]) self.game["players"][info["sender"]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][info["sender"]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][info["sender"]]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(info["sender"], "Your hand: %s" % (msg)) self.ircsend(channel, "%s now has %s card(s) left in his/her hand" % (info["sender"], len(self.game["players"][info["sender"]]["cards"]))) elif len(self.game["players"][args[1]]["cards"]) != 1 : self.ircsend(channel, "Wrong! That player does not have only one card in his/her hand!") for card in range(2) : self.game["players"][info["sender"]]["cards"].append(self.game["deck"][0]) self.game["players"][info["sender"]][self.game["deck"][0][0]].append(self.game["deck"][0].split("_")[1]) self.game["players"][info["sender"]][self.game["deck"][0].split("_")[1]].append(self.game["deck"][0][0]) self.game["deck"].pop(0) msg = "" for card in self.game["players"][info["sender"]]["cards"] : msg = msg + "[%s] " % (card) self.ircsend(info["sender"], "Your hand: %s" % (msg)) self.ircsend(channel, "%s now has %s card(s) left in his/her hand" % (info["sender"], len(self.game["players"][info["sender"]]["cards"]))) else : self.ircsend(info["channel"], "No such player!") else : self.ircsend(channel, "We are not playing a game right now!") def command_parser(self, info) : args = info["message"][1:].split(" ") if info["message"][0] == prefix and info["sender"] in admin : args = info["message"][1:].split(" ") if args[0] == "join" : self.rawsend("JOIN %s \n" % (args[1])) if args[0] == "part" : self.rawsend("PART %s \n" % (args[1])) if args[0] == "quit" : self.transport.loseConnection() if args[0] == "eval" : try : self.ircsend(info["channel"], str(eval(args[1]))) except : print "Error" if info["message"][0] == prefix : if args[0] == "start": self.on_GAME_START(info) elif args[0] == "me" : self.on_PLAYER_JOIN(info) elif args[0] == "go" and info["sender"] == self.game["starter"] and self.game["going"] : self.on_GO(info) elif args[0] == "play" : self.on_PLAY(info, args) elif args[0] == "choose" : self.on_CHOOSE(info, args) elif args[0] == "draw" : self.on_DRAW(info) elif args[0] == "uno": self.on_UNO(info) elif args[0] == "stop" and self.game["starter"] == info["sender"] : self.on_GAME_STOP(info) def ircsend(self, targ_channel, msg_out) : self.rawsend("PRIVMSG %s :%s\n" % (targ_channel, msg_out)) def rawsend(self, msg_out) : self.transport.write(msg_out) print ">>>%s" % (msg_out) class UnoFactory(protocol.ClientFactory): protocol = UnoBot def clientConnectionFailed(self, connector, reason): print "Connection failed - goodbye!" reactor.stop() def clientConnectionLost(self, connector, reason): print "Connection lost - goodbye!" reactor.stop() def main(): f = UnoFactory() reactor.connectTCP(host, port, f) reactor.run() if __name__ == '__main__': main()