mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-26 16:34:36 +00:00
enable pause on replay
This commit is contained in:
@@ -112,6 +112,7 @@ export async function createClientGame(
|
||||
const config = await getConfig(
|
||||
lobbyConfig.gameStartInfo.config,
|
||||
userSettings,
|
||||
lobbyConfig.gameRecord != null,
|
||||
);
|
||||
let gameMap: TerrainMapData | null = null;
|
||||
|
||||
@@ -170,6 +171,8 @@ export class ClientGameRunner {
|
||||
private lastMessageTime: number = 0;
|
||||
private connectionCheckInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
private turnsExecuted = 0;
|
||||
|
||||
constructor(
|
||||
private lobby: LobbyConfig,
|
||||
private eventBus: EventBus,
|
||||
@@ -218,6 +221,14 @@ export class ClientGameRunner {
|
||||
public start() {
|
||||
consolex.log("starting client game");
|
||||
|
||||
setInterval(() => {
|
||||
if (this.lobby.gameRecord) {
|
||||
if (this.turnsExecuted == this.turnsSeen) {
|
||||
this.transport.endTurn();
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
|
||||
this.isActive = true;
|
||||
this.lastMessageTime = Date.now();
|
||||
setTimeout(() => {
|
||||
@@ -242,6 +253,8 @@ export class ClientGameRunner {
|
||||
this.stop(true);
|
||||
return;
|
||||
}
|
||||
|
||||
this.turnsExecuted++;
|
||||
gu.updates[GameUpdateType.Hash].forEach((hu: HashUpdate) => {
|
||||
this.eventBus.emit(new SendHashEvent(hu.tick, hu.hash));
|
||||
});
|
||||
|
||||
@@ -16,7 +16,11 @@ import { LobbyConfig } from "./ClientGameRunner";
|
||||
import { getPersistentIDFromCookie } from "./Main";
|
||||
|
||||
export class LocalServer {
|
||||
// All turns from the game record on replay.
|
||||
private allTurns: Turn[] = [];
|
||||
|
||||
private turns: Turn[] = [];
|
||||
|
||||
private intents: Intent[] = [];
|
||||
private startedAt: number;
|
||||
|
||||
@@ -35,7 +39,7 @@ export class LocalServer {
|
||||
|
||||
start() {
|
||||
this.startedAt = Date.now();
|
||||
if (!this.lobbyConfig.gameRecord) {
|
||||
if (this.lobbyConfig.gameRecord == null) {
|
||||
this.endTurnIntervalID = setInterval(
|
||||
() => this.endTurn(),
|
||||
this.lobbyConfig.serverConfig.turnIntervalMs(),
|
||||
@@ -43,15 +47,15 @@ export class LocalServer {
|
||||
}
|
||||
this.clientConnect();
|
||||
if (this.lobbyConfig.gameRecord) {
|
||||
this.turns = decompressGameRecord(this.lobbyConfig.gameRecord).turns;
|
||||
console.log(`loaded turns: ${JSON.stringify(this.turns)}`);
|
||||
this.allTurns = decompressGameRecord(this.lobbyConfig.gameRecord).turns;
|
||||
console.log(`loaded turns: ${JSON.stringify(this.allTurns)}`);
|
||||
}
|
||||
this.clientMessage(
|
||||
ServerStartGameMessageSchema.parse({
|
||||
type: "start",
|
||||
gameID: this.lobbyConfig.gameStartInfo.gameID,
|
||||
gameStartInfo: this.lobbyConfig.gameStartInfo,
|
||||
turns: this.turns,
|
||||
turns: [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -90,7 +94,7 @@ export class LocalServer {
|
||||
return;
|
||||
}
|
||||
// If we are replaying a game then verify hash.
|
||||
const archivedHash = this.turns[clientMsg.turnNumber].hash;
|
||||
const archivedHash = this.allTurns[clientMsg.turnNumber].hash;
|
||||
if (!archivedHash) {
|
||||
console.warn(
|
||||
`no archived hash found for turn ${clientMsg.turnNumber}, client hash: ${clientMsg.hash}`,
|
||||
@@ -121,10 +125,13 @@ export class LocalServer {
|
||||
}
|
||||
}
|
||||
|
||||
private endTurn() {
|
||||
public endTurn() {
|
||||
if (this.paused) {
|
||||
return;
|
||||
}
|
||||
if (this.allTurns) {
|
||||
this.intents = this.allTurns[this.turns.length].intents;
|
||||
}
|
||||
const pastTurn: Turn = {
|
||||
turnNumber: this.turns.length,
|
||||
gameID: this.lobbyConfig.gameStartInfo.gameID,
|
||||
|
||||
@@ -313,6 +313,12 @@ export class Transport {
|
||||
this.connect(this.onconnect, this.onmessage);
|
||||
}
|
||||
|
||||
public endTurn() {
|
||||
if (this.isLocal) {
|
||||
this.localServer.endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
private onSendLogEvent(event: SendLogEvent) {
|
||||
this.sendMsg(
|
||||
JSON.stringify(
|
||||
|
||||
@@ -122,7 +122,8 @@ export class OptionsMenu extends LitElement implements Layer {
|
||||
init() {
|
||||
console.log("init called from OptionsMenu");
|
||||
this.showPauseButton =
|
||||
this.game.config().gameConfig().gameType == GameType.Singleplayer;
|
||||
this.game.config().gameConfig().gameType == GameType.Singleplayer ||
|
||||
this.game.config().isReplay();
|
||||
this.isVisible = true;
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ export interface Config {
|
||||
defaultNukeSpeed(): number;
|
||||
nukeDeathFactor(humans: number, tilesOwned: number): number;
|
||||
structureMinDist(): number;
|
||||
isReplay(): boolean;
|
||||
}
|
||||
|
||||
export interface Theme {
|
||||
|
||||
@@ -12,15 +12,16 @@ export let cachedSC: ServerConfig = null;
|
||||
export async function getConfig(
|
||||
gameConfig: GameConfig,
|
||||
userSettings: UserSettings | null = null,
|
||||
isReplay: boolean = false,
|
||||
): Promise<Config> {
|
||||
const sc = await getServerConfigFromClient();
|
||||
switch (sc.env()) {
|
||||
case GameEnv.Dev:
|
||||
return new DevConfig(sc, gameConfig, userSettings);
|
||||
return new DevConfig(sc, gameConfig, userSettings, isReplay);
|
||||
case GameEnv.Preprod:
|
||||
case GameEnv.Prod:
|
||||
consolex.log("using prod config");
|
||||
return new DefaultConfig(sc, gameConfig, userSettings);
|
||||
return new DefaultConfig(sc, gameConfig, userSettings, isReplay);
|
||||
default:
|
||||
throw Error(`unsupported server configuration: ${process.env.GAME_ENV}`);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,11 @@ export class DefaultConfig implements Config {
|
||||
private _serverConfig: ServerConfig,
|
||||
private _gameConfig: GameConfig,
|
||||
private _userSettings: UserSettings,
|
||||
private _isReplay: boolean,
|
||||
) {}
|
||||
isReplay(): boolean {
|
||||
return this._isReplay;
|
||||
}
|
||||
|
||||
samHittingChance(): number {
|
||||
return 0.8;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { DefaultConfig, DefaultServerConfig } from "./DefaultConfig";
|
||||
|
||||
export class DevServerConfig extends DefaultServerConfig {
|
||||
r2Bucket(): string {
|
||||
return "openfront-staging";
|
||||
return "openfront-prod";
|
||||
}
|
||||
adminToken(): string {
|
||||
return "WARNING_DEV_ADMIN_KEY_DO_NOT_USE_IN_PRODUCTION";
|
||||
@@ -44,8 +44,13 @@ export class DevServerConfig extends DefaultServerConfig {
|
||||
}
|
||||
|
||||
export class DevConfig extends DefaultConfig {
|
||||
constructor(sc: ServerConfig, gc: GameConfig, us: UserSettings) {
|
||||
super(sc, gc, us);
|
||||
constructor(
|
||||
sc: ServerConfig,
|
||||
gc: GameConfig,
|
||||
us: UserSettings,
|
||||
isReplay: boolean,
|
||||
) {
|
||||
super(sc, gc, us, isReplay);
|
||||
}
|
||||
|
||||
// numSpawnPhaseTurns(): number {
|
||||
|
||||
+6
-1
@@ -32,7 +32,12 @@ export async function setup(mapName: string, _gameConfig: GameConfig = {}) {
|
||||
instantBuild: false,
|
||||
..._gameConfig,
|
||||
};
|
||||
const config = new TestConfig(serverConfig, gameConfig, new UserSettings());
|
||||
const config = new TestConfig(
|
||||
serverConfig,
|
||||
gameConfig,
|
||||
new UserSettings(),
|
||||
false,
|
||||
);
|
||||
|
||||
// Create and return the game
|
||||
return createGame([], [], gameMap, miniGameMap, config);
|
||||
|
||||
Reference in New Issue
Block a user