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