Add safeguards for all queryOwnerInterface calls

Comments By: Angen, wraitii
Reviewed By: Freagarach
Differential Revision: D2973
This was SVN commit r24050.
This commit is contained in:
bb 2020-09-19 17:55:34 +00:00
parent ff9a5fe8f9
commit 31df44673a
11 changed files with 67 additions and 30 deletions

View File

@ -211,7 +211,11 @@ Trigger.prototype.StartAnEnemyWave = function()
}
// Don't spawn attackers for defeated players and players that lost their cc after win
let playerID = QueryOwnerInterface(point, IID_Player).GetPlayerID();
let cmpPlayer = QueryOwnerInterface(point, IID_Player);
if (!cmpPlayer)
continue;
let playerID = cmpPlayer.GetPlayerID();
let civicCentre = this.playerCivicCenter[playerID];
if (!civicCentre)
continue;

View File

@ -38,7 +38,7 @@ Trigger.prototype.CheckCaptureTheRelicVictory = function(data)
if (data.to == -1)
{
warn("Relic entity " + data.entity + " has been destroyed");
warn("Relic entity " + data.entity + " has been destroyed.");
this.relics.splice(this.relics.indexOf(data.entity), 1);
}
else
@ -130,6 +130,14 @@ Trigger.prototype.StartCaptureTheRelicCountdown = function(winningPlayers)
}
let cmpPlayer = QueryOwnerInterface(this.relics[0], IID_Player);
if (!cmpPlayer)
{
warn("Relic entity " + this.relics[0] + " has no owner.");
this.relics.splice(0, 1);
this.CheckCaptureTheRelicCountdown();
return;
}
let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
let captureTheRelicDuration = cmpEndGameManager.GetGameSettings().relicDuration;

View File

