From 26341e80166a99a9a5a32809bb3914ef278d827b Mon Sep 17 00:00:00 2001 From: Die4Ever Date: Sun, 9 Jul 2023 21:02:57 -0500 Subject: [PATCH] socket library --- src/api.ts | 191 ++++++++++++++++++++++++++++++++++++ src/modules/crowdcontrol.ts | 167 +------------------------------ 2 files changed, 194 insertions(+), 164 deletions(-) create mode 100644 src/api.ts diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 0000000..05d0c16 --- /dev/null +++ b/src/api.ts @@ -0,0 +1,191 @@ + +class APIConnection +{ + sock:Socket = null; + good: boolean = false; + reconnect_interval: number = null; + name:string = "API"; + port:number; + callback:CallableFunction; + onCloseCallback: (hadError: any) => void; + onExpectedCloseCallback: (hadError: any) => void; + onErrorCallback: (hadError: any) => void; + onDataCallback: (hadError: any) => void; + + constructor(name:string, port:number, callback:CallableFunction) { + this.name = name; + this.port = port; + this.callback = callback; + + var self = this; + this.onCloseCallback = function(hadError){self.onClose(hadError);}; + this.onExpectedCloseCallback = function(hadError){self.onExpectedClose(hadError);} + this.onErrorCallback = function(hadError){self.onError(hadError);}; + this.onDataCallback = function(hadError){self.onData(hadError);}; + + this.connect(); + } + + send(data:Object) { + try { + let r: string = JSON.stringify(data) + '\0'; + info(this.name+' sending:', r.length, r); + this.end(r); + } catch(e) { + printException('error sending '+this.name, e); + } + } + + destroy() { + if(!this.sock) return; + + info(this.name+'.destroy()'); + try { + this.sock.off('close', this.onCloseCallback); + } catch(e) { + printException('error closing event handlers in '+this.name+'.close', e); + } + + try { + this.sock.off('close', this.onExpectedCloseCallback); + } catch(e) { + printException('error closing event handlers in '+this.name+'.close', e); + } + + try { + this.sock.destroy(null); + } catch(e) { + printException('error destroying old '+this.name+' connection ', e); + } + + this.sock = null; + } + + private onError(hadError: boolean) { + info('error in '+this.name+' connection, will keep trying...'); + if(this.good) { + park.postMessage( + {type: 'blank', text: 'error in '+this.name+' connection, will keep trying...'} as ParkMessageDesc + ); + } + this.good = false; + this.connect(); + } + + private onClose(hadError: boolean) { + info(this.name+' connection closed, will keep trying...'); + if(this.good) { + park.postMessage( + {type: 'blank', text: this.name+' connection closed, will keep trying...'} as ParkMessageDesc + ); + } + this.good = false; + this.connect(); + } + + private onExpectedClose(hadError: boolean) { + info(this.name+' connection closed cc_onExpectedClose, will keep trying...'); + this.good = true; + this.connect(); + } + + private reconnect() { + debug(this.name+' reconnecting...'); + this.connect(); + } + + private onData(message: string) { + let data: Object = null; + let resp: Object = null; + + try { + // chop off the null-terminator + while(message[message.length-1] == '\0') + message = message.substring(0, message.length-1); + data = JSON.parse(message); + info(this.name+" received data: ", data); + } catch(e) { + printException('error parsing '+this.name+' request JSON: ' + message, e); + } + + try { + resp = this.callback(data); + } catch(e) { + printException('error handling '+this.name+' request: ' + message, e); + } + + this.send(resp); + } + + private reset_timeout() { + if(this.reconnect_interval !== null) { + context.clearInterval(this.reconnect_interval); + this.reconnect_interval = null; + } + + //this.reconnect_interval = context.setInterval(this.end, 5000); + } + + private end(data?:string) { + if(!this.sock) return; + + info(this.name+'.end()'); + try { + this.sock.off('close', this.onCloseCallback); + this.sock.on('close', this.onExpectedCloseCallback); + } catch(e) { + printException('error closing event handlers in '+this.name+'.close', e); + } + + try { + data = data ? data : '{"id": 0, "status": 0}\0'; + info(this.name+'.sock.end('+data+')'); + this.sock.end(data); + } catch(e) { + printException('error closing old '+this.name+' connection ', e); + } + + try { + this.sock.destroy(null); + } catch(e) { + printException('error destroying old '+this.name+' connection ', e); + } + + this.reset_timeout(); + this.good = true; + } + + private connect() { + var self = this; + + if (network.mode == "server") { + //info("This is a server..."); + } else if (network.mode == "client") { + //info("This is a client..."); + return; + } else { + //info("This is single player..."); + } + + this.reset_timeout(); + this.destroy(); + + info(this.name+'.connect'); + this.sock = network.createSocket(); + + this.sock.connect(this.port, '127.0.0.1', function() { + if(!self.good) { + info(self.name+' connected to port '+self.port); + park.postMessage( + {type: 'blank', text: self.name+' connected!'} as ParkMessageDesc + ); + } + self.good = true; + }); + this.sock.setNoDelay(true); + + this.sock.on('error', this.onErrorCallback); + this.sock.on('close', this.onCloseCallback); + this.sock.on('data', this.onDataCallback); + } +} diff --git a/src/modules/crowdcontrol.ts b/src/modules/crowdcontrol.ts index b4a73d8..e4655dc 100644 --- a/src/modules/crowdcontrol.ts +++ b/src/modules/crowdcontrol.ts @@ -11,169 +11,12 @@ class RCTRCrowdControl extends ModuleBase { registerModule(new RCTRCrowdControl()); -let cc_sock: Socket = null; -let cc_good: boolean = false; -let cc_reconnect_interval: number = null; - -function cc_onError(hadError: boolean) { - info('error in Crowd Control connection, will keep trying...'); - if(cc_good) { - park.postMessage( - {type: 'blank', text: 'error in Crowd Control connection, will keep trying...'} as ParkMessageDesc - ); - } - cc_good = false; - cc_connect(); -} - -function cc_onClose(hadError: boolean) { - info('Crowd Control connection closed, will keep trying...'); - if(cc_good) { - park.postMessage( - {type: 'blank', text: 'Crowd Control connection closed, will keep trying...'} as ParkMessageDesc - ); - } - cc_good = false; - cc_connect(); -} - -function cc_onExpectedClose(hadError: boolean) { - info('Crowd Control connection closed cc_onExpectedClose, will keep trying...'); - cc_good = true; - cc_connect(); -} - -function cc_reconnect() { - //info('Crowd Control reconnecting...'); - cc_connect(); -} - -function cc_onData(message: string) { - let data: Object = null; - let resp: Object = null; - - try { - // chop off the null-terminator - while(message[message.length-1] == '\0') - message = message.substring(0, message.length-1); - data = JSON.parse(message); - info("Crowd Control received data: ", data); - } catch(e) { - printException('error parsing Crowd Control request JSON: ' + message, e); - } - - try { - resp = cc_req(data); - } catch(e) { - printException('error handling Crowd Control request: ' + message, e); - } - - try { - let r: string = JSON.stringify(resp) + '\0'; - info(message, r.length, r); - cc_end(r); - } catch(e) { - printException('error sending Crowd Control response to: ' + message, e); - } -} - -function cc_reset_timeout() { - if(cc_reconnect_interval !== null) { - context.clearInterval(cc_reconnect_interval); - cc_reconnect_interval = null; - } - - //cc_reconnect_interval = context.setInterval(cc_end, 5000); -} - -function cc_end(data?:string) { - if(!cc_sock) return; - - info('cc_end()'); - try { - cc_sock.off('close', cc_onClose); - cc_sock.on('close', cc_onExpectedClose); - } catch(e) { - printException('error closing event handlers in cc_close', e); - } - - try { - data = data ? data : '{"id": 0, "status": 0}\0'; - info('cc_sock.end('+data+')'); - cc_sock.end(data); - } catch(e) { - printException('error closing old Crowd Control connection ', e); - } - - try { - cc_sock.destroy(null); - } catch(e) { - printException('error destroying old Crowd Control connection ', e); - } - - cc_reset_timeout(); - cc_good = true; -} - -function cc_destroy() { - if(!cc_sock) return; - - info('cc_destroy()'); - try { - cc_sock.off('close', cc_onClose); - } catch(e) { - printException('error closing event handlers in cc_close', e); - } - - try { - cc_sock.off('close', cc_onExpectedClose); - } catch(e) { - printException('error closing event handlers in cc_close', e); - } - - try { - cc_sock.destroy(null); - } catch(e) { - printException('error destroying old Crowd Control connection ', e); - } - - cc_sock = null; -} - -function cc_connect() { - if (network.mode == "server") { - //info("This is a server..."); - } else if (network.mode == "client") { - //info("This is a client..."); - return; - } else { - //info("This is single player..."); - } - - cc_reset_timeout(); - cc_destroy(); - - info('cc_connect'); - cc_sock = network.createSocket(); - - cc_sock.connect(43385, '127.0.0.1', function() { - if(!cc_good) { - info('Crowd Control connected!'); - park.postMessage( - {type: 'blank', text: 'Crowd Control connected!'} as ParkMessageDesc - ); - } - cc_good = true; - }); - cc_sock.setNoDelay(true); - - cc_sock.on('error', cc_onError); - cc_sock.on('close', cc_onClose); - cc_sock.on('data', cc_onData); +function cc_req(data) { + return { id: data.id, status: handle(data) }; } function init_crowdcontrol() { - cc_connect(); + var connection = new APIConnection("Crowd Control", 43385, cc_req); //Handle renames as guests enter the park context.subscribe("guest.generation", (e) => { @@ -255,7 +98,3 @@ function init_crowdcontrol() { return {}; }); } - -function cc_req(data) { - return { id: data.id, status: handle(data) }; -}