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))]
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 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))]
def on_message(self, message): """ Parse given message and manage parsed data (expected a string representation of a request). """ try: json_request = json.loads(message) if not isinstance(json_request, dict): raise ValueError( "Unable to convert a JSON string to a dictionary.") except ValueError as exc: # Error occurred because either message is not a JSON string or parsed JSON object is not a dict. response = responses.Error(message='%s/%s' % (type(exc).__name__, str(exc))) else: try: request = requests.parse_dict(json_request) if request.level is not None: # Link request token to this connection handler. self.server.users.attach_connection_handler( request.token, self) response = yield request_managers.handle_request( self.server, request, self) if response is None: response = responses.Ok(request_id=request.request_id) except exceptions.ResponseException as exc: response = responses.Error( message='%s/%s' % (type(exc).__name__, exc.message), request_id=json_request.get(strings.REQUEST_ID, None)) if response: try: yield self.write_message(response.json()) except WebSocketClosedError: LOGGER.error('Websocket is closed.')
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
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_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))]
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