Skip to content

Commit 0591531

Browse files
authored
chore: Merge pull request #9 from DEVUCP/dev
V2.0.0
2 parents 8ac379d + b46297e commit 0591531

54 files changed

Lines changed: 2585 additions & 374 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const express = require('express');
22
const cors = require('cors');
33
const { limiter } = require('./middleware/limiter.middleware');
4+
const logger = require('./middleware/logger.middleware');
45

56
const app = express();
67

@@ -12,6 +13,7 @@ const infoRoutes = require('./routes/info.routes');
1213

1314
app.use(cors());
1415
app.use(limiter)
16+
app.use(logger);
1517
app.use(express.json());
1618

1719
app.use('/server', serverRoutes);

api/controllers/info.controller.js

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,8 @@ async function playerCount(req, res) {
1616

1717
async function getUpTime(req, res) {
1818
try {
19-
if (infoService.getStartTime() === null) {
20-
res.status(200).send({ uptime: "0s" });
21-
return;
22-
}
2319

24-
const ms = Date.now() - infoService.getStartTime();
25-
26-
const totalSeconds = Math.floor(ms / 1000);
27-
const hours = Math.floor(totalSeconds / 3600);
28-
const minutes = Math.floor((totalSeconds % 3600) / 60);
29-
const seconds = totalSeconds % 60;
30-
31-
let formatted = [];
32-
if (hours > 0) formatted.push(`${hours}h`);
33-
if (minutes > 0 || hours > 0) formatted.push(`${minutes}m`);
34-
formatted.push(`${seconds}s`);
35-
36-
res.status(200).send({ uptime: formatted.join(" ") });
20+
res.status(200).send(await infoService.getUpTime());
3721
} catch (error) {
3822
console.error(error);
3923
res.status(500).send("error.. " + error.message);
@@ -80,11 +64,23 @@ async function getPlatform(req, res) {
8064
}
8165
}
8266

67+
async function getAllInfo(req, res) {
68+
try {
69+
let serverProcess = serverService.getServerProcess();
70+
let jarPath = consts.serverDirectory + "/" + consts.serverName
71+
res.status(200).send(await infoService.getInfo(serverProcess, jarPath, consts.serverDirectory));
72+
} catch (error) {
73+
console.error(error);
74+
res.status(500).send("error.. " + error.message);
75+
}
76+
}
77+
8378
module.exports = {
8479
playerCount,
8580
getUpTime,
8681
getMemoryUsage,
8782
getWorldSize,
8883
getVersion,
89-
getPlatform
84+
getPlatform,
85+
getAllInfo
9086
}

api/controllers/installations.controller.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ const { Sema } = require('async-sema');
55
const downloadSema = new Sema(1);
66

77
async function downloadServer(req, res) {
8-
await downloadSema.acquire();
9-
8+
await downloadSema.acquire();
9+
1010
try {
1111
await installationsService.downloadRouter(req.params.platform, req.params.version);
1212
res.status(201).send('Downloaded Successfully');

api/controllers/properties.controller.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ const { Sema } = require('async-sema');
66

77
let togglePropertySema = new Sema(1);
88

9-
async function toggleProperty(req, res) {
9+
async function updateProperty(req, res) {
1010
togglePropertySema.acquire();
1111

1212
try {
1313
console.log(req.params.property);
14-
await propertiesService.updateProperty(req.params.property, true);
14+
await propertiesService.updateProperty(req.params.property, req.params.newvalue);
1515
res.status(200).send("done");
1616
} catch(error) {
1717
console.error(error);
@@ -151,7 +151,7 @@ async function modifyBannedIPs(req, res) {
151151

152152

153153
module.exports = {
154-
toggleProperty,
154+
updateProperty,
155155
allocateRam,
156156
serverConfig,
157157
getWhitelist,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = (req, res, next) => {
2+
const colors = {
3+
GET: '\x1b[32m', // Green
4+
POST: '\x1b[33m', // Yellow
5+
PUT: '\x1b[34m', // Blue
6+
PATCH: '\x1b[35m',
7+
DELETE: '\x1b[31m', // Red
8+
RESET: '\x1b[0m' // Reset color
9+
};
10+
const color = colors[req.method] || colors.RESET;
11+
// console.log(
12+
// `${color}[${new Date().toISOString()}] ${req.method} ${req.url} - IP: ${req.ip} - User-Agent: ${req.headers['user-agent']}${colors.RESET}`
13+
// );
14+
console.log(
15+
`${color}[${new Date().toISOString()}] ${req.method} ${req.url} - IP: ${req.ip}${colors.RESET}`
16+
);
17+
next();
18+
};

api/routes/info.routes.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ const {
77
getMemoryUsage,
88
getWorldSize,
99
getVersion,
10-
getPlatform
10+
getPlatform,
11+
getAllInfo
1112
} = require('../controllers/info.controller');
1213

14+
router.get('/', getAllInfo);
15+
1316
router.get('/player-count', playerCount);
1417

1518
router.get('/uptime', getUpTime);

api/routes/properties.routes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const router = express.Router();
33
const propertiesServices = require('../services/properties.service');
44

55
const {
6-
toggleProperty,
6+
updateProperty,
77
allocateRam,
88
serverConfig,
99
getWhitelist,
@@ -25,7 +25,7 @@ router.get('/', async (req, res) => {
2525
}
2626
})
2727

28-
router.put('/toggle/:property', toggleProperty);
28+
router.put('/update/:property/:newvalue', updateProperty);
2929

3030
router.put('/allocate-ram/:mb', allocateRam);
3131

api/services/info.service.js

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ const fs = require('fs');
22
const path = require('path');
33
const pidusage = require('pidusage')
44
const AdmZip = require('adm-zip');
5+
const consts = require('../consts');
6+
const serverService = require("./server.service");
7+
const propertiesService = require("./properties.service");
58

69
let startTime = null;
710

@@ -56,13 +59,11 @@ function getDirectorySize(folderPath) {
5659
return sizeInMB;
5760
}
5861

59-
function getPlatform(jarPath) {
62+
function getPlatform(jarPath = consts.serverDirectory + "/" + consts.serverName) {
6063
const zip = new AdmZip(jarPath);
6164
const entries = zip.getEntries();
6265
const names = entries.map(e => e.entryName);
6366

64-
console.log(names);
65-
6667
const has = (file) => names.includes(file);
6768

6869
// Detect Paper
@@ -88,19 +89,20 @@ function getPlatform(jarPath) {
8889
}
8990

9091
function getVersion(jarPath) {
91-
if (getPlatform(jarPath) == "Fabric") {
92-
console.error("Unable to get version from fabric servers");
93-
return "Unable to fetch version";
94-
}
95-
92+
9693
const zip = new AdmZip(jarPath);
9794
const entries = zip.getEntries();
98-
95+
96+
if (getPlatform(jarPath) == "Fabric") {
97+
const installEntry = entries.find(entry => entry.entryName === 'install.properties');
98+
const text = zip.readAsText(installEntry);
99+
return text.split("game-version=")[1];
100+
}
101+
99102
const versionEntry = entries.find(e => e.entryName === "version.json");
100103
if (versionEntry) {
101104
try {
102105
const content = JSON.parse(zip.readAsText(versionEntry));
103-
console.log(content);
104106
return content.name || content.id || null;
105107
} catch (err) {
106108
console.warn("Failed to parse version.json:", err.message);
@@ -117,6 +119,86 @@ function getVersion(jarPath) {
117119
return null;
118120
}
119121

122+
async function getUpTime() {
123+
if (getStartTime() === null)
124+
return { uptime: "0s" };
125+
126+
const ms = Date.now() - getStartTime();
127+
128+
const totalSeconds = Math.floor(ms / 1000);
129+
const hours = Math.floor(totalSeconds / 3600);
130+
const minutes = Math.floor((totalSeconds % 3600) / 60);
131+
const seconds = totalSeconds % 60;
132+
133+
let formatted = [];
134+
if (hours > 0) formatted.push(`${hours}h`);
135+
if (minutes > 0 || hours > 0) formatted.push(`${minutes}m`);
136+
formatted.push(`${seconds}s`);
137+
138+
return { uptime: formatted.join(" ") };
139+
}
140+
141+
async function getInfo(serverProcess, jarPath, folderPath) {
142+
let memoryUsage = null;
143+
let platform = null;
144+
let version = null;
145+
let directorySizeMB = null;
146+
let serverStatus = null;
147+
let playerCount = null;
148+
149+
try {
150+
memoryUsage = await getMemoryUsage(serverProcess);
151+
} catch (err) {
152+
console.warn('Failed to get memory usage:', err.message);
153+
}
154+
155+
try {
156+
platform = getPlatform(jarPath);
157+
} catch (err) {
158+
console.warn('Failed to get platform:', err.message);
159+
}
160+
161+
try {
162+
version = getVersion(jarPath);
163+
} catch (err) {
164+
console.warn('Failed to get version:', err.message);
165+
}
166+
167+
try {
168+
directorySizeMB = getDirectorySize(folderPath);
169+
directorySizeMB = Math.round(directorySizeMB * 100) / 100;
170+
} catch (err) {
171+
console.warn('Failed to get directory size:', err.message);
172+
}
173+
174+
try {
175+
uptime = await getUpTime();
176+
} catch (err) {
177+
console.warn('Failed to calculate uptime:', err.message);
178+
}
179+
180+
try {
181+
serverStatus = serverService.isServerStarting();
182+
} catch (err) {
183+
console.warn('Failed to get server status:', err.message);
184+
}
185+
186+
try {
187+
playerCount = await propertiesService.getOnlinePlayers();
188+
} catch (err) {
189+
console.warn('Failed to get player count:', err.message);
190+
}
191+
192+
return {
193+
memoryUsage,
194+
platform,
195+
version,
196+
directorySizeMB,
197+
uptime: uptime.uptime,
198+
status: serverStatus,
199+
playerCount: playerCount
200+
};
201+
}
120202

121203
module.exports = {
122204
startCounting,
@@ -125,5 +207,7 @@ module.exports = {
125207
getMemoryUsage,
126208
getDirectorySize,
127209
getPlatform,
128-
getVersion
210+
getVersion,
211+
getInfo,
212+
getUpTime
129213
}

api/services/installations.service.js

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,56 @@
1-
const urlFetcher = require("../utils/platformURLFetcherUtil");
1+
const urlFetcher = require("../utils/url_fetcher.util");
2+
const infoService = require('../services/info.service');
3+
const consts = require('../consts');
24
const { writeDownloadedFile } = require("../utils/installations.util");
5+
const fs = require('fs/promises');
6+
const path = require('path');
7+
8+
const preserveList = [
9+
"world",
10+
"world_nether",
11+
"world_the_end",
12+
"banned-ips.json",
13+
"banned-players.json",
14+
"server.properties",
15+
"ops.json",
16+
"whitelist.json"
17+
];
18+
19+
async function purgeServer(preserveList) {
20+
let folderPath = consts.serverDirectory;
21+
try {
22+
const entries = await fs.readdir(folderPath, { withFileTypes: true });
23+
24+
for (const entry of entries) {
25+
if (preserveList.includes(entry.name)) continue;
26+
27+
const fullPath = path.join(folderPath, entry.name);
28+
if (entry.isDirectory())
29+
await fs.rm(fullPath, { recursive: true, force: true });
30+
else
31+
await fs.unlink(fullPath);
32+
}
33+
34+
console.log(`Deleted everything in ${folderPath} except preserved items.`);
35+
} catch (err) {
36+
console.error(`Error cleaning folder ${folderPath}:`, err.message);
37+
}
38+
}
339

440
async function downloadRouter(platform, version) {
41+
const oldPlatform = infoService.getPlatform();
42+
43+
const comingFromModded = oldPlatform === "fabric" || oldPlatform === "forge";
44+
const currentPreserveList = comingFromModded
45+
? preserveList.slice(3) // delete worlds
46+
: preserveList; // keep everything
47+
48+
if (oldPlatform != platform)
49+
await purgeServer(currentPreserveList);
50+
551
let response;
652
try {
7-
switch(platform) {
53+
switch (platform) {
854
case "vanilla":
955
response = await fetch(await urlFetcher.fetchVanillaURL(version));
1056
break;
@@ -17,9 +63,10 @@ async function downloadRouter(platform, version) {
1763
case "forge":
1864
response = await fetch(await urlFetcher.fetchForgeURL(version));
1965
break;
20-
case _:
21-
throw new Error(`Invalid platform --> ${platform}`)
66+
default:
67+
throw new Error(`Invalid platform --> ${platform}`);
2268
}
69+
2370
await writeDownloadedFile(response, version, platform.toUpperCase());
2471
} catch (error) {
2572
console.error(error);

0 commit comments

Comments
 (0)