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()
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()