Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions api/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const express = require('express');
const cors = require('cors');
const { limiter } = require('./middleware/limiter.middleware');

const app = express();

const adminRoutes = require('./routes/admin.routes');
const serverRoutes = require('./routes/server.routes');
const propertiesRoute = require('./routes/properties.routes');
const installationsRoutes = require('./routes/installations.routes');
const infoRoutes = require('./routes/info.routes');

app.use(cors());
app.use(limiter)
app.use(express.json());

app.use('/server', serverRoutes);
app.use('/installations', installationsRoutes);
app.use('/properties', propertiesRoute);
app.use('/info', infoRoutes);
app.use('/admin', adminRoutes);

app.get('/ping', async (req, res) => {
res.send(`pong`);
});

module.exports = {
app
}
20 changes: 7 additions & 13 deletions api/cleaner.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@

let cleanup_done = false;
const networkingUtils = require('./utils/networkingUtils');
const configUtils = require('./utils/configUtils');
const networkingUtils = require('./utils/networking.util');
const configUtils = require('./utils/config.util');
const debug = configUtils.getConfigAttribute("debug");


async function cleanup() {

if(debug){
console.log("\nDebug mode is turned on\n Skipping cleanup tasks...\n if you don't intend this, change 'debug' from true to false in server-config.json");
console.log("====== API TERMINATED! ======");
Expand All @@ -27,20 +24,17 @@ async function cleanup() {
}

process.on('exit', () => {
if (!cleanup_done) {
if (!cleanup_done)
cleanup();
}
});

process.on('SIGINT', async () => {
async function handleExit() {
await cleanup();
process.exit(0);
});
}

process.on('SIGTERM', async () => {
await cleanup();
process.exit(0);
});
process.on('SIGINT', handleExit);
process.on('SIGTERM', handleExit);

process.on('uncaughtException', async (err) => {
console.error('Uncaught Exception:', err);
Expand Down
6 changes: 6 additions & 0 deletions api/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ const configFilePath = "./server-config.json";
const eulaFilePath = `${serverDirectory}/eula.txt`;
const upnpcPath = '/upnpc';

const serverStatus = {
OFFLINE: 0,
RUNNING: 1,
STARTING: 2
};

module.exports = {
serverDirectory,
Expand All @@ -29,4 +34,5 @@ module.exports = {
serverBannedIPsPath,
keysJSONPath,
eulaFilePath,
serverStatus
};
90 changes: 90 additions & 0 deletions api/controllers/info.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const propertiesService = require('../services/properties.service');
const infoService = require('../services/info.service');
const serverService = require('../services/server.service');
const consts = require('../consts');

async function playerCount(req, res) {
try {
const playerCount = await propertiesService.getOnlinePlayers();

res.status(200).send({ playerCount: playerCount });
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getUpTime(req, res) {
try {
if (infoService.getStartTime() === null) {
res.status(200).send({ uptime: "0s" });
return;
}

const ms = Date.now() - infoService.getStartTime();

const totalSeconds = Math.floor(ms / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;

let formatted = [];
if (hours > 0) formatted.push(`${hours}h`);
if (minutes > 0 || hours > 0) formatted.push(`${minutes}m`);
formatted.push(`${seconds}s`);

res.status(200).send({ uptime: formatted.join(" ") });
} catch (error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getMemoryUsage(req, res) {
try {
let serverProcess = serverService.getServerProcess();
res.status(200).send(await infoService.getMemoryUsage(serverProcess));
} catch (error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getWorldSize(req, res) {
try {
let worldSize = await infoService.getDirectorySize(consts.serverDirectory + "/world");
res.status(200).send({ worldSize: `${worldSize.toFixed(2)}MB` });
} catch (error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getVersion(req, res) {
try {
let version = infoService.getVersion(consts.serverDirectory + "/" + consts.serverName);
res.status(200).send({ version: version });
} catch (error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getPlatform(req, res) {
try {
let platform = infoService.getPlatform(consts.serverDirectory + "/" + consts.serverName);
res.status(200).send({ platform: platform });
} catch (error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

module.exports = {
playerCount,
getUpTime,
getMemoryUsage,
getWorldSize,
getVersion,
getPlatform
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
const express = require('express');
const router = express.Router();
const installationsUtils = require('../utils/installationsUtils');
const { updateConfigAttribute } = require('../utils/configUtils');

const installationsService = require('../services/installations.service');
const { updateConfigAttribute } = require('../utils/config.util');
const { Sema } = require('async-sema');

const downloadSema = new Sema(1);

router.put('/download/:platform/:version', async (req, res) => {
async function downloadServer(req, res) {
await downloadSema.acquire();

try {
await installationsUtils.downloadRouter(req.params.platform, req.params.version);
await installationsService.downloadRouter(req.params.platform, req.params.version);
res.status(201).send('Downloaded Successfully');

updateConfigAttribute("platform", req.params.platform);
updateConfigAttribute("version", req.params.version);

} catch (error) {

res.status(500).send(`Error downloading server files: ${error}`);
} finally{
downloadSema.release();
}
});

}

module.exports = router;
module.exports = {
downloadServer
}
164 changes: 164 additions & 0 deletions api/controllers/properties.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
const propertiesService = require("../services/properties.service");
const configUtils = require("../utils/config.util");
const jsonFilesUtils = require("../utils/files.util");

const { Sema } = require('async-sema');

let togglePropertySema = new Sema(1);

async function toggleProperty(req, res) {
togglePropertySema.acquire();

try {
console.log(req.params.property);
await propertiesService.updateProperty(req.params.property, true);
res.status(200).send("done");
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
} finally {
togglePropertySema.release();
}
}

let ramAllocationSema = new Sema(1);

async function allocateRam(req, res) {
ramAllocationSema.acquire();

try {
configUtils.updateMemoryAllocated(req.params.mb, true);
res.status(200).send(`Ram allocation updated to ${req.params.mb}M`);
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
} finally {
ramAllocationSema.release();
}
}

async function serverConfig(req, res) {
try {
const configJSON = configUtils.getConfigJSON();
res.status(200).send(configJSON);
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getWhitelist(req, res) {
try {
const whitelistJSON = jsonFilesUtils.getWhitelistJSON();
res.status(200).send(whitelistJSON);
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getOps(req, res) {
try {
const opsJSON = jsonFilesUtils.getOpsJSON();
res.status(200).send(opsJSON);
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function getBannedPlayers(req, res) {
try {
const bannedplayersJSON = jsonFilesUtils.getBannedPlayersJSON();
res.status(200).send(bannedplayersJSON);
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function modifyOperator(req, res) {
try {
if (req.params.operation != "add" && req.params.operation != "remove") {
res.status(404).send(`Invalid operation ${req.params.operation}`);
return;
}

await jsonFilesUtils.modifyOpsJSON(req.params.playername, req.params.operation === "add");
res.status(200).send(`${req.params.operation === "add" ? "Added" : "Remove"} ${req.params.playername} as an Operator`);
} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function modifyWhitelist(req, res) {
try {
if (req.params.operation != "add" && req.params.operation != "remove") {
res.status(404).send(`Invalid operation ${req.params.operation}`);
return;
}

await jsonFilesUtils.modifyWhitelistJSON(req.params.playername, req.params.operation === "add");
if (req.params.operation === "add")
res.status(200).send(`Added ${req.params.playername} to the Whitelist`);
else
res.status(200).send(`Remove ${req.params.playername} from the Whitelist`);

} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function modifyBanned(req, res) {
try {
if (req.params.operation != "add" && req.params.operation != "remove") {
res.status(404).send(`Invalid operation ${req.params.operation}`);
return;
}

await jsonFilesUtils.modifyBannedPlayersJSON(req.params.playername, req.params.operation === "add");
if (req.params.operation === "add")
res.status(200).send(`Banned ${req.params.playername}`);
else
res.status(200).send(`Pardoned ${req.params.playername}`);

} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}

async function modifyBannedIPs(req, res) {
try {
if (req.params.operation != "add" && req.params.operation != "remove") {
res.status(404).send(`Invalid operation ${req.params.operation}`);
return;
}

await jsonFilesUtils.modifyBannedIPsJSON(req.params.playername, req.params.operation === "add");
if (req.params.operation === "add")
res.status(200).send(`Banned ${req.params.playername}`);
else
res.status(200).send(`Pardoned ${req.params.playername}`);

} catch(error) {
console.error(error);
res.status(500).send("error.. " + error.message);
}
}


module.exports = {
toggleProperty,
allocateRam,
serverConfig,
getWhitelist,
getOps,
getBannedPlayers,
modifyOperator,
modifyWhitelist,
modifyBanned,
modifyBannedIPs
}
Loading