Beispiel #1
0
    def add_user_to_game(self, user, game, subtle_message=False):
        if len(game.players) >= game.max_player_count:
            banter = ":warning: game's full, rip {0}".format(format_user(user))
            if subtle_message:
                self.update_game_message(game, banter)
            else:
                self.send_message(banter)
            return

        if not game.add_player(user):
            banter = "you're already in the '{}' game {}".format(
                game.description, format_user(user))
        else:
            banter = self.load_banter("joined", {
                "s": format_user(user),
                "d": game.description
            },
                                      for_user=user,
                                      in_channel=game.channel)

        self.history_sync()

        if not subtle_message:
            self.send_message(banter)
        self.update_game_message(game, banter if subtle_message else None)
        self.save()
Beispiel #2
0
    def maybe_cancel_game(self, message, rest):
        user = message.user

        if len(rest) == 0:
            user_games = self.games_created_by(message.user)
            if len(user_games) == 1:
                game = user_games[0]
            else:
                self.send_too_many_owned_games_message(user_games, "cancel")
                return
        else:
            try:
                when = parse_time(rest)
            except ValueError:
                self.send_message(
                    ":warning: scrubadubdub, when's this game you want to cancel?"
                    .format(rest))
                return

            game = self.game_occuring_at(when)
            if not game:
                self.send_game_not_found(when, user)
                return

        if game.creator != user:
            self.send_message(
                ":warning: scrubadubdub, only {} can cancel the {} {}".format(
                    format_user(game.creator), when_str(game.when),
                    game.description))
            return

        self.games = filter(lambda g: g != game, self.games)

        rip_players = game.pretty_players(with_creator=False)
        rip_players_message = " (just burn some time on kimble instead {})".format(rip_players) \
            if len(rip_players) else ""

        self.send_message(
            ":candle: {}'s {} ({}) has been flown out by {}{}".format(
                game.channel, game.description, when_str(game.when),
                format_user(user), rip_players_message))

        newtext = game.message.text + "\n:warning: Cancelled :warning: :candle::candle:"
        self.update_message(newtext, original_message=game.message)

        self.history.cancel_game(game)

        self.save()
Beispiel #3
0
            def stat_for_user(user_stats):
                user, users_stats = user_stats

                def get_stat_value(stat):
                    value = users_stats[stat]

                    # maybe highlight the value, if it was the latest
                    if last_updated_user_stat:
                        last_u, last_s = last_updated_user_stat
                        if user == last_u and stat == last_s:
                            return "[{}]".format(value)

                    return value

                if UserOption.mute in self.user_options[user]:
                    # we won't be @ing this user
                    user_name = user
                    user_padding = 0
                else:
                    padding_for_slackat = -2
                    user_name = format_user(user)
                    user_padding = format_user_padding(
                        user) + padding_for_slackat

                return [(user_padding, user_name)] \
                        + map(get_stat_value, allstats)
Beispiel #4
0
    def maybe_new_game(self, user, channel, rest):
        """
        Attempts to create a new game from freeform text
        Returns True on parse success (even if game creation failed)
        """
        parsed = parse_game_initiation(rest, channel)
        if not parsed:
            return False

        when, desc, max_player_count, play_time, mode = parsed
        if len(desc) == 0:
            desc = "big game"

        game = self.game_overlapping(when, play_time)
        if game:
            self.send_duplicate_game_message(game)
            return True

        banter = self.load_banter("created", {"s": format_user(user)},
                                  for_user=user,
                                  in_channel=channel)

        message = Game.create_message(banter, desc, when, max_player_count,
                                      mode, channel)
        posted_message = self.send_message(message)

        game = self.new_game(when, desc, channel, user, \
                posted_message, max_player_count, play_time, mode)

        self.add_user_to_game(user, game, subtle_message=True)
        return True
Beispiel #5
0
 def send_game_not_found(self, when, user):
     if random.randint(0, 1) == 0:
         self.send_message(":warning: {0}, there isnae game at {1}".format(
             format_user(user), when_str(when)))
     else:
         self.send_message(
             ":warning: scrubadubdub, there's no game at {}".format(
                 when_str(when)))
