mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 07:50:45 +00:00
add endpoint to kick players from a game given admin token, game id & client id
This commit is contained in:
@@ -82,7 +82,7 @@ export function joinLobby(
|
||||
if (message.type == "start") {
|
||||
// Trigger prestart for singleplayer games
|
||||
onPrestart();
|
||||
consolex.log(`lobby: game started: ${JSON.stringify(message)}`);
|
||||
consolex.log(`lobby: game started: ${JSON.stringify(message, null, 2)}`);
|
||||
onJoin();
|
||||
// For multiplayer games, GameStartInfo is not known until game starts.
|
||||
lobbyConfig.gameStartInfo = message.gameStartInfo;
|
||||
|
||||
@@ -57,6 +57,8 @@ export class GameServer {
|
||||
|
||||
private _hasPrestarted = false;
|
||||
|
||||
private kickedClients: Set<ClientID> = new Set();
|
||||
|
||||
constructor(
|
||||
public readonly id: string,
|
||||
readonly log_: Logger,
|
||||
@@ -103,6 +105,12 @@ export class GameServer {
|
||||
}
|
||||
|
||||
public addClient(client: Client, lastTurn: number) {
|
||||
if (this.kickedClients.has(client.clientID)) {
|
||||
this.log.warn(`cannot add client, already kicked`, {
|
||||
clientID: client.clientID,
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.log.info("client (re)joining game", {
|
||||
clientID: client.clientID,
|
||||
persistentID: client.persistentID,
|
||||
@@ -492,6 +500,31 @@ export class GameServer {
|
||||
return this.gameConfig.gameType == GameType.Public;
|
||||
}
|
||||
|
||||
public kickClient(clientID: ClientID): void {
|
||||
if (this.kickedClients.has(clientID)) {
|
||||
this.log.warn(`cannot kick client, already kicked`, {
|
||||
clientID,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const client = this.activeClients.find((c) => c.clientID === clientID);
|
||||
if (client) {
|
||||
this.log.info("Kicking client from game", {
|
||||
clientID: client.clientID,
|
||||
persistentID: client.persistentID,
|
||||
});
|
||||
client.ws.close(1000, "Kicked from game");
|
||||
this.activeClients = this.activeClients.filter(
|
||||
(c) => c.clientID !== clientID,
|
||||
);
|
||||
this.kickedClients.add(clientID);
|
||||
} else {
|
||||
this.log.warn(`cannot kick client, not found in game`, {
|
||||
clientID,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private handleSynchronization() {
|
||||
if (this.activeClients.length <= 1) {
|
||||
return;
|
||||
|
||||
@@ -160,6 +160,39 @@ app.get(
|
||||
}),
|
||||
);
|
||||
|
||||
app.post(
|
||||
"/api/kick_player/:gameID/:clientID",
|
||||
gatekeeper.httpHandler(LimiterType.Post, async (req, res) => {
|
||||
if (req.headers[config.adminHeader()] !== config.adminToken()) {
|
||||
res.status(401).send("Unauthorized");
|
||||
return;
|
||||
}
|
||||
|
||||
const { gameID, clientID } = req.params;
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`http://localhost:${config.workerPort(gameID)}/api/kick_player/${gameID}/${clientID}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
[config.adminHeader()]: config.adminToken(),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to kick player: ${response.statusText}`);
|
||||
}
|
||||
|
||||
res.status(200).send("Player kicked successfully");
|
||||
} catch (error) {
|
||||
log.error(`Error kicking player from game ${gameID}:`, error);
|
||||
res.status(500).send("Failed to kick player");
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
async function fetchLobbies(): Promise<number> {
|
||||
const fetchPromises = [];
|
||||
|
||||
|
||||
@@ -250,6 +250,27 @@ export function startWorker() {
|
||||
}),
|
||||
);
|
||||
|
||||
app.post(
|
||||
"/api/kick_player/:gameID/:clientID",
|
||||
gatekeeper.httpHandler(LimiterType.Post, async (req, res) => {
|
||||
if (req.headers[config.adminHeader()] !== config.adminToken()) {
|
||||
res.status(401).send("Unauthorized");
|
||||
return;
|
||||
}
|
||||
|
||||
const { gameID, clientID } = req.params;
|
||||
|
||||
const game = gm.game(gameID);
|
||||
if (!game) {
|
||||
res.status(404).send("Game not found");
|
||||
return;
|
||||
}
|
||||
|
||||
game.kickClient(clientID);
|
||||
res.status(200).send("Player kicked successfully");
|
||||
}),
|
||||
);
|
||||
|
||||
// WebSocket handling
|
||||
wss.on("connection", (ws: WebSocket, req) => {
|
||||
ws.on(
|
||||
|
||||
@@ -228,6 +228,7 @@ export default async (env, argv) => {
|
||||
"/api/archive_singleplayer_game",
|
||||
"/api/auth/callback",
|
||||
"/api/auth/discord",
|
||||
"/api/kick_player",
|
||||
],
|
||||
target: "http://localhost:3000",
|
||||
secure: false,
|
||||
|
||||
Reference in New Issue
Block a user