Exemple #1
0
    def confirm_result(self, message: Message, user: User, bot: TeleBot,
                       competitor: Competitor):
        res = user.check_result()
        if not len(res.scores) or len(res.scores) % 2:
            bot.send_message(
                message.chat.id,
                get_translation_for('result_scores_count_must_be_odd_msg'))
            return RET.OK, None, None, None
        if res.result is None:
            bot.send_message(
                message.chat.id,
                get_translation_for('result_winner_must_be_specified_msg'))
            return RET.OK, None, None, None

        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            res.delete()
            return teardown_challenge(
                competitor, message, user, bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent
                else 'challenge_confirm_cannot_fin_opponents_user_msg')

        opponent.previous_challenge_status = opponent.status
        opponent.change_status(
            COMPETITOR_STATUS.CHALLENGE_NEED_RESULTS_CONFIRMATION)
        opponent.save()

        ores = opponent_user.check_result()
        if ores:
            ores.delete()
        opponent_user.current_result = res
        opponent_user.states.append('ChallengeConfirmResultsState')
        if len(opponent_user.states) > STATES_HISTORY_LEN:
            del opponent_user.states[0]
        opponent_user.save()

        res.sent = True
        res.save()

        if not smwae_check(
                opponent_user.user_id,
                get_translation_for('result_confirmation_msg') + '\n' +
                render_result(res, final=False),
                opponent_user,
                reply_markup=get_result_confirmation_keyboard(),
        ):
            teardown_challenge(
                competitor, message, user, bot,
                'error_bot_blocked_by_opponent_challenge_canceled_msg')
            return RET.GO_TO_STATE, 'MenuState', message, user

        bot.send_message(message.chat.id,
                         get_translation_for('results_sent_to_opponent_msg'))
        return RET.GO_TO_STATE, 'MenuState', message, user
Exemple #2
0
    def dismiss_results(self, message: Message, user: User, bot: TeleBot,
                        competitor: Competitor):
        res = user.check_result()
        if not res:
            pass
            # TODO
        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            res.delete()
            return teardown_challenge(
                competitor, message, user, bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent
                else 'challenge_confirm_cannot_fin_opponents_user_msg')

        if opponent.previous_challenge_status:
            opponent.change_status(opponent.previous_challenge_status)
            opponent.previous_challenge_status = None
        opponent.save()

        competitor.change_status(competitor.previous_challenge_status)
        competitor.previous_challenge_status = None
        competitor.save()

        if not smwae_check(
                opponent_user.user_id,
                get_translation_for(
                    'result_confirmation_dismissed_opponent_msg'),
                opponent_user,
                reply_markup=get_menu_keyboard(status=opponent.status)):
            teardown_challenge(
                competitor, message, user, bot,
                'error_bot_blocked_by_opponent_challenge_canceled_msg')
            res.delete()
            opponent_user.reload()
            opponent_user.current_result = None
            opponent_user.save()
            user.current_result = None
            user.save()
            return RET.GO_TO_STATE, 'MenuState', message, user

        bot.send_message(
            message.chat.id,
            get_translation_for('result_confirmation_dismissed_msg'))

        res.delete()
        opponent_user.reload()
        opponent_user.current_result = None
        opponent_user.save()
        user.current_result = None
        user.save()
        return RET.GO_TO_STATE, 'MenuState', message, user
Exemple #3
0
    def process_result(self,
                       message: Message,
                       user: User,
                       bot: TeleBot,
                       competitor: Competitor,
                       final=False):
        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor, message, user, bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent
                else 'challenge_confirm_cannot_fin_opponents_user_msg')

        res = user.check_result()
        if not res:
            res = Result(player_a=competitor,
                         player_b=opponent,
                         confirmged=False)
            res.save()
            user.current_result = res
            user.save()

        text = render_result(res, final)

        bot.send_message(
            message.chat.id,
            text,
            reply_markup=self.__base_keyboard(confirmation_stage=final),
            parse_mode='html')
        return RET.OK, None, None, None