Beispiel #6
0
    def remove_user_from_game(self, user, game, subtle_message=False):
        if game.remove_player(user):
            banter = ":candle: {}".format(format_user(user))
        else:
            if subtle_message:
                # don't say anything - they're silently removing their failed join-attmept-emoji
                return

            banter = ":warning: you're not in the {} game {} (\"{}\")".format(
                when_str(game.when), format_user(user), game.description)

        self.history_sync()

        if not subtle_message:
            self.send_message(banter)
        self.update_game_message(game, banter if subtle_message else None)
        self.save()
Beispiel #7
0
    def handle_stats_request(self, message, rest, type=StatRequest.stats):
        anchor_message = True
        channel_name = None
        year = None
        k_factor = None
        history_length = None

        if len(rest):
            parsed = parse_stats_request(rest)
            if not parsed:
                self.send_message(
                    ":warning: ere {}: \"{} [year] [channel]\"".format(
                        type, format_user(message.user)))
                return
            channel_name, year, k_factor, history_length = parsed
            anchor_message = (channel_name is None or channel_name == message.channel.name) \
                    and (year is None or year.year == datetime.date.today().year)

        if not channel_name:
            channel_name = message.channel.name

        if type == StatRequest.elo:
            rankings = self.history.summary_elo(channel_name,
                                                year=year,
                                                k_factor=k_factor)

            if history_length:
                ranking_values = map(
                    lambda ranking: [
                        ranking.getName(), ranking.games_played,
                        ranking.getFormattedRanking(),
                        ranking.getHistory(history_length)
                    ], rankings.values())
                ranking_values.sort(key=lambda x: (x[1] > 10, x[2]),
                                    reverse=True)
                table = generate_table(
                    ['Player', 'Games Played', 'Ranking', 'Form'],
                    ranking_values)
            else:
                ranking_values = map(
                    lambda ranking: [
                        ranking.getName(), ranking.games_played,
                        ranking.getFormattedRanking()
                    ], rankings.values())
                ranking_values.sort(key=lambda x: (x[1] > 10, x[2]),
                                    reverse=True)
                table = generate_table(['Player', 'Games Played', 'Ranking'],
                                       ranking_values)

            self.send_message(table)
        else:
            stats = self.history.summary_stats(channel_name, year=year)
            self.update_stats_table(channel_name,
                                    stats,
                                    force_new=True,
                                    anchor_message=anchor_message)
            self.latest_stats_table[channel_name].year = year
Beispiel #8
0
    def handle_imminent_games(self):
        scheduled_games = filter(lambda g: g.state == GameStates.scheduled,
                                 self.games)
        active_games = filter(lambda g: g.state == GameStates.active,
                              self.games)

        self.update_game_states()

        # keep games until end-of-day (to allow late entrants, etc)
        self.games = filter(lambda g: g.state != GameStates.dead, self.games)

        imminent_games = filter(lambda g: g.state == GameStates.active,
                                scheduled_games)
        just_finished_games = filter(lambda g: g.state == GameStates.finished,
                                     active_games)

        for g in imminent_games:
            if len(g.players) == 0:
                banter = "big game ({0}) about to kick off at {1}, no one wants to play?".format(
                    g.description, when_str(g.when))
            else:
                banter = self.load_banter(
                    "kickoff", {
                        "s": g.pretty_players(),
                        "t": when_str(g.when),
                        "d": g.description,
                    })

            suggested_teams = suggest_teams(g)
            if suggested_teams:
                banter += "\n{}".format(suggested_teams)

            nextgame = self.game_straight_after(g,
                                                threshold=GAME_FOLLOWON_TIME)
            if nextgame:
                nextgame_banter = self.load_banter(
                    "follow-on", {
                        "s": format_user(nextgame.creator),
                        "d": nextgame.description,
                        "c": nextgame.channel,
                    })
                banter += "\n({})".format(nextgame_banter)

            self.send_message(banter, to_channel=g.channel)

        for g in just_finished_games:
            msg = vote_message(g)
            if msg:
                self.update_game_message(g, msg)
Beispiel #9
0
 def handle_game_reaction(self, game, reacting_user, emoji, removed):
     now = datetime.datetime.today()
     join_emojis = ["+1", "thumbsup", "plus1" "heavy_plus_sign"]
     if emoji in join_emojis:
         if now < game.endtime():
             if removed:
                 self.remove_user_from_game(reacting_user,
                                            game,
                                            subtle_message=True)
             else:
                 self.add_user_to_game(reacting_user,
                                       game,
                                       subtle_message=True)
         else:
             self.update_game_message(
                 game, "game's over {}, can't {}".format(
                     format_user(reacting_user),
                     "flyout" if removed else "flyin"))
