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

<img width="1291" height="871" alt="Screenshot 2025-07-15 002114"
src="https://github.com/user-attachments/assets/ea575f83-a0f4-45d1-9cfe-7521d373f3d5"
/>



### 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 <floriankilian@users.noreply.github.com>
This commit is contained in:
floriankilian
2025-08-01 07:01:10 +02:00
committed by GitHub
parent ee459b7410
commit bd59cd61cb
10 changed files with 211 additions and 54 deletions
+25 -14
View File
@@ -28,20 +28,31 @@ export class GameManager {
return false;
}
createGame(id: GameID, gameConfig: GameConfig | undefined) {
const game = new GameServer(id, this.log, Date.now(), this.config, {
gameMap: GameMapType.World,
gameType: GameType.Private,
difficulty: Difficulty.Medium,
disableNPCs: false,
infiniteGold: false,
infiniteTroops: false,
instantBuild: false,
gameMode: GameMode.FFA,
bots: 400,
disabledUnits: [],
...gameConfig,
});
createGame(
id: GameID,
gameConfig: GameConfig | undefined,
creatorClientID?: string,
) {
const game = new GameServer(
id,
this.log,
Date.now(),
this.config,
{
gameMap: GameMapType.World,
gameType: GameType.Private,
difficulty: Difficulty.Medium,
disableNPCs: false,
infiniteGold: false,
infiniteTroops: false,
instantBuild: false,
gameMode: GameMode.FFA,
bots: 400,
disabledUnits: [],
...gameConfig,
},
creatorClientID,
);
this.games.set(id, game);
return game;
}