Exemple #4
0
    def entry(self,
              message: Message,
              user: User,
              bot: TeleBot,
              competitor: Competitor = None):
        if competitor is None:
            competitor = user.check_association()
        res = user.check_result()
        if not res:
            pass
            # TODO
        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            res.delete()
            return teardown_challenge(
                competitor, message, user, bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent
                else 'challenge_confirm_cannot_fin_opponents_user_msg')

        bot.send_message(message.chat.id,
                         get_translation_for('result_confirmation_msg') +
                         '\n' + render_result(res, final=False),
                         reply_markup=get_result_confirmation_keyboard(),
                         parse_mode='html')
        return RET.OK, None, None, None
Exemple #5
0
    def confirm_cancellation_opponent(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
        if competitor.status != COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION:
            return RET.OK, None, None, None
        if not user.dismiss_confirmed:
            bot.send_message(
                message.chat.id,
                get_translation_for('challenge_cancel_msg'),
                reply_markup=self.__base_keyboard(status=competitor.status)
            )
            user.dismiss_confirmed = True
            user.save()
            return RET.OK, None, None, None
        else:
            user.dismiss_confirmed = False
            user.save()

        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg'
            )

        opponent.change_status(opponent.previous_status)
        opponent.previous_status = None
        opponent.previous_challenge_status = None
        opponent.in_challenge_with = None
        opponent.challenge_started_at = None
        opponent.save()

        competitor.change_status(competitor.previous_status)
        competitor.previous_status = None
        competitor.previous_challenge_status = None
        competitor.in_challenge_with = None
        competitor.challenge_started_at = None
        competitor.save()

        smwae_check(
            opponent_user.user_id,
            get_translation_for('challenge_canceled_msg').format(competitor.name),
            opponent_user,
            reply_markup=self.__base_keyboard(status=opponent.status)
        )

        bot.send_message(
            message.chat.id,
            get_translation_for('challenge_canceled_msg').format(opponent.name),
            reply_markup=self.__base_keyboard(status=competitor.status)
        )
        LogsSheet.glog(get_translation_for('gsheet_log_game_canceled').format(opponent.name, competitor.name))
        return RET.OK, None, None, None
Exemple #6
0
    def dismiss_cancellation_opponent(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
        if competitor.status != COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION:
            return RET.OK, None, None, None

        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg'
            )

        competitor.change_status(competitor.previous_challenge_status)
        competitor.previous_challenge_status = None
        competitor.save()

        user.dismiss_confirmed = False
        user.save()

        if not smwae_check(
            opponent_user.user_id,
            get_translation_for('challenge_cancellation_denied_opponent_msg').format(competitor.name),
            opponent_user,
            reply_markup=self.__base_keyboard(status=opponent.status)
        ):
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'error_bot_blocked_by_opponent_challenge_canceled_msg'
            )

        bot.send_message(
            user.user_id,
            get_translation_for('challenge_cancellation_denied_msg').format(opponent.name),
            reply_markup=self.__base_keyboard(status=competitor.status)
        )
        return RET.OK, None, None, None
Exemple #7
0
    def cancel_challenge_request(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
        if competitor.status != COMPETITOR_STATUS.CHALLENGE_INITIATED:
            return RET.OK, None, None, None
        if not user.dismiss_confirmed:
            bot.send_message(
                message.chat.id,
                get_translation_for('challenge_request_cancel_confirm_msg'),
                reply_markup=self.__base_keyboard(status=competitor.status)
            )
            user.dismiss_confirmed = True
            user.save()
            return RET.OK, None, None, None
        else:
            user.dismiss_confirmed = False
            user.save()

        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        LogsSheet.glog(
            get_translation_for('gsheet_log_player_canceled_challenge_for_player').format(competitor.name)
        )
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_request_canceled_to_competitor_msg',
                canceled_by_bot=False
            )
        else:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_request_canceled_to_competitor_msg',
                canceled_by_bot=False,
                opponent=opponent,
                opponent_msg_key='challenge_request_canceled_to_opponent_msg'
            )
