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_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_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
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_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_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
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_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_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