def __call__(self, game, index, spy): """This function pretends to be a Builder, but in fact just configures this object in place as it's easier to setup and maintain.""" Player.__init__(self, self.name, index) self.state = game self.spy = spy self.channel = '%s-player-%i' % (self.game, index) self.client.send_message(message.Join(self.channel)) self.client.send_message(message.Join(self.game)) self._join = Event() # Use elegant /INVITE command for humans that have better clients. self.client.send_message(message.Command([self.name, self.channel], 'INVITE')) return self
def __call__(self, client, msg): if msg.command == '001': self.client = client client.send_message(message.Join('#resistance')) Greenlet.spawn(self._loop) elif msg.command == 'PING': client.send_message(message.Command(msg.params, 'PONG')) elif msg.command == '353': if msg.params[2] != '#resistance': # When joining specific bot private channels, see if the bot is # already there waiting and don't require rejoin. waiting = [u.strip('+@') for u in msg.params[3:]] for g in self.games: for b in [b for b in g.bots if b.name in waiting]: if b.channel == msg.params[ 2] and b._join and not b._join.ready(): b._join.set() return self.competitors = [u.strip('+@') for u in msg.params[3:]] self.competitors.remove(client.nick) elif msg.command == 'JOIN': user = msg.prefix.split('!')[0].strip('+@') if user == client.nick: return channel = msg.params[0].lstrip(':') if channel != '#resistance': for g in self.games: for b in g.bots: if b.channel == channel and b._join: b._join.set() return assert False, "Not waiting for a player to join this channel." else: self.competitors.append(user) elif msg.command == 'PART': user = msg.prefix.split('!')[0].strip('+@') if user == client.nick: return channel = msg.params[0].lstrip(':') if channel == '#resistance': self.competitors.remove(user) return else: for g in self.games: for b in g.bots: if b.channel == channel and b._part: # Only leave the channel once the other has left, to avoid # synchronization problems when batch processing games. b._part.set() return elif msg.command == 'PRIVMSG': channel = msg.params[0].lstrip(':') if channel == '#resistance': if msg.params[1] == 'PLAY': self.run(' '.join(msg.params[2:])) return if msg.params[1] == 'BOT': self.identities.append(msg.prefix.split('!')[0]) for g in self.games: # First check if this is a report message about sabotages in # games played between humans alone or with bots. if g.channel == channel and msg.params[1].upper( ) == 'SABOTAGES': remaining = int(msg.params[2].strip('.,!;')) for bot in g.bots: if bot._sabotage is not None: bot.send("SABOTAGES %i" % (remaining)) if bot.spy: bot._sabotage.set(bool(remaining > 0)) remaining -= 1 else: bot._sabotage.set(False) # Now check if a bot is expecting a message, and pass it along. for bot in g.bots: if bot.channel != channel: continue name = 'process_' + msg.params[1].upper() if name == 'process_COMMENT': pass elif hasattr(bot, name): process = getattr(bot, name) process(msg.params) elif bot.expecting: bot.expecting(msg.params)
def __call__(self, client, msg): client.send_message(message.Join(self.channel))
def __call__(self, client, msg): if msg.command == '001': self.client = client client.send_message(message.Join('#resistance')) Greenlet.spawn(self._loop) elif msg.command == 'PING': client.send_message(message.Command(msg.params, 'PONG')) elif msg.command == '353': if msg.params[2] != '#resistance': # When joining specific bot private channels, see if the bot is # already there waiting and don't require rejoin. waiting = [u.strip('+@') for u in msg.params[3:]] for g in self.games: for b in [b for b in g.bots if b.name in waiting]: if b.channel == msg.params[2]: if b._join: b._join.set() return self.competitors = [u.strip('+@') for u in msg.params[3:]] self.competitors.remove(client.nick) elif msg.command == 'JOIN': user = msg.prefix.split('!')[0].strip('+@') if user == client.nick: return channel = msg.params[0].lstrip(':') if channel != '#resistance': for g in self.games: for b in g.bots: if b.channel == channel: if b._join: b._join.set() return if channel in b.channel: # Bot joined shared game channel, used for global chat. return print("Not waiting for a player to join this channel.", file=sys.stderr) else: self.competitors.append(user) elif msg.command == 'PART': user = msg.prefix.split('!')[0].strip('+@') if user == client.nick: return channel = msg.params[0].lstrip(':') if channel == '#resistance': self.competitors.remove(user) return else: for g in self.games: for b in g.bots: if b.channel == channel and b._part: # Only leave the channel once the other has left, to avoid # synchronization problems when batch processing games. b._part.set() return elif msg.command == 'PRIVMSG': # Any human may ask this server to run games with available players. channel = msg.params[0].lstrip(':') if channel == '#resistance': if msg.params[1].lower() == 'play': self.run(' '.join(msg.params[2:])) return # Connecting bots always self-identify as bot for future reference. if len(msg.params) > 1 and msg.params[1] == 'BOT': self.identities.append(msg.prefix.split('!')[0]) for g in self.games: user = msg.prefix.split('!')[0].strip('+@') if g.channel == channel: g.file.write('[%s] ' % user + ' '.join(msg.params[1:])+'\n') g.file.flush() # Check if this is a report message about sabotages in # games played between humans alone or with bots. if g.channel == channel and msg.params[1].upper() == 'SABOTAGES': try: remaining = int(msg.params[2].strip('.,!;')) except ValueError: return for bot in g.bots: if bot._sabotage is not None: r = bool(remaining > 0) bot.send("SABOTAGED %s" % showYesOrNo(r)) if bot.spy: bot._sabotage.set(r) remaining -= 1 else: bot._sabotage.set(False) bot._sabotage = None if g.channel == channel and msg.params[1].upper() == 'VOTES': votes = [parseYesOrNo(v) for v in msg.params[2:]] for bot in g.bots: if bot._vote is not None and bot.name not in self.identities: v = votes.pop(0) bot.send("VOTED %s." % showYesOrNo(v)) bot._vote.set(v) if g.channel == channel and msg.params[1].upper() == 'SELECTS': for bot in g.bots: if bot._select is not None: bot.send("SELECTED %s" % ' '.join(msg.params[2:])) bot.process_SELECTED(msg.params) # Now check if a bot is expecting a message, and pass it along. for bot in g.bots: if bot.channel != channel: continue name = 'process_'+msg.params[1].upper() if hasattr(self, name): process = getattr(self, name) process(msg.params) elif hasattr(bot, name): process = getattr(bot, name) process(msg.params) elif bot.expecting: try: bot.expecting(msg.params) except: # Comments can overflow in multiple lines. pass
def test_join(self): another_channel = TEST_CHANNEL + '_other' self.client.send_message(message.Join(another_channel)) gevent.sleep(0.1) client_list = self.server.channels[another_channel].clients assert self.client.nick in [c.nick for c in client_list]