Beispiel #10
0
    def handle_command(self, message, command, rest):
        if len(command.strip()) == 0 and len(rest) == 0:
            self.send_dialect_reply(message)
            return

        if command.lower() in PS4Bot_commands:
            PS4Bot_commands[command.lower()][1](self, message, rest)
            return

        # attempt to parse a big game, if unsuccessful, show usage:
        if not self.maybe_new_game(message.user, message.channel.name,
                                   command + " " + rest):
            self.send_message((
                ":warning: Hew {}, here's what I listen to: `{} {}`, " +
                "or try adding a :+1: to a game invite (or typing `+:+1:` as a response)."
            ).format(
                format_user(message.user), self.botname,
                "/".join(command
                         for command, (show, _) in PS4Bot_commands.iteritems()
                         if show)))
Beispiel #11
0
 def replace_user(match):
     id = match.group(1)
     name = lookup_user(self.slackconnection, id)
     if name:
         return format_user(name)
     return match.group(0)
Beispiel #12
0
def scrub_entry(player, i):
    return ":{}: {}".format(number_emojis[i], format_user(player))
Beispiel #13
0
 def send_thanks_reply(self, message, rest):
     reply = self.load_banter("thanked", {"s": format_user(message.user)},
                              for_user=message.user,
                              in_channel=message.channel.name)
     self.send_message(reply)
Beispiel #14
0
 def send_dialect_reply(self, message):
     reply = self.load_banter("dialect", {"u": format_user(message.user)},
                              for_user=message.user,
                              in_channel=message.channel.name)
     self.send_message(reply)
Beispiel #15
0
    def maybe_scuttle_game(self, message, rest):
        tokens = rest.split(" ")

        if len(tokens) >= 3 and tokens[-2] == "to":
            str_to = tokens[-1]
            str_from = " ".join(tokens[:-2])
        elif len(tokens) == 1:
            str_from = None
            str_to = tokens[0]
        else:
            self.send_scuttle_usage()
            return

        try:
            when_desc = None
            when_to = parse_time(str_to)
        except ValueError:
            self.send_scuttle_usage()
            return

        try:
            when_from = parse_time(str_from) if str_from else None
        except ValueError:
            when_desc = str_from

        if when_desc:
            game_to_move = None
            for g in self.games:
                if g.description == when_desc:
                    if game_to_move:
                        self.send_message(
                            ":warning: scrubadubdub - there's multiple games called \"{}\""
                            .format(when_desc))
                        return
                    game_to_move = g

        elif when_from:
            # we've been given an explicit game to move
            game_to_move = self.game_occuring_at(when_from)
            if not game_to_move:
                self.send_game_not_found(when_from, message.user)
                return
        else:
            # no explicit game to move, if the user has just one, move it
            created_games = self.games_created_by(message.user)
            if len(created_games) != 1:
                self.send_too_many_owned_games_message(created_games,
                                                       "scuttle")
                return
            game_to_move = created_games[0]

        if game_to_move.creator != message.user:
            self.send_message(
                ":warning: scrubadubdub, only {} can scuttle the {} {}".format(
                    format_user(game_to_move.creator),
                    when_str(game_to_move.when), game_to_move.description))
            return

        game_in_slot = self.game_overlapping(when_to,
                                             game_to_move.play_time,
                                             ignoring=game_to_move)
        if game_in_slot:
            self.send_duplicate_game_message(game_in_slot)
            return

        old_when = game_to_move.when

        banter = self.load_banter("created", {"s": format_user(message.user)},
                                  for_user=message.user,
                                  in_channel=game_to_move.channel)

        game_to_move.update_when(when_to, banter)
        self.update_game_message(
            game_to_move, "moved by {} to {}".format(format_user(message.user),
                                                     when_str(when_to)))

        pretty_players = game_to_move.pretty_players(with_creator=False)
        self.send_message(
            ":alarm_clock: {}{} moved from {} to {} by {}".format(
                pretty_players + " - " if len(pretty_players) else "",
                game_to_move.description, when_str(old_when),
                when_str(when_to), format_user(message.user)))

        self.save()