Exemple #8
0
 def submit_results(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
     if competitor.status not in (COMPETITOR_STATUS.CHALLENGE_STARTER, COMPETITOR_STATUS.CHALLENGE_RECEIVER):
         return RET.OK, None, None, None
     opponent, opponent_user = get_opponent_and_opponent_user(competitor)
     if not opponent or not opponent_user:
         return teardown_challenge(
             competitor,
             message,
             user,
             bot,
             'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg'
         )
     if opponent.status == COMPETITOR_STATUS.CHALLENGE_NEED_RESULTS_CONFIRMATION:
         bot.send_message(
             message.chat.id,
             get_translation_for('results_already_sent_msg')
         )
         return RET.OK, None, None, None
     return RET.GO_TO_STATE, 'ChallengeSendResultsState', message, user
Exemple #9
0
 def register_opponent_wins(self, message: Message, user: User,
                            bot: TeleBot, competitor: Competitor):
     res = user.check_result()
     opponent, opponent_user = get_opponent_and_opponent_user(competitor)
     if not opponent or not opponent_user:
         return teardown_challenge(
             competitor, message, user, bot,
             'challenge_confirm_cannot_find_opponent_msg' if not opponent
             else 'challenge_confirm_cannot_fin_opponents_user_msg')
     if res.player_a == opponent:
         res.result = RESULT.A_WINS
     elif res.player_b == opponent:
         res.result = RESULT.B_WINS
     else:
         logger.error(
             f'Opponent {opponent.name} record vanished from results record {str(res.id)}'
         )
         return RET.GO_TO_STATE, 'MenuState', message, user
     res.save()
     return self.process_result(message, user, bot, competitor, True)
Exemple #10
0
 def entry(self,
           message: Message,
           user: User,
           bot: TeleBot,
           competitor: Competitor = None):
     if competitor is None:
         competitor = user.check_association()
     if competitor.status not in (COMPETITOR_STATUS.CHALLENGE_STARTER,
                                  COMPETITOR_STATUS.CHALLENGE_RECEIVER):
         logger.error(
             f"User ({user.user_id}) - {competitor.name} entered ChallengeSendResultsState with incorrect competitor status {competitor.status}"
         )
         return RET.GO_TO_STATE, 'MenuState', message, user
     opponent, opponent_user = get_opponent_and_opponent_user(competitor)
     if not opponent or not opponent_user:
         return teardown_challenge(
             competitor, message, user, bot,
             'challenge_confirm_cannot_find_opponent_msg' if not opponent
             else 'challenge_confirm_cannot_fin_opponents_user_msg')
     if not user.check_result():
         res = Result(player_a=competitor,
                      player_b=opponent,
                      confirmed=False)
         res.save()
         user.current_result = res
         user.save()
     elif not user.check_result().sent:
         bot.send_message(user.user_id,
                          get_translation_for('results_enter_results_msg'))
     else:
         bot.send_message(message.chat.id,
                          get_translation_for('results_already_sent_msg'))
         return RET.GO_TO_STATE, 'MenuState', message, user
     return self.process_result(message,
                                user,
                                bot,
                                competitor,
                                final=user.check_result().result
                                is not None)
    def check_challenges():
        bconfig = get_config()
        n = datetime.now(tz=tz)
        tbot = None
        for competitor in Competitor.objects(
                status=COMPETITOR_STATUS.CHALLENGE_NEED_RESPONSE):
            try:
                if not competitor.latest_challenge_received_at:
                    logger.error(
                        f'Competitor {competitor.name} {competitor.legacy_number} has no latest_challenge_received_at'
                    )
                    competitor.latest_challenge_received_at = datetime.now(
                        tz=tz)
                    competitor.save()
                    continue
                cs = mongo_time_to_local(
                    competitor.latest_challenge_received_at, tz)
                if (n - cs) > timedelta(days=max(
                        0, bconfig.time_to_accept_challenge -
                        bconfig.accept_challenge_reminder
                )) and not competitor.challenge_remainder_sent:
                    if tbot is None:
                        tbot = TeleBot(PROJECT_NAME, threaded=False)
                    cuser = User.objects(associated_with=competitor).first()
                    if cuser is None:
                        continue
                    if not smwae_check(
                            cuser.user_id,
                            get_translation_for(
                                'remainder_challenge_accept_msg').format(
                                    bconfig.accept_challenge_reminder), cuser):
                        opponent, opponent_user = get_opponent_and_opponent_user(
                            competitor)
                        if opponent and opponent_user:
                            teardown_challenge(
                                opponent, None, opponent_user, tbot,
                                'error_bot_blocked_by_opponent_challenge_canceled_msg'
                            )
                            continue
                    competitor.reload()
                    competitor.challenge_remainder_sent = True
                    competitor.save()
                elif (n -
                      cs) > timedelta(days=bconfig.time_to_accept_challenge):
                    if tbot is None:
                        tbot = TeleBot(PROJECT_NAME, threaded=False)
                    cuser = User.objects(associated_with=competitor).first()
                    skip_comp = False
                    if cuser is None:
                        skip_comp = True

                    opponent_user: User
                    opponent, opponent_user = get_opponent_and_opponent_user(
                        competitor)

                    prev_level, new_level = None, None
                    level_change = None
                    if opponent and opponent.level > competitor.level:
                        new_level = competitor.level
                        prev_level = opponent.level
                        level_change = f'{prev_level}->{new_level}'
                        ResultsSheet.upload_canceled_result(opponent,
                                                            competitor,
                                                            level_change,
                                                            was_ignored=True)

                    if opponent:
                        config = get_config()
                        if config.group_chat_id:
                            gmsg = get_translation_for(
                                'group_chat_technical_win_report_msg').format(
                                    opponent.name, competitor.name)
                            if level_change:
                                gmsg += '.\n'
                                gmsg += get_translation_for(
                                    'group_chat_players_level_changed').format(
                                        level_change)

                                LogsSheet.glog(
                                    get_translation_for(
                                        'gsheet_log_player_ignored_challenge_from_player'
                                    ).format(competitor.name, opponent.name) +
                                    '. ' + get_translation_for(
                                        'group_chat_players_level_changed').
                                    format(level_change))
                            else:
                                LogsSheet.glog(
                                    get_translation_for(
                                        'gsheet_log_player_ignored_challenge_from_player'
                                    ).format(competitor.name, opponent.name))

                            try:
                                tbot.send_message(config.group_chat_id,
                                                  gmsg,
                                                  parse_mode='html')
                            except:
                                logger.exception(
                                    'Exception occurred while sending message to group chat'
                                )

                            res = Result(player_a=opponent,
                                         player_a_s=opponent.name,
                                         player_b=competitor,
                                         player_b_s=competitor.name,
                                         result=RESULT.IGNORED,
                                         canceled=True,
                                         date=datetime.now(tz=tz),
                                         level_change=level_change)
                            res.save()

                    competitor.in_challenge_with = None
                    competitor.change_status(competitor.previous_status)
                    competitor.previous_status = None
                    competitor.latest_challenge_received_at = None
                    if prev_level:
                        competitor.level = prev_level

                    competitor.challenges_ignored = (
                        competitor.challenges_ignored +
                        1) if competitor.challenges_ignored is not None else 1
                    competitor.challenges_ignored_total = (
                        competitor.challenges_ignored_total + 1
                    ) if competitor.challenges_ignored_total is not None else 1
                    competitor.losses = competitor.losses + 1 if competitor.losses is not None else 1
                    competitor.matches = competitor.matches + 1 if competitor.matches is not None else 1
                    if competitor.challenges_ignored >= bconfig.maximum_challenges_ignored:
                        competitor.change_status(COMPETITOR_STATUS.INACTIVE)
                        LogsSheet.glog(
                            get_translation_for(
                                'gsheet_log_player_moved_to_inactive').format(
                                    competitor.name))
                    competitor.save()
                    UsersSheet.update_competitor_table_record(competitor)

                    t = get_translation_for(
                        'challenge_was_ignored_msg').format(
                            competitor.challenges_ignored,
                            bconfig.maximum_challenges_ignored)

                    if not skip_comp:
                        if competitor.status == COMPETITOR_STATUS.INACTIVE:
                            t += '.\n<b>'
                            t += get_translation_for(
                                'user_was_moved_to_inactive')
                            t += '</b>'
                        elif prev_level:
                            t += '.\n'
                            t += get_translation_for(
                                'your_level_changed_str').format(
                                    new_level, prev_level)

                        smwae_check(cuser.user_id,
                                    t,
                                    cuser,
                                    reply_markup=get_menu_keyboard(
                                        status=competitor.status),
                                    parse_mode='html')

                    if opponent:
                        opponent.reload()
                        opponent.in_challenge_with = None
                        if opponent.status != COMPETITOR_STATUS.INACTIVE:
                            opponent.change_status(opponent.previous_status)
                        opponent.previous_status = None
                        opponent.latest_challenge_received_at = None
                        opponent.wins = opponent.wins + 1 if opponent.wins is not None else 1
                        opponent.matches = opponent.matches + 1 if opponent.matches is not None else 1
                        opponent.level = new_level
                        opponent.save()
                        UsersSheet.update_competitor_table_record(opponent)

                        t = get_translation_for(
                            'challenge_was_ignored_opponent_msg')
                        if prev_level:
                            t += '\n'
                            t += get_translation_for(
                                'your_level_changed_str').format(
                                    prev_level, new_level)
                        if opponent_user:
                            smwae_check(opponent_user.user_id,
                                        t,
                                        opponent_user,
                                        reply_markup=get_menu_keyboard(
                                            status=opponent.status),
                                        parse_mode='html')
            except:
                logger.exception(
                    f'Exception occurred while checking challenge requests for competitor {competitor.name} {competitor.legacy_number}'
                )

        for competitor in Competitor.objects(status__in=(
                COMPETITOR_STATUS.CHALLENGE_STARTER,
                COMPETITOR_STATUS.CHALLENGE_RECEIVER,
                COMPETITOR_STATUS.CHALLENGE_NEED_RESULTS_CONFIRMATION,
                COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION)):
            try:
                if not competitor.challenge_started_at:
                    logger.error(
                        f'Competitor {competitor.name} {competitor.legacy_number} has no challenge_started_at'
                    )
                    competitor.challenge_started_at = datetime.now(tz=tz)
                    competitor.save()
                    continue
                cs = mongo_time_to_local(competitor.challenge_started_at, tz)
                if (n - cs) > timedelta(days=max(
                        0, bconfig.time_to_play_challenge -
                        bconfig.challenge_play_reminder
                )) and not competitor.challenge_remainder_sent:
                    if tbot is None:
                        tbot = TeleBot(PROJECT_NAME, threaded=False)
                    cuser = User.objects(associated_with=competitor).first()
                    if cuser is None:
                        continue
                    if not smwae_check(
                            cuser.user_id,
                            get_translation_for('remainder_challenge_play_msg')
                            .format(bconfig.challenge_play_reminder), cuser):
                        opponent, opponent_user = get_opponent_and_opponent_user(
                            competitor)
                        if opponent and opponent_user:
                            teardown_challenge(
                                opponent, None, opponent_user, tbot,
                                'error_bot_blocked_by_opponent_challenge_canceled_msg'
                            )
                            continue
                    competitor.reload()
                    competitor.challenge_remainder_sent = True
                    competitor.save()
                elif (n - cs) > timedelta(days=bconfig.time_to_play_challenge):
                    # TODO
                    pass
            except:
                logger.exception(
                    f'Exception occurred while checking challenges in progress (for competitor {competitor.name} {competitor.legacy_number})'
                )
Exemple #12
0
    def cancel_challenge(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
        if competitor.status != COMPETITOR_STATUS.CHALLENGE_STARTER:
            return RET.OK, None, None, None
        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg'
            )

        if opponent.status == COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION:
            bot.send_message(
                user.user_id,
                get_translation_for('challenge_cancellation_in_progress_msg').format(opponent.name),
                reply_markup=self.__base_keyboard(status=competitor.status)
            )
            return RET.OK, None, None, None
        if opponent.status == COMPETITOR_STATUS.CHALLENGE_NEED_RESULTS_CONFIRMATION:
            bot.send_message(
                user.user_id,
                get_translation_for('challenge_cancellation_opponent_is_verifying_results_msg').format(opponent.name),
                reply_markup=self.__base_keyboard(status=competitor.status)
            )
            return RET.OK, None, None, None

        if not user.dismiss_confirmed:
            bot.send_message(
                message.chat.id,
                get_translation_for('challenge_cancel_msg'),
                reply_markup=self.__base_keyboard(status=competitor.status)
            )
            user.dismiss_confirmed = True
            user.save()
            return RET.OK, None, None, None
        else:
            user.dismiss_confirmed = False
            user.save()

        opponent.previous_challenge_status = opponent.status
        opponent.change_status(COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION)
        opponent.save()

        opponent_user.dismiss_confirmed = False
        opponent_user.save()

        if not smwae_check(
            opponent_user.user_id,
            get_translation_for('challenge_cancel_request_opponent_msg').format(competitor.name),
            opponent_user,
            reply_markup=self.__base_keyboard(status=opponent.status)
        ):
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'error_bot_blocked_by_opponent_challenge_canceled_msg'
            )

        bot.send_message(
            message.chat.id,
            get_translation_for('challenge_cancel_request_sent_msg'),
            reply_markup=self.__base_keyboard(status=competitor.status)
        )
        return RET.OK, None, None, None
