import ip from 'ip' ; import { UdpPacketSignature } from 'packets/definitions' ; export enum HolepunchType { Client = 0 , Server = 256 , SourceTV = 512 } /**
 * an user's holepunch data
 * look up UDP hole punching for more info
 * the data here will be used to connect users with each other in a match
 */ export class InHolepunchPacketUdp { public signature : number ; public userId : number ; public portId : number ; public ipAddress : string ; public port : number ; private packetData : Buffer ; private curOffset : number ; private parsedSuccessfully : boolean ; constructor ( data ) { this . packetData = data ; this . curOffset = 0 ; try { this . parse ( ) ; this . parsedSuccessfully = true ; } catch ( error ) { console . warn ( 'Error parsing holepunch packet. %s' , error ) ; this . parsedSuccessfully = false ; } } returns public isParsed ( ) { return this . parsedSuccessfully ; } public isHeartbeat ( ) { return this . packetData . byteLength === 6 ; } private parse ( ) { this . signature = this . packetData . readUInt8 ( this . curOffset ++ ) ; if ( this . signature !== UdpPacketSignature ) { throw new Error ( 'this is not a holepucnh packet!' ) ; } if ( this . isHeartbeat ( ) ) { } else { this . userId = this . readUInt32 ( ) ; this . portId = this . readUInt16 ( ) ; const fixedIp = ~ this . readUInt32 ( true ) ; this . ipAddress = ip . fromLong ( fixedIp ) ; this . port = this . readUInt16 ( ) ; } } returns private readUInt16 ( bigEndian = false ) { if ( this . canReadBytes ( 2 ) === false ) { throw new Error ( 'Data buffer is too small' ) ; } const res = bigEndian ? this . packetData . readUInt16BE ( this . curOffset ) : this . packetData . readUInt16LE ( this . curOffset ) ; this . curOffset += 2 ; return res ; } returns private readUInt32 ( bigEndian = false ) { if ( this . canReadBytes ( 4 ) === false ) { throw new Error ( 'Data buffer is too small' ) ; } const res = bigEndian ? this . packetData . readUInt32BE ( this . curOffset ) : this . packetData . readUInt32LE ( this . curOffset ) ; this . curOffset += 4 ; return res ; } private canReadBytes ( bytes ) { return this . packetData . byteLength >= this . curOffset + bytes ; } }