mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 00:41:58 +00:00
feat: Kick player in game (#2969)
If this PR fixes an issue, link it below. If not, delete these two lines. Resolves #2686 ## Description: - Implemented feature for lobby creator to kick players in game. - Added new moderation option for lobby creator, with a kick player option if they aren't the creator, a bot, and exist in game. - Includes a confirm kick option, and keeps track of kicked players so that the kick option changes to "Already Kicked" if the kicked player panel is opened again on the kicked player. Screenshot order: 1) Open player panel 2) Click on moderation 3) Click on kick player and confirm kick 4) Player is kicked, open same player panel again and observe change in kick status 5) Receiving player kick message <img width="1470" height="776" alt="Screenshot 2026-01-20 at 12 33 55 PM" src="https://github.com/user-attachments/assets/7c47b5a2-a0f8-4e92-833c-7b9732f751a8" /> <img width="1470" height="776" alt="Screenshot 2026-01-20 at 11 58 58 AM" src="https://github.com/user-attachments/assets/3aa026af-9a42-4512-91b8-916f146849a6" /> <img width="1470" height="776" alt="Screenshot 2026-01-20 at 12 31 46 PM" src="https://github.com/user-attachments/assets/5e1d271b-bf32-4335-8eb1-bcdf84aba8ce" /> <img width="1470" height="776" alt="Screenshot 2026-01-20 at 11 57 58 AM" src="https://github.com/user-attachments/assets/7cbd5ea6-bcb6-4a35-a003-ea0add936925" /> <img width="1470" height="776" alt="Screenshot 2026-01-20 at 11 57 39 AM" src="https://github.com/user-attachments/assets/4309b3e3-2fe6-48dd-8e0c-55036e567461" /> ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: mitchfz
This commit is contained in:
@@ -31,6 +31,9 @@ export enum GamePhase {
|
||||
Finished = "FINISHED",
|
||||
}
|
||||
|
||||
const KICK_REASON_DUPLICATE_SESSION = "kick_reason.duplicate_session";
|
||||
const KICK_REASON_LOBBY_CREATOR = "kick_reason.lobby_creator";
|
||||
|
||||
export class GameServer {
|
||||
private sentDesyncMessageClients = new Set<ClientID>();
|
||||
|
||||
@@ -219,7 +222,7 @@ export class GameServer {
|
||||
});
|
||||
// Kick the existing client instead of the new one, because this was causing issues when
|
||||
// a client wanted to replay the game afterwards.
|
||||
this.kickClient(conflicting.clientID);
|
||||
this.kickClient(conflicting.clientID, KICK_REASON_DUPLICATE_SESSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +359,10 @@ export class GameServer {
|
||||
kickMethod: "websocket",
|
||||
});
|
||||
|
||||
this.kickClient(clientMsg.intent.target);
|
||||
this.kickClient(
|
||||
clientMsg.intent.target,
|
||||
KICK_REASON_LOBBY_CREATOR,
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "update_game_config": {
|
||||
@@ -776,33 +782,49 @@ export class GameServer {
|
||||
return this.gameConfig.gameType === GameType.Public;
|
||||
}
|
||||
|
||||
public kickClient(clientID: ClientID): void {
|
||||
public kickClient(
|
||||
clientID: ClientID,
|
||||
reasonKey: string = KICK_REASON_DUPLICATE_SESSION,
|
||||
): void {
|
||||
if (this.kickedClients.has(clientID)) {
|
||||
this.log.warn(`cannot kick client, already kicked`, {
|
||||
clientID,
|
||||
reasonKey,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.allClients.has(clientID)) {
|
||||
this.log.warn(`cannot kick client, not found in game`, {
|
||||
clientID,
|
||||
reasonKey,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.kickedClients.add(clientID);
|
||||
|
||||
const client = this.activeClients.find((c) => c.clientID === clientID);
|
||||
if (client) {
|
||||
this.log.info("Kicking client from game", {
|
||||
clientID: client.clientID,
|
||||
persistentID: client.persistentID,
|
||||
reasonKey,
|
||||
});
|
||||
client.ws.send(
|
||||
JSON.stringify({
|
||||
type: "error",
|
||||
error: "Kicked from game (you may have been playing on another tab)",
|
||||
error: reasonKey,
|
||||
} satisfies ServerErrorMessage),
|
||||
);
|
||||
client.ws.close(1000, "Kicked from game");
|
||||
client.ws.close(1000, reasonKey);
|
||||
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,
|
||||
reasonKey,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user