mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:30:45 +00:00
Fix deselected host lobby settings persisting for joiners 🐛 (#3607)
## Description: ### Problem When a host toggled off certain settings (game length, PVP immunity, starting gold, gold multiplier, disable alliances) in the host lobby modal, joiners still saw the old values. The settings appeared "stuck" once enabled. ### Root Cause `putGameConfig()` sent `undefined` for disabled settings, but `JSON.stringify` strips `undefined` properties entirely. The server's `!== undefined` guard never fired, so the old value was never cleared. ### Fix - **HostLobbyModal**: Send `null` instead of `undefined` when these settings are toggled off (`null` survives JSON serialization) - **Schemas**: Add `.nullable()` to the five affected fields (`maxTimerValue`, `spawnImmunityDuration`, `goldMultiplier`, `startingGold`, `disableAlliances`) - **GameServer**: Use `?? undefined` (nullish coalescing) to convert incoming `null` back to `undefined` when storing on the config Other settings are unaffected. Booleans like `infiniteGold` always send `true`/`false`, and fields like `bots`/`gameMap` always have a concrete value.. ## 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: FloPinguin --------- Co-authored-by: Evan <evanpelle@gmail.com>
This commit is contained in:
@@ -789,23 +789,20 @@ export class HostLobbyModal extends BaseModal {
|
||||
disabledUnits: this.disabledUnits,
|
||||
spawnImmunityDuration: this.spawnImmunity
|
||||
? spawnImmunityTicks
|
||||
: undefined,
|
||||
: null,
|
||||
playerTeams: this.teamCount,
|
||||
nations: sliderToNationsConfig(
|
||||
this.nations,
|
||||
this.defaultNationCount,
|
||||
),
|
||||
maxTimerValue:
|
||||
this.maxTimer === true ? this.maxTimerValue : undefined,
|
||||
maxTimerValue: this.maxTimer === true ? this.maxTimerValue : null,
|
||||
goldMultiplier:
|
||||
this.goldMultiplier === true
|
||||
? this.goldMultiplierValue
|
||||
: undefined,
|
||||
this.goldMultiplier === true ? this.goldMultiplierValue : null,
|
||||
startingGold:
|
||||
this.startingGold === true && this.startingGoldValue !== undefined
|
||||
? Math.round(this.startingGoldValue * 1_000_000)
|
||||
: undefined,
|
||||
disableAlliances: this.disableAlliances || undefined,
|
||||
: null,
|
||||
disableAlliances: this.disableAlliances || null,
|
||||
} satisfies Partial<GameConfig>,
|
||||
},
|
||||
bubbles: true,
|
||||
|
||||
@@ -99,7 +99,10 @@ export class GameRightSidebar extends LitElement implements Layer {
|
||||
const elapsedSeconds = Math.floor(gameTicks / 10); // 10 ticks per second
|
||||
|
||||
if (this.game.inSpawnPhase()) {
|
||||
this.timer = maxTimerValue !== undefined ? maxTimerValue * 60 : 0;
|
||||
this.timer =
|
||||
maxTimerValue !== null && maxTimerValue !== undefined
|
||||
? maxTimerValue * 60
|
||||
: 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,7 +110,7 @@ export class GameRightSidebar extends LitElement implements Layer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxTimerValue !== undefined) {
|
||||
if (maxTimerValue !== null && maxTimerValue !== undefined) {
|
||||
this.timer = Math.max(0, maxTimerValue * 60 - elapsedSeconds);
|
||||
} else {
|
||||
this.timer = elapsedSeconds;
|
||||
@@ -179,6 +182,7 @@ export class GameRightSidebar extends LitElement implements Layer {
|
||||
|
||||
const timerColor =
|
||||
this.game.config().gameConfig().maxTimerValue !== undefined &&
|
||||
this.game.config().gameConfig().maxTimerValue !== null &&
|
||||
this.timer < 60
|
||||
? "text-red-400"
|
||||
: "";
|
||||
|
||||
+5
-5
@@ -247,15 +247,15 @@ export const GameConfigSchema = z.object({
|
||||
infiniteTroops: z.boolean(),
|
||||
instantBuild: z.boolean(),
|
||||
disableNavMesh: z.boolean().optional(),
|
||||
disableAlliances: z.boolean().optional(),
|
||||
disableAlliances: z.boolean().nullable().optional(),
|
||||
randomSpawn: z.boolean(),
|
||||
maxPlayers: z.number().optional(),
|
||||
maxTimerValue: z.number().int().min(1).max(120).optional(), // In minutes
|
||||
spawnImmunityDuration: z.number().int().min(0).optional(), // In ticks
|
||||
maxTimerValue: z.number().int().min(1).max(120).nullable().optional(), // In minutes
|
||||
spawnImmunityDuration: z.number().int().min(0).nullable().optional(), // In ticks
|
||||
disabledUnits: z.enum(UnitType).array().optional(),
|
||||
playerTeams: TeamCountConfigSchema.optional(),
|
||||
goldMultiplier: z.number().min(0.1).max(1000).optional(),
|
||||
startingGold: z.number().int().min(0).max(1000000000).optional(),
|
||||
goldMultiplier: z.number().min(0.1).max(1000).nullable().optional(),
|
||||
startingGold: z.number().int().min(0).max(1000000000).nullable().optional(),
|
||||
});
|
||||
|
||||
export const TeamSchema = z.string();
|
||||
|
||||
@@ -141,7 +141,7 @@ export class GameServer {
|
||||
this.gameConfig.donateTroops = gameConfig.donateTroops;
|
||||
}
|
||||
if (gameConfig.maxTimerValue !== undefined) {
|
||||
this.gameConfig.maxTimerValue = gameConfig.maxTimerValue;
|
||||
this.gameConfig.maxTimerValue = gameConfig.maxTimerValue ?? undefined;
|
||||
}
|
||||
if (gameConfig.instantBuild !== undefined) {
|
||||
this.gameConfig.instantBuild = gameConfig.instantBuild;
|
||||
@@ -150,7 +150,8 @@ export class GameServer {
|
||||
this.gameConfig.randomSpawn = gameConfig.randomSpawn;
|
||||
}
|
||||
if (gameConfig.spawnImmunityDuration !== undefined) {
|
||||
this.gameConfig.spawnImmunityDuration = gameConfig.spawnImmunityDuration;
|
||||
this.gameConfig.spawnImmunityDuration =
|
||||
gameConfig.spawnImmunityDuration ?? undefined;
|
||||
}
|
||||
if (gameConfig.gameMode !== undefined) {
|
||||
this.gameConfig.gameMode = gameConfig.gameMode;
|
||||
@@ -162,13 +163,14 @@ export class GameServer {
|
||||
this.gameConfig.playerTeams = gameConfig.playerTeams;
|
||||
}
|
||||
if (gameConfig.goldMultiplier !== undefined) {
|
||||
this.gameConfig.goldMultiplier = gameConfig.goldMultiplier;
|
||||
this.gameConfig.goldMultiplier = gameConfig.goldMultiplier ?? undefined;
|
||||
}
|
||||
if (gameConfig.startingGold !== undefined) {
|
||||
this.gameConfig.startingGold = gameConfig.startingGold;
|
||||
this.gameConfig.startingGold = gameConfig.startingGold ?? undefined;
|
||||
}
|
||||
if (gameConfig.disableAlliances !== undefined) {
|
||||
this.gameConfig.disableAlliances = gameConfig.disableAlliances;
|
||||
this.gameConfig.disableAlliances =
|
||||
gameConfig.disableAlliances ?? undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user