Example #1
0
def on_send_message_request(server, request, connection_handler, game):
    """ Manage SND request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, _, token, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    message = ' '.join([
        str(
            tokens.Token(from_bytes=(request.message_bytes[i],
                                     request.message_bytes[i + 1])))
        for i in range(0, len(request.message_bytes), 2)
    ])

    for recipient_power_name in request.powers:
        game_message = Message(sender=power_name,
                               recipient=recipient_power_name,
                               phase=game.get_current_phase(),
                               message=message)
        send_game_message_request = internal_requests.SendGameMessage(
            power_name=power_name,
            message=game_message,
            game_role=power_name,
            phase=game.get_current_phase(),
            game_id=game.game_id,
            token=token)
        yield internal_request_managers.handle_request(
            server, send_game_message_request, connection_handler)

    return [responses.YES(bytes(request))]
Example #2
0
def on_go_flag_request(server, request, connection_handler, game):
    """ Manage GOF request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, _, token, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    set_wait_flag_request = internal_requests.SetWaitFlag(
        power_name=power_name,
        wait=False,
        game_id=request.game_id,
        game_role=power_name,
        phase=game.get_current_phase(),
        token=token)
    yield internal_request_managers.handle_request(server,
                                                   set_wait_flag_request,
                                                   connection_handler)

    if not game.get_power(power_name).order_is_set:
        set_orders_request = internal_requests.SetOrders(
            power_name=power_name,
            orders=[],
            game_id=request.game_id,
            game_role=power_name,
            phase=game.get_current_phase(),
            token=token)
        yield internal_request_managers.handle_request(server,
                                                       set_orders_request,
                                                       connection_handler)

    return [responses.YES(bytes(request))]
Example #3
0
def on_status_update_notification(server, notification, connection_handler, game):
    """ Build the list of notificaitons for a status update event

        :param server: server which receives the request
        :param notification: internal notification
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: list of notifications
    """
    _, daide_user, _, power_name = utils.get_user_connection(server.users, game, connection_handler)
    powers = [game.powers[power_name] for power_name in sorted(game.powers)]
    notifs = []

    # HLO notification
    if notification.status == strings.ACTIVE and game.get_current_phase() == 'S1901M':
        passcode = daide_user.passcode
        level = DEFAULT_LEVEL
        deadline = game.deadline
        rules = game.rules
        notifs.append(notifications.HLO(power_name, passcode, level, deadline, rules))
        notifs += _build_active_notifications(game.get_current_phase(), powers, game.map_name, game.deadline)

    elif notification.status == strings.COMPLETED:
        notifs += _build_completed_notifications(server.users, game.has_draw_vote(), powers, game.state_history)

    elif notification.status == strings.CANCELED:
        notifs.append(notifications.OFF())

    return notifs
Example #4
0
def on_accept_request(server, request, connection_handler, game):
    """ Manage YES request

        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, daide_user, token, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    response = None
    accept_response = request.response_bytes
    lead_token, _ = parse_bytes(clauses.SingleToken, accept_response)

    if bytes(lead_token) == bytes(tokens.MAP):

        # Assigning a power to the user
        if not power_name:
            uncontrolled_powers = [
                pow_name for pow_name, power in game.powers.items()
                if not power.is_eliminated() and not power.is_controlled()
            ]
            if not uncontrolled_powers:
                return [responses.OFF()]

            # 1 - Trying to respect the choice specified by the DAIDE user
            # i.e. if the Daide client is 'FRA:Dumbbot', it wants to be assigned to a power starting with 'FRA'
            if ':' in daide_user.client_name:
                prefix = daide_user.client_name.split(':')[0].upper()
                selected_powers = [
                    pow_name for pow_name in uncontrolled_powers
                    if pow_name.upper().startswith(prefix)
                ]
                if selected_powers:
                    power_name = selected_powers[0]

            # 2 - Otherwise, assigning to the first uncontrolled power
            if not power_name:
                power_name = sorted(uncontrolled_powers)[0]

            join_game_request = internal_requests.JoinGame(
                game_id=game.game_id,
                power_name=power_name,
                registration_password=None,
                token=token)
            yield internal_request_managers.handle_request(
                server, join_game_request, connection_handler)

    return [response] if response else None
Example #5
0
def on_missing_orders_request(server, request, connection_handler, game):
    """ Manage MIS request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, _, _, power_name = utils.get_user_connection(server.users, game,
                                                    connection_handler)
    if not power_name:
        return [responses.REJ(bytes(request))]
    return [
        responses.MIS(game.get_current_phase(), game.get_power(power_name))
    ]
