mirror of
https://github.com/GoodStartLabs/AI_Diplomacy.git
synced 2026-04-30 17:40:47 +00:00
394 lines
21 KiB
TypeScript
394 lines
21 KiB
TypeScript
// diplomacy/daide/requests.ts
|
|
|
|
import {
|
|
AbstractClauseTs, StringTs, NumberTs, PowerTs, OrderTs, TurnTs, SingleTokenTs,
|
|
strip_parentheses_ts, break_next_group_ts, parse_bytes_ts
|
|
} from './clauses';
|
|
import * as daideTokens from './tokens'; // Import all tokens
|
|
import { Token } from './tokens';
|
|
|
|
// Logger
|
|
const logger = {
|
|
debug: (message: string) => console.debug(message),
|
|
info: (message: string) => console.info(message),
|
|
warn: (message: string) => console.warn(message),
|
|
error: (message: string, error?: any) => console.error(message, error),
|
|
};
|
|
|
|
// Base DaideRequest class
|
|
// This replaces the Python DaideRequest which inherited from _AbstractGameRequest.
|
|
// For DAIDE server-side parsing, we might not need all fields from _AbstractGameRequest
|
|
// immediately, or they are added by the ConnectionHandler/MasterServer context.
|
|
export abstract class DaideRequest {
|
|
protected _bytes: Uint8Array = new Uint8Array(0);
|
|
protected _str: string = ''; // Full string representation of the DAIDE command
|
|
|
|
// Context fields that might be populated by ConnectionHandler or further up
|
|
public game_id?: string;
|
|
public token?: string; // Client's channel token
|
|
public game_role?: string; // Role in the game (e.g. power name, OBS)
|
|
public phase?: string; // Current game phase
|
|
|
|
constructor() {}
|
|
|
|
// This method is called by RequestBuilderTs.fromBytes AFTER the specific request object is instantiated.
|
|
// It receives the full original DAIDE byte sequence for the command.
|
|
public abstract parseBytes(daideBytes: Uint8Array): void;
|
|
|
|
public toBytes(): Uint8Array {
|
|
return this._bytes;
|
|
}
|
|
|
|
public toString(): string {
|
|
return this._str;
|
|
}
|
|
|
|
// Helper to build the basic string representation from any DAIDE byte sequence
|
|
protected buildBaseStringRepresentation(daideBytes: Uint8Array): void {
|
|
let tempStr = '';
|
|
for (let i = 0; i < daideBytes.length; i += 2) {
|
|
const tokenBytes = daideBytes.slice(i, i + 2);
|
|
if (tokenBytes.length < 2) break; // Should not happen if length is even
|
|
const token = new Token({ from_bytes: tokenBytes });
|
|
const new_str = token.toString();
|
|
const pad = (tempStr === '' || tempStr.endsWith('(') || new_str === ')' || (daideTokens.isAsciiToken(token) && new_str !== '(')) ? '' : ' ';
|
|
tempStr = tempStr + pad + new_str;
|
|
}
|
|
this._str = tempStr;
|
|
}
|
|
}
|
|
|
|
// Specific DAIDE Request Classes
|
|
|
|
export class NameRequestTs extends DaideRequest {
|
|
__type__ = "NameRequest"; // For potential type guarding or mapping
|
|
client_name: string = '';
|
|
client_version: string = '';
|
|
|
|
constructor() { super(); }
|
|
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; // Store raw bytes
|
|
this.buildBaseStringRepresentation(daideBytes); // Build basic string like "NME (client_name_str) (client_version_str)"
|
|
|
|
let remainingBytes = daideBytes;
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'NME') throw new Error('Expected NME request');
|
|
remainingBytes = r0;
|
|
|
|
const [client_name_obj, r1] = parse_bytes_ts(StringTs, remainingBytes);
|
|
if (!client_name_obj?.isValid) throw new Error('Invalid client name string in NME request');
|
|
this.client_name = client_name_obj.toString();
|
|
remainingBytes = r1;
|
|
|
|
const [client_version_obj, r2] = parse_bytes_ts(StringTs, remainingBytes);
|
|
if (!client_version_obj?.isValid) throw new Error('Invalid client version string in NME request');
|
|
this.client_version = client_version_obj.toString();
|
|
remainingBytes = r2;
|
|
|
|
if (remainingBytes.length > 0) throw new Error(`NME request malformed, ${remainingBytes.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
export class ObserverRequestTs extends DaideRequest {
|
|
__type__ = "ObserverRequest";
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, daideBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'OBS') throw new Error('Expected OBS request');
|
|
if (r0.length > 0) throw new Error(`OBS request malformed, ${r0.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
export class IAmRequestTs extends DaideRequest {
|
|
__type__ = "IAmRequest";
|
|
power_name: string = ''; // Long name, e.g. "AUSTRIA"
|
|
passcode: string = ''; // Parsed as string token in Python example
|
|
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
let remainingBytes = daideBytes;
|
|
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'IAM') throw new Error('Expected IAM request');
|
|
remainingBytes = r0;
|
|
|
|
const [power_group_bytes, r1] = break_next_group_ts(remainingBytes);
|
|
if (!power_group_bytes) throw new Error("IAM: Missing power group");
|
|
let inner_power_group = strip_parentheses_ts(power_group_bytes);
|
|
const [power_obj, r_pg] = parse_bytes_ts(PowerTs, inner_power_group);
|
|
if (!power_obj?.isValid) throw new Error("IAM: Invalid power in power group");
|
|
if (r_pg.length > 0) throw new Error("IAM: Extra bytes in power group");
|
|
this.power_name = power_obj.toString(); // PowerTs.toString() gives long name
|
|
remainingBytes = r1;
|
|
|
|
const [passcode_group_bytes, r2] = break_next_group_ts(remainingBytes);
|
|
if (!passcode_group_bytes) throw new Error("IAM: Missing passcode group");
|
|
let inner_passcode_group = strip_parentheses_ts(passcode_group_bytes);
|
|
// Python parses passcode as SingleToken, implying it could be non-numeric string.
|
|
const [passcode_obj, r_pcg] = parse_bytes_ts(StringTs, add_parentheses_ts(inner_passcode_group)); // StringTs expects parentheses
|
|
if (!passcode_obj?.isValid) throw new Error("IAM: Invalid passcode string");
|
|
// Python code: passcode, passcode_group_bytes = parse_bytes(SingleToken, passcode_group_bytes)
|
|
// This means passcode is a single token, not a StringTs. Let's adjust.
|
|
// Re-parsing passcode as a sequence of single tokens if it's not a simple string.
|
|
// For simplicity, if passcode is simple string/number, StringTs or NumberTs might be better.
|
|
// Python's `str(passcode)` suggests it resolves to a string.
|
|
// Let's assume passcode is a string of characters, each a token.
|
|
this.passcode = "";
|
|
let current_passcode_bytes = inner_passcode_group;
|
|
while(current_passcode_bytes.length > 0) {
|
|
const [char_token_obj, next_passcode_bytes] = parse_bytes_ts(SingleTokenTs, current_passcode_bytes);
|
|
if (!char_token_obj?.isValid) throw new Error("IAM: Invalid token in passcode");
|
|
this.passcode += char_token_obj.toString();
|
|
current_passcode_bytes = next_passcode_bytes;
|
|
}
|
|
remainingBytes = r2;
|
|
|
|
if (remainingBytes.length > 0) throw new Error(`IAM request malformed, ${remainingBytes.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
// ... Other request classes will follow similar pattern ...
|
|
// HelloRequest, MapRequest, MapDefinitionRequest, SupplyCentreOwnershipRequest, CurrentPositionRequest, HistoryRequest
|
|
// SubmitOrdersRequest, MissingOrdersRequest, GoFlagRequest, TimeToDeadlineRequest, DrawRequest, SendMessageRequest
|
|
// NotRequest, AcceptRequest, RejectRequest, ParenthesisErrorRequest, SyntaxErrorRequest, AdminMessageRequest
|
|
|
|
// Stubs for remaining classes for now
|
|
export class HelloRequestTs extends DaideRequest { __type__ = "HelloRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class MapRequestTs extends DaideRequest { __type__ = "MapRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class MapDefinitionRequestTs extends DaideRequest { __type__ = "MapDefinitionRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class SupplyCentreOwnershipRequestTs extends DaideRequest { __type__ = "SupplyCentreOwnershipRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class CurrentPositionRequestTs extends DaideRequest { __type__ = "CurrentPositionRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
|
|
export class HistoryRequestTs extends DaideRequest {
|
|
__type__ = "HistoryRequest";
|
|
phase: string = ''; // Parsed from Turn clause
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
let remainingBytes = daideBytes;
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'HST') throw new Error('Expected HST request');
|
|
remainingBytes = r0;
|
|
const [turn_obj, r1] = parse_bytes_ts(TurnTs, remainingBytes);
|
|
if (!turn_obj?.isValid) throw new Error("HST: Invalid Turn clause");
|
|
this.phase = turn_obj.toString();
|
|
remainingBytes = r1;
|
|
if (remainingBytes.length > 0) throw new Error(`HST request malformed, ${remainingBytes.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
export class SubmitOrdersRequestTs extends DaideRequest {
|
|
__type__ = "SubmitOrdersRequest";
|
|
power_name: string | null = null; // Long name
|
|
parsedPhase: string = ''; // Parsed from optional Turn clause
|
|
orders: string[] = []; // Array of string orders
|
|
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
let remainingBytes = daideBytes;
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'SUB') throw new Error('Expected SUB request');
|
|
remainingBytes = r0;
|
|
|
|
const [turn_obj, r_turn] = parse_bytes_ts(TurnTs, remainingBytes, 'ignore'); // Optional Turn
|
|
if (turn_obj?.isValid) {
|
|
this.parsedPhase = turn_obj.toString();
|
|
remainingBytes = r_turn;
|
|
}
|
|
|
|
const parsedOrders: OrderTs[] = [];
|
|
while(remainingBytes.length > 0) {
|
|
const [order_obj, r_order] = parse_bytes_ts(OrderTs, remainingBytes);
|
|
if (!order_obj?.isValid) throw new Error("SUB: Invalid Order clause in submission");
|
|
parsedOrders.push(order_obj);
|
|
remainingBytes = r_order;
|
|
}
|
|
if (parsedOrders.length > 0) {
|
|
this.power_name = parsedOrders[0].power_name; // Assuming all orders for same power
|
|
this.orders = parsedOrders.map(o => o.toString());
|
|
}
|
|
// Note: Python sets self.phase, self.power_name, self.orders.
|
|
// this.phase is part of DaideRequest base, might be game context phase.
|
|
// parsedPhase stores phase from message if present.
|
|
}
|
|
}
|
|
|
|
export class MissingOrdersRequestTs extends DaideRequest { __type__ = "MissingOrdersRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class GoFlagRequestTs extends DaideRequest { __type__ = "GoFlagRequest"; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
|
|
export class TimeToDeadlineRequestTs extends DaideRequest {
|
|
__type__ = "TimeToDeadlineRequest";
|
|
seconds: number | null = null;
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
let remainingBytes = daideBytes;
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'TME') throw new Error('Expected TME request');
|
|
remainingBytes = r0;
|
|
|
|
const [seconds_group_bytes, r1] = break_next_group_ts(remainingBytes);
|
|
if (seconds_group_bytes) {
|
|
const inner_seconds = strip_parentheses_ts(seconds_group_bytes);
|
|
const [num_obj, r_num] = parse_bytes_ts(NumberTs, inner_seconds);
|
|
if (!num_obj?.isValid) throw new Error("TME: Invalid number for seconds");
|
|
if (r_num.length > 0) throw new Error("TME: Extra bytes in seconds group");
|
|
this.seconds = num_obj.toInt();
|
|
remainingBytes = r1;
|
|
} // If no group, seconds remains null (for TME without params)
|
|
if (remainingBytes.length > 0) throw new Error(`TME request malformed, ${remainingBytes.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
export class DrawRequestTs extends DaideRequest {
|
|
__type__ = "DrawRequest";
|
|
powers: string[] = []; // Long power names
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
let remainingBytes = daideBytes;
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'DRW') throw new Error('Expected DRW request');
|
|
remainingBytes = r0;
|
|
|
|
const [powers_group_bytes, r1] = break_next_group_ts(remainingBytes);
|
|
if (powers_group_bytes) {
|
|
let inner_powers = strip_parentheses_ts(powers_group_bytes);
|
|
while(inner_powers.length > 0) {
|
|
const [power_obj, r_power] = parse_bytes_ts(PowerTs, inner_powers);
|
|
if (!power_obj?.isValid) throw new Error("DRW: Invalid power in list");
|
|
this.powers.push(power_obj.toString());
|
|
inner_powers = r_power;
|
|
}
|
|
}
|
|
remainingBytes = r1;
|
|
if (remainingBytes.length > 0) throw new Error(`DRW request malformed, ${remainingBytes.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
export class SendMessageRequestTs extends DaideRequest {
|
|
__type__ = "SendMessageRequest";
|
|
parsedPhase: string = ''; // Optional turn
|
|
powers: string[] = []; // List of long power names (recipients)
|
|
message_bytes: Uint8Array = new Uint8Array(0); // Raw bytes of the inner message clause
|
|
|
|
constructor() { super(); }
|
|
parseBytes(daideBytes: Uint8Array): void {
|
|
this._bytes = daideBytes; this.buildBaseStringRepresentation(daideBytes);
|
|
let remainingBytes = daideBytes;
|
|
|
|
const [lead_token_obj, r0] = parse_bytes_ts(SingleTokenTs, remainingBytes);
|
|
if (!lead_token_obj || lead_token_obj.getToken()?.toString() !== 'SND') throw new Error('Expected SND request');
|
|
remainingBytes = r0;
|
|
|
|
const [turn_obj, r_turn] = parse_bytes_ts(TurnTs, remainingBytes, 'ignore');
|
|
if (turn_obj?.isValid) {
|
|
this.parsedPhase = turn_obj.toString();
|
|
remainingBytes = r_turn;
|
|
}
|
|
|
|
const [powers_group_bytes, r_pg] = break_next_group_ts(remainingBytes);
|
|
if (!powers_group_bytes) throw new Error("SND: Missing powers group");
|
|
let inner_powers = strip_parentheses_ts(powers_group_bytes);
|
|
while(inner_powers.length > 0) {
|
|
const [power_obj, r_p] = parse_bytes_ts(PowerTs, inner_powers);
|
|
if (!power_obj?.isValid) throw new Error("SND: Invalid power in list");
|
|
this.powers.push(power_obj.toString());
|
|
inner_powers = r_p;
|
|
}
|
|
if (this.powers.length === 0) throw new Error("SND: Expected at least one power in powers group");
|
|
remainingBytes = r_pg;
|
|
|
|
const [message_group_bytes, r_mg] = break_next_group_ts(remainingBytes);
|
|
if (!message_group_bytes) throw new Error("SND: Missing message group");
|
|
this.message_bytes = strip_parentheses_ts(message_group_bytes);
|
|
remainingBytes = r_mg;
|
|
|
|
if (remainingBytes.length > 0) throw new Error(`SND request malformed, ${remainingBytes.length} bytes remaining.`);
|
|
}
|
|
}
|
|
|
|
// ... Stubs for NotRequest, AcceptRequest, RejectRequest, ParenthesisErrorRequest, SyntaxErrorRequest, AdminMessageRequest ...
|
|
export class NotRequestTs extends DaideRequest { __type__ = "NotRequest"; requestToNegate: DaideRequest | null = null; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class AcceptRequestTs extends DaideRequest { __type__ = "AcceptRequest"; response_bytes: Uint8Array = new Uint8Array(0); constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class RejectRequestTs extends DaideRequest { __type__ = "RejectRequest"; response_bytes: Uint8Array = new Uint8Array(0); constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class ParenthesisErrorRequestTs extends DaideRequest { __type__ = "ParenthesisErrorRequest"; message_bytes: Uint8Array = new Uint8Array(0); constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class SyntaxErrorRequestTs extends DaideRequest { __type__ = "SyntaxErrorRequest"; message_bytes: Uint8Array = new Uint8Array(0); constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
export class AdminMessageRequestTs extends DaideRequest { __type__ = "AdminMessageRequest"; adm_message: string = ''; constructor() {super();} parseBytes(db: Uint8Array){this._bytes=db; this.buildBaseStringRepresentation(db);} }
|
|
|
|
|
|
// RequestBuilder Class
|
|
type DaideRequestConstructor = new (...args: any[]) => DaideRequest;
|
|
const REQUEST_CONSTRUCTOR_MAP_TS = new Map<string, DaideRequestConstructor>();
|
|
|
|
function bytesToKey(bytes: Uint8Array): string {
|
|
return `${bytes[0]},${bytes[1]}`;
|
|
}
|
|
|
|
// Populate map (Token bytes are Uint8Array, convert to string key)
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.NME.toBytes()), NameRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.OBS.toBytes()), ObserverRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.IAM.toBytes()), IAmRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.HLO.toBytes()), HelloRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.MAP.toBytes()), MapRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.MDF.toBytes()), MapDefinitionRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.SCO.toBytes()), SupplyCentreOwnershipRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.NOW.toBytes()), CurrentPositionRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.HST.toBytes()), HistoryRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.SUB.toBytes()), SubmitOrdersRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.MIS.toBytes()), MissingOrdersRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.GOF.toBytes()), GoFlagRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.TME.toBytes()), TimeToDeadlineRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.DRW.toBytes()), DrawRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.SND.toBytes()), SendMessageRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.NOT.toBytes()), NotRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.YES.toBytes()), AcceptRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.REJ.toBytes()), RejectRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.PRN.toBytes()), ParenthesisErrorRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.HUH.toBytes()), SyntaxErrorRequestTs);
|
|
REQUEST_CONSTRUCTOR_MAP_TS.set(bytesToKey(daideTokens.ADM.toBytes()), AdminMessageRequestTs);
|
|
|
|
|
|
export class RequestBuilderTs {
|
|
static fromBytes(daideBytes: Uint8Array, ...constructorArgs: any[]): DaideRequest | null {
|
|
if (daideBytes.length < 2) return null;
|
|
const initialTokenBytes = daideBytes.slice(0, 2);
|
|
const key = bytesToKey(initialTokenBytes);
|
|
|
|
const RequestClass = REQUEST_CONSTRUCTOR_MAP_TS.get(key);
|
|
if (!RequestClass) {
|
|
throw new Error(`RequestBuilderTs: Unable to find a constructor for token bytes ${key} (${new Token({from_bytes: initialTokenBytes}).toString()})`);
|
|
}
|
|
const requestInstance = new RequestClass(...constructorArgs);
|
|
requestInstance.parseBytes(daideBytes); // Pass the full original bytes
|
|
return requestInstance;
|
|
}
|
|
}
|
|
|
|
// Aliases
|
|
export const NME = NameRequestTs;
|
|
export const OBS = ObserverRequestTs;
|
|
// ... Add all other aliases similarly
|
|
export const IAM = IAmRequestTs;
|
|
export const HLO = HelloRequestTs;
|
|
export const MAP = MapRequestTs;
|
|
export const MDF = MapDefinitionRequestTs;
|
|
export const SCO = SupplyCentreOwnershipRequestTs;
|
|
export const NOW = CurrentPositionRequestTs;
|
|
export const HST = HistoryRequestTs;
|
|
export const SUB = SubmitOrdersRequestTs;
|
|
export const MIS = MissingOrdersRequestTs;
|
|
export const GOF = GoFlagRequestTs;
|
|
export const TME = TimeToDeadlineRequestTs;
|
|
export const DRW = DrawRequestTs;
|
|
export const SND = SendMessageRequestTs;
|
|
export const NOT = NotRequestTs;
|
|
export const YES = AcceptRequestTs;
|
|
export const REJ = RejectRequestTs;
|
|
export const PRN = ParenthesisErrorRequestTs;
|
|
export const HUH = SyntaxErrorRequestTs;
|
|
export const ADM = AdminMessageRequestTs;
|