Exemple #13
0
    def confirm_results(self, message: Message, user: User, bot: TeleBot,
                        competitor: Competitor):
        res = user.check_result()
        if not res:
            pass
            # TODO
        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            res.delete()
            return teardown_challenge(
                competitor, message, user, bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent
                else 'challenge_confirm_cannot_fin_opponents_user_msg')

        if not user.dismiss_confirmed:
            bot.send_message(
                message.chat.id,
                get_translation_for('result_confirmation_confirm_msg'))
            user.dismiss_confirmed = True
            user.save()
            return RET.OK, None, None, None
        else:
            user.dismiss_confirmed = False
            user.save()

        pa = res.player_a.fetch()
        pb = res.player_b.fetch()
        winner: Competitor
        loser: Competitor
        if res.result == RESULT.A_WINS:
            winner = pa
            loser = pb
        elif res.result == RESULT.B_WINS:
            winner = pb
            loser = pa
        else:
            logger.error('INCONSISTENT RESULT OF A RESULT')
            return RET.GO_TO_STATE, 'MenuState', None, None

        res.confirmed = True
        res.date = datetime.now(timezone('Europe/Kiev'))
        res.player_a_s = pa.name
        res.player_b_s = pb.name

        winner.wins = winner.wins + 1 if winner.wins is not None else 1
        winner.matches = winner.matches + 1 if winner.matches is not None else 1
        winner.change_status(COMPETITOR_STATUS.ACTIVE)
        winner.previous_status = None
        winner.previous_challenge_status = None
        winner.challenge_started_at = None
        winner.in_challenge_with = None
        winner.save()
        UsersSheet.update_competitor_table_record(winner)

        loser.losses = loser.losses + 1 if loser.losses is not None else 1
        loser.matches = loser.matches + 1 if loser.matches is not None else 1
        loser.change_status(loser.previous_status)
        loser.previous_status = None
        loser.previous_challenge_status = None
        loser.challenge_started_at = None
        loser.in_challenge_with = None
        loser.save()
        UsersSheet.update_competitor_table_record(loser)

        prev_level, new_level = None, None
        if winner.level > loser.level:
            prev_level = winner.level
            new_level = loser.level
            res.level_change = f'{prev_level}->{new_level}'
        res.save()

        opponent.reload()
        competitor.reload()
        if prev_level:
            if opponent == winner:
                sw = smwae_check(
                    opponent_user.user_id,
                    get_translation_for(
                        'result_confirmation_confirmed_opponent_msg') + '\n' +
                    get_translation_for('your_level_changed_str').format(
                        prev_level, new_level),
                    opponent_user,
                    reply_markup=get_menu_keyboard(status=opponent.status))
                bot.send_message(
                    message.chat.id,
                    get_translation_for('result_confirmation_confirmed_msg') +
                    '\n' +
                    get_translation_for('your_level_changed_str').format(
                        new_level, prev_level),
                )
                opponent.reload()
                opponent.level = new_level
                opponent.save()
                UsersSheet.update_competitor_table_record(opponent)
                competitor.reload()
                competitor.level = prev_level
                competitor.save()
                UsersSheet.update_competitor_table_record(competitor)
            else:
                sw = smwae_check(
                    opponent_user.user_id,
                    get_translation_for(
                        'result_confirmation_confirmed_opponent_msg') + '\n' +
                    get_translation_for('your_level_changed_str').format(
                        new_level, new_level),
                    opponent_user,
                    reply_markup=get_menu_keyboard(status=opponent.status))
                bot.send_message(
                    message.chat.id,
                    get_translation_for('result_confirmation_confirmed_msg') +
                    '\n' +
                    get_translation_for('your_level_changed_str').format(
                        prev_level, new_level),
                )
                competitor.reload()
                competitor.level = new_level
                competitor.save()
                UsersSheet.update_competitor_table_record(competitor)
                opponent.reload()
                opponent.level = prev_level
                opponent.save()
                UsersSheet.update_competitor_table_record(opponent)
        else:
            sw = smwae_check(
                opponent_user.user_id,
                get_translation_for(
                    'result_confirmation_confirmed_opponent_msg'),
                opponent_user,
                reply_markup=get_menu_keyboard(status=opponent.status))

        opponent_user.reload()
        opponent_user.current_result = None
        opponent_user.states.append('MenuState')
        if len(opponent_user.states) > STATES_HISTORY_LEN:
            del opponent_user.states[0]
        opponent_user.save()

        user.reload()
        user.current_result = None
        user.save()

        res.reload()
        ResultsSheet.upload_result(res)
        if not res.level_change:
            LogsSheet.glog(
                get_translation_for('gsheet_log_game_finished').format(
                    competitor.name, opponent.name, winner.name,
                    res.repr_score()))
        else:
            LogsSheet.glog(
                get_translation_for('gsheet_log_game_finished').format(
                    competitor.name, opponent.name, winner.name,
                    res.repr_score()) + '. ' +
                get_translation_for('group_chat_players_level_changed').format(
                    res.level_change))

        config = get_config()
        if config.group_chat_id:
            score = res.repr_score()
            gmsg = get_translation_for('group_chat_match_result_msg').format(
                winner.name, loser.name, score)
            if res.level_change:
                gmsg += '.\n'
                gmsg += get_translation_for(
                    'group_chat_players_level_changed').format(
                        res.level_change)

            try:
                bot.send_message(config.group_chat_id, gmsg, parse_mode='html')
            except:
                logger.exception(
                    'Exception occurred while sending message to group chat')

        return RET.GO_TO_STATE, 'MenuState', message, user
