mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 12:40:46 +00:00
Bugfix: don't allow other players to move warships (#879)
## Description: The MoveWarshipExecution now verifies that the player who requested to move owns the warship. This prevents players from moving other players' warships. ## Please complete the following: - [x] I have added screenshots for all UI updates - [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:
@@ -63,7 +63,7 @@ export class Executor {
|
||||
case "cancel_boat":
|
||||
return new BoatRetreatExecution(playerID, intent.unitID);
|
||||
case "move_warship":
|
||||
return new MoveWarshipExecution(intent.unitId, intent.tile);
|
||||
return new MoveWarshipExecution(player, intent.unitId, intent.tile);
|
||||
case "spawn":
|
||||
return new SpawnExecution(
|
||||
player.info(),
|
||||
|
||||
@@ -1,36 +1,33 @@
|
||||
import { Execution, Game } from "../game/Game";
|
||||
|
||||
const cancelDelay = 2;
|
||||
import { Execution, Game, Player, UnitType } from "../game/Game";
|
||||
import { TileRef } from "../game/GameMap";
|
||||
|
||||
export class MoveWarshipExecution implements Execution {
|
||||
private active = true;
|
||||
private mg: Game | null = null;
|
||||
|
||||
constructor(
|
||||
public readonly unitId: number,
|
||||
public readonly position: number,
|
||||
private readonly owner: Player,
|
||||
private readonly unitId: number,
|
||||
private readonly position: TileRef,
|
||||
) {}
|
||||
|
||||
init(mg: Game, ticks: number): void {
|
||||
this.mg = mg;
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.mg === null) {
|
||||
throw new Error("Not initialized");
|
||||
}
|
||||
const warship = this.mg.units().find((u) => u.id() === this.unitId);
|
||||
const warship = this.owner
|
||||
.units(UnitType.Warship)
|
||||
.find((u) => u.id() === this.unitId);
|
||||
if (!warship) {
|
||||
console.log("MoveWarshipExecution: warship is already dead");
|
||||
console.warn("MoveWarshipExecution: warship not found");
|
||||
return;
|
||||
}
|
||||
if (!warship.isActive()) {
|
||||
console.warn("MoveWarshipExecution: warship is not active");
|
||||
return;
|
||||
}
|
||||
warship.setPatrolTile(this.position);
|
||||
warship.setTargetTile(undefined);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
tick(ticks: number): void {}
|
||||
|
||||
isActive(): boolean {
|
||||
return this.active;
|
||||
return false;
|
||||
}
|
||||
|
||||
activeDuringSpawnPhase(): boolean {
|
||||
|
||||
+49
-1
@@ -175,7 +175,7 @@ describe("Warship", () => {
|
||||
game.addExecution(new WarshipExecution(warship));
|
||||
|
||||
game.addExecution(
|
||||
new MoveWarshipExecution(warship.id(), game.ref(coastX + 5, 15)),
|
||||
new MoveWarshipExecution(player1, warship.id(), game.ref(coastX + 5, 15)),
|
||||
);
|
||||
|
||||
executeTicks(game, 10);
|
||||
@@ -211,4 +211,52 @@ describe("Warship", () => {
|
||||
// Trade ship should not be captured
|
||||
expect(tradeShip.owner().id()).toBe(player2.id());
|
||||
});
|
||||
|
||||
test("MoveWarshipExecution fails if player is not the owner", async () => {
|
||||
const originalPatrolTile = game.ref(coastX + 1, 10);
|
||||
const warship = player1.buildUnit(
|
||||
UnitType.Warship,
|
||||
game.ref(coastX + 1, 5),
|
||||
{
|
||||
patrolTile: originalPatrolTile,
|
||||
},
|
||||
);
|
||||
new MoveWarshipExecution(
|
||||
player2,
|
||||
warship.id(),
|
||||
game.ref(coastX + 5, 15),
|
||||
).init(game, 0);
|
||||
expect(warship.patrolTile()).toBe(originalPatrolTile);
|
||||
});
|
||||
|
||||
test("MoveWarshipExecution fails if warship is not active", async () => {
|
||||
const originalPatrolTile = game.ref(coastX + 1, 10);
|
||||
const warship = player1.buildUnit(
|
||||
UnitType.Warship,
|
||||
game.ref(coastX + 1, 5),
|
||||
{
|
||||
patrolTile: originalPatrolTile,
|
||||
},
|
||||
);
|
||||
warship.delete();
|
||||
new MoveWarshipExecution(
|
||||
player1,
|
||||
warship.id(),
|
||||
game.ref(coastX + 5, 15),
|
||||
).init(game, 0);
|
||||
expect(warship.patrolTile()).toBe(originalPatrolTile);
|
||||
});
|
||||
|
||||
test("MoveWarshipExecution fails gracefully if warship not found", async () => {
|
||||
const exec = new MoveWarshipExecution(
|
||||
player1,
|
||||
123,
|
||||
game.ref(coastX + 5, 15),
|
||||
);
|
||||
|
||||
// Verify that no error is thrown.
|
||||
exec.init(game, 0);
|
||||
|
||||
expect(exec.isActive()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user