Added ability to start a server
This commit is contained in:
		| @@ -1,3 +1,4 @@ | |||||||
|  | const { exec } = require("child_process"); | ||||||
| const fs = require('fs'); | const fs = require('fs'); | ||||||
|  |  | ||||||
| class Server { | class Server { | ||||||
| @@ -11,21 +12,44 @@ class Server { | |||||||
|     if (fs.existsSync(versionFilePath)) { |     if (fs.existsSync(versionFilePath)) { | ||||||
|       this.version = fs.readFileSync(versionFilePath, {encoding:'utf8', flag:'r'});       |       this.version = fs.readFileSync(versionFilePath, {encoding:'utf8', flag:'r'});       | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // set server state |  | ||||||
|     if (fs.existsSync(this.pidFilePath)) { |  | ||||||
|       this.state = true; |  | ||||||
|     } else { |  | ||||||
|       this.state = false; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   start() { |   start() { | ||||||
|     console.log('Starting server...'); |     console.log(`Starting server ${this.name}...`); | ||||||
|  |  | ||||||
|  |     // create shell command and execute it | ||||||
|  |     let cmd = `${this.rootDir}/start.sh`; | ||||||
|  |     exec(cmd, (err, stdout, stderr) => { | ||||||
|  |       if (err) { | ||||||
|  |         console.log(`Error while starting server: ${error.message}`); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       console.log(`Server ${this.name} has been started.`); | ||||||
|  |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   stop() { |   stop() { | ||||||
|     console.log('Stopping server...'); |     console.log(`Stopping server ${this.name}...`); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getStatus() { | ||||||
|  |     if (fs.existsSync(this.pidFilePath)) { | ||||||
|  |       let pid = fs.readFileSync(this.pidFilePath, {encoding: 'utf8', flag: 'r'}); | ||||||
|  |       try { | ||||||
|  |         return process.kill(pid, 0); | ||||||
|  |       } catch (err) { | ||||||
|  |         // ESRCH error means the process doesn't exist, so should return false | ||||||
|  |         if (err.code !== 'ESRCH') { | ||||||
|  |           console.error(err); | ||||||
|  |           return err.code === 'EPERM'; | ||||||
|  |         } else { | ||||||
|  |           // delete pid.txt so we don't have to worry about checking it again | ||||||
|  |           fs.unlinkSync(this.pidFilePath); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getPid() { |   getPid() { | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								index.js
									
									
									
									
									
								
							| @@ -18,11 +18,13 @@ var serverRoutes = require('./routes/server'); | |||||||
| app.get('/', homeRoutes.getIndex); | app.get('/', homeRoutes.getIndex); | ||||||
| app.get('/server/create', serverRoutes.getCreate); | app.get('/server/create', serverRoutes.getCreate); | ||||||
| app.post('/server/create', serverRoutes.postCreate); | app.post('/server/create', serverRoutes.postCreate); | ||||||
|  | app.get('/server/:serverName/start', serverRoutes.getStart); | ||||||
|  | app.get('/server/:serverName/stop', serverRoutes.getStop); | ||||||
|  |  | ||||||
| // set Express to serve static files (ideally this is only used in development) | // set Express to serve static files (ideally this is only used in development) | ||||||
| app.use(express.static('./static/')); | app.use(express.static('./static/')); | ||||||
|  |  | ||||||
| // start Express.js app | // start Express.js app | ||||||
| app.listen(port, () => { | app.listen(port, () => { | ||||||
|   console.log(`Example app listening on port ${port}`); |   console.log(`MCST has started and is listening on port ${port}.`); | ||||||
| }); | }); | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -9,6 +9,7 @@ | |||||||
|       "version": "0.1.0", |       "version": "0.1.0", | ||||||
|       "license": "BSD-2-Clause", |       "license": "BSD-2-Clause", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|  |         "config": "^3.3.8", | ||||||
|         "express": "^4.18.1", |         "express": "^4.18.1", | ||||||
|         "pug": "^3.0.2" |         "pug": "^3.0.2" | ||||||
|       } |       } | ||||||
| @@ -153,6 +154,17 @@ | |||||||
|         "is-regex": "^1.0.3" |         "is-regex": "^1.0.3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/config": { | ||||||
|  |       "version": "3.3.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/config/-/config-3.3.8.tgz", | ||||||
|  |       "integrity": "sha512-rFzF6VESOdp7wAXFlB9IOZI4ouL05g3A03v2eRcTHj2JBQaTNJ40zhAUl5wRbWHqLZ+uqp/7OE0BWWtAVgrong==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "json5": "^2.2.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 10.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/constantinople": { |     "node_modules/constantinople": { | ||||||
|       "version": "4.0.1", |       "version": "4.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", |       "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", | ||||||
| @@ -462,6 +474,17 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", | ||||||
|       "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" |       "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/json5": { | ||||||
|  |       "version": "2.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", | ||||||
|  |       "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", | ||||||
|  |       "bin": { | ||||||
|  |         "json5": "lib/cli.js" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/jstransformer": { |     "node_modules/jstransformer": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", | ||||||
| @@ -1051,6 +1074,14 @@ | |||||||
|         "is-regex": "^1.0.3" |         "is-regex": "^1.0.3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "config": { | ||||||
|  |       "version": "3.3.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/config/-/config-3.3.8.tgz", | ||||||
|  |       "integrity": "sha512-rFzF6VESOdp7wAXFlB9IOZI4ouL05g3A03v2eRcTHj2JBQaTNJ40zhAUl5wRbWHqLZ+uqp/7OE0BWWtAVgrong==", | ||||||
|  |       "requires": { | ||||||
|  |         "json5": "^2.2.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "constantinople": { |     "constantinople": { | ||||||
|       "version": "4.0.1", |       "version": "4.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", |       "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", | ||||||
| @@ -1290,6 +1321,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", | ||||||
|       "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" |       "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" | ||||||
|     }, |     }, | ||||||
|  |     "json5": { | ||||||
|  |       "version": "2.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", | ||||||
|  |       "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" | ||||||
|  |     }, | ||||||
|     "jstransformer": { |     "jstransformer": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|   "author": "Gregory Ballantine <gballantine@bitgoblin.tech>", |   "author": "Gregory Ballantine <gballantine@bitgoblin.tech>", | ||||||
|   "license": "BSD-2-Clause", |   "license": "BSD-2-Clause", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "config": "^3.3.8", | ||||||
|     "express": "^4.18.1", |     "express": "^4.18.1", | ||||||
|     "pug": "^3.0.2" |     "pug": "^3.0.2" | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ const config = require('config'); | |||||||
| const fs = require('fs'); | const fs = require('fs'); | ||||||
| const https = require('https'); | const https = require('https'); | ||||||
| const path = require('path'); | const path = require('path'); | ||||||
|  | const minecraft = require('../app/MinecraftServer'); | ||||||
|  |  | ||||||
| exports.getCreate = function(req, res) { | exports.getCreate = function(req, res) { | ||||||
|   // render view |   // render view | ||||||
| @@ -30,7 +31,7 @@ exports.postCreate = function(req, res) { | |||||||
|  |  | ||||||
|   // create the start.sh shell script |   // create the start.sh shell script | ||||||
|   scriptFilePath = path.join(serverDir, 'start.sh'); |   scriptFilePath = path.join(serverDir, 'start.sh'); | ||||||
|   scriptContent = "#!/bin/sh\n\ncd " + serverDir + "\njava -Xmx2048M -Xms2048M -jar server_" + req.body.serverVersion + ".jar nogui"; |   scriptContent = "#!/bin/sh\n\ncd " + serverDir + "\njava -Xmx2048M -Xms2048M -jar server_" + req.body.serverVersion + ".jar nogui &\n\necho \"$!\" > ./pid.txt"; | ||||||
|   fs.writeFileSync(scriptFilePath, scriptContent); |   fs.writeFileSync(scriptFilePath, scriptContent); | ||||||
|   fs.chmodSync(scriptFilePath, 0o755); |   fs.chmodSync(scriptFilePath, 0o755); | ||||||
|  |  | ||||||
| @@ -43,3 +44,27 @@ exports.postCreate = function(req, res) { | |||||||
|   // redirect the user back to the home page |   // redirect the user back to the home page | ||||||
|   res.redirect('/'); |   res.redirect('/'); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | exports.getStart = function(req, res) { | ||||||
|  |   let serverName = req.params.serverName; | ||||||
|  |   let rootDir = config.get('server_directory'); | ||||||
|  |   let server = new minecraft.Server(path.join(rootDir, serverName)); | ||||||
|  |  | ||||||
|  |   // start the server | ||||||
|  |   server.start(); | ||||||
|  |  | ||||||
|  |   // redirect the user back to the home page | ||||||
|  |   res.redirect('/'); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | exports.getStop = function(req, res) { | ||||||
|  |   let serverName = req.params.serverName; | ||||||
|  |   let rootDir = config.get('server_directory'); | ||||||
|  |   let server = new minecraft.Server(path.join(rootDir, serverName)); | ||||||
|  |  | ||||||
|  |   // stop the server | ||||||
|  |   server.stop(); | ||||||
|  |  | ||||||
|  |   // redirect the user back to the home page | ||||||
|  |   res.redirect('/'); | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ block content | |||||||
|               tr.serverItem |               tr.serverItem | ||||||
|                 td.serverName= m.name |                 td.serverName= m.name | ||||||
|                 td.serverVersion= m.version |                 td.serverVersion= m.version | ||||||
|                 td.serverState= m.state |                 td.serverState= m.getStatus() | ||||||
|                 td |                 td | ||||||
|                   a(href='/server/' + m.name + '/start') Start |                   a(href='/server/' + m.name + '/start') Start | ||||||
|                   a(href='/server/' + m.name + '/stop') Stop |                   a(href='/server/' + m.name + '/stop') Stop | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user