Exemple #14
0
    def accept_button(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
        opponent_user: User
        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg'
            )

        opponent.change_status(COMPETITOR_STATUS.CHALLENGE_STARTER)
        competitor.change_status(COMPETITOR_STATUS.CHALLENGE_RECEIVER)
        competitor.latest_challenge_received_at = None

        n = datetime.now(tz=timezone('Europe/Kiev'))
        opponent.challenge_started_at = n
        competitor.challenge_started_at = n

        opponent.challenge_remainder_sent = False
        competitor.challenge_remainder_sent = False

        competitor.challenges_dismissed_in_a_row = 0

        opponent.save()
        competitor.save()

        config = get_config()
        if not smwae_check(
            opponent_user.user_id,
            get_translation_for('challenge_confirm_challenge_accepted_opponent_msg').format(
                f'<a href="tg://user?id={user.user_id}">{competitor.name}</a>',
                config.time_to_play_challenge
            ),
            opponent_user,
            reply_markup=get_menu_keyboard(status=opponent.status),
            parse_mode='html'
        ):
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'error_bot_blocked_by_opponent_challenge_canceled_msg'
            )
        opponent_user.reload()
        opponent_user.dismiss_confirmed = False
        opponent_user.states.append('MenuState')
        if len(opponent_user.states) > STATES_HISTORY_LEN:
            del opponent_user.states[0]
        opponent_user.save()

        user.dismiss_confirmed = False
        user.save()
        bot.send_message(
            user.user_id,
            get_translation_for('challenge_confirm_challenge_accepted_competitor_msg').format(
                f'<a href="tg://user?id={opponent_user.user_id}">{opponent.name}</a>',  # TODO
                config.time_to_play_challenge
            ),
            parse_mode='html'
        )

        LogsSheet.glog(
            get_translation_for('gsheet_log_player_accepted_challenge_from_player').format(competitor.name, opponent.name)
        )

        return RET.GO_TO_STATE, 'MenuState', message, user
