Exemple #1
0
def handle_reply_undo_request(message):
    msg_data = json.loads(message['msg_data'])
    match = match_driver.get_match(current_user.user_id)
    if not msg_data or not msg_data.get('approved'):
        msg_data = {'approved': False}
        match.send_message_from(current_user.user_id, MSG_TYPE_REPLYUNDOREQ,
                                msg_data)
        return msg_data
    try:
        lock, chessboard = match.lock_and_get_chessboard()
        if not chessboard:
            match.send_message_from(current_user.user_id,
                                    MSG_TYPE_REPLYUNDOREQ, msg_data)
            return msg_data
        step = chessboard.undo()
        if not step:
            match.send_message_from(current_user.user_id,
                                    MSG_TYPE_REPLYUNDOREQ, msg_data)
            return msg_data
        match.chessboard = chessboard
        step['undone_color'] = Chessman.id2color(step['chess_id']).value
        kill_chess_id = step['kill_chess_id']
        if kill_chess_id is not None:
            killed_color = Chessman.id2color(kill_chess_id)
            step['killed_color'] = killed_color.value
            step['killed_char'] = Chessman.role2char(
                Chessman.id2role(kill_chess_id), color=killed_color)
            step['killed_pic'] = Chessman.role2pic(
                Chessman.id2role(kill_chess_id), color=killed_color)
        msg_data = {'approved': True, 'step': step}
        match.send_message_from(current_user.user_id, MSG_TYPE_REPLYUNDOREQ,
                                msg_data)
        return msg_data
    finally:
        MatchDB.delete(
            'undoreq', "{}-{}".format(match.another_player_uid,
                                      match.match_id))
        lock.release()
Exemple #2
0
def leave_match(player_uid):
    blocking_timeout = min(settings.GAME_TTL // 2, 5)
    match_id = MatchDB.takeaway(_USER_2_MATCH_ID, player_uid)
    if not match_id:
        raise exceptions.InvalidMatchState(
            "Can't find the match_id for user {}.".format(player_uid))
    try:
        join_token = None
        match = Match.from_dict(MatchDB.get(_ALL_MATCHES, match_id))
        if not match:
            raise exceptions.InvalidMatchState(
                "Can't find the match {} to leave.".format(match_id))
        join_token = match.join_token
        if join_token:
            match_room_door, can_use_door = MatchDB.lock(
                'match_room_door',
                join_token,
                blocking_timeout=blocking_timeout)
            if not can_use_door:
                raise exceptions.CannotAcquireMatchDoor(
                    'the door {} is too crowded.'.format(join_token))

        match.remove_player(player_uid)
        MatchDB.delete(_USER_2_MATCH_ID, player_uid)
        if match.active_players_cnt == 1:
            match.send_message_from(player_uid, msg_meta.MSG_TYPE_CONTROL,
                                    msg_meta.MSG_CONST_LEFT)
            MatchDB.set(_ALL_MATCHES, match.match_id, match.to_dict())
            return
        # the last one leaving the match should clean up the mess
        match = Match.from_dict(MatchDB.takeaway(_ALL_MATCHES, match_id))
        if match.join_token:
            MatchDB.delete(_PRIVATE_PENDING_MATCH_IDS, match.join_token)
        else:
            MatchDB.force_remove_from_queue(_PUBLIC_PENDING_MATCH_IDS, None,
                                            match_id)
        MatchDB.delete(_CHESSBOARD, match.chessboard_id)
    finally:
        if join_token:
            match_room_door.release()