diff options
Diffstat (limited to 'diplomacy/daide')
-rw-r--r-- | diplomacy/daide/clauses.py | 38 | ||||
-rw-r--r-- | diplomacy/daide/connection_handler.py | 11 | ||||
-rw-r--r-- | diplomacy/daide/messages.py | 1 | ||||
-rw-r--r-- | diplomacy/daide/notification_managers.py | 8 | ||||
-rw-r--r-- | diplomacy/daide/notifications.py | 91 | ||||
-rw-r--r-- | diplomacy/daide/request_managers.py | 22 | ||||
-rw-r--r-- | diplomacy/daide/requests.py | 102 | ||||
-rw-r--r-- | diplomacy/daide/responses.py | 206 | ||||
-rw-r--r-- | diplomacy/daide/server.py | 4 | ||||
-rw-r--r-- | diplomacy/daide/tests/test_daide_game.py | 21 | ||||
-rw-r--r-- | diplomacy/daide/tokens.py | 4 | ||||
-rw-r--r-- | diplomacy/daide/utils.py | 3 |
12 files changed, 396 insertions, 115 deletions
diff --git a/diplomacy/daide/clauses.py b/diplomacy/daide/clauses.py index 9815527..bd3ab98 100644 --- a/diplomacy/daide/clauses.py +++ b/diplomacy/daide/clauses.py @@ -30,7 +30,7 @@ def break_next_group(daide_bytes): e.g. bytes for ENG AMY PAR would return -> '' + ENG AMY PAR since the byte array does not start with a "(" :return: A tuple consisting of the parenthesis group and the remaining bytes after the group - or an empty byte array and the entire byte array if the byte array does not start with a parenthesis + or an empty byte array and the entire byte array if the byte array does not start with a parenthesis """ if not daide_bytes: return b'', b'' @@ -69,6 +69,7 @@ def strip_parentheses(daide_bytes): def parse_bytes(clause_constructor, daide_bytes, on_error='raise'): """ Creates a clause object from a string of bytes + :param clause_constructor: The type of clause to build :param daide_bytes: The bytes to use to build this clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') @@ -83,6 +84,7 @@ def parse_bytes(clause_constructor, daide_bytes, on_error='raise'): def parse_string(clause_constructor, string, on_error='raise'): """ Creates a clause object from a string + :param clause_constructor: The type of clause to build :param string: The string to use to build this clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') @@ -114,6 +116,7 @@ class AbstractClause(metaclass=ABCMeta): @abstractmethod def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -123,6 +126,7 @@ class AbstractClause(metaclass=ABCMeta): @abstractmethod def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -130,6 +134,7 @@ class AbstractClause(metaclass=ABCMeta): def error(self, on_error, message=''): """ Performs the error action + :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :param message: The message to display """ @@ -141,9 +146,7 @@ class AbstractClause(metaclass=ABCMeta): self._is_valid = False class SingleToken(AbstractClause): - """ Extracts a single token - e.g. NME - """ + """ Extracts a single token (e.g. NME) """ def __init__(self): """ Constructor """ super(SingleToken, self).__init__() @@ -160,6 +163,7 @@ class SingleToken(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -178,6 +182,7 @@ class SingleToken(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build this clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -205,6 +210,7 @@ class Power(SingleToken): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -215,6 +221,7 @@ class Power(SingleToken): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build this clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -241,6 +248,7 @@ class String(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -260,6 +268,7 @@ class String(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -290,6 +299,7 @@ class Number(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -311,6 +321,7 @@ class Number(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -319,8 +330,10 @@ class Number(AbstractClause): class Province(AbstractClause): """ Each clause is an province token - Syntax: ADR - (STP ECS) + Syntax: + + - ADR + - (STP ECS) """ _alias_from_bytes = {'ECS': '/EC', 'NCS': '/NC', @@ -347,6 +360,7 @@ class Province(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -381,6 +395,7 @@ class Province(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -433,6 +448,7 @@ class Turn(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -460,6 +476,7 @@ class Turn(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -483,6 +500,7 @@ class UnitType(SingleToken): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -493,6 +511,7 @@ class UnitType(SingleToken): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build this clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -530,6 +549,7 @@ class Unit(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -559,6 +579,7 @@ class Unit(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -610,6 +631,7 @@ class OrderType(SingleToken): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -620,6 +642,7 @@ class OrderType(SingleToken): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build this clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ @@ -628,6 +651,7 @@ class OrderType(SingleToken): def parse_order_to_bytes(phase_type, order_split): """ Builds an order clause from a byte array + :param phase_type: The game phase :param order_split: An instance of diplomacy.utils.subject_split.OrderSplit :return: The order clause's bytes @@ -720,6 +744,7 @@ class Order(AbstractClause): def from_bytes(self, daide_bytes, on_error='raise'): """ Builds the clause from a byte array + :param daide_bytes: The bytes to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') :return: The remaining (unparsed) bytes @@ -796,6 +821,7 @@ class Order(AbstractClause): def from_string(self, string, on_error='raise'): """ Builds the clause from a string + :param string: The string to use to build the clause :param on_error: The action to take when an error is encountered ('raise', 'warn', 'ignore') """ diff --git a/diplomacy/daide/connection_handler.py b/diplomacy/daide/connection_handler.py index 0b606bf..ab8d6cd 100644 --- a/diplomacy/daide/connection_handler.py +++ b/diplomacy/daide/connection_handler.py @@ -29,9 +29,12 @@ from diplomacy.utils import exceptions # Constants LOGGER = logging.getLogger(__name__) -class ConnectionHandler(): - """ ConnectionHandler class. Properties: - - server: server object representing running server. +class ConnectionHandler: + """ ConnectionHandler class. + + Properties: + + - **server**: server object representing running server. """ _NAME_VARIANT_PREFIX = 'DAIDE' _NAME_VARIANTS_POOL = [] @@ -54,6 +57,7 @@ class ConnectionHandler(): def initialize(self, stream, server, game_id): """ Initialize the connection handler. + :param server: a Server object. :type server: diplomacy.Server """ @@ -152,6 +156,7 @@ class ConnectionHandler(): def translate_notification(self, notification): """ Translate a notification to a DAIDE notification. + :param notification: a notification object to pass to handler function. See diplomacy.communication.notifications for possible notifications. :return: either None or an array of daide notifications. diff --git a/diplomacy/daide/messages.py b/diplomacy/daide/messages.py index d192d6e..30a037f 100644 --- a/diplomacy/daide/messages.py +++ b/diplomacy/daide/messages.py @@ -69,6 +69,7 @@ class DaideMessage(metaclass=ABCMeta): @gen.coroutine def from_stream(stream): """ Builds a message from the stream + :param stream: An opened Tornado stream. :type stream: tornado.iostream.BaseIOStream """ diff --git a/diplomacy/daide/notification_managers.py b/diplomacy/daide/notification_managers.py index f226a27..6f0957f 100644 --- a/diplomacy/daide/notification_managers.py +++ b/diplomacy/daide/notification_managers.py @@ -28,6 +28,7 @@ from diplomacy.utils import strings, splitter def _build_active_notifications(current_phase, powers, map_name, deadline): """ Build the list of notifications corresponding to an active game state + :param current_phase: the current phase :param powers: the list of game's powers :param map_name: the map name @@ -52,6 +53,7 @@ def _build_active_notifications(current_phase, powers, map_name, deadline): def _build_completed_notifications(server_users, has_draw_vote, powers, state_history): """ Build the list of notifications corresponding to a completed game state + :param server_users: the instance of `diplomacy.server.users` of the game's server :param has_draw_vote: true if the game has completed due to a draw vote :param powers: the list of game's powers @@ -88,6 +90,7 @@ def _build_completed_notifications(server_users, has_draw_vote, powers, state_hi 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 @@ -130,6 +133,7 @@ def on_processed_notification(server, notification, connection_handler, game): 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 @@ -159,11 +163,12 @@ def on_status_update_notification(server, notification, connection_handler, game def on_message_received_notification(server, notification, connection_handler, game): """ Build the list of notificaitons for a message received 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 notificaitons + :return: list of notifications """ del server, connection_handler, game # Unused args notifs = [] @@ -173,6 +178,7 @@ def on_message_received_notification(server, notification, connection_handler, g def translate_notification(server, notification, connection_handler): """ Find notification handler function for associated notification, run it and return its result. + :param server: a Server object to pass to handler function. :param notification: a notification object to pass to handler function. See diplomacy.communication.notifications for possible notifications. diff --git a/diplomacy/daide/notifications.py b/diplomacy/daide/notifications.py index e9f6366..625c46a 100644 --- a/diplomacy/daide/notifications.py +++ b/diplomacy/daide/notifications.py @@ -22,7 +22,7 @@ from diplomacy.daide import tokens from diplomacy.daide.tokens import Token from diplomacy.daide.utils import bytes_to_str, str_to_bytes -class DaideNotification(): +class DaideNotification: """ Represents a DAIDE response. """ def __init__(self, **kwargs): """ Constructor """ @@ -48,7 +48,9 @@ class DaideNotification(): class MapNameNotification(DaideNotification): """ Represents a MAP DAIDE response. Sends the name of the current map to the client. - Syntax: + + Syntax: :: + MAP ('name') """ def __init__(self, map_name, **kwargs): @@ -60,19 +62,26 @@ class MapNameNotification(DaideNotification): + bytes(parse_string(String, map_name)) class HelloNotification(DaideNotification): - """ Represents a HLO DAIDE response. Sends the power to be played by the client with the passcode to rejoin the - game and the details of the game. - Syntax: + """ Represents a HLO DAIDE response. Sends the power to be played by the client with the + passcode to rejoin the game and the details of the game. + + Syntax: :: + HLO (power) (passcode) (variant) (variant) ... - Variant syntax: + + Variant syntax: :: + LVL n # Level of the syntax accepted MTL seconds # Movement time limit RTL seconds # Retreat time limit BTL seconds # Build time limit DSD # Disables the time limit when a client disconects AOA # Any orders accepted + LVL 10: - Variant syntax: + + Variant syntax: :: + PDA # Accept partial draws NPR # No press during retreat phases NPB # No press during build phases @@ -80,6 +89,7 @@ class HelloNotification(DaideNotification): """ def __init__(self, power_name, passcode, level, deadline, rules, **kwargs): """ Builds the response + :param power_name: The name of the power being played. :param passcode: Integer. A passcode to rejoin the game. :param level: Integer. The daide syntax level of the game @@ -109,11 +119,14 @@ class HelloNotification(DaideNotification): class SupplyCenterNotification(DaideNotification): """ Represents a SCO DAIDE notification. Sends the current supply centre ownership. - Syntax: + + Syntax: :: + SCO (power centre centre ...) (power centre centre ...) ... """ def __init__(self, powers_centers, map_name, **kwargs): """ Builds the notification + :param powers_centers: A dict of {power_name: centers} objects :param map_name: The name of the map """ @@ -150,14 +163,19 @@ class SupplyCenterNotification(DaideNotification): class CurrentPositionNotification(DaideNotification): """ Represents a NOW DAIDE notification. Sends the current turn, and the current unit positions. - Syntax: + + Syntax: :: + NOW (turn) (unit) (unit) ... - Unit syntax: + + Unit syntax: :: + power unit_type province power unit_type province MRT (province province ...) """ def __init__(self, phase_name, powers_units, powers_retreats, **kwargs): """ Builds the notification + :param phase_name: The name of the current phase (e.g. 'S1901M') :param powers: A list of `diplomacy.engine.power.Power` objects """ @@ -187,9 +205,11 @@ class CurrentPositionNotification(DaideNotification): self._bytes = bytes(tokens.NOW) + bytes(turn_clause) + b''.join(units_bytes_buffer) class MissingOrdersNotification(DaideNotification): - """ Represents a MIS DAIDE response. Sends the list of unit for which an order is missing or indication about - required disbands or builds. - Syntax: + """ Represents a MIS DAIDE response. Sends the list of unit for which an order is missing + or indication about required disbands or builds. + + Syntax: :: + MIS (unit) (unit) ... MIS (unit MRT (province province ...)) (unit MRT (province province ...)) ... MIS (number) @@ -268,10 +288,14 @@ class MissingOrdersNotification(DaideNotification): class OrderResultNotification(DaideNotification): """ Represents a ORD DAIDE response. Sends the result of an order after the turn has been processed. - Syntax: + + Syntax: :: + ORD (turn) (order) (result) ORD (turn) (order) (result RET) - Result syntax: + + Result syntax: :: + SUC # Order succeeded (can apply to any order). BNC # Move bounced (only for MTO, CTO or RTO orders). CUT # Support cut (only for SUP orders). @@ -281,6 +305,7 @@ class OrderResultNotification(DaideNotification): """ def __init__(self, phase_name, order_bytes, results, **kwargs): """ Builds the response + :param phase_name: The name of the current phase (e.g. 'S1901M') :param order_bytes: The bytes received for the order :param results: An array containing the error codes. @@ -299,7 +324,9 @@ class OrderResultNotification(DaideNotification): class TimeToDeadlineNotification(DaideNotification): """ Represents a TME DAIDE response. Sends the time to the next deadline. - Syntax: + + Syntax: :: + TME (seconds) """ def __init__(self, seconds, **kwargs): @@ -311,7 +338,9 @@ class TimeToDeadlineNotification(DaideNotification): class PowerInCivilDisorderNotification(DaideNotification): """ Represents a CCD DAIDE response. Sends the name of the power in civil disorder. - Syntax: + + Syntax: :: + CCD (power) """ def __init__(self, power_name, **kwargs): @@ -324,7 +353,9 @@ class PowerInCivilDisorderNotification(DaideNotification): class PowerIsEliminatedNotification(DaideNotification): """ Represents a OUT DAIDE response. Sends the name of the power eliminated. - Syntax: + + Syntax: :: + OUT (power) """ def __init__(self, power_name, **kwargs): @@ -337,7 +368,9 @@ class PowerIsEliminatedNotification(DaideNotification): class DrawNotification(DaideNotification): """ Represents a DRW DAIDE response. Indicates that the game has ended due to a draw - Syntax: + + Syntax: :: + DRW """ def __init__(self, **kwargs): @@ -348,7 +381,9 @@ class DrawNotification(DaideNotification): class MessageFromNotification(DaideNotification): """ Represents a FRM DAIDE response. Indicates that the game has ended due to a draw - Syntax: + + Syntax: :: + FRM (power) (power power ...) (press_message) FRM (power) (power power ...) (reply) """ @@ -367,7 +402,9 @@ class MessageFromNotification(DaideNotification): class SoloNotification(DaideNotification): """ Represents a SLO DAIDE response. Indicates that the game has ended due to a solo by the specified power - Syntax: + + Syntax: :: + SLO (power) """ def __init__(self, power_name, **kwargs): @@ -380,9 +417,13 @@ class SoloNotification(DaideNotification): class SummaryNotification(DaideNotification): """ Represents a SMR DAIDE response. Sends the summary for each power at the end of the game - Syntax: + + Syntax: :: + SMR (turn) (power_summary) ... - power_summary syntax: + + power_summary syntax: :: + power ('name') ('version') number_of_centres power ('name') ('version') number_of_centres year_of_elimination """ @@ -425,7 +466,9 @@ class SummaryNotification(DaideNotification): class TurnOffNotification(DaideNotification): """ Represents an OFF DAIDE response. Requests a client to exit - Syntax: + + Syntax: :: + OFF """ def __init__(self, **kwargs): diff --git a/diplomacy/daide/request_managers.py b/diplomacy/daide/request_managers.py index 085c5ef..8e3e5cb 100644 --- a/diplomacy/daide/request_managers.py +++ b/diplomacy/daide/request_managers.py @@ -35,6 +35,7 @@ from diplomacy.utils.order_results import OK @gen.coroutine 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 @@ -77,6 +78,7 @@ def on_name_request(server, request, connection_handler, game): 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 @@ -89,6 +91,7 @@ def on_observer_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -137,6 +140,7 @@ def on_i_am_request(server, request, connection_handler, game): 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 @@ -158,6 +162,7 @@ def on_hello_request(server, request, connection_handler, game): def on_map_request(server, request, connection_handler, game): """ Manage MAP request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -169,6 +174,7 @@ def on_map_request(server, request, connection_handler, game): def on_map_definition_request(server, request, connection_handler, game): """ Manage MDF request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -180,6 +186,7 @@ def on_map_definition_request(server, request, connection_handler, game): def on_supply_centre_ownership_request(server, request, connection_handler, game): """ Manage SCO request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -192,6 +199,7 @@ def on_supply_centre_ownership_request(server, request, connection_handler, game def on_current_position_request(server, request, connection_handler, game): """ Manage NOW request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -205,6 +213,7 @@ def on_current_position_request(server, request, connection_handler, game): 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 @@ -266,6 +275,7 @@ def on_history_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -328,6 +338,7 @@ def on_submit_orders_request(server, request, connection_handler, game): 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 @@ -342,6 +353,7 @@ def on_missing_orders_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -371,6 +383,7 @@ def on_go_flag_request(server, request, connection_handler, game): 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 @@ -383,6 +396,7 @@ def on_time_to_deadline_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -404,6 +418,7 @@ def on_draw_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -433,6 +448,7 @@ def on_send_message_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -489,6 +505,7 @@ def on_not_request(server, request, connection_handler, game): @gen.coroutine 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 @@ -532,6 +549,7 @@ def on_accept_request(server, request, connection_handler, game): def on_reject_request(server, request, connection_handler, game): """ Manage REJ request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -550,6 +568,7 @@ def on_reject_request(server, request, connection_handler, game): def on_parenthesis_error_request(server, request, connection_handler, game): """ Manage PAR request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -560,6 +579,7 @@ def on_parenthesis_error_request(server, request, connection_handler, game): def on_syntax_error_request(server, request, connection_handler, game): """ Manage ERR request + :param server: server which receives the request :param request: request to manage :param connection_handler: connection handler from which the request was sent @@ -570,6 +590,7 @@ def on_syntax_error_request(server, request, connection_handler, game): 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 @@ -608,6 +629,7 @@ MAPPING = { 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. diff --git a/diplomacy/daide/requests.py b/diplomacy/daide/requests.py index 0a47a52..b0e5a2b 100644 --- a/diplomacy/daide/requests.py +++ b/diplomacy/daide/requests.py @@ -22,11 +22,12 @@ from diplomacy.daide import tokens from diplomacy.daide.tokens import Token, is_ascii_token from diplomacy.utils import parsing, strings -class RequestBuilder(): +class RequestBuilder: """ Builds DaideRequest from bytes or tokens """ @staticmethod def from_bytes(daide_bytes, **kwargs): """ Builds a request from DAIDE bytes + :param daide_bytes: The bytes representation of a request :return: The DaideRequest built from the bytes """ @@ -82,7 +83,9 @@ class DaideRequest(_AbstractGameRequest): class NameRequest(DaideRequest): """ Represents a NME DAIDE request. Can be sent by the client as soon as it connects to the server. - Syntax: + + Syntax: :: + NME ('name') ('version') """ __slots__ = ['client_name', 'client_version'] @@ -114,7 +117,9 @@ class NameRequest(DaideRequest): class ObserverRequest(DaideRequest): """ Represents a NME DAIDE request. Can be sent by the client as soon as it connects to the server. - Syntax: + + Syntax: :: + OBS """ __slots__ = [] @@ -131,7 +136,9 @@ class ObserverRequest(DaideRequest): class IAmRequest(DaideRequest): """ Represents a IAM DAIDE request. Can be sent by the client at anytime to rejoin the game. - Syntax: + + Syntax: :: + IAM (power) (passcode) """ __slots__ = ['power_name', 'passcode'] @@ -173,7 +180,9 @@ class IAmRequest(DaideRequest): class HelloRequest(DaideRequest): """ Represents a HLO DAIDE request. Sent by the client to request a copy of the HLO message. - Syntax: + + Syntax: :: + HLO """ __slots__ = [] @@ -190,7 +199,9 @@ class HelloRequest(DaideRequest): class MapRequest(DaideRequest): """ Represents a MAP DAIDE request. Sent by the client to request a copy of the MAP message. - Syntax: + + Syntax: :: + MAP """ __slots__ = [] @@ -207,7 +218,9 @@ class MapRequest(DaideRequest): class MapDefinitionRequest(DaideRequest): """ Represents a MDF DAIDE request. Sent by the client to request the map definition of the game. - Syntax: + + Syntax: :: + MDF """ __slots__ = [] @@ -229,7 +242,9 @@ class MapDefinitionRequest(DaideRequest): class SupplyCentreOwnershipRequest(DaideRequest): """ Represents a SCO DAIDE request. Sent by the client to request a copy of the last SCO message. - Syntax: + + Syntax: :: + SCO """ __slots__ = [] @@ -246,7 +261,9 @@ class SupplyCentreOwnershipRequest(DaideRequest): class CurrentPositionRequest(DaideRequest): """ Represents a NOW DAIDE request. Sent by the client to request a copy of the last NOW message. - Syntax: + + Syntax: :: + NOW """ __slots__ = [] @@ -263,7 +280,9 @@ class CurrentPositionRequest(DaideRequest): class HistoryRequest(DaideRequest): """ Represents a HST DAIDE request. Sent by the client to request a copy of a previous ORD, SCO and NOW messages. - Syntax: + + Syntax: :: + HST (turn) """ def __init__(self, **kwargs): @@ -293,10 +312,14 @@ class HistoryRequest(DaideRequest): class SubmitOrdersRequest(DaideRequest): """ Represents a SUB DAIDE request. Sent by the client to submit orders. - Syntax: + + Syntax: :: + SUB (order) (order) ... SUB (turn) (order) (order) ... - order syntax: + + order syntax: :: + (unit) HLD # Hold (unit) MTO province # Move to (unit) SUP (unit) # Support @@ -343,7 +366,9 @@ class SubmitOrdersRequest(DaideRequest): class MissingOrdersRequest(DaideRequest): """ Represents a MIS DAIDE request. Sent by the client to request a copy of the current MIS message. - Syntax: + + Syntax: :: + MIS """ __slots__ = [] @@ -360,7 +385,9 @@ class MissingOrdersRequest(DaideRequest): class GoFlagRequest(DaideRequest): """ Represents a GOF DAIDE request. Sent by the client to notify that the client is ready to process the turn. - Syntax: + + Syntax: :: + GOF """ __slots__ = [] @@ -382,7 +409,9 @@ class GoFlagRequest(DaideRequest): class TimeToDeadlineRequest(DaideRequest): """ Represents a TME DAIDE request. Sent by the client to request a TME message or to request it at a later time. - Syntax: + + Syntax: :: + TME TME (seconds) """ @@ -421,9 +450,13 @@ class TimeToDeadlineRequest(DaideRequest): class DrawRequest(DaideRequest): """ Represents a DRW DAIDE request. Sent by the client to notify that the client would accept a draw. - Syntax: + + Syntax: :: + DRW - LVL 10: + + LVL 10: :: + DRW (power power ...) """ __slots__ = ['powers'] @@ -465,17 +498,23 @@ class DrawRequest(DaideRequest): class SendMessageRequest(DaideRequest): """ Represents a SND DAIDE request - Syntax: + + Syntax: :: + SND (power ...) (press_message) SND (power ...) (reply) SND (turn) (power ...) (press_message) SND (turn) (power ...) (reply) - Press message syntax: + + Press message syntax: :: + PRP (arrangement) CCL (press_message) FCT (arrangement) TRY (tokens) - Reply syntax: + + Reply syntax: :: + YES (press_message) REJ (press_message) BWX (press_message) @@ -531,7 +570,9 @@ class SendMessageRequest(DaideRequest): class NotRequest(DaideRequest): """ Represents a NOT DAIDE request. Sent by the client to cancel a previous request. - Syntax: + + Syntax: :: + NOT (SUB) # Cancel all submitted orders NOT (SUB (order)) # Cancel specific submitted order NOT (GOF) # Do not process orders until the deadline @@ -572,7 +613,9 @@ class NotRequest(DaideRequest): class AcceptRequest(DaideRequest): """ Represents a YES DAIDE request. - Syntax: + + Syntax: :: + YES (MAP ('name')) YES (SVE ('gamename')) """ @@ -602,7 +645,9 @@ class AcceptRequest(DaideRequest): class RejectRequest(DaideRequest): """ Represents a REJ DAIDE request. - Syntax: + + Syntax: :: + REJ (SVE ('gamename')) """ __slots__ = ['response_bytes'] @@ -635,7 +680,9 @@ class RejectRequest(DaideRequest): class ParenthesisErrorRequest(DaideRequest): """ Represents a PRN DAIDE request. Sent by the client to specify an error in the set of parenthesis. - Syntax: + + Syntax: :: + PRN (message) """ __slots__ = ['message_bytes'] @@ -668,7 +715,9 @@ class ParenthesisErrorRequest(DaideRequest): class SyntaxErrorRequest(DaideRequest): """ Represents a HUH DAIDE request. Sent by the client to specify an error in a message. - Syntax: + + Syntax: :: + HUH (message) """ __slots__ = ['message_bytes'] @@ -704,7 +753,8 @@ class AdminMessageRequest(DaideRequest): """ Represents a ADM DAIDE request. Can be sent by the client to send a message to all clients. Should not be used for negotiation. - Syntax: + Syntax: :: + ADM ('message') """ __slots__ = ['adm_message'] diff --git a/diplomacy/daide/responses.py b/diplomacy/daide/responses.py index cd7a5b4..fe77e1a 100644 --- a/diplomacy/daide/responses.py +++ b/diplomacy/daide/responses.py @@ -41,7 +41,9 @@ class DaideResponse(_AbstractResponse): class MapNameResponse(DaideResponse): """ Represents a MAP DAIDE response. Sends the name of the current map to the client. - Syntax: + + Syntax: :: + MAP ('name') """ def __init__(self, map_name, **kwargs): @@ -54,11 +56,17 @@ class MapNameResponse(DaideResponse): class MapDefinitionResponse(DaideResponse): """ Represents a MDF DAIDE response. Sends configuration of a map to a client - Syntax: + + Syntax: :: + MDF (powers) (provinces) (adjacencies) - powers syntax: + + powers syntax: :: + power power ... - power syntax: + + power syntax: :: + AUS # Austria ENG # England FRA # France @@ -66,11 +74,17 @@ class MapDefinitionResponse(DaideResponse): ITA # Italy RUS # Russia TUR # Turkey - provinces syntax: + + provinces syntax: :: + (supply_centres) (non_supply_centres) - supply_centres syntax: + + supply_centres syntax: :: + (power centre centre ...) (power centre centre ...) ... - supply_centres power syntax: + + supply_centres power syntax: :: + (power power ...) # This is currently not supported AUS # Austria ENG # England @@ -80,22 +94,33 @@ class MapDefinitionResponse(DaideResponse): RUS # Russia TUR # Turkey UNO # Unknown power - non_supply_centres syntax: + + non_supply_centres syntax: :: + province province ... # List of provinces - adjacencies syntax: + + adjacencies syntax: :: + (prov_adjacencies) (prov_adjacencies) ... - prov_adjacencies syntax: + + prov_adjacencies syntax: :: + province (unit_type adjacent_prov adjacent_prov ...) (unit_type adjacent_prov adjacent_prov ...) ... - unit_type syntax: + + unit_type syntax: :: + AMY # List of provinces an army can move to FLT # List of provinces a fleet can move to (FLT coast) # List of provinces a fleet can move to from the given coast - adjacent_prov syntax: + + adjacent_prov syntax: :: + province # A province which can be moved to (province coast) # A coast of a province that can be moved to """ def __init__(self, map_name, **kwargs): """ Builds the response + :param map_name: The name of the map """ super(MapDefinitionResponse, self).__init__(**kwargs) @@ -116,11 +141,17 @@ class MapDefinitionResponse(DaideResponse): @staticmethod def _build_powers_clause(game_map): """ Build the powers clause - Syntax: + + Syntax: :: + (powers) - powers syntax: + + powers syntax: :: + power power ... - power syntax: + + power syntax: :: + AUS # Austria ENG # England FRA # France @@ -140,13 +171,21 @@ class MapDefinitionResponse(DaideResponse): @staticmethod def _build_provinces_clause(game_map): """ Build the provinces clause - Syntax: + + Syntax: :: + (provinces) - provinces syntax: + + provinces syntax: :: + (supply_centres) (non_supply_centres) - supply_centres syntax: + + supply_centres syntax: :: + (power centre centre ...) (power centre centre ...) ... - supply_centres power syntax: + + supply_centres power syntax: :: + (power power ...) # This is currently not supported AUS # Austria ENG # England @@ -156,7 +195,9 @@ class MapDefinitionResponse(DaideResponse): RUS # Russia TUR # Turkey UNO # Unknown power - non_supply_centres syntax: + + non_supply_centres syntax: :: + province province ... # List of provinces """ unowned_scs = game_map.scs[:] @@ -215,17 +256,27 @@ class MapDefinitionResponse(DaideResponse): @staticmethod def _build_adjacencies_clause(game_map): """ Build the adjacencies clause - Syntax: + + Syntax: :: + (adjacencies) - adjacencies syntax: + + adjacencies syntax: :: + (prov_adjacencies) (prov_adjacencies) ... - prov_adjacencies syntax: + + prov_adjacencies syntax: :: + province (unit_type adjacent_prov adjacent_prov ...) (unit_type adjacent_prov adjacent_prov ...) ... - unit_type syntax: + + unit_type syntax: :: + AMY # List of provinces an army can move to FLT # List of provinces a fleet can move to (FLT coast) # List of provinces a fleet can move to from the given coast - adjacent_prov syntax: + + adjacent_prov syntax: :: + province # A province which can be moved to (province coast) # A coast of a province that can be moved to """ @@ -309,17 +360,24 @@ class MapDefinitionResponse(DaideResponse): class HelloResponse(DaideResponse): """ Represents a HLO DAIDE response. Sends the power to be played by the client with the passcode to rejoin the game and the details of the game. - Syntax: + + Syntax: :: + HLO (power) (passcode) (variant) (variant) ... - Variant syntax: + + Variant syntax: :: + LVL n # Level of the syntax accepted MTL seconds # Movement time limit RTL seconds # Retreat time limit BTL seconds # Build time limit DSD # Disables the time limit when a client disconects AOA # Any orders accepted + LVL 10: - Variant syntax: + + Variant syntax: :: + PDA # Accept partial draws NPR # No press during retreat phases NPB # No press during build phases @@ -327,6 +385,7 @@ class HelloResponse(DaideResponse): """ def __init__(self, power_name, passcode, level, deadline, rules, **kwargs): """ Builds the response + :param power_name: The name of the power being played. :param passcode: Integer. A passcode to rejoin the game. :param level: Integer. The daide syntax level of the game @@ -356,11 +415,14 @@ class HelloResponse(DaideResponse): class SupplyCenterResponse(DaideResponse): """ Represents a SCO DAIDE response. Sends the current supply centre ownership. - Syntax: + + Syntax: :: + SCO (power centre centre ...) (power centre centre ...) ... """ def __init__(self, powers_centers, map_name, **kwargs): """ Builds the response + :param powers_centers: A dict of {power_name: centers} objects :param map_name: The name of the map """ @@ -397,15 +459,20 @@ class SupplyCenterResponse(DaideResponse): class CurrentPositionResponse(DaideResponse): """ Represents a NOW DAIDE response. Sends the current turn, and the current unit positions. - Syntax: + + Syntax: :: + NOW (turn) (unit) (unit) ... - Unit syntax: + + Unit syntax: :: + power unit_type province power unit_type province MRT (province province ...) """ def __init__(self, phase_name, powers_units, powers_retreats, **kwargs): """ Builds the response + :param phase_name: The name of the current phase (e.g. 'S1901M') :param powers: A list of `diplomacy.engine.power.Power` objects """ @@ -436,9 +503,13 @@ class CurrentPositionResponse(DaideResponse): class ThanksResponse(DaideResponse): """ Represents a THX DAIDE response. Sends the result of an order after submission. - Syntax: + + Syntax: :: + THX (order) (note) - Note syntax: + + Note syntax: :: + MBV # Order is OK. FAR # Not adjacent. NSP # No such province @@ -461,6 +532,7 @@ class ThanksResponse(DaideResponse): """ def __init__(self, order_bytes, results, **kwargs): """ Builds the response + :param order_bytes: The bytes received for the order :param results: An array containing the error codes. """ @@ -476,13 +548,16 @@ class ThanksResponse(DaideResponse): class MissingOrdersResponse(DaideResponse): """ Represents a MIS DAIDE response. Sends the list of unit for which an order is missing or indication about required disbands or builds. - Syntax: + + Syntax: :: + MIS (unit) (unit) ... MIS (unit MRT (province province ...)) (unit MRT (province province ...)) ... MIS (number) """ def __init__(self, phase_name, power, **kwargs): """ Builds the response + :param phase_name: The name of the current phase (e.g. 'S1901M') :param power: The power to check for missing orders :type power: diplomacy.engine.power.Power @@ -558,10 +633,14 @@ class MissingOrdersResponse(DaideResponse): class OrderResultResponse(DaideResponse): """ Represents a ORD DAIDE response. Sends the result of an order after the turn has been processed. - Syntax: + + Syntax: :: + ORD (turn) (order) (result) ORD (turn) (order) (result RET) - Result syntax: + + Result syntax: :: + SUC # Order succeeded (can apply to any order). BNC # Move bounced (only for MTO, CTO or RTO orders). CUT # Support cut (only for SUP orders). @@ -571,6 +650,7 @@ class OrderResultResponse(DaideResponse): """ def __init__(self, phase_name, order_bytes, results, **kwargs): """ Builds the response + :param phase_name: The name of the current phase (e.g. 'S1901M') :param order_bytes: The bytes received for the order :param results: An array containing the error codes. @@ -587,11 +667,14 @@ class OrderResultResponse(DaideResponse): class TimeToDeadlineResponse(DaideResponse): """ Represents a TME DAIDE response. Sends the time to the next deadline. - Syntax: + + Syntax: :: + TME (seconds) """ def __init__(self, seconds, **kwargs): """ Builds the response + :param seconds: Integer. The number of seconds before deadline """ super(TimeToDeadlineResponse, self).__init__(**kwargs) @@ -599,7 +682,9 @@ class TimeToDeadlineResponse(DaideResponse): class AcceptResponse(DaideResponse): """ Represents a YES DAIDE request. - Syntax: + + Syntax: :: + YES (TME (seconds)) # Accepts to set the time when a TME message will be sent YES (NOT (TME)) # Accepts to cancel all requested time messages @@ -610,7 +695,9 @@ class AcceptResponse(DaideResponse): processing the orders for the turn YES (DRW) # Accepts to draw YES (NOT (DRW)) # Accepts to cancel a draw request - LVL 10: + + LVL 10: :: + YES (DRW (power power ...)) # Accepts a partial draw YES (NOT (DRW (power power ...))) # Accepts to cancel a partial draw request (? not mentinned in the DAIDE doc) @@ -619,6 +706,7 @@ class AcceptResponse(DaideResponse): """ def __init__(self, request_bytes, **kwargs): """ Builds the response + :param request_bytes: The bytes received for the request """ super(AcceptResponse, self).__init__(**kwargs) @@ -626,7 +714,9 @@ class AcceptResponse(DaideResponse): class RejectResponse(DaideResponse): """ Represents a REJ DAIDE request. - Syntax: + + Syntax: :: + REJ (NME ('name') ('version')) # Rejects a client in the game REJ (IAM (power) (passcode)) # Rejects a client to rejoin the game REJ (HLO) # Rejects to send the HLO message @@ -647,7 +737,9 @@ class RejectResponse(DaideResponse): REJ (ADM ('name') ('message') # Rejects the admin message REJ (DRW) # Rejects to draw REJ (NOT (DRW)) # Rejects to cancel a draw request - LVL 10: + + LVL 10: :: + REJ (DRW (power power ...)) # Rejects to partially draw REJ (NOT (DRW (power power ...))) # Rejects to cancel a partial draw request REJ (SND (power power ...) (press_message)) # Rejects a press message @@ -655,6 +747,7 @@ class RejectResponse(DaideResponse): """ def __init__(self, request_bytes, **kwargs): """ Builds the response + :param request_bytes: The bytes received for the request """ super(RejectResponse, self).__init__(**kwargs) @@ -662,7 +755,9 @@ class RejectResponse(DaideResponse): class NotResponse(DaideResponse): """ Represents a NOT DAIDE response. - Syntax: + + Syntax: :: + NOT (CCD (power)) """ def __init__(self, response_bytes, **kwargs): @@ -674,11 +769,14 @@ class NotResponse(DaideResponse): class PowerInCivilDisorderResponse(DaideResponse): """ Represents a CCD DAIDE response. Sends the name of the power in civil disorder. - Syntax: + + Syntax: :: + CCD (power) """ def __init__(self, power_name, **kwargs): """ Builds the response + :param power_name: The name of the power being played. """ super(PowerInCivilDisorderResponse, self).__init__(**kwargs) @@ -687,11 +785,14 @@ class PowerInCivilDisorderResponse(DaideResponse): class PowerIsEliminatedResponse(DaideResponse): """ Represents a OUT DAIDE response. Sends the name of the power eliminated. - Syntax: + + Syntax: :: + OUT (power) """ def __init__(self, power_name, **kwargs): """ Builds the response + :param power_name: The name of the power being played. """ super(PowerIsEliminatedResponse, self).__init__(**kwargs) @@ -700,11 +801,14 @@ class PowerIsEliminatedResponse(DaideResponse): class ParenthesisErrorResponse(DaideResponse): """ Represents a PRN DAIDE response. - Syntax: + + Syntax: :: + PRN (message) """ def __init__(self, request_bytes, **kwargs): """ Builds the response + :param request_bytes: The bytes received for the request """ super(ParenthesisErrorResponse, self).__init__(**kwargs) @@ -712,11 +816,14 @@ class ParenthesisErrorResponse(DaideResponse): class SyntaxErrorResponse(DaideResponse): """ Represents a HUH DAIDE response. - Syntax: + + Syntax: :: + HUH (message) """ def __init__(self, request_bytes, error_index, **kwargs): """ Builds the response + :param request_bytes: The bytes received for the request :param error_index: The index of the faulty token """ @@ -726,12 +833,13 @@ class SyntaxErrorResponse(DaideResponse): class TurnOffResponse(DaideResponse): """ Represents an OFF DAIDE response. Requests a client to exit - Syntax: + + Syntax: :: + OFF """ def __init__(self, **kwargs): - """ Builds the response - """ + """ Builds the response """ super(TurnOffResponse, self).__init__(**kwargs) self._bytes = bytes(tokens.OFF) diff --git a/diplomacy/daide/server.py b/diplomacy/daide/server.py index ceca122..70324ed 100644 --- a/diplomacy/daide/server.py +++ b/diplomacy/daide/server.py @@ -27,7 +27,8 @@ LOGGER = logging.getLogger(__name__) class Server(TCPServer): """ Represents a server to receive DAIDE communications """ def __init__(self, master_server, game_id): - """ Contructor + """ Constructor + :param master_server: the internal server :param game_id: the game id for which this server will receive communications """ @@ -55,6 +56,7 @@ class Server(TCPServer): @gen.coroutine def handle_stream(self, stream, address): """ Handle an open stream + :param stream: the stream to handle :param address: the address of the client """ diff --git a/diplomacy/daide/tests/test_daide_game.py b/diplomacy/daide/tests/test_daide_game.py index 1c7159a..3e970b2 100644 --- a/diplomacy/daide/tests/test_daide_game.py +++ b/diplomacy/daide/tests/test_daide_game.py @@ -62,10 +62,11 @@ def run_with_timeout(callable_fn, timeout): finally: signal.alarm(0) -class ClientCommsSimulator(): +class ClientCommsSimulator: """ Represents a client's comms """ def __init__(self, client_id): """ Constructor + :param client_id: the id """ self._id = client_id @@ -92,7 +93,8 @@ class ClientCommsSimulator(): """ Set the client's communications. The client's comms will be sorted to have the requests of a phase - preceeding the responses / notifications of the phase + preceding the responses / notifications of the phase + :param comms: the game's communications """ self._comms = [comm for comm in comms if comm.client_id == self._id] @@ -126,8 +128,9 @@ class ClientCommsSimulator(): def pop_next_request(self, comms): """ Pop the next request from a DAIDE communications list + :return: The next request along with the updated list of communications - or None and the updated list of communications + or None and the updated list of communications """ com = next(iter(comms), None) request = None @@ -148,8 +151,9 @@ class ClientCommsSimulator(): def pop_next_resp_notif(self, comms): """ Pop the next response or notifcation from a DAIDE communications list + :return: The next response or notifcation along with the updated list of communications - or None and the updated list of communications + or None and the updated list of communications """ com = next(iter(comms), None) resp_notif = None @@ -170,6 +174,7 @@ class ClientCommsSimulator(): @gen.coroutine def connect(self, game_port): """ Connect to the DAIDE server + :param game_port: the DAIDE game's port """ self._stream = yield TCPClient().connect('localhost', game_port) @@ -181,6 +186,7 @@ class ClientCommsSimulator(): @gen.coroutine def send_request(self, request): """ Sends a request + :param request: the request to send """ message = messages.DiplomacyMessage() @@ -190,6 +196,7 @@ class ClientCommsSimulator(): @gen.coroutine def validate_resp_notifs(self, expected_resp_notifs): """ Validate that expected response / notifications are received regardless of the order + :param expected_resp_notifs: the response / notifications to receive """ while expected_resp_notifs: @@ -211,6 +218,7 @@ class ClientCommsSimulator(): @gen.coroutine def execute_phase(self, game_id, channels): """ Execute a single communications phase + :param game_id: The game id of the current game :param channels: A dictionary of power name to its channel (BOT_KEYWORD for dummies) :return: True if there are communications left to execute in the game @@ -267,10 +275,11 @@ class ClientCommsSimulator(): return bool(self._comms) -class ClientsCommsSimulator(): +class ClientsCommsSimulator: """ Represents multi clients's communications """ def __init__(self, nb_clients, csv_file, game_id, channels): """ Constructor + :param nb_clients: the number of clients :param csv_file: the csv containing the communications in chronological order :param game_id: The game id on the server @@ -291,6 +300,7 @@ class ClientsCommsSimulator(): @gen.coroutine def retrieve_game_port(self, host, port): """ Retreive and store the game's port + :param host: the host :param port: the port :param game_id: the game id @@ -347,6 +357,7 @@ class ClientsCommsSimulator(): def run_game_data(nb_daide_clients, rules, csv_file): """ Start a server and a client to test DAIDE communications + :param port: The port of the DAIDE server :param csv_file: the csv file containing the list of DAIDE communications """ diff --git a/diplomacy/daide/tokens.py b/diplomacy/daide/tokens.py index 5009170..93500b0 100644 --- a/diplomacy/daide/tokens.py +++ b/diplomacy/daide/tokens.py @@ -27,6 +27,7 @@ class Token: def __init__(self, from_str=None, from_int=None, from_bytes=None): """ Initialize a token from its string representation, or from its bytes representation + :param from_str: The string representation of the token :param from_int: The integer representation of the token :param from_bytes: The byte representation of the token @@ -139,6 +140,7 @@ class Token: def is_ascii_token(token): """ Check if the token is an ascii token + :param token: An instance of Token :return: True if `token` is an acsii token. False otherwise """ @@ -147,6 +149,7 @@ def is_ascii_token(token): def is_integer_token(token): """ Check if the token is an integer token + :param token: An instance of Token :return: True if `token` is an integer token. False otherwise """ @@ -155,6 +158,7 @@ def is_integer_token(token): def register_token(str_repr, bytes_repr): """ Registers a token in the registry + :param str_repr: The DAIDE string representation of the token (e.g. 'ECS') :param bytes_repr: The bytes representation of the token (i.e. bytes of length 2) :return: The token that has been registered diff --git a/diplomacy/daide/utils.py b/diplomacy/daide/utils.py index e300071..8e6072f 100644 --- a/diplomacy/daide/utils.py +++ b/diplomacy/daide/utils.py @@ -22,6 +22,7 @@ ClientConnection = namedtuple('ClientConnection', ['username', 'daide_user', 'to def get_user_connection(server_users, game, connection_handler): """ Get the DAIDE user connection informations + :param server_users: The instance of `diplomacy.server.users` of the game's server :param game: The game the user has joined :param connection_handler: The connection_handler of the user @@ -38,6 +39,7 @@ def get_user_connection(server_users, game, connection_handler): def str_to_bytes(daide_str): """ Converts a str into its bytes representation + :param daide_str: A DAIDE string with tokens separated by spaces :return: The bytes representation of the string @@ -56,6 +58,7 @@ def str_to_bytes(daide_str): def bytes_to_str(daide_bytes): """ Converts a bytes into its str representation + :param daide_bytes: A DAIDE bytes with tokens separated by spaces :return: The bytes representation of the string |