mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 19:24:36 +00:00
rate limit start & create private lobby, change max game duration to 3 hours
This commit is contained in:
@@ -63,11 +63,11 @@ export class GameManager {
|
||||
|
||||
hasActiveGame(gameID: GameID): boolean {
|
||||
const game = this.games
|
||||
.filter((g) => g.id == gameID)
|
||||
.filter(
|
||||
(g) => g.phase() == GamePhase.Lobby || g.phase() == GamePhase.Active
|
||||
)
|
||||
.find((g) => g.id == gameID);
|
||||
return game != null;
|
||||
);
|
||||
return game.length > 0;
|
||||
}
|
||||
|
||||
// TODO: stop private games to prevent memory leak.
|
||||
@@ -106,7 +106,13 @@ export class GameManager {
|
||||
.forEach((g) => {
|
||||
g.start();
|
||||
});
|
||||
finished.map((g) => g.endGame()); // Fire and forget
|
||||
finished.forEach((g) => {
|
||||
try {
|
||||
g.endGame();
|
||||
} catch (error) {
|
||||
console.log(`error ending game ${g.id}: `, error);
|
||||
}
|
||||
});
|
||||
this.games = [...lobbies, ...active];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export class GameServer {
|
||||
duration: 1, // per 1 second
|
||||
});
|
||||
|
||||
private maxGameDuration = 5 * 60 * 60 * 1000; // 5 hours
|
||||
private maxGameDuration = 3 * 60 * 60 * 1000; // 3 hours
|
||||
|
||||
private turns: Turn[] = [];
|
||||
private intents: Intent[] = [];
|
||||
@@ -224,8 +224,8 @@ export class GameServer {
|
||||
async endGame() {
|
||||
// Close all WebSocket connections
|
||||
clearInterval(this.endTurnIntervalID);
|
||||
this.activeClients.forEach((client) => {
|
||||
client.ws.removeAllListeners("message"); // TODO: remove this?
|
||||
this.allClients.forEach((client) => {
|
||||
client.ws.removeAllListeners("message");
|
||||
if (client.ws.readyState === WebSocket.OPEN) {
|
||||
client.ws.close(1000, "game has ended");
|
||||
}
|
||||
@@ -298,10 +298,7 @@ export class GameServer {
|
||||
}
|
||||
}
|
||||
this.activeClients = alive;
|
||||
if (
|
||||
now >
|
||||
this.createdAt + this.config.lobbyLifetime() + this.maxGameDuration
|
||||
) {
|
||||
if (now > this.createdAt + this.maxGameDuration) {
|
||||
console.warn(`${this.id}: game past max duration ${this.id}`);
|
||||
return GamePhase.Finished;
|
||||
}
|
||||
|
||||
+35
-5
@@ -49,6 +49,11 @@ const rateLimiter = new RateLimiterMemory({
|
||||
duration: 1, // per 1 second
|
||||
});
|
||||
|
||||
const updateRateLimiter = new RateLimiterMemory({
|
||||
points: 10,
|
||||
duration: 240, // 4 minutes
|
||||
});
|
||||
|
||||
const gm = new GameManager(getServerConfig());
|
||||
|
||||
const bot = new DiscordBot();
|
||||
@@ -65,15 +70,32 @@ app.get("/lobbies", (req: Request, res: Response) => {
|
||||
res.send(lobbiesString);
|
||||
});
|
||||
|
||||
app.post("/private_lobby", (req, res) => {
|
||||
app.post("/private_lobby", async (req, res) => {
|
||||
let clientIP = "";
|
||||
try {
|
||||
clientIP = req.ip || req.socket.remoteAddress || "unknown";
|
||||
await updateRateLimiter.consume(clientIP);
|
||||
} catch (error) {
|
||||
console.warn(`create private lobby rate limited for IP ${clientIP}`);
|
||||
return;
|
||||
}
|
||||
const id = gm.createPrivateGame();
|
||||
console.log("creating private lobby with id ${id}");
|
||||
console.log(`ip ${clientIP} creating private lobby with id ${id}`);
|
||||
res.json({
|
||||
id: id,
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/archive_singleplayer_game", (req, res) => {
|
||||
app.post("/archive_singleplayer_game", async (req, res) => {
|
||||
let clientIP = "";
|
||||
try {
|
||||
clientIP = req.ip || req.socket.remoteAddress || "unknown";
|
||||
await updateRateLimiter.consume(clientIP);
|
||||
} catch (error) {
|
||||
console.warn(`archive singleplayer game limited for IP ${clientIP}`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const gameRecord: GameRecord = req.body;
|
||||
const clientIP = req.ip || req.socket.remoteAddress || "unknown"; // Added this line
|
||||
@@ -99,12 +121,20 @@ app.post("/archive_singleplayer_game", (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/start_private_lobby/:id", (req, res) => {
|
||||
app.post("/start_private_lobby/:id", async (req, res) => {
|
||||
let clientIP = "";
|
||||
try {
|
||||
clientIP = req.ip || req.socket.remoteAddress || "unknown";
|
||||
await updateRateLimiter.consume(clientIP);
|
||||
} catch (error) {
|
||||
console.warn(`start private lobby rate limited for IP ${clientIP}`);
|
||||
return;
|
||||
}
|
||||
console.log(`starting private lobby with id ${req.params.id}`);
|
||||
gm.startPrivateGame(req.params.id);
|
||||
});
|
||||
|
||||
app.put("/private_lobby/:id", (req, res) => {
|
||||
app.put("/private_lobby/:id", async (req, res) => {
|
||||
const lobbyID = req.params.id;
|
||||
gm.updateGameConfig(lobbyID, {
|
||||
gameMap: req.body.gameMap,
|
||||
|
||||
Reference in New Issue
Block a user