Example #6
0
def on_processed_notification(server, notification, connection_handler, game):
    """ Build the list of notifications for a game processed event

        :param server: server which receives the request
        :param notification: internal notification
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: list of notifications
    """
    _, _, _, power_name = utils.get_user_connection(server.users, game, connection_handler)
    previous_phase_data = notification.previous_phase_data
    previous_state = previous_phase_data.state
    previous_phase = splitter.PhaseSplitter(previous_state['name'])
    powers = [game.powers[power_name] for power_name in sorted(game.powers)]

    notifs = []

    # ORD notifications
    for order in previous_phase_data.orders[power_name]:
        order = splitter.OrderSplitter(order)

        # WAIVE
        if len(order) == 1:
            order.order_type = ' '.join([power_name, order.order_type])
            results = [OK]
        else:
            results = previous_phase_data.results[order.unit]
            order.unit = ' '.join([power_name, order.unit])

        if order.supported_unit:
            order.supported_unit = ' '.join([power_name, order.supported_unit])

        order_bytes = parse_order_to_bytes(previous_phase.phase_type, order)
        notifs.append(notifications.ORD(previous_phase.input_str, order_bytes, [result.code for result in results]))

    if game.status == strings.ACTIVE:
        notifs += _build_active_notifications(game.get_current_phase(), powers, game.map_name, game.deadline)

    elif game.status == strings.COMPLETED:
        notifs += _build_completed_notifications(server.users, game.has_draw_vote(), powers, game.state_history)

    return notifs
Example #7
0
def on_draw_request(server, request, connection_handler, game):
    """ Manage DRW request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, _, token, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    vote_request = internal_requests.Vote(power_name=power_name,
                                          vote=strings.YES,
                                          game_role=power_name,
                                          phase=game.get_current_phase(),
                                          game_id=game.game_id,
                                          token=token)
    yield internal_request_managers.handle_request(server, vote_request,
                                                   connection_handler)

    return [responses.YES(bytes(request))]
Example #8
0
def on_hello_request(server, request, connection_handler, game):
    """ Manage HLO request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, daide_user, _, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    # User not in game
    if not daide_user or not power_name:
        return [responses.REJ(bytes(request))]

    passcode = daide_user.passcode
    level = DEFAULT_LEVEL
    deadline = game.deadline
    rules = game.rules

    return [responses.HLO(power_name, passcode, level, deadline, rules)]