Exemple #15
0
    def dismiss_button(self, message: Message, user: User, bot: TeleBot, competitor: Competitor):
        defeat = False
        if not user.dismiss_confirmed:
            if competitor.previous_status == COMPETITOR_STATUS.PASSIVE:
                bot.send_message(
                    message.chat.id,
                    get_translation_for('challenge_confirm_technical_defeat')
                )
            else:
                bot.send_message(
                    message.chat.id,
                    get_translation_for('challenge_received_dismiss_confirm_msg')
                )
            user.dismiss_confirmed = True
            user.save()
            return RET.OK, None, None, None
        else:
            user.dismiss_confirmed = False
            user.save()
            if competitor.previous_status == COMPETITOR_STATUS.PASSIVE and competitor.challenges_dismissed_in_a_row >= 1:
                defeat = True

        opponent, opponent_user = get_opponent_and_opponent_user(competitor)
        if not opponent or not opponent_user:
            return teardown_challenge(
                competitor,
                message,
                user,
                bot,
                'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg'
            )

        opponent.in_challenge_with = None
        opponent.change_status(opponent.previous_status)
        opponent.previous_status = None
        opponent.save()

        if defeat:
            opponent.wins = opponent.wins + 1 if opponent.wins is not None else 1
            opponent.matches = opponent.matches + 1 if opponent.matches is not None else 1
            level_change = None
            if opponent.level > competitor.level:
                level_change = f'{opponent.level}->{competitor.level}'
                c = opponent.level
                opponent.level = competitor.level
                competitor.level = c
                ResultsSheet.upload_canceled_result(opponent, competitor, level_change, was_dismissed=True)
            UsersSheet.update_competitor_table_record(opponent)
            res = Result(
                player_a=opponent,
                player_a_s=opponent.name,
                player_b=competitor,
                player_b_s=competitor.name,
                result=RESULT.DISMISSED,
                canceled=True,
                date=datetime.now(tz=timezone('Europe/Kiev')),
                level_change=level_change
            )
            res.save()

            config = get_config()
            if config.group_chat_id:
                gmsg = get_translation_for('group_chat_technical_win_report_msg').format(opponent.name, competitor.name)
                if level_change:
                    gmsg += '.\n'
                    gmsg += get_translation_for('group_chat_players_level_changed').format(level_change)

                try:
                    bot.send_message(
                        config.group_chat_id,
                        gmsg,
                        parse_mode='html'
                    )
                except:
                    logger.exception('Exception occurred while sending message to group chat')

            result = Result(
                player_a=opponent,
                player_b=competitor,
                result=RESULT.A_WINS
            )
            result.save()

        opponent.save()

        competitor.in_challenge_with = None
        if defeat:
            competitor.change_status(COMPETITOR_STATUS.ACTIVE)
            competitor.challenges_dismissed_in_a_row = 0
            competitor.losses += competitor.losses + 1 if competitor.losses is not None else 1
            competitor.matches += competitor.matches + 1 if competitor.matches is not None else 1
            UsersSheet.update_competitor_table_record(competitor)
        else:
            competitor.change_status(COMPETITOR_STATUS.PASSIVE)
            competitor.challenges_dismissed_in_a_row = 1
        competitor.challenges_dismissed_total = competitor.challenges_dismissed_total + 1 if competitor.challenges_dismissed_total is not None else 1
        competitor.latest_challenge_received_at = None
        competitor.save()

        opponent_user.states.append('MenuState')
        if len(opponent_user.states) > STATES_HISTORY_LEN:
            del opponent_user.states[0]
        opponent_user.save()

        if defeat:
            smwae_check(
                opponent_user.user_id,
                get_translation_for('challenge_confirm_opponent_wins') + ' ' + str(opponent.level),
                opponent_user,
                reply_markup=get_menu_keyboard(status=opponent.status)
            )
            bot.send_message(
                user.user_id,
                get_translation_for('challenge_confirm_competitor_losses') + ' ' + str(competitor.level),
            )
        else:
            smwae_check(
                opponent_user.user_id,
                get_translation_for('challenge_confirmation_dismissed_opponent_msg'),
                opponent_user,
                reply_markup=get_menu_keyboard(status=opponent.status)
            )
            bot.send_message(
                user.user_id,
                get_translation_for('challenge_confirmation_dismissed_competitor_msg'),
            )

        LogsSheet.glog(
            get_translation_for('gsheet_log_player_dismissed_challenge_from_player').format(competitor.name, opponent.name)
        )

        return RET.GO_TO_STATE, 'MenuState', message, user