示例#1
0
    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
示例#2
0
    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)
示例#3
0
 def __call__(self, client, msg):
     client.send_message(message.Join(self.channel))
示例#4
0
    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
示例#5
0
 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]