import { resolve } from "bun"; import {v4 as uuidv4} from "uuid" import { EventEmitter } from "events"; type SAAConfig = { autoConnectToExercise: boolean } enum SAAState { CREATED = 0, CONNECTED = 1, REGISTERED = 3, CONNECTION_FAILED = 4 }; export class SAASimulator extends EventEmitter{ private exerciseId: number | undefined; private partyId: number | undefined; private uri: string | undefined; private wsExm?: WebSocket; private wsTabPlugin?: WebSocket; private wsPpm?: WebSocket; private openRequests: Map void> = new Map void>(); private config: SAAConfig = { autoConnectToExercise: false }; private state: SAAState = SAAState.CREATED; constructor(config?: SAAConfig, exerciseId?: number, partyId?: number) { super(); if (config) this.config = config; if (exerciseId) { this.exerciseId = exerciseId; } } public setExerciseId(exerciseId: number) { if ((this.state == SAAState.CONNECTED) || this.state == SAAState.REGISTERED) return; this.exerciseId = exerciseId; } public getExId(): number{ return this.exerciseId || 0; } public getPartyId(): number{ return this.partyId || 0; } private loadTelegrams() { const file = Bun.file("telegrams.json"); const contents = file.json(); } public async register(partyId:number) { return new Promise((resolve,reject)=>{ this.sendTelegram({ uuid: "", version: "", timestamp: 1, sender: "", reciver: "", referenceUuid: "" }, { type: "EX-Anmeldung", typeId: 1, data: { partyId: partyId } }); }); } public getPartys(uri: string, port: number, exerciseId: number) { return new Promise((resolve, reject) => { const ws = new WebSocket(`${uri}:${port}`) ws.addEventListener("message", event => { if (!event.data) reject(); const eventData = JSON.parse(event.data); const servicePortsInformation = eventData["data"].find((servicePortsInformation: any) => { return servicePortsInformation["exerciseId"] == exerciseId }); const ppmService = servicePortsInformation["services"].find((servicePort: any) => { return servicePort["name"] == "ParticipantManagement"; }); const ppmPort = ppmService["ports"].find((portInfo: any) => { return portInfo["typeId"] == 1; })["number"]; const wsPpm = new WebSocket(`${uri}:${ppmPort}`) wsPpm.addEventListener("message", event => { if (!event.data) reject(); const eventData = JSON.parse(event.data); if(eventData["type"] != "partyBaseData")return; const partys = eventData["data"].map((party:any )=>{return {id:party["id"],name:party["name"]}}); resolve(partys); }); // socket opened wsPpm.addEventListener("open", (event: any) => { wsPpm.send(`{"type":"baseDlRequest","uuid":"12345"}`) }); // socket closed wsPpm.addEventListener("close", (event: any) => { console.log(event) reject(); }); // error handler wsPpm.addEventListener("error", (event: any) => { reject() }); }); // socket opened ws.addEventListener("open", (event: any) => { ws.send(`{"type":"servicePortsInformationRequest","uuid":"12345"}`) }); // socket closed ws.addEventListener("close", (event: any) => { console.log(event) reject(); }); // error handler ws.addEventListener("error", (event: any) => { reject() }); }); } public sendTelegram(telegram: any, data:any){ let tele = {...telegram,...data}; const uuid = uuidv4(); tele["uuid"] = uuid; this.openRequests.set(uuid, (data: any) => { console.log(data) }); this.wsTabPlugin?.send(JSON.stringify(tele)); } public getParticipantNumbers(){ this.wsPpm?.send(`{"type":"baseDlRequest","uuid":"12345"}`) } private getServicePortsInformationRequest(uuid: string) { this.wsExm?.send(`{"type":"servicePortsInformationRequest","uuid":"${uuid}"}`) this.openRequests.set(uuid, (data: any) => { this.handleServicePortsInformationResponse(data) }); } private onOpen(event) { this.getServicePortsInformationRequest("1234"); } private handleServicePortsInformationResponse(data: any) { const servicePortsInformation = data["data"].find((servicePortsInformation: any) => { return servicePortsInformation["exerciseId"] == this.exerciseId }); const serviceTab = servicePortsInformation["services"].find((servicePort: any) => { return servicePort["name"] == "TrainingAreaBase"; }); const tabPort = serviceTab["ports"].find((portInfo: any) => { return portInfo["typeId"] == 3; })["number"]; const servicePpm = servicePortsInformation["services"].find((servicePort: any) => { return servicePort["name"] == "ParticipantManagement"; }); const ppmPort = servicePpm["ports"].find((portInfo: any) => { return portInfo["typeId"] == 1; })["number"]; this.connectToPpm(ppmPort); this.connectToTabPlugin(tabPort); } public getExerciseIds(uri: string, port: number): Promise { return new Promise((resolve, reject) => { const ws = new WebSocket(`${uri}:${port}`) ws.addEventListener("message", event => { if (!event.data) reject(); const eventData = JSON.parse(event.data); resolve(eventData["data"].map((exerciseInfo: any) => { return Number.parseInt(exerciseInfo["exerciseId"]); })); }); // socket opened ws.addEventListener("open", (event: any) => { ws.send(`{"type":"servicePortsInformationRequest","uuid":"12345"}`) }); // socket closed ws.addEventListener("close", (event: any) => { console.log(event) reject(); }); // error handler ws.addEventListener("error", (event: any) => { console.log(event) reject(); }); }); } public connect(uri: string, port: number) { this.uri = uri; this.wsExm = new WebSocket(`${uri}:${port}`) this.wsExm.addEventListener("message", event => { if (!event.data) return; const eventData = JSON.parse(event.data); const uuid = eventData["uuid"] if(this.openRequests.has(uuid)){ const func = this.openRequests.get(uuid); if (!func) return; this.openRequests.delete(uuid); func(eventData); } }); // socket opened this.wsExm.addEventListener("open", (event) => { this.onOpen(event); }); // socket closed this.wsExm.addEventListener("close", event => { console.log(event) }); // error handler this.wsExm.addEventListener("error", event => { console.log(event) }); } public getAvailableCommands(): string[] { } private connectToTabPlugin(port: number) { this.wsTabPlugin = new WebSocket(`${this.uri}:${port}`) this.wsTabPlugin.addEventListener("message", event => { if (!event.data) return; const eventData = JSON.parse(event.data); const uuid = eventData["referenceUuid"] const func = this.openRequests.get(uuid); if (!func) return; func(eventData); }); // socket opened this.wsTabPlugin.addEventListener("open", (event) => { console.log("Connected to TabPlugin") }); // socket closed this.wsTabPlugin.addEventListener("close", event => { console.log(event) }); // error handler this.wsTabPlugin.addEventListener("error", event => { console.log(event) }); } public connectToPpm(port: number) { this.wsPpm = new WebSocket(`${this.uri}:${port}`) this.wsPpm.addEventListener("message", event => { if (!event.data) return; const eventData = JSON.parse(event.data); console.log(JSON.parse(event.data)["data"]); const path = "/shd/CTC/TOOLS/julius/json.json"; Bun.write(path, event.data); }); // socket opened this.wsPpm.addEventListener("open", (event) => { console.log("Connected to Ppm") }); // socket closed this.wsPpm.addEventListener("close", event => { console.log(event) }); // error handler this.wsPpm.addEventListener("error", event => { console.log(event) }); } }