SquadJS/squad-server/plugins/squad-io-api.js
2021-03-04 23:36:57 +01:00

134 lines
3.6 KiB
JavaScript

import { createServer } from 'http';
import { Server } from 'socket.io';
import BasePlugin from './base-plugin.js';
export default class SquadIOAPI extends BasePlugin {
static get description() {
return 'The <code>SquadIOAPI</code> plugin allows remote access to a SquadJS instance via Socket.IO';
}
static get defaultEnabled() {
return false;
}
static get optionsSpecification() {
return {
websocketPort: {
required: true,
description: 'The port for the websocket.',
default: '',
example: '3000'
},
securityToken: {
required: true,
description: 'Your secret token/password for connecting.',
default: '',
example: 'MySecretPassword'
}
};
}
constructor(server, options, connectors) {
super(server, options, connectors);
this.httpServer = createServer();
this.io = new Server(this.httpServer, {
cors: {
origin: 'http://localhost:3000',
methods: ['GET', 'POST'],
allowedHeaders: ['squadJS-connection-panel'],
credentials: true
}
});
this.io.use((socket, next) => {
if (socket.handshake.auth && socket.handshake.auth.token === this.options.securityToken) {
next();
} else {
next(new Error('Invalid token.'));
}
});
this.io.on('connection', (socket) => {
this.verbose(1, 'New Connection Made.');
this.bindListeners(socket, this.server);
this.bindListeners(socket, this.server.rcon, 'rcon.');
});
}
async mount() {
this.httpServer.listen(this.options.websocketPort);
}
async unmount() {
this.httpServer.close();
}
bindListeners(socket, obj, prefix = '') {
const ignore = [
'options',
'constructor',
'watch',
'unwatch',
'setupRCON',
'setupLogParser',
'getPlayerByCondition',
'pingSquadJSAPI',
'_events',
'_eventsCount',
'_maxListeners',
'plugins',
'rcon',
'logParser',
'updatePlayerListInterval',
'updatePlayerListTimeout',
'updateLayerInformationInterval',
'updateLayerInformationTimeout',
'updateA2SInformationInterval',
'updateA2SInformationTimeout',
'pingSquadJSAPIInterval',
'pingSquadJSAPI',
'pingSquadJSAPITimeout',
'rcon.constructor',
'rcon.processChatPacket',
'rcon._events',
'rcon._eventsCount',
'rcon._maxListeners',
'rcon.password',
'rcon.connect',
'rcon.onData',
'rcon.onClose',
'rcon.onError',
'rcon.client',
'rcon.autoReconnect',
'rcon.autoReconnectTimeout',
'rcon.incomingData',
'rcon.incomingResponse',
'rcon.responseCallbackQueue'
];
for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(obj))) {
if (ignore.includes(`${prefix}${key}`)) continue;
this.verbose(1, `Setting method listener for ${prefix}${key}...`);
socket.on(`${prefix}${key}`, async (...rawArgs) => {
const args = rawArgs.slice(0, rawArgs.length - 1);
const callback = rawArgs[rawArgs.length - 1];
this.verbose(1, `Call to ${prefix}${key}(${args.join(', ')})`);
const reponse = await obj[key](...args);
callback(reponse);
});
}
for (const key of Object.getOwnPropertyNames(obj)) {
if (ignore.includes(`${prefix}${key}`)) continue;
this.verbose(1, `Setting properties listener for ${prefix}${key}...`);
socket.on(`${prefix}${key}`, (callback) => {
this.verbose(1, `Call to ${prefix}${key}...`);
const reponse = obj[key];
callback(reponse);
});
}
}
}