1
0
forked from mirrors/0ad

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;
}