From bd59cd61cbb67a9f8205af70f354a3734b1f2a7b Mon Sep 17 00:00:00 2001 From: floriankilian <34104015+floriankilian@users.noreply.github.com> Date: Fri, 1 Aug 2025 07:01:10 +0200 Subject: [PATCH] Private Lobbies: Add kick player functionality (#1436) ## Description: Added player management features so lobby hosts can kick players from private games. This includes both UI changes and backend work. ### What's new: - Hosts can now kick players from private lobbies with a simple button - Added host badges and remove buttons to the UI - Made sure only hosts can kick people, and hosts can't kick themselves ### How it works: - When someone creates a private game, they automatically become the host - Kicking happens through WebSocket "kick-player" events - Server checks that you're actually the host before letting you kick anyone Screenshot 2025-07-15 002114 ### Known Issues: - Kicked player gets general message (same when kicked for multi tab) ### Other Issues: - Host abandoment still existent (host clicks on x; or is closing tab) ## 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 - [x] I have read and accepted the CLA agreement (only required once). ## Please put your Discord username so you can be contacted if a bug or regression is found: [UN]nvm --------- Co-authored-by: floriankilian --- resources/lang/en.json | 3 +- src/client/ClientGameRunner.ts | 3 +- src/client/HostLobbyModal.ts | 67 ++++++++++++++++++++++++++-------- src/client/Main.ts | 14 +++++++ src/client/Transport.ts | 15 ++++++++ src/client/styles.css | 49 ++++++++++++++++--------- src/core/Schemas.ts | 11 +++++- src/server/GameManager.ts | 39 +++++++++++++------- src/server/GameServer.ts | 51 +++++++++++++++++++++++++- src/server/Worker.ts | 13 ++++++- 10 files changed, 211 insertions(+), 54 deletions(-) diff --git a/resources/lang/en.json b/resources/lang/en.json index 51157c2e7..7395d4e66 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -215,7 +215,8 @@ "player": "Player", "players": "Players", "waiting": "Waiting for players...", - "start": "Start Game" + "start": "Start Game", + "host_badge": "Host" }, "team_colors": { "red": "Red", diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index 9904822c4..b0c3150d8 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -60,12 +60,11 @@ export interface LobbyConfig { } export function joinLobby( + eventBus: EventBus, lobbyConfig: LobbyConfig, onPrestart: () => void, onJoin: () => void, ): () => void { - const eventBus = new EventBus(); - console.log( `joining lobby: gameID: ${lobbyConfig.gameID}, clientID: ${lobbyConfig.clientID}`, ); diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index 0296c29dc..5362311b8 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -14,7 +14,12 @@ import { mapCategories, } from "../core/game/Game"; import { UserSettings } from "../core/game/UserSettings"; -import { GameConfig, GameInfo, TeamCountConfig } from "../core/Schemas"; +import { + ClientInfo, + GameConfig, + GameInfo, + TeamCountConfig, +} from "../core/Schemas"; import { generateID } from "../core/Util"; import "./components/baseComponents/Modal"; import "./components/Difficulties"; @@ -40,9 +45,10 @@ export class HostLobbyModal extends LitElement { @state() private instantBuild: boolean = false; @state() private lobbyId = ""; @state() private copySuccess = false; - @state() private players: string[] = []; + @state() private clients: ClientInfo[] = []; @state() private useRandomMap: boolean = false; @state() private disabledUnits: UnitType[] = [UnitType.Factory]; + @state() private lobbyCreatorClientID: string = ""; @state() private lobbyIdVisible: boolean = true; private playersInterval: NodeJS.Timeout | null = null; @@ -395,29 +401,45 @@ export class HostLobbyModal extends LitElement {
- ${this.players.length} + ${this.clients.length} ${ - this.players.length === 1 + this.clients.length === 1 ? translateText("host_modal.player") : translateText("host_modal.players") }
- ${this.players.map( - (player) => html`${player}`, + ${this.clients.map( + (client) => html` + + ${client.username} + ${client.clientID === this.lobbyCreatorClientID + ? html`(${translateText("host_modal.host_badge")})` + : html` + + `} + + `, )} -