1
0
forked from mirrors/0ad

Wrap game settings initialisation from persistent data in a try-catch block.

Summary:
The persistent settings have historically often led to bugs (see A26,
but that's far from the only example).
The trouble is that this usually leads to the game setup being
completely unusable, often requiring clearing the MatchSettings.json
file (or de-activating it in the settings if one knows that is there).
Furthermore, mods can make the persistentSettings take 'bad' values, and
in general this behaviour is prone to unexpected breakage and difficult
to defend against.

This wraps it in a try-catch block to ensure the game remains usable. It
still relays the error with a more useful error message.

Differential Revision: https://code.wildfiregames.com/D4794
This was SVN commit r27314.
This commit is contained in:
wraitii
2022-12-29 10:44:22 +00:00
parent c0e888e2af
commit a38744fba4
@@ -77,17 +77,29 @@ class GameSettingsController
onLoad(initData, hotloadData)
{
if (hotloadData)
this.parseSettings(hotloadData.initAttributes);
else if (g_IsController && (initData?.gameSettings || this.persistentMatchSettings.enabled))
{
// Allow opting-in to persistence when sending initial data (though default off)
if (initData?.gameSettings)
this.persistentMatchSettings.enabled = !!initData.gameSettings?.usePersistence;
const settings = initData?.gameSettings || this.persistentMatchSettings.loadFile();
if (settings)
this.parseSettings(settings);
// This initial settings parsing in wrapped in a try-catch because it can fail unexpectedly,
// and particularly could fail with mods that change persistent settings, so this is
// difficult to fully fix from the gameSettings code.
// Also include hotloaded data because that can also fail and having to restart isn't very useful.
try {
if (hotloadData)
this.parseSettings(hotloadData.initAttributes);
else if (g_IsController && (initData?.gameSettings || this.persistentMatchSettings.enabled))
{
// Allow opting-in to persistence when sending initial data (though default off)
if (initData?.gameSettings)
this.persistentMatchSettings.enabled = !!initData.gameSettings?.usePersistence;
const settings = initData?.gameSettings || this.persistentMatchSettings.loadFile();
if (settings)
this.parseSettings(settings);
}
} catch(err) {
error("There was an error loading game settings. You may need to disable persistent match settings.");
warn(err?.toString() ?? uneval(err));
if (err.stack)
warn(err.stack)
}
// If the new settings led to AI & players conflict, remove the AI.
for (const guid in g_PlayerAssignments)
if (g_PlayerAssignments[guid].player !== -1 &&