def on_i_am_request(server, request, connection_handler, game): """ Manage IAM 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, passcode = request.power_name, request.passcode # find user username = None for user in server.users.values(): if not isinstance(user, DaideUser): continue is_passcode_valid = bool(user.passcode == passcode) if is_passcode_valid and game.is_controlled_by(power_name, user.username): username = user.username break if username is None: return [responses.REJ(bytes(request))] try: server.assert_token(connection_handler.token, connection_handler) except exceptions.TokenException: connection_handler.token = None if not connection_handler.token: sign_in_request = internal_requests.SignIn(username=username, password='******', create_user=False) try: token_response = yield internal_request_managers.handle_request( server, sign_in_request, connection_handler) connection_handler.token = token_response.data except exceptions.UserException: return [responses.REJ(bytes(request))] join_game_request = internal_requests.JoinGame( game_id=game.game_id, power_name=power_name, registration_password=None, token=connection_handler.token) yield internal_request_managers.handle_request(server, join_game_request, connection_handler) return [responses.YES(bytes(request))]
def test_rej(): """ Tests the REJ response """ daide_str = 'REJ ( TME ( #60 ) )' request_daide_str = 'TME ( #60 )' response = responses.REJ(request_bytes=str_to_bytes(request_daide_str)) assert isinstance(response, responses.REJ), 'Expected a REJ response' assert bytes(response) == str_to_bytes(daide_str)
def handle_request(server, request, connection_handler): """ (coroutine) Find request handler function for associated request, run it and return its result. :param server: a Server object to pass to handler function. :param request: a request object to pass to handler function. See diplomacy.communication.requests for possible requests. :param connection_handler: a ConnectionHandler object to pass to handler function. :return: (future) either None or a response object. See module diplomacy.communication.responses for possible responses. """ request_handler_fn = MAPPING.get(type(request), None) if not request_handler_fn: raise exceptions.RequestException() game = server.get_game(request.game_id) # Game not found if not game or game.is_game_completed or game.is_game_canceled: future = Future() future.set_result([responses.REJ(bytes(request))]) return future if gen.is_coroutine_function(request_handler_fn): # Throw the future returned by this coroutine. return request_handler_fn(server, request, connection_handler, game) # Create and return a future. future = Future() try: result = request_handler_fn(server, request, connection_handler, game) future.set_result(result) except exceptions.DiplomacyException as exc: future.set_exception(exc) return future
def on_name_request(server, request, connection_handler, game): """ Manage NME 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 """ username = connection_handler.get_name_variant() + request.client_name try: server.assert_token(connection_handler.token, connection_handler) except exceptions.TokenException: connection_handler.token = None if not connection_handler.token: user_exists = server.users.has_username(username) sign_in_request = internal_requests.SignIn(username=username, password='******', create_user=not user_exists) try: token_response = yield internal_request_managers.handle_request( server, sign_in_request, connection_handler) connection_handler.token = token_response.data if not isinstance(server.users.get_user(username), DaideUser): daide_user = DaideUser( passcode=random.randint(1, 8191), client_name=request.client_name, client_version=request.client_version, **server.users.get_user(username).to_dict()) server.users.replace_user(username, daide_user) server.save_data() except exceptions.UserException: return [responses.REJ(bytes(request))] # find next available power power_name = [ power_name for power_name, power in game.powers.items() if not power.is_controlled() ] if not power_name: return [responses.REJ(bytes(request))] return [responses.YES(bytes(request)), responses.MAP(game.map.name)]
def on_observer_request(server, request, connection_handler, game): """ Manage OBS 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 """ del server, connection_handler, game # Unused args return [responses.REJ(bytes(request))] # No DAIDE observeres allowed
def on_time_to_deadline_request(server, request, connection_handler, game): """ Manage TME 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 """ del server, connection_handler, game # Unused args return [responses.REJ(bytes(request))]
def on_admin_message_request(server, request, connection_handler, game): """ Manage ADM 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 """ del server, connection_handler, game # Unused args if not ADM_MESSAGE_ENABLED: return [responses.REJ(bytes(request))] return None
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)) ]
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)]
def _on_diplomacy_message(self, in_message): """ Handle a diplomacy message """ messages = [] request = RequestBuilder.from_bytes(in_message.content) try: LOGGER.info('[%d] request:[%s]', self._socket_no, bytes_to_str(in_message.content)) request.game_id = self.game_id message_responses = yield request_managers.handle_request( self.server, request, self) except exceptions.ResponseException: message_responses = [responses.REJ(bytes(request))] if message_responses: for response in message_responses: response_bytes = bytes(response) LOGGER.info('[%d] response:[%s]', self._socket_no, bytes_to_str(response_bytes) \ if response_bytes else None) message = DiplomacyMessage() message.content = response_bytes messages.append(message) return messages
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))]
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
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