aboutsummaryrefslogtreecommitdiff
path: root/diplomacy/daide/tokens.py
diff options
context:
space:
mode:
Diffstat (limited to 'diplomacy/daide/tokens.py')
-rw-r--r--diplomacy/daide/tokens.py436
1 files changed, 436 insertions, 0 deletions
diff --git a/diplomacy/daide/tokens.py b/diplomacy/daide/tokens.py
new file mode 100644
index 0000000..5009170
--- /dev/null
+++ b/diplomacy/daide/tokens.py
@@ -0,0 +1,436 @@
+# ==============================================================================
+# Copyright (C) 2019 - Philip Paquette
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+# ==============================================================================
+""" Contains the list of valid tokens and their byte representation """
+
+# Constants
+BYTES_TO_STR = {} # (0x46, 0x04) -> 'ECS'
+STR_TO_BYTES = {} # 'ECS' -> (0x46, 0x04)
+ASCII_BYTE = 0x4B # Byte identifying an ASCII char
+
+# Utilities
+class Token:
+ """ Contains the representation of a 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
+ """
+ self.repr_str = ''
+ self.repr_int = None
+ self.repr_bytes = b''
+
+ # From string
+ if from_str is not None:
+ assert from_int is None, 'Cannot provide both a string and an integer'
+ assert from_bytes is None, 'Cannot provide both a string and bytes'
+ self._load_from_str(str(from_str))
+
+ # From integer
+ elif from_int is not None:
+ assert from_bytes is None, 'Cannot provide both an integer and bytes'
+ self._load_from_int(int(from_int))
+
+ # From bytes
+ elif from_bytes is not None:
+ self._load_from_bytes(from_bytes)
+
+ else:
+ raise ValueError('You must provide a string, integer, or bytes representation')
+
+ def _load_from_str(self, from_str):
+ """ Creates a token from a DAIDE string representation"""
+ assert isinstance(from_str, str), 'Expected a string'
+
+ # 1) Known token
+ # 2) ASCII Text
+ if from_str in STR_TO_BYTES:
+ self.repr_str = BYTES_TO_STR[STR_TO_BYTES[from_str]]
+ self.repr_bytes = STR_TO_BYTES[from_str]
+ elif len(from_str) == 1 and ord(from_str[0]) <= 255:
+ self.repr_str = from_str
+ self.repr_bytes = bytes((ASCII_BYTE, ord(from_str[0])))
+ else:
+ raise ValueError('Unable to parse %s as a token' % from_str)
+
+ def _load_from_int(self, from_int):
+ """ Creates a token from an integer representation """
+ assert isinstance(from_int, int), 'Expected an integer'
+
+ # Integers - Encoded as 14 bits
+ if from_int > 8191 or from_int < -8192:
+ raise ValueError('Valid values for strings are -8192 to +8191.')
+
+ # Negative numbers start with a 1
+ prefix = '0'
+ if from_int < 0:
+ prefix = '1'
+ from_int += 8192
+
+ # Encoding the number as 14 bit. + a prefix of '00' for a total of 16 bit
+ bit_encoding = bin(from_int)[2:]
+ bit_encoding = '00' + prefix + '0' * (13 - len(bit_encoding)) + bit_encoding
+ self.repr_str = str(from_int)
+ self.repr_int = from_int
+ self.repr_bytes = bytes((int(bit_encoding[0:8], 2), int(bit_encoding[8:16], 2)))
+
+ def _load_from_bytes(self, from_bytes):
+ """ Creates a token from its bytes representation """
+ if isinstance(from_bytes, tuple):
+ from_bytes = bytes(from_bytes)
+ if len(from_bytes) != 2:
+ raise ValueError('Expected a couple of 2 bytes 0x000xFF. Got [{}]' \
+ .format(''.join([hex(b) for b in from_bytes])))
+
+ # Known token
+ if from_bytes in BYTES_TO_STR:
+ self.repr_str = BYTES_TO_STR[from_bytes]
+ self.repr_bytes = from_bytes
+
+ # Ascii text
+ elif from_bytes[0] == ASCII_BYTE:
+ self.repr_str = chr(from_bytes[1])
+ self.repr_bytes = from_bytes
+
+ # Integer
+ elif from_bytes[0] < 64:
+ bin_0, bin_1 = bin(from_bytes[0])[2:], bin(from_bytes[1])[2:]
+ from_binary = '0' * (6 - len(bin_0)) + bin_0 + '0' * (8 - len(bin_1)) + bin_1
+ is_negative = int(from_binary[0] == '1')
+ self.repr_int = is_negative * -8192 + int(from_binary[1:14], 2)
+ self.repr_str = str(self.repr_int)
+ self.repr_bytes = from_bytes
+
+ else:
+ # Unknown value
+ raise ValueError('Unable to parse bytes %s as a token' % (from_bytes,))
+
+ def __bytes__(self):
+ """ Returns bytes representation """
+ return self.repr_bytes
+
+ def __int__(self):
+ """ Returns integer representation """
+ return self.repr_int
+
+ def __str__(self):
+ """ Returns string representation """
+ return self.repr_str
+
+ def __eq__(self, other):
+ """ Define the equal """
+ return isinstance(other, Token) and ((self.repr_int and self.repr_int == other.repr_int)
+ or self.repr_str == other.repr_str)
+
+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
+ """
+ return isinstance(token, Token) and \
+ len(token.repr_bytes) == 2 and token.repr_bytes[0] == ASCII_BYTE
+
+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
+ """
+ return isinstance(token, Token) and \
+ len(token.repr_bytes) == 2 and token.repr_bytes[0] < 64
+
+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
+ """
+ if str_repr in STR_TO_BYTES:
+ raise ValueError('String %s has already been registered.' % str_repr)
+ if bytes_repr in BYTES_TO_STR:
+ raise ValueError('Bytes %s have already been registered.' % bytes_repr)
+ STR_TO_BYTES[str_repr] = bytes_repr
+ BYTES_TO_STR[bytes_repr] = str_repr
+ return Token(from_str=str_repr)
+
+
+# ------------------------
+# Registering tokens
+# Coasts
+ECS = register_token('ECS', b'\x46\x04') # ECS Coast East Coast
+NCS = register_token('NCS', b'\x46\x00') # NCS Coast North Coast
+NEC = register_token('NEC', b'\x46\x02') # NEC Coast North East Coast
+NWC = register_token('NWC', b'\x46\x0E') # NWC Coast North West Coast
+SCS = register_token('SCS', b'\x46\x08') # SCS Coast South Coast
+SEC = register_token('SEC', b'\x46\x06') # SEC Coast South East Coast
+SWC = register_token('SWC', b'\x46\x0A') # SWC Coast South West Coast
+WCS = register_token('WCS', b'\x46\x0C') # WCS Coast West Coast
+COAST_TOKENS = [ECS, NCS, NEC, NWC, SCS, SEC, SWC, WCS]
+
+# Orders
+BLD = register_token('BLD', b'\x43\x80') # BLD Order Build Phase Build
+CTO = register_token('CTO', b'\x43\x20') # CTO Order Movement Phase Move by Convoy to
+CVY = register_token('CVY', b'\x43\x21') # CVY Order Movement Phase Convoy
+DSB = register_token('DSB', b'\x43\x40') # DSB Order Retreat Phase Disband
+HLD = register_token('HLD', b'\x43\x22') # HLD Order Movement Phase Hold
+MTO = register_token('MTO', b'\x43\x23') # MTO Order Movement Phase Move To
+REM = register_token('REM', b'\x43\x81') # REM Order Build Phase Remove
+RTO = register_token('RTO', b'\x43\x41') # RTO Order Retreat Phase Retreat to
+SUP = register_token('SUP', b'\x43\x24') # SUP Order Movement Phase Support
+VIA = register_token('VIA', b'\x43\x25') # VIA Order Movement Phase Move via
+WVE = register_token('WVE', b'\x43\x82') # WVE Order Build Phase Waive
+ORDER_TOKENS = [BLD, CTO, CVY, DSB, HLD, MTO, REM, RTO, SUP, VIA, WVE]
+MOVEMENT_ORDER_TOKENS = [CTO, CVY, HLD, MTO, SUP]
+RETREAT_ORDER_TOKENS = [RTO, DSB]
+BUILD_ORDER_TOKENS = [BLD, REM, WVE]
+
+# Seasons
+AUT = register_token('AUT', b'\x47\x03') # AUT Phase Fall Retreats
+FAL = register_token('FAL', b'\x47\x02') # FAL Phase Fall Movements
+SPR = register_token('SPR', b'\x47\x00') # SPR Phase Spring Movement
+SUM = register_token('SUM', b'\x47\x01') # SUM Phase Spring Retreats
+WIN = register_token('WIN', b'\x47\x04') # WIN Phase Fall Builds
+SEASON_TOKENS = [AUT, FAL, SPR, SUM, WIN]
+
+# Powers
+AUS = register_token('AUS', b'\x41\x00') # AUS Power Austria
+ENG = register_token('ENG', b'\x41\x01') # ENG Power England
+FRA = register_token('FRA', b'\x41\x02') # FRA Power France
+GER = register_token('GER', b'\x41\x03') # GER Power Germany
+ITA = register_token('ITA', b'\x41\x04') # ITA Power Italy
+RUS = register_token('RUS', b'\x41\x05') # RUS Power Russia
+TUR = register_token('TUR', b'\x41\x06') # TUR Power Turkey
+POWER_TOKENS = [AUS, ENG, FRA, GER, ITA, RUS, TUR]
+
+# Units
+AMY = register_token('AMY', b'\x42\x00') # AMY Unit Type Army
+FLT = register_token('FLT', b'\x42\x01') # FLT Unit Type Fleet
+
+# Symbols
+OPE_PAR = register_token('(', b'\x40\x00') # BRA - ( - Opening Bracket
+CLO_PAR = register_token(')', b'\x40\x01') # KET - ) - Closing Bracket
+
+# Provinces
+ADR = register_token('ADR', b'\x52\x0E') # ADR Province Sea Adriatic Sea
+AEG = register_token('AEG', b'\x52\x0F') # AEG Province Sea Aegean Sea
+ALB = register_token('ALB', b'\x54\x21') # ALB Province Coastal Albania
+ANK = register_token('ANK', b'\x55\x30') # ANK Province Coastal Supply Center Ankara
+APU = register_token('APU', b'\x54\x22') # APU Province Coastal Apulia
+ARM = register_token('ARM', b'\x54\x23') # ARM Province Coastal Armenia
+BAL = register_token('BAL', b'\x52\x10') # BAL Province Sea Baltic Sea
+BAR = register_token('BAR', b'\x52\x11') # BAR Province Sea Barents Sea
+BEL = register_token('BEL', b'\x55\x31') # BEL Province Coastal Supply Center Belgium
+BER = register_token('BER', b'\x55\x32') # BER Province Coastal Supply Center Berlin
+BLA = register_token('BLA', b'\x52\x12') # BLA Province Sea Black Sea
+BOH = register_token('BOH', b'\x50\x00') # BOH Province Inland Bohemia
+BRE = register_token('BRE', b'\x55\x33') # BRE Province Coastal Supply Center Brest
+BUD = register_token('BUD', b'\x51\x07') # BUD Province Inland Supply Center Budapest
+BUL = register_token('BUL', b'\x57\x48') # BUL Province Bicoastal Supply Center Bulgaria
+BUR = register_token('BUR', b'\x50\x01') # BUR Province Inland Burgundy
+CLY = register_token('CLY', b'\x54\x24') # CLY Province Coastal Clyde
+CON = register_token('CON', b'\x55\x34') # CON Province Coastal Supply Center Constantinople
+DEN = register_token('DEN', b'\x55\x35') # DEN Province Coastal Supply Center Denmark
+EAS = register_token('EAS', b'\x52\x13') # EAS Province Sea Eastern Mediterranean Sea
+ECH = register_token('ECH', b'\x52\x14') # ECH Province Sea English Channel
+EDI = register_token('EDI', b'\x55\x36') # EDI Province Coastal Supply Center Edinburgh
+FIN = register_token('FIN', b'\x54\x25') # FIN Province Coastal Finland
+GAL = register_token('GAL', b'\x50\x02') # GAL Province Inland Galecia
+GAS = register_token('GAS', b'\x54\x26') # GAS Province Coastal Gascony
+GOB = register_token('GOB', b'\x52\x15') # GOB Province Sea Gulf of Bothnia
+GOL = register_token('GOL', b'\x52\x16') # GOL Province Sea Gulf of Lyons
+GRE = register_token('GRE', b'\x55\x37') # GRE Province Coastal Supply Center Greece
+HEL = register_token('HEL', b'\x52\x17') # HEL Province Sea Helgoland Bight
+HOL = register_token('HOL', b'\x55\x38') # HOL Province Coastal Supply Center Holland
+ION = register_token('ION', b'\x52\x18') # ION Province Sea Ionian Sea
+IRI = register_token('IRI', b'\x52\x19') # IRI Province Sea Irish Sea
+KIE = register_token('KIE', b'\x55\x39') # KIE Province Coastal Supply Center Kiel
+LON = register_token('LON', b'\x55\x3A') # LON Province Coastal Supply Center London
+LVN = register_token('LVN', b'\x54\x27') # LVN Province Coastal Livonia
+LVP = register_token('LVP', b'\x55\x3B') # LVP Province Coastal Supply Center Liverpool
+MAO = register_token('MAO', b'\x52\x1A') # MAO Province Sea Mid Atlantic Ocean
+MAR = register_token('MAR', b'\x55\x3C') # MAR Province Coastal Supply Center Marseilles
+MOS = register_token('MOS', b'\x51\x08') # MOS Province Inland Supply Center Moscow
+MUN = register_token('MUN', b'\x51\x09') # MUN Province Inland Supply Center Munich
+NAF = register_token('NAF', b'\x54\x28') # NAF Province Coastal North Africa
+NAO = register_token('NAO', b'\x52\x1B') # NAO Province Sea North Atlantic Ocean
+NAP = register_token('NAP', b'\x55\x3D') # NAP Province Coastal Supply Center Naples
+NTH = register_token('NTH', b'\x52\x1C') # NTH Province Sea North Sea
+NWG = register_token('NWG', b'\x52\x1D') # NWG Province Sea Norwegian Sea
+NWY = register_token('NWY', b'\x55\x3E') # NWY Province Coastal Supply Center Norway
+PAR = register_token('PAR', b'\x51\x0A') # PAR Province Inland Supply Center Paris
+PIC = register_token('PIC', b'\x54\x29') # PIC Province Coastal Picardy
+PIE = register_token('PIE', b'\x54\x2A') # PIE Province Coastal Piedmont
+POR = register_token('POR', b'\x55\x3F') # POR Province Coastal Supply Center Portugal
+PRU = register_token('PRU', b'\x54\x2B') # PRU Province Coastal Prussia
+ROM = register_token('ROM', b'\x55\x40') # ROM Province Coastal Supply Center Rome
+RUH = register_token('RUH', b'\x50\x03') # RUH Province Inland Ruhr
+RUM = register_token('RUM', b'\x55\x41') # RUM Province Coastal Supply Center Rumania
+SER = register_token('SER', b'\x51\x0B') # SER Province Inland Supply Center Serbia
+SEV = register_token('SEV', b'\x55\x42') # SEV Province Coastal Supply Center Sevastopol
+SIL = register_token('SIL', b'\x50\x04') # SIL Province Inland Silesia
+SKA = register_token('SKA', b'\x52\x1E') # SKA Province Sea Skaggerack
+SMY = register_token('SMY', b'\x55\x43') # SMY Province Coastal Supply Center Smyrna
+SPA = register_token('SPA', b'\x57\x49') # SPA Province Bicoastal Supply Center Spain
+STP = register_token('STP', b'\x57\x4A') # STP Province Bicoastal Supply Center St Petersburg
+SWE = register_token('SWE', b'\x55\x44') # SWE Province Coastal Supply Center Sweden
+SYR = register_token('SYR', b'\x54\x2C') # SYR Province Coastal Syria
+TRI = register_token('TRI', b'\x55\x45') # TRI Province Coastal Supply Center Trieste
+TUN = register_token('TUN', b'\x55\x46') # TUN Province Coastal Supply Center Tunis
+TUS = register_token('TUS', b'\x54\x2D') # TUS Province Coastal Tuscany
+TYR = register_token('TYR', b'\x50\x05') # TYR Province Inland Tyrolia
+TYS = register_token('TYS', b'\x52\x1F') # TYS Province Sea Tyrrhenian Sea
+UKR = register_token('UKR', b'\x50\x06') # UKR Province Inland Ukraine
+VEN = register_token('VEN', b'\x55\x47') # VEN Province Coastal Supply Center Venice
+VIE = register_token('VIE', b'\x51\x0C') # VIE Province Inland Supply Center Vienna
+WAL = register_token('WAL', b'\x54\x2E') # WAL Province Coastal Wales
+WAR = register_token('WAR', b'\x51\x0D') # WAR Province Inland Supply Center Warsaw
+WES = register_token('WES', b'\x52\x20') # WES Province Sea Western Mediterranean Sea
+YOR = register_token('YOR', b'\x54\x2F') # YOR Province Coastal Yorkshire
+PROVINCE_TOKENS = [ADR, AEG, ALB, ANK, APU, ARM, BAL, BAR,
+ BEL, BER, BLA, BOH, BRE, BUD, BUL, BUR,
+ CLY, CON, DEN, EAS, ECH, EDI, FIN, GAL,
+ GAS, GOB, GOL, GRE, HEL, HOL, ION, IRI,
+ KIE, LON, LVN, LVP, MAO, MAR, MOS, MUN,
+ NAF, NAO, NAP, NTH, NWG, NWY, PAR, PIC,
+ PIE, POR, PRU, ROM, RUH, RUM, SER, SEV,
+ SIL, SKA, SMY, SPA, STP, SWE, SYR, TRI,
+ TUN, TUS, TYR, TYS, UKR, VEN, VIE, WAL,
+ WAR, WES, YOR]
+
+# Commands
+ADM = register_token('ADM', b'\x48\x1D') # AMD Command / Press Client <-> Server Admin Messages
+CCD = register_token('CCD', b'\x48\x00') # CCD Command Server to Client Power in Civil Disorder
+DRW = register_token('DRW', b'\x48\x01') # DRW Command / Press Client <-> Server Draw + NOT(DRW)
+FRM = register_token('FRM', b'\x48\x02') # FRM Command / Press Server to Client Message From
+GOF = register_token('GOF', b'\x48\x03') # GOF Command Client to Server Go Flag + NOT(GOF)
+HLO = register_token('HLO', b'\x48\x04') # HLO Command Server to Client Hello (Start of Game)
+HST = register_token('HST', b'\x48\x05') # HST Command Client to Server History
+HUH = register_token('HUH', b'\x48\x06') # HUH Command / Press Server to Client Syntax Error
+IAM = register_token('IAM', b'\x48\x07') # IAM Command Client to Server I am
+LOD = register_token('LOD', b'\x48\x08') # LOD Command Server to Client Load Game
+MAP = register_token('MAP', b'\x48\x09') # MAP Cmd Server to Client Map to be used for this game
+MDF = register_token('MDF', b'\x48\x0A') # MDF Command Client <---> Server Map definition
+MIS = register_token('MIS', b'\x48\x0B') # MIS Command Server to Client Missing Orders
+NME = register_token('NME', b'\x48\x0C') # NME Command Client to Server Name
+NOT = register_token('NOT', b'\x48\x0D') # NOT Command / Press Client <---> Server Logical NOT
+NOW = register_token('NOW', b'\x48\x0E') # NOW Command Client <---> Server Current Position
+OBS = register_token('OBS', b'\x48\x0F') # OBS Command Client to Server Observer
+OFF = register_token('OFF', b'\x48\x10') # OFF Command Server to Client Turn Off (Exit)
+ORD = register_token('ORD', b'\x48\x11') # ORD Command Server to Client Order Results
+OUT = register_token('OUT', b'\x48\x12') # OUT Command Server to Client Power is Eliminated
+PRN = register_token('PRN', b'\x48\x13') # PRN Command Server to Client Parenthesis error
+REJ = register_token('REJ', b'\x48\x14') # REJ Command / Press Server to Client Reject
+SCO = register_token('SCO', b'\x48\x15') # SCO Command Client <-> Server Supply Center Ownership
+SLO = register_token('SLO', b'\x48\x16') # SLO Command Server to Client Solo
+SMR = register_token('SMR', b'\x48\x1E') # SMR Command Server to Client Summary
+SND = register_token('SND', b'\x48\x17') # SND Command / Press Client to Server Send Message
+SUB = register_token('SUB', b'\x48\x18') # SUB Command Client to Server Submit Order
+SVE = register_token('SVE', b'\x48\x19') # SVE Command Server to Client Save Game
+THX = register_token('THX', b'\x48\x1A') # THX Command Server to Client Thanks for the order
+TME = register_token('TME', b'\x48\x1B') # TME Command Client <---> Server Time to Deadline
+YES = register_token('YES', b'\x48\x1C') # YES Command / Press Server to Client Accept
+
+# Order Notes (ORD)
+BNC = register_token('BNC', b'\x45\x01') # BNC Order Note ORD Move Bounced
+CUT = register_token('CUT', b'\x45\x02') # CUT Order Note ORD Support Cut
+DSR = register_token('DSR', b'\x45\x03') # DSR Order Note ORD Convoy Disrupted
+FLD = register_token('FLD', b'\x45\x04') # FLD Order Note ORD REMOVED
+NSO = register_token('NSO', b'\x45\x05') # NSO Order Note ORD No Such Order
+RET = register_token('RET', b'\x45\x06') # RET Order Note ORD Unit must retreat
+SUC = register_token('SUC', b'\x45\x00') # SUC Order Note ORD Order Succeeds
+ORDER_RESULT_TOKENS = [BNC, CUT, DSR, NSO, SUC]
+
+# Order Notes (THX)
+BPR = register_token('BPR', b'\x44\x01') # BPR Order Note THX REMOVED
+CST = register_token('CST', b'\x44\x02') # CST Order Note THX No Coast Specified
+ESC = register_token('ESC', b'\x44\x03') # ESC Order Note THX Not an Empty Supply Center
+FAR = register_token('FAR', b'\x44\x04') # FAR Order Note THX Not Adjacent
+HSC = register_token('HSC', b'\x44\x05') # HSC Order Note THX Not a Home Supply Center
+MBV = register_token('MBV', b'\x44\x00') # MBV Order Note THX Might Be Valid
+NAS = register_token('NAS', b'\x44\x06') # NAS Order Note THX Not At Sea
+NMB = register_token('NMB', b'\x44\x07') # NMB Order Note THX No More Builds Allowed
+NMR = register_token('NMR', b'\x44\x08') # NMR Order Note THX No More Retreats Allowed
+NRN = register_token('NRN', b'\x44\x09') # NRN Order Note THX No Retreat Needed
+NRS = register_token('NRS', b'\x44\x0A') # NRS Order Note THX Not the Right Season
+NSA = register_token('NSA', b'\x44\x0B') # NSA Order Note THX No Such Army
+NSC = register_token('NSC', b'\x44\x0C') # NSC Order Note THX Not a Supply Center
+NSF = register_token('NSF', b'\x44\x0D') # NSF Order Note THX No Such Fleet
+NSP = register_token('NSP', b'\x44\x0E') # NSP Order Note THX No Such Province
+NSU = register_token('NSU', b'\x44\x10') # NSU Order Note THX No Such Unit
+NVR = register_token('NVR', b'\x44\x11') # NVR Order Note THX Not a Valid Retreat
+NYU = register_token('NYU', b'\x44\x12') # NYU Order Note THX Not Your Unit
+YSC = register_token('YSC', b'\x44\x13') # YSC Order Note THX Not Your Supply Center
+ORDER_NOTE_TOKENS = [MBV, FAR, NSP, NSU, NAS, NSF, NSA, NYU,
+ NRN, NVR, YSC, ESC, HSC, NSC, CST, NMB,
+ NMR, NRS, FLD]
+
+# Parameters
+AOA = register_token('AOA', b'\x49\x00') # AOA Parameter HLO Any Orders Allowed
+BTL = register_token('BTL', b'\x49\x01') # BTL Parameter HLO Build Time Limit
+DSD = register_token('DSD', b'\x49\x0D') # DSD Parameter HLO Deadline stops on disconnect
+ERR = register_token('ERR', b'\x49\x02') # ERR Parameter HUH Error location
+LVL = register_token('LVL', b'\x49\x03') # LVL Parameter HLO Level (Language Level)
+MRT = register_token('MRT', b'\x49\x04') # MRT Parameter NOW Must Retreat to
+MTL = register_token('MTL', b'\x49\x05') # MTL Parameter HLO Movement Time Limit
+NPB = register_token('NPB', b'\x49\x06') # NPB Parameter HLO No Press During Builds
+NPR = register_token('NPR', b'\x49\x07') # NPR Parameter HLO No Press During Retreats
+PDA = register_token('PDA', b'\x49\x08') # PDA Parameter HLO Partial Draws Allowed
+PTL = register_token('PTL', b'\x49\x09') # PTL Parameter HLO Press Time Limit
+RTL = register_token('RTL', b'\x49\x0A') # RTL Parameter HLO Retreat Time Limit
+UNO = register_token('UNO', b'\x49\x0B') # UNO Parameter SCO Unowned
+
+# Valid tokens for variant option
+VARIANT_OPT_NUM_TOKENS = [LVL, MTL, RTL, BTL, PTL]
+VARIANT_OPT_NO_NUM_TOKENS = [AOA, DSD, PDA, NPR, NPB]
+
+# Press
+ALY = register_token('ALY', b'\x4A\x00') # ALY Press Ally
+AND = register_token('AND', b'\x4A\x01') # AND Press Logical AND
+BCC = register_token('BCC', b'\x4A\x23') # BCC Press Request to Blind Carbon Copy
+BWX = register_token('BWX', b'\x4A\x02') # BWX Press None of Your Business
+CCL = register_token('CCL', b'\x4A\x26') # CCL Press Cancel
+CHO = register_token('CHO', b'\x4A\x22') # CHO Press Choose
+DMZ = register_token('DMZ', b'\x4A\x03') # DMZ Press Demilitarised Zone
+ELS = register_token('ELS', b'\x4A\x04') # ELS Press IFF Else
+EXP = register_token('EXP', b'\x4A\x05') # EXP Press Explain
+FCT = register_token('FCT', b'\x4A\x06') # FCT Press Fact
+FOR = register_token('FOR', b'\x4A\x07') # FOR Press For specified Turn
+FWD = register_token('FWD', b'\x4A\x08') # FWD Press Request to Forward
+HOW = register_token('HOW', b'\x4A\x09') # HOW Press How to attack
+IDK = register_token('IDK', b'\x4A\x0A') # IDK Press I Do Not Know
+IFF = register_token('IFF', b'\x4A\x0B') # IFF Press If
+INS = register_token('INS', b'\x4A\x0C') # INS Press Insist
+NAR = register_token('NAR', b'\x4A\x25') # NAR Press No Agreement
+OCC = register_token('OCC', b'\x4A\x0E') # OCC Press Occupy
+ORR = register_token('ORR', b'\x4A\x0F') # ORR Press Logical OR
+PCE = register_token('PCE', b'\x4A\x10') # PCE Press Peace
+POB = register_token('POB', b'\x4A\x11') # POB Press Position on Board
+PRP = register_token('PRP', b'\x4A\x13') # PRP Press Propose
+QRY = register_token('QRY', b'\x4A\x14') # QRY Press Query
+SCD = register_token('SCD', b'\x4A\x15') # SCD Press Supply Center Distribution
+SRY = register_token('SRY', b'\x4A\x16') # SRY Press Sorry
+SUG = register_token('SUG', b'\x4A\x17') # SUG Press Suggest
+THK = register_token('THK', b'\x4A\x18') # THK Press Think
+THN = register_token('THN', b'\x4A\x19') # THN Press IFF Then
+TRY = register_token('TRY', b'\x4A\x1A') # TRY Press Try the following tokens
+UNT = register_token('UNT', b'\x4A\x24') # UNT Press OCC Unit
+VSS = register_token('VSS', b'\x4A\x1C') # VSS Press ALY Versus
+WHT = register_token('WHT', b'\x4A\x1D') # WHT Press What to do with
+WHY = register_token('WHY', b'\x4A\x1E') # WHY Press Why
+XDO = register_token('XDO', b'\x4A\x1F') # XDO Press Moves to do
+XOY = register_token('XOY', b'\x4A\x20') # XOY Press X owes Y
+YDO = register_token('YDO', b'\x4A\x21') # YDO Press You provide the order for these units