Deepfreeze Aura, Technology and Resource Templates, Simulation states, GameAttributes and few other JS objects.

This reveals unintentional modifications to these objects which would
most often imply hidden bugs.

Differential Revision: https://code.wildfiregames.com/D829
Fixes #4257
Refs #3647

This was SVN commit r20100.
This commit is contained in:
elexis
2017-09-03 16:37:09 +00:00
parent 1b47451d32
commit 9cb0a60d73
9 changed files with 43 additions and 26 deletions
@@ -60,6 +60,11 @@ function Resources()
this.resourceData.find(resource => resource.code == a),
this.resourceData.find(resource => resource.code == b)
));
deepfreeze(this.resourceData);
deepfreeze(this.resourceDataObj);
deepfreeze(this.resourceCodes);
deepfreeze(this.resourceNames);
}
/**
@@ -30,5 +30,5 @@ function loadCivData(selectableOnly, gaia)
if (gaia)
civData.gaia = { "Code": "gaia", "Name": translate("Gaia") };
return civData;
return deepfreeze(civData);
}
@@ -51,10 +51,10 @@ function getMapDescriptionAndPreview(mapType, mapName)
else if (Engine.FileExists(mapName + ".xml"))
mapData = Engine.LoadMapSettings(mapName + ".xml");
return {
return deepfreeze({
"description": mapData && mapData.settings && mapData.settings.Description ? translate(mapData.settings.Description) : translate("Sorry, no description available."),
"preview": mapData && mapData.settings && mapData.settings.Preview ? mapData.settings.Preview : "nopreview.png"
};
});
}
/**
@@ -45,7 +45,7 @@ function loadSettingsValues()
if (Object.keys(settings).some(key => settings[key] === undefined))
return undefined;
return settings;
return deepfreeze(settings);
}
/**
@@ -307,7 +307,7 @@ function prepareForDropdown(settingValues)
if (settingValues[index].Default)
settings.Default = +index;
}
return settings;
return deepfreeze(settings);
}
/**
@@ -972,8 +972,7 @@ function init(attribs)
function initDefaults()
{
// Remove gaia from both arrays
g_DefaultPlayerData = g_Settings.PlayerDefaults;
g_DefaultPlayerData.shift();
g_DefaultPlayerData = clone(g_Settings.PlayerDefaults.slice(1));
// Don't change the underlying defaults file, as Atlas uses that file too
for (let i in g_DefaultPlayerData)
@@ -981,6 +980,8 @@ function initDefaults()
g_DefaultPlayerData[i].Civ = "random";
g_DefaultPlayerData[i].Team = -1;
}
g_DefaultPlayerData = deepfreeze(g_DefaultPlayerData);
}
/**
@@ -1,6 +1,5 @@
/**
* All known cheat commands.
* @type {Object}
*/
const g_Cheats = getCheatsData();
@@ -455,8 +454,6 @@ var g_NotificationsTypes =
/**
* Loads all known cheat commands.
*
* @returns {Object}
*/
function getCheatsData()
{
@@ -471,7 +468,7 @@ function getCheatsData()
else
cheats[currentCheat.Name] = currentCheat.Data;
}
return cheats;
return deepfreeze(cheats);
}
/**
@@ -30,7 +30,7 @@ var g_Ambient = ["audio/ambient/dayscape/day_temperate_gen_03.ogg"];
/**
* Map, player and match settings set in gamesetup.
*/
const g_GameAttributes = Object.freeze(Engine.GetInitAttributes());
const g_GameAttributes = deepfreeze(Engine.GetInitAttributes());
/**
* Is this user in control of game settings (i.e. is a network server, or offline player).
@@ -191,7 +191,7 @@ var g_HasIdleWorker = false;
function GetSimState()
{
if (!g_SimState)
g_SimState = Engine.GuiInterfaceCall("GetSimulationState");
g_SimState = deepfreeze(Engine.GuiInterfaceCall("GetSimulationState"));
return g_SimState;
}
@@ -199,23 +199,32 @@ function GetSimState()
function GetEntityState(entId)
{
if (!g_EntityStates[entId])
{
g_EntityStates[entId] = Engine.GuiInterfaceCall("GetEntityState", entId);
// Freeze all existing properties, but allow GetExtendedEntityState to extend the object
if (g_EntityStates[entId])
for (let name of Object.getOwnPropertyNames(g_EntityStates[entId]))
if (typeof prop == 'object' && prop !== null)
deepfreeze(g_EntityStates[entId][name])
}
return g_EntityStates[entId];
}
function GetExtendedEntityState(entId)
{
let entState = GetEntityState(entId);
if (!entState || entState.extended)
return entState;
if (entState && !entState.extended)
{
let extension = Engine.GuiInterfaceCall("GetExtendedEntityState", entId);
for (let prop in extension)
entState[prop] = extension[prop];
entState.extended = true;
g_EntityStates[entId] = deepfreeze(entState);
}
let extension = Engine.GuiInterfaceCall("GetExtendedEntityState", entId);
for (let prop in extension)
entState[prop] = extension[prop];
entState.extended = true;
g_EntityStates[entId] = entState;
return entState;
return g_EntityStates[entId];
}
function GetTemplateData(templateName)
@@ -224,7 +233,7 @@ function GetTemplateData(templateName)
{
let template = Engine.GuiInterfaceCall("GetTemplateData", templateName);
translateObjectKeys(template, ["specific", "generic", "tooltip"]);
g_TemplateData[templateName] = template;
g_TemplateData[templateName] = deepfreeze(template);
}
return g_TemplateData[templateName];
@@ -239,7 +248,7 @@ function GetTechnologyData(technologyName, civ)
{
let template = Engine.GuiInterfaceCall("GetTechnologyData", { "name": technologyName, "civ": civ });
translateObjectKeys(template, ["specific", "generic", "description", "tooltip", "requirementsTooltip"]);
g_TechnologyData[civ][technologyName] = template;
g_TechnologyData[civ][technologyName] = deepfreeze(template);
}
return g_TechnologyData[civ][technologyName];
@@ -806,9 +815,9 @@ function onSimulationUpdate()
// g_TechnologyData data never changes, so it shouldn't be deleted.
g_EntityStates = {};
g_TemplateData = {};
g_SimState = undefined;
g_SimState = Engine.GuiInterfaceCall("GetSimulationState");
if (!g_SimState)
if (!GetSimState())
return;
updateCinemaPath();
@@ -16,6 +16,9 @@ DataTemplateManager.prototype.Init = function()
for (let auraName of this.ListAllAuras())
this.GetAuraTemplate(auraName);
deepfreeze(this.allTechs);
deepfreeze(this.allAuras);
};
DataTemplateManager.prototype.GetTechnologyTemplate = function(template)
+3 -1
View File
@@ -305,6 +305,8 @@ JS::Value SavedGames::GetEngineInfo(const ScriptInterface& scriptInterface)
scriptInterface.SetProperty(metainfo, "version_minor", SAVED_GAME_VERSION_MINOR);
scriptInterface.SetProperty(metainfo, "engine_version", std::string(engine_version));
scriptInterface.SetProperty(metainfo, "mods", g_modsLoaded);
scriptInterface.FreezeObject(metainfo, true);
return metainfo;
}