const { Client } = require("../Client"); let {addService, addListener} = require("../WebSocket.js"); class APNumber{ /** * @type {Map} */ static busyNumbers = new Map(); /** * @type {number} * @param {Client} client */ static lock(client) { let c = 24; while(true){ if(!APNumber.busyNumbers.has(c)) { APNumber.busyNumbers.set(c,client); process.send({ type: 'AP_NUMBER/LOCK', uuid: client.id, value: c }) return c; } c++; } } /** * @param {number} num */ static release(num) { process.send({ type: 'AP_NUMBER/RELEASE', uuid: APNumber.busyNumbers.get(num).id, value: num }) APNumber.busyNumbers.delete(num); } static whois(num){ return APNumber.busyNumbers.get(num)?.id; } } class APShortCode{ /** * @type {Map} */ static busyCodes = new Map(); /** * * @param {Client} client * @returns */ static lock(client){ let firstLetter = new ShortCodeLetter(); let secondLetter = new ShortCodeLetter(); let thirdLetter = new ShortCodeLetter(); while(1) { let code = [firstLetter.code,secondLetter.code,thirdLetter.code].join(''); if(APShortCode.busyCodes.has(code) == false) { APShortCode.busyCodes.set(code, client); process.send({ type: 'AP_SHORTCODE/LOCK', uuid: APShortCode.busyCodes.get(code).id, value: code }) return code; } if(!thirdLetter.end()) { thirdLetter.next() }else{ thirdLetter.reset() if(!secondLetter.end()) { secondLetter.next(); }else{ secondLetter.reset(); if(!firstLetter.end()) { firstLetter.next(); }else{ break; } } } } } static release(code){ if(APShortCode.busyCodes.has(code)) { process.send({ type: 'AP_SHORTCODE/RELEASE', uuid: APShortCode.busyCodes.get(code).id, value: code }) APShortCode.busyCodes.delete(code); } } static whois(num){ return APShortCode.busyCodes.get(num)?.id; } }; class ShortCodeLetter{ chars = 'ABCDEFGHIKLMNOPRSTVXYZ'.split(''); now = 0; code = 'A'; next(){ this.now++ this.code = this.chars.at(this.now); return this.code; } reset(){ this.now = 0; this.code = 'A'; } end(){ return !this.chars.at(this.now + 1) } } class APIPAddress{ /** * @type {Map<[number,number,number,number], Client>} */ static busyIP = new Map(); /** * @param {Client} client */ static lock(client){ let A = 10; let B = 0; let C = 0; let D = 1; while(1) { let code = [A,B,C,D].join('.'); if(APIPAddress.busyIP.has(code) == false) { APIPAddress.busyIP.set(code, client); process.send({ type: 'AP_IPADDRESS/LOCK', uuid: APIPAddress.busyIP.get(code).id, value: code }) return code; } if(D != 255) { D++; continue; }else{ D = 0; } if(C != 255) { C++; continue; }else{ C = 0; } if(B != 255) { B++; continue; }else{ B = 0; } if(A != 255) { A++; continue; }else{ A = 0; } return; } } static release(code){ if(APIPAddress.busyIP.has(code)) { process.send({ type: 'AP_IPADDRESS/RELEASE', uuid: APIPAddress.busyIP.get(code).id, value: code }) APIPAddress.busyIP.delete(code); } } static whois(num){ return APIPAddress.busyIP.get(num)?.id; } }; exports.APNumber = APNumber; exports.APShortCode = APShortCode; exports.APIPAddress = APIPAddress; addService(({ client, message, end, next })=>{ let {type,whois} = message; switch(type) { case "alloc/APIPAddress":{ if(client.APIPAddress) { end({ status : "success", ip : client.APIPAddress }) }; let value = APIPAddress.lock(client); client.APIPAddress = value; client.sync('APIPAddress'); end({ status : "success", ip : value }) break; } case "alloc/APNumber":{ if(client.APNumber) { end({ status : "success", number : client.APNumber }) }; let value = APNumber.lock(client); client.APNumber = value; client.sync('APNumber'); end({ status : "success", number : value }) break; } case "alloc/APShortCode":{ if(client.APShortCode) { end({ status : "success", code : client.APShortCode }) }; let value = APShortCode.lock(client); client.APShortCode = value; client.sync('APShortCode'); end({ status : "success", code : value }) break; } case "realloc/APIPAddress":{ if(client.APIPAddress == 0){ return end({ status : "fail" }) } APIPAddress.release(client.APIPAddress); let value = APIPAddress.lock(client); client.sync('APIPAddress'); end({ status : "success", ip : value }) break; } case "realloc/APNumber":{ if(client.APNumber == 0){ return end({ status : "fail" }) } APNumber.release(client.APNumber); let value = APNumber.lock(client); client.sync('APNumber'); end({ status : "success", number : value }) break; } case "realloc/APShortCode":{ if(client.APShortCode == 0){ return end({ status : "fail" }) } APShortCode.release(client.APShortCode); let value = APShortCode.lock(client); client.sync('APShortCode'); end({ status : "success", code : value }) break; } case "release/APIPAddress":{ APIPAddress.release(client.APIPAddress); client.APIPAddress = void 0; client.sync('APShortCode'); end({ status : "success" }) break; } case "release/APNumber":{ APNumber.release(client.APNumber); client.APNumber = void 0; client.sync('APIPAddress'); end({ status : "success" }) break; } case "release/APShortCode":{ APShortCode.release(client.APShortCode); client.APShortCode = void 0; client.sync('APIPAddress'); end({ status : "success" }) break; } case "whois/APIPAddress":{ let socketId = APIPAddress.whois(whois); if(socketId) { end({ status : "success", socket : socketId }) }else{ end({ status : "fail" }) } break; } case "whois/APNumber":{ let socketId = APNumber.whois(whois); if(socketId) { end({ status : "success", socket : socketId }) }else{ end({ status : "fail" }) } break; } case "whois/APShortCode":{ let socketId = APShortCode.whois(whois); if(socketId) { end({ status : "success", socket : socketId }) }else{ end({ status : "fail" }) } break; } } }) process.on('message',({type, uuid, value}) => { switch(type) { case "AP_NUMBER/LOCK":{ let client = Client.clients.get(uuid); APNumber.busyNumbers.set(value, client); if(client) { client.APNumber = value; } break; } case "AP_NUMBER/RELEASE":{ APNumber.busyNumbers.delete(value); let client = Client.clients.get(uuid); if(client) { client.APNumber = void 0; } break; } case "AP_SHORTCODE/LOCK":{ let client = Client.clients.get(uuid); APShortCode.busyCodes.set(value, client); if(client) { client.APShortCode = value; } break; } case "AP_SHORTCODE/RELEASE":{ APShortCode.busyCodes.delete(value); let client = Client.clients.get(uuid); if(client) { client.APShortCode = void 0; } break; } case "AP_IPADDRESS/LOCK":{ let client = Client.clients.get(uuid); APIPAddress.busyIP.set(value, client); if(client) { client.APIPAddress = value; } break; } case "AP_IPADDRESS/RELEASE":{ APIPAddress.busyIP.delete(value); let client = Client.clients.get(uuid); if(client) { client.APIPAddress = void 0; } break; } } }) addListener('disconnect',(global, client)=>{ if(client.APIPAddress != 0) { APIPAddress.release(client.APIPAddress); } if(client.APNumber != 0) { APNumber.release(client.APNumber); } if(client.APShortCode != 0) { APShortCode.release(client.APShortCode); } });