0ad/binaries/data/mods/public/gui/session/message_box/QuitConfirmationDefeat.js
Vantha 2520c45220 Only call Engine.EndGame right before closing
Since #7786, the GUI tick completed normally after calling
`closePageCallback` instead of being cancelled like previously. Since
`Engine.EndGame` deletes the internal `g_Game` pointer, every Engine call
after it that tried to access `g_Game` caused a segfault.
This patch solves it by moving `Engine.EndGame` to the very end, right
before closing the session page.
In order to follow the convention that only functions directly closing
the page are called `closePageCallback`, that function is in turn
renamed to `closeSession`. Additionally, this allows only resolving
the promise with a bool (`showSummary`) and then only calling
`getNextPageOpenRequest` at the end of `init` for reasons of simplicity.
2026-07-22 23:51:49 +02:00

57 lines
1.7 KiB
JavaScript

/**
* This class will spawn a dialog asking to exit the game in case the user was an assigned player who has been defeated.
*/
class QuitConfirmationDefeat extends QuitConfirmation
{
constructor(closeSession)
{
super();
if (Engine.IsAtlasRunning())
return;
this.confirmHandler = undefined;
registerPlayersFinishedHandler(this.onPlayersFinished.bind(this, closeSession));
}
onPlayersFinished(closeSession, players, won)
{
if (players.indexOf(Engine.GetPlayerID()) == -1)
return;
// Defer simulation result until
// 1. the loading screen finished for all networked clients (g_IsNetworkedActive)
// 2. all messages modifying g_Players victory state were processed (next turn)
this.confirmHandler = this.confirmExit.bind(this, won, closeSession);
registerSimulationUpdateHandler(this.confirmHandler);
}
confirmExit(won, closeSession)
{
if (g_IsNetworked && !g_IsNetworkedActive)
return;
unregisterSimulationUpdateHandler(this.confirmHandler);
// Don't invite the host to exit if other humans are still playing.
const askExit = !Engine.HasNetServer() || g_Players.every((player, i) =>
i == 0 ||
player.state != "active" ||
g_InitAttributes.settings.PlayerData[i].AI != "");
this.Title = won ? this.TitleVictory : this.TitleDefeated;
this.Caption =
g_PlayerStateMessages[won ? "won" : "defeated"] +
(askExit ? "\n" + this.Question : "");
this.Buttons = askExit ? super.Buttons : undefined;
this.display(closeSession);
}
}
QuitConfirmationDefeat.prototype.TitleVictory = translate("VICTORIOUS!");
QuitConfirmationDefeat.prototype.TitleDefeated = translate("DEFEATED!");
QuitConfirmationDefeat.prototype.Question = translate("Do you want to quit?");