slopsite/api/index.ts
2025-02-27 10:34:17 +02:00

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}`);
});