UNPKG

fivem-docker-cli

Version:

Command-line tool to create and administer FiveM Servers running in Docker.

171 lines (155 loc) 5.32 kB
const { Command, flags } = require('@oclif/command'); const inquirer = require('inquirer'); const Docker = require('dockerode'); const { getPorts } = require('../modules/getPorts'); // Initialization const docker = new Docker({ socketPath: "/var/run/docker.sock" }); class InitCommand extends Command { async run() { const {flags} = this.parse(InitCommand); let servername = flags.servername; let licensekey = flags.licensekey; let rconpass = flags.rconpass; const startingPort = 30120; const endingPort = 30139; const currentNames = []; const currentPorts = []; let isImage = false; let availablePort; if (!flags.servername) { let responses = await inquirer.prompt([{ name: 'servername', message: 'Enter a name for your server. \n>', type: 'input' }]); servername = responses.servername; } if (!flags.licensekey) { let responses = await inquirer.prompt([{ name: 'licensekey', message: 'Enter your server license key. This can be obtained from https://keymaster.fivem.net. \n>', type: 'input' }]); licensekey = responses.licensekey; } if (!flags.rconpass) { let responses = await inquirer.prompt([{ name: 'rconpass', message: 'Enter the password you would like to use for RCON access. \n>', type: 'input' }]); rconpass = responses.rconpass; } docker.pull('spritsail/fivem:latest', (err, stream) => { console.log(stream); if (err) { console.error(err); } else { isImage = true; } }); // Check existing containers function checkExistingContainers() { return new Promise((resolve,reject) => { let error; docker.listContainers({ all: true, }).then((containers) => { containers.forEach((container) => { // Get names for existing containers currentNames.push(container.Names[0]); // Get ports for existing containers getPorts(container) .then((ports) => { ports.forEach((port) => { if (!currentPorts.includes(parseInt(port.External))){ currentPorts.push(parseInt(port.External, 10)); } }); }) .catch((err) => error = err); }); }) .catch((err) => error = err); if (!error) { resolve('checkExistingContainers'); } else { reject(error); } }) .catch((err) => console.error(err)); } // Check server name to see if it already exists //TODO: Add validation to servername. Must match /?[a-zA-Z0-9_-]+ function checkServerName(servername) { currentNames.forEach((name) => { if (name === (servername)) { return false; } else { return true; } }); } // Check designated port range against existing containers for an available port function getAvailablePort(currentPorts) { return new Promise((resolve, reject) => { let err; for (let i = startingPort; i <= endingPort; i++) { if (!currentPorts.includes(i) && !availablePort) { availablePort = i.toString(); break; } else if(i === endingPort && !availablePort) { err = 'There are no available ports.'; } else { err = 'There was an error while checking available ports.'; } } if (!err) { resolve(availablePort); } else { reject(err); } }) .catch((err) => console.error(err)); } // Check to make sure all information is available Promise.all([servername, licensekey, checkExistingContainers(), getAvailablePort(currentPorts)], isImage) .then((values) => { createContainer(); }); // Creates new FiveM server in Docker container function createContainer () { docker.createContainer({ name: servername, Image: 'spritsail/fivem:latest', RestartPolicy: { name: 'unless-stopped' }, Binds: [ "/volumes/fivem/" + servername + ":/config" ], Env: ["LICENCE_KEY=" + licensekey, "RCON_PASSWORD=" + rconpass, ], PortBindings: { "30120/tcp": [{ "HostIp": "", "HostPort": availablePort }], "30120/udp": [{ "HostIp": "", "HostPort": availablePort }] } }).then(container => { console.log('FiveM Container Started:'); console.table({ ID: container.id.slice(0, 11), Name: servername, Port: availablePort, Directory: '/volume/fivem/' + servername }); return container.start(); }).catch((err) => console.error(err)); } } } InitCommand.description = `Creates a new FiveM server running in Docker.`; InitCommand.flags = { servername: flags.string({char: 's', description: 'Name of the FiveM Docker container.'}), licensekey: flags.string({char: 'k', description: 'Server license key - This can be obtained from https://keymaster.fivem.net.'}), rconpass: flags.string({char: 'p', description: 'Password for RCON access.'}) }; module.exports = InitCommand;