@ -92,8 +92,11 @@ BuildRestrictions.prototype.CheckPlacement = function()
"translateParameters": ["name"],
};
// TODO: AI has no visibility info
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
if (!cmpPlayer)
return result; // Fail
// TODO: AI has no visibility info
if (!cmpPlayer.IsAI())
{
// Check whether it's in a visible or fogged region
@ -164,9 +167,8 @@ BuildRestrictions.prototype.CheckPlacement = function()
// Check territory restrictions
var cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager);
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
if (!(cmpTerritoryManager && cmpPlayer && cmpPosition && cmpPosition.IsInWorld()))
if (!cmpTerritoryManager || !cmpPosition || !cmpPosition.IsInWorld())
return result; // Fail
var pos = cmpPosition.GetPosition2D();
@ -239,7 +241,6 @@ BuildRestrictions.prototype.CheckPlacement = function()
if (this.template.Distance)
{
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
var cat = this.template.Distance.FromClass;
var filter = function(id)

View File

@ -34,6 +34,7 @@ Looter.prototype.Collect = function(targetEntity)
// Transfer resources
var cmpPlayer = QueryOwnerInterface(this.entity);
if (cmpPlayer)
cmpPlayer.AddResources(resources);
// Update statistics

View File

@ -303,6 +303,8 @@ ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech)
return false;
let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
if (!cmpTechnologyManager)
return false;
let template = TechnologyTemplates.Get(tech);
if (template.top)
@ -323,6 +325,8 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
// TODO: there should be a way for the GUI to determine whether it's going
// to be possible to add a batch (based on resource costs and length limits).
let cmpPlayer = QueryOwnerInterface(this.entity);
if (!cmpPlayer)
return;
if (this.queue.length < this.MaxQueueSize)
{
@ -376,6 +380,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
{
let unitCategory = template.TrainingRestrictions.Category;
let cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits);
if (cmpPlayerEntityLimits)
cmpPlayerEntityLimits.ChangeCount(unitCategory, count);
}
@ -718,13 +723,12 @@ ProductionQueue.prototype.SpawnUnits = function(templateName, count, metadata)
// since it will be increased by EntityLimits.OnGlobalOwnershipChanged function,
// i.e. we replace a 'trained' entity by 'alive' one.
// Must be done after spawn check so EntityLimits decrements only if unit spawns.
if (cmpPlayerEntityLimits)
{
let cmpTrainingRestrictions = Engine.QueryInterface(ent, IID_TrainingRestrictions);
if (cmpTrainingRestrictions)
{
let unitCategory = cmpTrainingRestrictions.GetCategory();
cmpPlayerEntityLimits.ChangeCount(unitCategory, -1);
cmpPlayerEntityLimits.ChangeCount(cmpTrainingRestrictions.GetCategory(), -1);
}
cmpNewOwnership.SetOwner(cmpOwnership.GetOwner());
if (cmpPlayerStatisticsTracker)
@ -773,11 +777,15 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
// Check if the production is paused (eg the entity is garrisoned)
if (this.paused)
return;
let cmpPlayer = QueryOwnerInterface(this.entity);
if (!cmpPlayer)
return;
// Allocate available time to as many queue items as it takes
// until we've used up all the time (so that we work accurately
// with items that take fractions of a second).
let time = this.ProgressInterval;
let cmpPlayer = QueryOwnerInterface(this.entity);
let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
while (time > 0 && this.queue.length)
@ -815,7 +823,11 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
{
// Mark the research as started.
let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
if (cmpTechnologyManager)
cmpTechnologyManager.StartedResearch(item.technologyTemplate, true);
else
warn("Failed to start researching " + item.technologyTemplate + ": No TechnologyManager available.");
this.SetAnimation("researching");
}
@ -877,13 +889,16 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
else if (item.technologyTemplate)
{
let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
if (cmpTechnologyManager)
cmpTechnologyManager.ResearchTechnology(item.technologyTemplate);
else
warn("Failed to stop researching " + item.technologyTemplate + ": No TechnologyManager available.");
this.SetAnimation("idle");
let template = TechnologyTemplates.Get(item.technologyTemplate);
if (template && template.soundComplete)
{
let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager);
if (cmpSoundManager)
cmpSoundManager.PlaySoundGroup(template.soundComplete, this.entity);
}

View File

@ -60,19 +60,23 @@ Promotion.prototype.IncreaseXp = function(amount)
return;
}
this.currentXp += +(amount);
var requiredXp = this.GetRequiredXp();
this.currentXp += +amount;
let requiredXp = this.GetRequiredXp();
if (this.currentXp >= requiredXp)
{
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var playerID = QueryOwnerInterface(this.entity, IID_Player).GetPlayerID();
let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
if (!cmpPlayer)
return;
let playerID = cmpPlayer.GetPlayerID();
this.currentXp -= requiredXp;
var promotedTemplateName = this.GetPromotedTemplateName();
let promotedTemplateName = this.GetPromotedTemplateName();
// check if we can upgrade a second time (or even more)
while (true)
{
var template = cmpTemplateManager.GetTemplate(promotedTemplateName);
let template = cmpTemplateManager.GetTemplate(promotedTemplateName);
if (!template.Promotion)
break;
requiredXp = ApplyValueModificationsToTemplate("Promotion/RequiredXp", +template.Promotion.RequiredXp, playerID, template);

View File

@ -358,7 +358,8 @@ ResourceGatherer.prototype.OnGlobalInitGame = function(msg)
ResourceGatherer.prototype.OnMultiplierChanged = function(msg)
{
if (msg.player == QueryOwnerInterface(this.entity, IID_Player).GetPlayerID())
let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
if (cmpPlayer && msg.player == cmpPlayer.GetPlayerID())
this.RecalculateGatherRatesAndCapacities();
};

View File

@ -29,6 +29,9 @@ SkirmishReplacer.prototype.OnOwnershipChanged = function(msg)
SkirmishReplacer.prototype.ReplaceEntities = function()
{
var cmpPlayer = QueryOwnerInterface(this.entity);
if (!cmpPlayer)
return;
var civ = cmpPlayer.GetCiv();
var replacementEntities = getReplacementEntities(civ);

View File

@ -81,7 +81,7 @@ Trader.prototype.RemoveTargetMarket = function(target)
this.index = -1;
this.markets = [];
return true;
}
};
// Set target as target market.
// Return true if at least one of markets was changed.
@ -184,7 +184,7 @@ Trader.prototype.CanTrade = function(target)
let cmpTraderPlayer = QueryOwnerInterface(this.entity, IID_Player);
let cmpTargetPlayer = QueryOwnerInterface(target, IID_Player);
return !cmpTraderPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID());
return cmpTraderPlayer && cmpTargetPlayer && !cmpTraderPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID());
};
Trader.prototype.AddResources = function(ent, gain)

View File

@ -230,7 +230,7 @@ Upgrade.prototype.Upgrade = function(template)
let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
this.expendedResources = this.GetResourceCosts(template);
if (!cmpPlayer.TrySubtractResources(this.expendedResources))
if (!cmpPlayer || !cmpPlayer.TrySubtractResources(this.expendedResources))
{
this.expendedResources = {};
return false;

View File

@ -296,7 +296,7 @@ var g_Commands = {
if (unitCategory)
{
var cmpPlayerEntityLimits = QueryOwnerInterface(ent, IID_EntityLimits);
if (!cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count))
if (cmpPlayerEntityLimits && !cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count))
{
if (g_DebugCommands)
warn(unitCategory + " train limit is reached: " + uneval(cmd));
@ -305,7 +305,7 @@ var g_Commands = {
}
var cmpTechnologyManager = QueryOwnerInterface(ent, IID_TechnologyManager);
if (!cmpTechnologyManager.CanProduce(cmd.template))
if (cmpTechnologyManager && !cmpTechnologyManager.CanProduce(cmd.template))
{
if (g_DebugCommands)
warn("Invalid command: training requires unresearched technology: " + uneval(cmd));
@ -348,7 +348,7 @@ var g_Commands = {
}
var cmpTechnologyManager = QueryOwnerInterface(cmd.entity, IID_TechnologyManager);
if (!cmpTechnologyManager.CanResearch(cmd.template))
if (cmpTechnologyManager && !cmpTechnologyManager.CanResearch(cmd.template))
{
if (g_DebugCommands)
warn("Invalid command: Requirements to research technology are not met: " + uneval(cmd));