117 lines
No EOL
3.6 KiB
TypeScript
117 lines
No EOL
3.6 KiB
TypeScript
/*
|
|
Ziedu Vija, armija, Ziedu Vija leģions
|
|
Pagāju garām es tavai kucei, zivju paviljons
|
|
Ēdu sēnes, šampinjons
|
|
Tu neēd neko, tu ir bomzis
|
|
Nomirs badā paļubom
|
|
Nomirs badā paļubom
|
|
|
|
2025 sad.ovh dev
|
|
|
|
*/
|
|
|
|
import express, { type Request, type Response, type NextFunction } from 'express';
|
|
import { InstantVector, PrometheusDriver, ResponseType, SampleValue } from 'prometheus-query';
|
|
import { PacketType, Rcon } from "./rcon";
|
|
|
|
if(!process.env.prometheusHost) {
|
|
throw new Error("missing prometheus host")
|
|
}
|
|
if(process.env.prometheusUsername || process.env.prometheusPassword) {
|
|
if(!process.env.prometheusUsername) {
|
|
throw new Error("missing prometheus username")
|
|
}
|
|
if(!process.env.prometheusPassword) {
|
|
throw new Error("missing prometheus password")
|
|
}
|
|
}
|
|
if(!process.env.rconHost || !process.env.rconPassword) {
|
|
throw new Error("missing rcon host or rcon password")
|
|
}
|
|
const rcon = new Rcon(process.env.rconHost.split(":")[0], +process.env.rconHost.split(":")[1], process.env.rconPassword);
|
|
let rconReconnectTimeout: Timer | null | undefined;
|
|
let whitelistedPlayers: string[] = [];
|
|
let lastRequested = 0;
|
|
|
|
const playerRegex = /There are \d* whitelisted player\(s\): /gm;
|
|
|
|
rcon.on("connect", () => {
|
|
console.log("RCON connected.");
|
|
});
|
|
|
|
rcon.on("auth", () => {
|
|
console.log("RCON authenicated.");
|
|
});
|
|
|
|
rcon.on("response", (a: string) => {
|
|
if (playerRegex.test(a)) {
|
|
whitelistedPlayers = a.replace(playerRegex, "").split(", ");
|
|
}
|
|
})
|
|
|
|
rcon.on("end", () => {
|
|
console.log("RCON ended. Reconnecting in 2000ms.")
|
|
if(rconReconnectTimeout) {
|
|
clearTimeout(rconReconnectTimeout);
|
|
}
|
|
rconReconnectTimeout = setTimeout(() => {
|
|
rcon.connect()
|
|
}, 2000)
|
|
})
|
|
const app = express();
|
|
|
|
//@ts-expect-error
|
|
app.use((req, res, next) => {
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
if (req.method === 'OPTIONS') {
|
|
return res.sendStatus(200);
|
|
}
|
|
next();
|
|
});
|
|
|
|
const host = process.env.host || "localhost";
|
|
const port = +(process.env.port || 3000);
|
|
|
|
const prom = new PrometheusDriver({
|
|
endpoint: process.env.prometheusHost,
|
|
auth: process.env.prometheusUsername ? {
|
|
username: process.env.prometheusUsername!,
|
|
password: process.env.prometheusPassword!
|
|
} : undefined
|
|
})
|
|
|
|
app.get("/api/getTps", async (req, res) => {
|
|
const query = await prom.instantQuery(`minecraft_tps`);
|
|
const value = (query.result[0] as InstantVector).value as SampleValue;
|
|
res.json(value.value)
|
|
})
|
|
|
|
app.get("/api/getPlayersOnline", async (req, res) => {
|
|
const query = await prom.instantQuery(`sum(minecraft_players_online{instance="172.18.0.1:25585", job="prometheus"})`);
|
|
const value = (query.result[0] as InstantVector).value as SampleValue;
|
|
res.json(value.value)
|
|
})
|
|
|
|
app.get("/api/uptime", async (req, res) => {
|
|
const query = await prom.instantQuery(`process_start_time_seconds`);
|
|
const value = (query.result[0] as InstantVector).value as SampleValue;
|
|
res.json(Date.now() - (value.value*1000))
|
|
})
|
|
|
|
app.get("/api/whitelist", async (req, res) => {
|
|
if ( Date.now() - lastRequested > 60000) {
|
|
lastRequested = Date.now();
|
|
rcon.send("whitelist list", PacketType.COMMAND);
|
|
rcon.once("response", () => {
|
|
res.json(whitelistedPlayers);
|
|
});
|
|
} else {
|
|
res.json(whitelistedPlayers);
|
|
}
|
|
})
|
|
app.listen(port, host, () => {
|
|
rcon.connect()
|
|
console.log(`Server is running on http://${host}:${port}`);
|
|
}); |