Add host cheats for streamers (Specifically Enzo) (#3671)

## Description:

- Adds a "Host Cheats" toggle in the private lobby options section that
reveals a dedicated section with four host-only cheats: infinite gold,
infinite troops, gold multiplier, and starting gold
- Only the lobby creator receives the cheat effects in-game (checked via
`isLobbyCreator` in DefaultConfig)
- Joining players see active host cheats displayed as yellow badges in
the lobby UI
- Adds `hostCheats` optional object to `GameConfigSchema` and wires it
through the server config update whitelist
- Raises the intent size limit for `update_game_config` messages
(lobby-only, not stored in turn history) to prevent rate-limiter kicks
(I always got too-much-data-kicked after selecting "host cheats" lol)

<img width="861" height="525" alt="image"
src="https://github.com/user-attachments/assets/51e51ec4-c2e8-46ca-b258-11a93487964f"
/>


<img width="933" height="825" alt="image"
src="https://github.com/user-attachments/assets/5acbd38d-2097-42e1-ba78-0fb17d6afe82"
/>

## 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
This commit is contained in:
FloPinguin
2026-04-16 00:20:08 +02:00
committed by GitHub
parent f32994fbc7
commit 9821e8e041
13 changed files with 388 additions and 30 deletions
+59 -1
View File
@@ -636,7 +636,7 @@ export class JoinLobbyModal extends BaseModal {
${cards}
</div>`
: html``}
${this.renderDisabledUnits()}
${this.renderDisabledUnits()} ${this.renderHostCheats()}
`;
}
@@ -691,6 +691,64 @@ export class JoinLobbyModal extends BaseModal {
`;
}
private renderHostCheats(): TemplateResult {
if (!this.gameConfig?.hostCheats) {
return html``;
}
const hc = this.gameConfig.hostCheats;
const items: TemplateResult[] = [];
if (hc.infiniteGold)
items.push(
html`<span
class="px-2 py-1 bg-yellow-500/20 text-yellow-200 text-xs rounded font-bold border border-yellow-500/30"
>
${translateText("host_modal.infinite_gold")}
</span>`,
);
if (hc.infiniteTroops)
items.push(
html`<span
class="px-2 py-1 bg-yellow-500/20 text-yellow-200 text-xs rounded font-bold border border-yellow-500/30"
>
${translateText("host_modal.infinite_troops")}
</span>`,
);
if (hc.goldMultiplier)
items.push(
html`<span
class="px-2 py-1 bg-yellow-500/20 text-yellow-200 text-xs rounded font-bold border border-yellow-500/30"
>
${translateText("host_modal.gold_multiplier")}: x${hc.goldMultiplier}
</span>`,
);
if (hc.startingGold)
items.push(
html`<span
class="px-2 py-1 bg-yellow-500/20 text-yellow-200 text-xs rounded font-bold border border-yellow-500/30"
>
${translateText("private_lobby.starting_gold")}:
${parseFloat((hc.startingGold / 1_000_000).toPrecision(12))}M
</span>`,
);
if (items.length === 0) return html``;
return html`
<div
class="mt-4 mb-6 p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-lg"
>
<div
class="text-xs font-bold text-yellow-400 uppercase tracking-widest mb-2"
>
${translateText("private_lobby.host_cheats")}
</div>
<div class="flex flex-wrap gap-2">${items}</div>
</div>
`;
}
// --- Lobby event handling ---
private updateFromLobby(lobby: GameInfo | PublicGameInfo) {