Example #9
0
def on_not_request(server, request, connection_handler, game):
    """ Manage NOT request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, _, token, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    response = None
    not_request = request.request

    # Cancelling orders
    if isinstance(not_request, requests.SUB):
        if not_request.orders:  # cancel one order
            pass
        else:
            clear_orders_request = internal_requests.ClearOrders(
                power_name=power_name,
                game_id=game.game_id,
                game_role=power_name,
                phase=game.get_current_phase(),
                token=token)
            yield internal_request_managers.handle_request(
                server, clear_orders_request, connection_handler)
            response = responses.YES(bytes(request))

    # Cancel wait flag
    elif isinstance(not_request, requests.GOF):
        set_wait_flag_request = internal_requests.SetWaitFlag(
            power_name=power_name,
            wait=True,
            game_id=game.game_id,
            game_role=power_name,
            phase=game.get_current_phase(),
            token=token)
        yield internal_request_managers.handle_request(server,
                                                       set_wait_flag_request,
                                                       connection_handler)
        response = responses.YES(bytes(request))

    # Cancel get deadline request
    elif isinstance(not_request, requests.TME):
        response = responses.REJ(bytes(request))

    # Cancel vote
    elif isinstance(not_request, requests.DRW):
        vote_request = internal_requests.Vote(power_name=power_name,
                                              vote=strings.NEUTRAL,
                                              game_role=power_name,
                                              phase=game.get_current_phase(),
                                              game_id=game.game_id,
                                              token=token)
        yield internal_request_managers.handle_request(server, vote_request,
                                                       connection_handler)
        response = responses.YES(bytes(request))

    # Returning response
    return [response if response else responses.REJ(bytes(request))]
Example #10
0
def on_submit_orders_request(server, request, connection_handler, game):
    """ Manage SUB request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    _, _, token, power_name = utils.get_user_connection(
        server.users, game, connection_handler)

    if request.phase and not request.phase == game.get_current_phase():
        return [responses.REJ(bytes(request))]

    request.token = token
    request.phase = game.get_current_phase()

    power = game.get_power(power_name)
    initial_power_adjusts = power.adjust[:]
    initial_power_orders = []
    initial_game_errors = game.error[:]

    order_responses = []

    # Parsing lead token and turn
    _, request_bytes = parse_bytes(clauses.SingleToken, bytes(request))
    _, request_bytes = parse_bytes(clauses.Turn,
                                   request_bytes,
                                   on_error='ignore')

    # Validate each order individually
    while request_bytes:
        daide_order, request_bytes = parse_bytes(clauses.Order, request_bytes)
        order = str(daide_order)

        set_orders_request = internal_requests.SetOrders(
            power_name=request.power_name,
            orders=[order],
            game_id=request.game_id,
            game_role=request.power_name,
            phase=request.phase,
            token=request.token)
        yield internal_request_managers.handle_request(server,
                                                       set_orders_request,
                                                       connection_handler)

        new_power_adjusts = [
            adjust for adjust in power.adjust
            if adjust not in initial_power_adjusts
        ]
        new_power_orders = {
            id: val
            for id, val in power.orders.items()
            if id not in initial_power_orders
        }
        new_game_errors = [
            error.code for error in game.error
            if error not in initial_game_errors
        ]

        if not new_power_adjusts and not new_power_orders and not new_game_errors:
            new_game_errors.append((err.GAME_ORDER_NOT_ALLOWED % order).code)

        order_responses.append(
            responses.THX(bytes(daide_order), new_game_errors))

    # Setting orders
    set_orders_request = internal_requests.SetOrders(
        power_name=request.power_name,
        orders=request.orders,
        game_id=request.game_id,
        game_role=request.power_name,
        phase=request.phase,
        token=request.token)
    yield internal_request_managers.handle_request(server, set_orders_request,
                                                   connection_handler)

    # Returning results and missing orders
    order_responses.append(responses.MIS(game.get_current_phase(), power))
    return order_responses
Example #11
0
def on_history_request(server, request, connection_handler, game):
    """ Manage HST request
        :param server: server which receives the request
        :param request: request to manage
        :param connection_handler: connection handler from which the request was sent
        :param game: the game
        :return: the list of responses
    """
    history_responses = []

    _, _, _, power_name = utils.get_user_connection(server.users, game,
                                                    connection_handler)
    phase, current_phase = request.phase, game.get_current_phase()
    phase_order = game.order_history.get(phase, None)
    phase_result = game.result_history.get(phase, None)

    if phase_result is None:
        return [responses.REJ(bytes(request))]

    next_phase = game.map.phase_abbr(
        game.map.find_next_phase(game.map.phase_long(phase)))
    next_phase_state = game.state_history.get(next_phase, None)

    while next_phase_state is None and next_phase != current_phase:
        next_phase = game.map.phase_abbr(
            game.map.find_next_phase(game.map.phase_long(next_phase)))
        next_phase_state = game.state_history.get(next_phase, None)

    if next_phase == current_phase:
        next_phase_state = game.get_state()

    phase = splitter.PhaseSplitter(phase)
    next_phase = splitter.PhaseSplitter(next_phase)

    # ORD responses
    for order in phase_order[power_name]:
        order = splitter.OrderSplitter(order)

        # WAIVE
        if len(order) == 1:
            order.order_type = ' '.join([power_name, order.order_type])
            results = [OK]
        else:
            results = phase_result[order.unit]
            order.unit = ' '.join([power_name, order.unit])

        if order.supported_unit:
            order.supported_unit = ' '.join([power_name, order.supported_unit])

        order_bytes = parse_order_to_bytes(phase.phase_type, order)
        history_responses.append(
            notifications.ORD(phase.input_str, order_bytes,
                              [result.code for result in results]))

    # SCO response
    history_responses.append(
        responses.SCO(next_phase_state['centers'], game.map.name))

    # NOW response
    units = {
        power_name: [unit for unit in units if not unit.startswith('*')]
        for power_name, units in next_phase_state['units'].items()
    }
    retreats = next_phase_state['retreats'].copy()
    history_responses.append(
        responses.NOW(next_phase.input_str, units, retreats))

    return history_responses