validate coords in construction execution (#1339)

## Description:

Passing in invalidate coordinates in a BuildIntent can cause
ExecutionManager to throw an exception because the coords are not
validated.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
evanpelle
2025-07-03 20:02:39 -07:00
committed by GitHub
parent 29170321e4
commit 7a3a3a59e8
4 changed files with 20 additions and 7 deletions
+15 -1
View File
@@ -1,4 +1,5 @@
import {
Cell,
Execution,
Game,
Gold,
@@ -26,15 +27,28 @@ export class ConstructionExecution implements Execution {
private ticksUntilComplete: Tick;
private cost: Gold;
private tile: TileRef;
constructor(
private player: Player,
private tile: TileRef,
private constructionType: UnitType,
private tileOrCell: TileRef | Cell,
) {}
init(mg: Game, ticks: number): void {
this.mg = mg;
if (this.tileOrCell instanceof Cell) {
if (!this.mg.isValidCoord(this.tileOrCell.x, this.tileOrCell.y)) {
console.warn(
`cannot build construction invalid coordinates ${this.tileOrCell.x}, ${this.tileOrCell.y}`,
);
this.active = false;
return;
}
this.tile = this.mg.ref(this.tileOrCell.x, this.tileOrCell.y);
} else {
this.tile = this.tileOrCell;
}
}
tick(ticks: number): void {
+2 -3
View File
@@ -1,4 +1,4 @@
import { Execution, Game } from "../game/Game";
import { Cell, Execution, Game } from "../game/Game";
import { PseudoRandom } from "../PseudoRandom";
import { ClientID, GameID, Intent, Turn } from "../Schemas";
import { simpleHash } from "../Util";
@@ -107,11 +107,10 @@ export class Executor {
case "embargo":
return new EmbargoExecution(player, intent.targetID, intent.action);
case "build_unit":
// TODO: fix this
return new ConstructionExecution(
player,
this.mg.ref(intent.x, intent.y),
intent.unit,
new Cell(intent.x, intent.y),
);
case "allianceExtension": {
return new AllianceExtensionExecution(player, intent.recipient);
+2 -2
View File
@@ -483,7 +483,7 @@ export class FakeHumanExecution implements Execution {
if (canBuild === false) {
return false;
}
this.mg.addExecution(new ConstructionExecution(this.player, tile, type));
this.mg.addExecution(new ConstructionExecution(this.player, type, tile));
return true;
}
@@ -522,7 +522,7 @@ export class FakeHumanExecution implements Execution {
return false;
}
this.mg.addExecution(
new ConstructionExecution(this.player, targetTile, UnitType.Warship),
new ConstructionExecution(this.player, UnitType.Warship, targetTile),
);
return true;
}
+1 -1
View File
@@ -15,7 +15,7 @@ export function constructionExecution(
unit: UnitType,
ticks = 4,
) {
game.addExecution(new ConstructionExecution(_owner, game.ref(x, y), unit));
game.addExecution(new ConstructionExecution(_owner, unit, game.ref(x, y)));
// 4 ticks by default as it usually goes like this
// Init of construction execution