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:
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user