Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions backend/src/main/java/server/SecretHitlerServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,14 @@ private static void onWebSocketMessage(WsMessageContext ctx) {
String iconId = message.getString(PARAM_ICON);
lobby.trySetUserIcon(iconId, ctx);
break;

case COMMAND_SET_LOBBY_SIZE:
// Ensure the game hasn't started yet
if (!lobby.isInGame()) {
int newSize = message.getInt("size");
lobby.setMinLobbySize(newSize);
}
break;

default: // This is an invalid command.
throw new RuntimeException("unrecognized command " + message.get(PARAM_COMMAND));
Expand Down
14 changes: 11 additions & 3 deletions backend/src/main/java/server/util/Lobby.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public class Lobby implements Serializable {

static String DEFAULT_ICON = "p_default";

private int minLobbySize = SecretHitlerGame.MIN_PLAYERS;
synchronized public void setMinLobbySize(int size) {
if (size >= SecretHitlerGame.MIN_PLAYERS && size <= SecretHitlerGame.MAX_PLAYERS) {
this.minLobbySize = size;
}
}

/**
* Constructs a new Lobby.
*/
Expand Down Expand Up @@ -392,6 +399,7 @@ synchronized public void updateUser(WsContext ctx, String userName) {
message = new JSONObject();
message.put(SecretHitlerServer.PARAM_PACKET_TYPE, SecretHitlerServer.PACKET_LOBBY);
message.put("usernames", activeUsernames.toArray());
message.put("minLobbySize", minLobbySize);
}
// Add user icons to the update message
JSONObject icons = new JSONObject(usernameToIcon);
Expand Down Expand Up @@ -494,11 +502,11 @@ synchronized public void startNewGame() {
usersInGame.clear();
usersInGame.addAll(userToUsername.values());

// Generate CpuPlayers if the lobby size has not been met
// Generate CpuPlayers if the target lobby size has not been met
List<String> cpuNames = new ArrayList<>();
cpuPlayers.clear();
if (usersInGame.size() < SecretHitlerGame.MIN_PLAYERS) {
int numCpuPlayersToGenerate = SecretHitlerGame.MIN_PLAYERS - usersInGame.size();
if (usersInGame.size() < minLobbySize) {
int numCpuPlayersToGenerate = minLobbySize - usersInGame.size();
int i = 1;
while (numCpuPlayersToGenerate > 0) {
String botName = "Bot " + i;
Expand Down
39 changes: 38 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ type AppState = {
lobbyFromURL: boolean;
usernames: string[];
icons: { [key: string]: string };
minLobbySize: number;
gameState: GameState;
/* Stores the last gameState[PARAM_STATE] value to check for changes. */
lastState: any;
Expand Down Expand Up @@ -177,6 +178,7 @@ const defaultAppState: AppState = {
lobbyFromURL: false,
usernames: [],
icons: {},
minLobbySize: 5,
gameState: DEFAULT_GAME_STATE,
lastState: {},
liberalPolicies: 0,
Expand Down Expand Up @@ -429,6 +431,7 @@ class App extends Component<{}, AppState> {
usernames: message[PARAM_USERNAMES],
icons: message[PARAM_ICON],
page: PAGE.LOBBY,
minLobbySize: message["minLobbySize"] || 5,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please make minLobbySize into a constant?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've extracted the string key into a PARAM_MIN_LOBBY_SIZE constant on both the constants/index.ts and the SecretHitlerServer.java.

});
if (message[PARAM_ICON][this.state.name] === defaultPortrait) {
this.showChangeIconAlert();
Expand Down Expand Up @@ -918,7 +921,7 @@ class App extends Component<{}, AppState> {
<div id={"lobby-player-area-container"}>
<div id={"lobby-player-text-choose-container"}>
<p id={"lobby-player-count-text"}>
Players ({this.state.usernames.length}/10)
Players ({this.state.usernames.length}/{this.state.minLobbySize})
</p>
<button
id={"lobby-change-icon-button"}
Expand All @@ -927,6 +930,40 @@ class App extends Component<{}, AppState> {
CHANGE ICON
</button>
Comment on lines 927 to 932
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

It looks like this button got taller because of the added player configuration controls. Could you try reorganizing where the player select dropdown is in the DOM to prevent that? (This is also likely my fault due to some outdated button styling rules, sorry!)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the new controls completely out of the top flex container, so the 'Change Icon' button is back to its normal size.

</div>

<div style={{ marginBottom: "15px", display: "flex", flexDirection: "column", alignItems: "flex-start" }}>
{isVIP ? (
<>
<label style={{ color: "white", display: "flex", alignItems: "center", cursor: "pointer" }}>
<span style={{ marginRight: "10px" }}>Game Size:</span>
<select
value={this.state.minLobbySize}
onChange={(e) => this.sendWSCommand({
command: WSCommandType.SET_LOBBY_SIZE,
size: parseInt(e.target.value)
})}
style={{ padding: "5px", borderRadius: "4px", backgroundColor: "#333", color: "white", border: "1px solid #555", cursor: "pointer" }}
>
{[5, 6, 7, 8, 9, 10].map(n => (
<option key={n} value={n}>
{n === 10 ? "10 Players" : `${n}+ Players`}
</option>
))}
</select>
</label>
<span style={{ color: "#aaaaaa", fontSize: "0.8em", marginTop: "4px" }}>
(Empty spots will be filled by bots)
</span>
</>
) : (
<p style={{ color: "gray", fontSize: "0.9em", margin: 0 }}>
Game Size: {this.state.minLobbySize === 10 ? "10 Players" : `${this.state.minLobbySize}+ Players`}
<br/>
<span style={{ fontSize: "0.9em" }}>(Empty spots will be filled by bots)</span>
</p>
)}
</div>

<div id={"lobby-player-container"}>{this.renderPlayerList()}</div>
</div>

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/types/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const enum WSCommandType {
PING = "ping",
START_GAME = "start-game",
GET_STATE = "get-state",
SET_LOBBY_SIZE = "set-lobby-size",
REGISTER_CHANCELLOR_VETO = "chancellor-veto",
REGISTER_PRESIDENT_VETO = "president-veto",
REGISTER_PEEK = "register-peek",
Expand All @@ -25,6 +26,7 @@ export const enum WSCommandType {
export type ServerRequestPayload =
| { command: WSCommandType.PING }
| { command: WSCommandType.START_GAME }
| { command: WSCommandType.SET_LOBBY_SIZE; size: number }
| { command: WSCommandType.GET_STATE }
| { command: WSCommandType.REGISTER_CHANCELLOR_VETO }
| { command: WSCommandType.REGISTER_PRESIDENT_VETO; veto: boolean }
Expand Down