mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 10:00:44 +00:00
Fix type errors in /server related to typescript strict mode (#1468)
## Description: Task: #1075 Enable typescript strict mode First (out of many) PR in order to enable typescript Strict mode in the project. This PR fixes all type issues present under the `/server` path. ## Specifics Most changes are just basic type fixes, however here are some further explanation for some of the more complex changes: 1. `PatternDecoder.ts` used to accept `Uint8Array` as an input, however this was never used, so to simplify the typing and avoid casting in various places, I just removed support for it. 2. `MapPlaylist.ts` has a `frequency` object with map names, used to specify how often each map should appear in the playlist. However this list is not in sync with the actual map list, so some maps were missing from that list. I fixed that while adding stronger typing for the future. Also removed an un-necessary call to `parseInt`. ## 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 have read and accepted the CLA aggreement (only required once). ## Please put your Discord username so you can be contacted if a bug or regression is found: azlod
This commit is contained in:
@@ -5,10 +5,7 @@ export class PatternDecoder {
|
||||
readonly width: number;
|
||||
readonly scale: number;
|
||||
|
||||
constructor(
|
||||
base64: string,
|
||||
base64urlDecode: (input: Uint8Array | string) => Uint8Array,
|
||||
) {
|
||||
constructor(base64: string, base64urlDecode: (input: string) => Uint8Array) {
|
||||
this.bytes = base64urlDecode(base64);
|
||||
|
||||
if (this.bytes.length < 3) {
|
||||
|
||||
@@ -84,6 +84,8 @@ export enum GameMapType {
|
||||
Italia = "Italia",
|
||||
}
|
||||
|
||||
export type GameMapName = keyof typeof GameMapType;
|
||||
|
||||
export const mapCategories: Record<string, GameMapType[]> = {
|
||||
continental: [
|
||||
GameMapType.World,
|
||||
|
||||
+51
-17
@@ -35,11 +35,20 @@ export async function archive(gameRecord: GameRecord) {
|
||||
);
|
||||
await archiveFullGameToR2(gameRecord);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: unknown) {
|
||||
// If the error is not an instance of Error, log it as a string
|
||||
if (!(error instanceof Error)) {
|
||||
log.error(
|
||||
`${gameRecord.info.gameID}: Final archive error. Non-Error type: ${String(error)}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { message, stack, name } = error;
|
||||
log.error(`${gameRecord.info.gameID}: Final archive error: ${error}`, {
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
message: message,
|
||||
stack: stack,
|
||||
name: name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
});
|
||||
}
|
||||
@@ -68,11 +77,20 @@ async function archiveAnalyticsToR2(gameRecord: GameRecord) {
|
||||
});
|
||||
|
||||
log.info(`${info.gameID}: successfully wrote game analytics to R2`);
|
||||
} catch (error) {
|
||||
} catch (error: unknown) {
|
||||
// If the error is not an instance of Error, log it as a string
|
||||
if (!(error instanceof Error)) {
|
||||
log.error(
|
||||
`${gameRecord.info.gameID}: Error writing game analytics to R2. Non-Error type: ${String(error)}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { message, stack, name } = error;
|
||||
log.error(`${info.gameID}: Error writing game analytics to R2: ${error}`, {
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
message: message,
|
||||
stack: stack,
|
||||
name: name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
});
|
||||
throw error;
|
||||
@@ -116,12 +134,20 @@ export async function readGameRecord(
|
||||
if (response.Body === undefined) return null;
|
||||
const bodyContents = await response.Body.transformToString();
|
||||
return JSON.parse(bodyContents) as GameRecord;
|
||||
} catch (error) {
|
||||
} catch (error: unknown) {
|
||||
// If the error is not an instance of Error, log it as a string
|
||||
if (!(error instanceof Error)) {
|
||||
log.error(
|
||||
`${gameId}: Error reading game record from R2. Non-Error type: ${String(error)}`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
const { message, stack, name } = error;
|
||||
// Log the error for monitoring purposes
|
||||
log.error(`${gameId}: Error reading game record from R2: ${error}`, {
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
message: message,
|
||||
stack: stack,
|
||||
name: name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
});
|
||||
|
||||
@@ -137,14 +163,22 @@ export async function gameRecordExists(gameId: GameID): Promise<boolean> {
|
||||
Key: `${gameFolder}/${gameId}`, // Fixed - needed to include gameFolder
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error.name === "NotFound") {
|
||||
} catch (error: unknown) {
|
||||
// If the error is not an instance of Error, log it as a string
|
||||
if (!(error instanceof Error)) {
|
||||
log.error(
|
||||
`${gameId}: Error checking archive existence. Non-Error type: ${String(error)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
const { message, stack, name } = error;
|
||||
if (name === "NotFound") {
|
||||
return false;
|
||||
}
|
||||
log.error(`${gameId}: Error checking archive existence: ${error}`, {
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
message: message,
|
||||
stack: stack,
|
||||
name: name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
});
|
||||
return false;
|
||||
|
||||
@@ -46,13 +46,14 @@ export class GameServer {
|
||||
private _hasStarted = false;
|
||||
private _startTime: number | null = null;
|
||||
|
||||
private endTurnIntervalID;
|
||||
private endTurnIntervalID: ReturnType<typeof setInterval> | undefined;
|
||||
|
||||
private lastPingUpdate = 0;
|
||||
|
||||
private winner: ClientSendWinnerMessage | null = null;
|
||||
|
||||
private gameStartInfo: GameStartInfo;
|
||||
// Note: This can be undefined if accessed before the game starts.
|
||||
private gameStartInfo!: GameStartInfo;
|
||||
|
||||
private log: Logger;
|
||||
|
||||
@@ -402,7 +403,9 @@ export class GameServer {
|
||||
|
||||
async end() {
|
||||
// Close all WebSocket connections
|
||||
clearInterval(this.endTurnIntervalID);
|
||||
if (this.endTurnIntervalID) {
|
||||
clearInterval(this.endTurnIntervalID);
|
||||
}
|
||||
this.allClients.forEach((client) => {
|
||||
client.ws.removeAllListeners("message");
|
||||
if (client.ws.readyState === WebSocket.OPEN) {
|
||||
|
||||
@@ -24,7 +24,7 @@ const loggerProvider = new LoggerProvider({
|
||||
if (config.env() === GameEnv.Prod && config.otelEnabled()) {
|
||||
console.log("OTEL enabled");
|
||||
// Configure OpenTelemetry endpoint with basic auth (if provided)
|
||||
const headers = {};
|
||||
const headers: Record<string, string> = {};
|
||||
if (config.otelUsername() && config.otelPassword()) {
|
||||
headers["Authorization"] =
|
||||
"Basic " +
|
||||
|
||||
@@ -2,6 +2,7 @@ import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
|
||||
import {
|
||||
Difficulty,
|
||||
Duos,
|
||||
GameMapName,
|
||||
GameMapType,
|
||||
GameMode,
|
||||
GameType,
|
||||
@@ -17,7 +18,9 @@ const log = logger.child({});
|
||||
|
||||
const config = getServerConfigFromServer();
|
||||
|
||||
const frequency = {
|
||||
// How many times each map should appear in the playlist.
|
||||
// Note: The Partial should eventually be removed for better type safety.
|
||||
const frequency: Partial<Record<GameMapName, number>> = {
|
||||
World: 3,
|
||||
Europe: 2,
|
||||
Africa: 2,
|
||||
@@ -27,7 +30,6 @@ const frequency = {
|
||||
GatewayToTheAtlantic: 1,
|
||||
Iceland: 1,
|
||||
SouthAmerica: 1,
|
||||
KnownWorld: 1,
|
||||
DeglaciatedAntarctica: 1,
|
||||
EuropeClassic: 1,
|
||||
Mena: 1,
|
||||
@@ -109,8 +111,8 @@ export class MapPlaylist {
|
||||
|
||||
private shuffleMapsPlaylist(): boolean {
|
||||
const maps: GameMapType[] = [];
|
||||
Object.keys(GameMapType).forEach((key) => {
|
||||
for (let i = 0; i < parseInt(frequency[key]); i++) {
|
||||
(Object.keys(GameMapType) as GameMapName[]).forEach((key) => {
|
||||
for (let i = 0; i < (frequency[key] ?? 0); i++) {
|
||||
maps.push(GameMapType[key]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ export function initWorkerMetrics(gameManager: GameManager): void {
|
||||
const resource = getOtelResource();
|
||||
|
||||
// Configure auth headers
|
||||
const headers = {};
|
||||
const headers: Record<string, string> = {};
|
||||
if (config.otelEnabled()) {
|
||||
headers["Authorization"] =
|
||||
"Basic " +
|
||||
|
||||
Reference in New Issue
Block a user