This commit is contained in:
evanpelle
2026-01-12 15:52:28 -08:00
parent a7714cd798
commit 5766d71995
33 changed files with 153 additions and 154 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
"${workspaceFolder}/src/server/Server.ts"
],
"env": {
"GAME_ENV": "dev"
"GAME_ENV": "Dev"
},
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
+3
View File
@@ -0,0 +1,3 @@
{
"html.validate.scripts": false
}
+5
View File
@@ -56,6 +56,11 @@
/>
<meta property="og:type" content="game" />
<!-- Server Configuration -->
<script>
window.SERVER_CONFIG = <%- serverConfig %>;
</script>
<!-- CrazyGames SDK -->
<script
src="https://sdk.crazygames.com/crazygames-sdk-v3.js"
-19
View File
@@ -113,25 +113,6 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
}
# /api/env endpoint - Cache for 1 hour
location = /api/env {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# Cache configuration
proxy_cache API_CACHE;
proxy_cache_valid 200 1h; # Cache successful responses for 1 hour
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# /commit.txt endpoint - Cache for 5 seconds
location = /commit.txt {
proxy_pass http://127.0.0.1:3000;
+4 -4
View File
@@ -5,10 +5,10 @@
"build-prod": "concurrently --kill-others-on-fail \"tsc --noEmit\" \"vite build\"",
"start:client": "vite",
"start:server": "tsx src/server/Server.ts",
"start:server-dev": "cross-env GAME_ENV=dev tsx src/server/Server.ts",
"dev": "cross-env GAME_ENV=dev concurrently \"npm run start:client\" \"npm run start:server-dev\"",
"dev:staging": "cross-env GAME_ENV=dev API_DOMAIN=api.openfront.dev concurrently \"npm run start:client\" \"npm run start:server-dev\"",
"dev:prod": "cross-env GAME_ENV=dev API_DOMAIN=api.openfront.io concurrently \"npm run start:client\" \"npm run start:server-dev\"",
"start:server-dev": "cross-env GAME_ENV=Dev tsx src/server/Server.ts",
"dev": "cross-env GAME_ENV=Dev concurrently \"npm run start:client\" \"npm run start:server-dev\"",
"dev:staging": "cross-env GAME_ENV=Dev API_DOMAIN=api.openfront.dev concurrently \"npm run start:client\" \"npm run start:server-dev\"",
"dev:prod": "cross-env GAME_ENV=Dev API_DOMAIN=api.openfront.io concurrently \"npm run start:client\" \"npm run start:server-dev\"",
"docs:map-generator": "cd map-generator && go doc -cmd -u -all",
"tunnel": "npm run build-prod && npm run start:server",
"test": "vitest run",
+4 -1
View File
@@ -1,3 +1,4 @@
import { Env } from "src/core/configuration/Env";
import { translateText } from "../client/Utils";
import { EventBus } from "../core/EventBus";
import {
@@ -182,8 +183,9 @@ async function createClientGame(
if (lobbyConfig.gameStartInfo === undefined) {
throw new Error("missing gameStartInfo");
}
const config = await getConfig(
const config = getConfig(
lobbyConfig.gameStartInfo.config,
Env.GAME_ENV,
userSettings,
lobbyConfig.gameRecord !== undefined,
);
@@ -200,6 +202,7 @@ async function createClientGame(
}
const worker = new WorkerClient(
lobbyConfig.gameStartInfo,
Env.GAME_ENV,
lobbyConfig.clientID,
);
await worker.initialize();
+4 -4
View File
@@ -1,7 +1,7 @@
import { TemplateResult, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { copyToClipboard, translateText } from "../client/Utils";
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import {
Difficulty,
Duos,
@@ -1156,7 +1156,7 @@ export class HostLobbyModal extends BaseModal {
console.log(
`Starting private game with map: ${GameMapType[this.selectedMap as keyof typeof GameMapType]} ${this.useRandomMap ? " (Randomly selected)" : ""}`,
);
const config = await getServerConfigFromClient();
const config = getServerConfig();
const response = await fetch(
`${window.location.origin}/${config.workerPath(this.lobbyId)}/api/start_game/${this.lobbyId}`,
{
@@ -1178,7 +1178,7 @@ export class HostLobbyModal extends BaseModal {
}
private async pollPlayers() {
const config = await getServerConfigFromClient();
const config = getServerConfig();
fetch(`/${config.workerPath(this.lobbyId)}/api/game/${this.lobbyId}`, {
method: "GET",
headers: {
@@ -1231,7 +1231,7 @@ export class HostLobbyModal extends BaseModal {
}
async function createLobby(creatorClientID: string): Promise<GameInfo> {
const config = await getServerConfigFromClient();
const config = getServerConfig();
try {
const id = generateID();
const response = await fetch(
+6 -24
View File
@@ -1,5 +1,6 @@
import { html, TemplateResult } from "lit";
import { customElement, query, state } from "lit/decorators.js";
import { Env } from "src/core/configuration/Env";
import { copyToClipboard, translateText } from "../client/Utils";
import {
ClientInfo,
@@ -8,7 +9,7 @@ import {
GameRecordSchema,
} from "../core/Schemas";
import { generateID } from "../core/Util";
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { GameMode } from "../core/game/Game";
import { UserSettings } from "../core/game/UserSettings";
import { getApiBase } from "./Api";
@@ -511,7 +512,7 @@ export class JoinPrivateLobbyModal extends BaseModal {
}
private async checkActiveLobby(lobbyId: string): Promise<boolean> {
const config = await getServerConfigFromClient();
const config = getServerConfig();
const url = `/${config.workerPath(lobbyId)}/api/game/${lobbyId}/exists`;
const response = await fetch(url, {
@@ -548,22 +549,12 @@ export class JoinPrivateLobbyModal extends BaseModal {
private async checkArchivedGame(
lobbyId: string,
): Promise<"success" | "not_found" | "version_mismatch" | "error"> {
const archivePromise = fetch(`${getApiBase()}/game/${lobbyId}`, {
const archiveResponse = await fetch(`${getApiBase()}/game/${lobbyId}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const gitCommitPromise = fetch(`/commit.txt`, {
method: "GET",
headers: { "Content-Type": "application/json" },
cache: "no-cache",
});
const [archiveResponse, gitCommitResponse] = await Promise.all([
archivePromise,
gitCommitPromise,
]);
if (archiveResponse.status === 404) {
return "not_found";
@@ -578,16 +569,7 @@ export class JoinPrivateLobbyModal extends BaseModal {
return "version_mismatch";
}
let myGitCommit = "";
if (gitCommitResponse.status === 404) {
// commit.txt is not found when running locally
myGitCommit = "DEV";
} else if (gitCommitResponse.status === 200) {
myGitCommit = (await gitCommitResponse.text()).trim();
} else {
console.error("Error getting git commit:", gitCommitResponse.status);
return "error";
}
const myGitCommit = Env.GIT_COMMIT;
// Allow DEV to join games created with a different version for debugging.
if (myGitCommit !== "DEV" && parsed.data.gitCommit !== myGitCommit) {
@@ -616,7 +598,7 @@ export class JoinPrivateLobbyModal extends BaseModal {
private async pollPlayers() {
const lobbyId = this.currentLobbyId;
if (!lobbyId) return;
const config = await getServerConfigFromClient();
const config = getServerConfig();
fetch(`/${config.workerPath(lobbyId)}/api/game/${lobbyId}`, {
method: "GET",
+4 -4
View File
@@ -3,7 +3,7 @@ import { UserMeResponse } from "../core/ApiSchemas";
import { EventBus } from "../core/EventBus";
import { GameRecord, GameStartInfo, ID } from "../core/Schemas";
import { GameEnv } from "../core/configuration/Config";
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { GameType } from "../core/game/Game";
import { UserSettings } from "../core/game/UserSettings";
import "./AccountModal";
@@ -735,7 +735,7 @@ class Client {
this.gameStop();
document.body.classList.remove("in-game");
}
const config = await getServerConfigFromClient();
const config = getServerConfig();
const pattern = this.userSettings.getSelectedPatternName(
await fetchCosmetics(),
@@ -895,7 +895,7 @@ class Client {
private async getTurnstileToken(
lobby: JoinLobbyEvent,
): Promise<string | null> {
const config = await getServerConfigFromClient();
const config = getServerConfig();
if (
config.env() === GameEnv.Dev ||
lobby.gameStartInfo?.config.gameType === GameType.Singleplayer
@@ -955,7 +955,7 @@ async function getTurnstileToken(): Promise<{
throw new Error("Failed to load Turnstile script");
}
const config = await getServerConfigFromClient();
const config = getServerConfig();
const widgetId = window.turnstile.render("#turnstile-container", {
sitekey: config.turnstileSiteKey(),
size: "normal",
+3 -3
View File
@@ -1,7 +1,7 @@
import { html, LitElement } from "lit";
import { customElement, query, state } from "lit/decorators.js";
import { UserMeResponse } from "../core/ApiSchemas";
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { generateID } from "../core/Util";
import { getUserMe } from "./Api";
import { getPlayToken } from "./Auth";
@@ -143,7 +143,7 @@ export class MatchmakingModal extends BaseModal {
}
private async connect() {
const config = await getServerConfigFromClient();
const config = getServerConfig();
this.socket = new WebSocket(`${config.jwtIssuer()}/matchmaking/join`);
this.socket.onopen = async () => {
@@ -222,7 +222,7 @@ export class MatchmakingModal extends BaseModal {
if (this.gameID === null) {
return;
}
const config = await getServerConfigFromClient();
const config = getServerConfig();
const url = `/${config.workerPath(this.gameID)}/api/game/${this.gameID}/exists`;
const response = await fetch(url, {
+1 -1
View File
@@ -31,7 +31,7 @@ export class MultiTabModal extends LitElement implements Layer {
if (
this.game.inSpawnPhase() ||
this.game.config().gameConfig().gameType === GameType.Singleplayer ||
this.game.config().serverConfig().env() === GameEnv.Dev
this.game.config().env() === GameEnv.Dev
) {
return;
}
+3 -1
View File
@@ -1,4 +1,5 @@
import { placeName } from "../client/graphics/NameBoxCalculator";
import { GameEnv } from "./configuration/Config";
import { getConfig } from "./configuration/ConfigLoader";
import { Executor } from "./execution/ExecutionManager";
import { WinCheckExecution } from "./execution/WinCheckExecution";
@@ -34,11 +35,12 @@ import { censorNameWithClanTag } from "./validations/username";
export async function createGameRunner(
gameStart: GameStartInfo,
env: GameEnv,
clientID: ClientID,
mapLoader: GameMapLoader,
callBack: (gu: GameUpdateViewData | ErrorUpdate) => void,
): Promise<GameRunner> {
const config = await getConfig(gameStart.config, null);
const config = getConfig(gameStart.config, env, null, false);
const gameMap = await loadGameMap(
gameStart.config.gameMap,
gameStart.config.gameMapSize,
+2 -2
View File
@@ -22,7 +22,7 @@ import { NukeType } from "../StatsSchemas";
export enum GameEnv {
Dev,
Preprod,
Staging,
Prod,
}
@@ -68,8 +68,8 @@ export interface NukeMagnitude {
}
export interface Config {
env(): GameEnv;
spawnImmunityDuration(): Tick;
serverConfig(): ServerConfig;
gameConfig(): GameConfig;
theme(): Theme;
percentageTilesOwnedToWin(): number;
+11 -33
View File
@@ -7,56 +7,34 @@ import { Env } from "./Env";
import { preprodConfig } from "./PreprodConfig";
import { prodConfig } from "./ProdConfig";
export let cachedSC: ServerConfig | null = null;
export async function getConfig(
export function getConfig(
gameConfig: GameConfig,
gameEnv: GameEnv,
userSettings: UserSettings | null,
isReplay: boolean = false,
): Promise<Config> {
const sc = await getServerConfigFromClient();
switch (sc.env()) {
): Config {
switch (gameEnv) {
case GameEnv.Dev:
return new DevConfig(sc, gameConfig, userSettings, isReplay);
case GameEnv.Preprod:
return new DevConfig(gameConfig, gameEnv, userSettings, isReplay);
case GameEnv.Staging:
case GameEnv.Prod:
console.log("using prod config");
return new DefaultConfig(sc, gameConfig, userSettings, isReplay);
return new DefaultConfig(gameConfig, gameEnv, userSettings, isReplay);
default:
throw Error(`unsupported server configuration: ${Env.GAME_ENV}`);
}
}
export async function getServerConfigFromClient(): Promise<ServerConfig> {
if (cachedSC) {
return cachedSC;
}
const response = await fetch("/api/env");
if (!response.ok) {
throw new Error(
`Failed to fetch server config: ${response.status} ${response.statusText}`,
);
}
const config = await response.json();
// Log the retrieved configuration
console.log("Server config loaded:", config);
cachedSC = getServerConfig(config.game_env);
return cachedSC;
}
export function getServerConfigFromServer(): ServerConfig {
export function getServerConfig(): ServerConfig {
const gameEnv = Env.GAME_ENV;
return getServerConfig(gameEnv);
}
export function getServerConfig(gameEnv: string) {
switch (gameEnv) {
case "dev":
case GameEnv.Dev:
console.log("using dev server config");
return new DevServerConfig();
case "staging":
case GameEnv.Staging:
console.log("using preprod server config");
return preprodConfig;
case "prod":
case GameEnv.Prod:
console.log("using prod server config");
return prodConfig;
default:
+5 -5
View File
@@ -244,12 +244,16 @@ export class DefaultConfig implements Config {
private pastelTheme: PastelTheme = new PastelTheme();
private pastelThemeDark: PastelThemeDark = new PastelThemeDark();
constructor(
private _serverConfig: ServerConfig,
private _gameConfig: GameConfig,
private _gameEnv: GameEnv,
private _userSettings: UserSettings | null,
private _isReplay: boolean,
) {}
env(): GameEnv {
return this._gameEnv;
}
stripePublishableKey(): string {
return Env.STRIPE_PUBLISHABLE_KEY ?? "";
}
@@ -275,10 +279,6 @@ export class DefaultConfig implements Config {
return this._gameConfig;
}
serverConfig(): ServerConfig {
return this._serverConfig;
}
userSettings(): UserSettings {
if (this._userSettings === null) {
throw new Error("userSettings is null");
+3 -3
View File
@@ -1,6 +1,6 @@
import { UserSettings } from "../game/UserSettings";
import { GameConfig } from "../Schemas";
import { GameEnv, ServerConfig } from "./Config";
import { GameEnv } from "./Config";
import { DefaultConfig, DefaultServerConfig } from "./DefaultConfig";
export class DevServerConfig extends DefaultServerConfig {
@@ -49,11 +49,11 @@ export class DevServerConfig extends DefaultServerConfig {
export class DevConfig extends DefaultConfig {
constructor(
sc: ServerConfig,
gc: GameConfig,
gameEnv: GameEnv,
us: UserSettings | null,
isReplay: boolean,
) {
super(sc, gc, us, isReplay);
super(gc, gameEnv, us, isReplay);
}
}
+60 -5
View File
@@ -4,6 +4,14 @@
* - In Node.js (Server), it uses `process.env`.
*/
import { GameEnv } from "./Config";
export interface ServerConfigVars {
gameEnv: string;
numWorkers: number;
gitCommit: string;
}
declare global {
interface ImportMetaEnv {
[key: string]: string | boolean | undefined;
@@ -11,6 +19,9 @@ declare global {
interface ImportMeta {
readonly env: ImportMetaEnv;
}
interface Window {
SERVER_CONFIG?: ServerConfigVars;
}
}
function getEnv(key: string, viteKey?: string): string | undefined {
@@ -44,8 +55,32 @@ function getEnv(key: string, viteKey?: string): string | undefined {
return undefined;
}
// Helper function to get GameEnv value case-insensitively
function getGameEnvValue(envString: string | undefined): GameEnv {
if (!envString) {
throw new Error("GAME_ENV is not defined");
}
const normalizedEnv = envString.toLowerCase();
const enumKey = Object.keys(GameEnv).find(
(key) => key.toLowerCase() === normalizedEnv,
);
return enumKey ? GameEnv[enumKey as keyof typeof GameEnv] : GameEnv.Dev;
}
export const Env = {
get GAME_ENV(): string {
get GAME_ENV(): GameEnv {
// Check window.SERVER_CONFIG first (injected at build time)
try {
if (typeof window !== "undefined" && window.SERVER_CONFIG) {
console.log("using server config from window");
return getGameEnvValue(window.SERVER_CONFIG.gameEnv);
}
} catch {
// Ignore errors accessing window
}
// Check MODE for Vite, GAME_ENV for Node
try {
if (
@@ -53,13 +88,14 @@ export const Env = {
import.meta.env &&
import.meta.env.MODE
) {
return import.meta.env.MODE;
console.log("using server config from import.meta.env");
return getGameEnvValue(import.meta.env.MODE);
}
} catch {
// Ignore errors accessing import.meta
}
return getEnv("GAME_ENV") ?? "dev";
console.log("using server config from environment variable");
return getGameEnvValue(getEnv("GAME_ENV"));
},
get TURNSTILE_SECRET_KEY() {
@@ -80,7 +116,14 @@ export const Env = {
get OTEL_AUTH_HEADER() {
return getEnv("OTEL_AUTH_HEADER");
},
get GIT_COMMIT() {
get GIT_COMMIT(): string | undefined {
try {
if (typeof window !== "undefined" && window.SERVER_CONFIG) {
return window.SERVER_CONFIG.gitCommit;
}
} catch {
// Ignore errors accessing window
}
return getEnv("GIT_COMMIT");
},
get API_KEY() {
@@ -89,4 +132,16 @@ export const Env = {
get ADMIN_TOKEN() {
return getEnv("ADMIN_TOKEN");
},
get NUM_WORKERS() {
// Check window.SERVER_CONFIG first (injected at build time)
try {
if (typeof window !== "undefined" && window.SERVER_CONFIG) {
return String(window.SERVER_CONFIG.numWorkers);
}
} catch {
// Ignore errors accessing window
}
return getEnv("NUM_WORKERS");
},
};
+1 -1
View File
@@ -3,7 +3,7 @@ import { DefaultServerConfig } from "./DefaultConfig";
export const preprodConfig = new (class extends DefaultServerConfig {
env(): GameEnv {
return GameEnv.Preprod;
return GameEnv.Staging;
}
numWorkers(): number {
return 2;
+1
View File
@@ -43,6 +43,7 @@ ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
try {
gameRunner = createGameRunner(
message.gameStartInfo,
message.env,
message.clientID,
mapLoader,
gameUpdate,
+3
View File
@@ -1,3 +1,4 @@
import { GameEnv } from "../configuration/Config";
import {
Cell,
PlayerActions,
@@ -21,6 +22,7 @@ export class WorkerClient {
constructor(
private gameStartInfo: GameStartInfo,
private env: GameEnv,
private clientID: ClientID,
) {
this.worker = new Worker(new URL("./Worker.worker.ts", import.meta.url), {
@@ -71,6 +73,7 @@ export class WorkerClient {
type: "init",
id: messageId,
gameStartInfo: this.gameStartInfo,
env: this.env,
clientID: this.clientID,
});
+2
View File
@@ -1,3 +1,4 @@
import { GameEnv } from "../configuration/Config";
import {
PlayerActions,
PlayerBorderTiles,
@@ -39,6 +40,7 @@ export interface HeartbeatMessage extends BaseWorkerMessage {
export interface InitMessage extends BaseWorkerMessage {
type: "init";
gameStartInfo: GameStartInfo;
env: GameEnv;
clientID: ClientID;
}
+2 -2
View File
@@ -1,5 +1,5 @@
import z from "zod";
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import {
GameID,
GameRecord,
@@ -10,7 +10,7 @@ import {
import { replacer } from "../core/Util";
import { logger } from "./Logger";
const config = getServerConfigFromServer();
const config = getServerConfig();
const log = logger.child({ component: "Archive" });
+2 -2
View File
@@ -7,11 +7,11 @@ import {
import { OpenTelemetryTransportV3 } from "@opentelemetry/winston-transport";
import * as dotenv from "dotenv";
import winston from "winston";
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { getOtelResource } from "./OtelResource";
dotenv.config();
const config = getServerConfigFromServer();
const config = getServerConfig();
const resource = getOtelResource();
+2 -2
View File
@@ -1,4 +1,4 @@
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import {
Difficulty,
Duos,
@@ -17,7 +17,7 @@ import { logger } from "./Logger";
const log = logger.child({});
const config = getServerConfigFromServer();
const config = getServerConfig();
// How many times each map should appear in the playlist.
// Note: The Partial should eventually be removed for better type safety.
+2 -10
View File
@@ -6,13 +6,13 @@ import http from "http";
import path from "path";
import { fileURLToPath } from "url";
import { WebSocket, WebSocketServer } from "ws";
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { GameInfo } from "../core/Schemas";
import { generateID } from "../core/Util";
import { logger } from "./Logger";
import { MapPlaylist } from "./MapPlaylist";
const config = getServerConfigFromServer();
const config = getServerConfig();
const playlist = new MapPlaylist();
const readyWorkers = new Set();
@@ -203,14 +203,6 @@ export async function startMaster() {
});
}
app.get("/api/env", async (req, res) => {
const envConfig = {
game_env: process.env.GAME_ENV,
};
if (!envConfig.game_env) return res.sendStatus(500);
res.json(envConfig);
});
// Add lobbies endpoint to list public games for this worker
app.get("/api/public_lobbies", async (req, res) => {
res.json(publicLobbiesData);
+2 -2
View File
@@ -3,9 +3,9 @@ import {
ATTR_SERVICE_NAME,
ATTR_SERVICE_VERSION,
} from "@opentelemetry/semantic-conventions";
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
const config = getServerConfigFromServer();
const config = getServerConfig();
export function getOtelResource() {
return resourceFromAttributes({
+2
View File
@@ -1,5 +1,6 @@
import cluster from "cluster";
import * as dotenv from "dotenv";
import { getServerConfig } from "src/core/configuration/ConfigLoader";
import { startMaster } from "./Master";
import { startWorker } from "./Worker";
@@ -8,6 +9,7 @@ dotenv.config();
// Main entry point of the application
async function main() {
getServerConfig();
// Check if this is the primary (master) process
if (cluster.isPrimary) {
console.log("Starting master process...");
+2 -2
View File
@@ -7,7 +7,7 @@ import path from "path";
import { fileURLToPath } from "url";
import { WebSocket, WebSocketServer } from "ws";
import { z } from "zod";
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { GameMapSize, GameType } from "../core/game/Game";
import {
ClientMessageSchema,
@@ -30,7 +30,7 @@ import { PrivilegeRefresher } from "./PrivilegeRefresher";
import { verifyTurnstileToken } from "./Turnstile";
import { initWorkerMetrics } from "./WorkerMetrics";
const config = getServerConfigFromServer();
const config = getServerConfig();
const workerId = parseInt(process.env.WORKER_ID ?? "0");
const log = logger.child({ comp: `w_${workerId}` });
+2 -2
View File
@@ -4,7 +4,7 @@ import {
PeriodicExportingMetricReader,
} from "@opentelemetry/sdk-metrics";
import * as dotenv from "dotenv";
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
import { getServerConfig } from "../core/configuration/ConfigLoader";
import { GameManager } from "./GameManager";
import { getOtelResource, getPromLabels } from "./OtelResource";
@@ -12,7 +12,7 @@ dotenv.config();
export function initWorkerMetrics(gameManager: GameManager): void {
// Get server configuration
const config = getServerConfigFromServer();
const config = getServerConfig();
// Create resource with worker information
const resource = getOtelResource();
+2 -3
View File
@@ -1,5 +1,6 @@
// Minimal test maps for pathfinding unit tests
import { GameEnv } from "src/core/configuration/Config";
import {
Difficulty,
Game,
@@ -12,7 +13,6 @@ import { createGame as createGameImpl } from "../../../src/core/game/GameImpl";
import { GameMapImpl } from "../../../src/core/game/GameMap";
import { UserSettings } from "../../../src/core/game/UserSettings";
import { TestConfig } from "../../util/TestConfig";
import { TestServerConfig } from "../../util/TestServerConfig";
export const W = "W"; // Water
export const L = "L"; // Land
@@ -130,7 +130,6 @@ export function createGame(data: TestMapData): Game {
miniNumLand,
);
const serverConfig = new TestServerConfig();
const gameConfig = {
gameMap: GameMapType.Asia,
gameMapSize: GameMapSize.Normal,
@@ -148,8 +147,8 @@ export function createGame(data: TestMapData): Game {
randomSpawn: false,
};
const config = new TestConfig(
serverConfig,
gameConfig,
GameEnv.Dev,
new UserSettings(),
false,
);
+2 -1
View File
@@ -1,5 +1,6 @@
import fs from "fs";
import path, { dirname } from "path";
import { GameEnv } from "src/core/configuration/Config";
import { fileURLToPath } from "url";
import {
Difficulty,
@@ -248,7 +249,6 @@ export async function setupFromPath(
// Configure the game
const config = new TestConfig(
new (await import("../util/TestServerConfig")).TestServerConfig(),
{
gameMap: GameMapType.Asia,
gameMapSize: GameMapSize.Normal,
@@ -265,6 +265,7 @@ export async function setupFromPath(
randomSpawn: false,
...gameConfig,
},
GameEnv.Dev,
new UserSettings(),
false,
);
+2 -3
View File
@@ -1,5 +1,6 @@
import fs from "fs";
import path from "path";
import { GameEnv } from "src/core/configuration/Config";
import {
Difficulty,
Game,
@@ -18,7 +19,6 @@ import {
import { UserSettings } from "../../src/core/game/UserSettings";
import { GameConfig } from "../../src/core/Schemas";
import { TestConfig } from "./TestConfig";
import { TestServerConfig } from "./TestServerConfig";
export async function setup(
mapName: string,
@@ -54,7 +54,6 @@ export async function setup(
const miniGameMap = await genTerrainFromBin(manifest.map4x, miniMapBinBuffer);
// Configure the game
const serverConfig = new TestServerConfig();
const gameConfig: GameConfig = {
gameMap: GameMapType.Asia,
gameMapSize: GameMapSize.Normal,
@@ -72,8 +71,8 @@ export async function setup(
..._gameConfig,
};
const config = new ConfigClass(
serverConfig,
gameConfig,
GameEnv.Dev,
new UserSettings(),
false,
);
+5 -14
View File
@@ -56,7 +56,11 @@ export default defineConfig(({ mode }) => {
template: "index.html",
inject: {
data: {
// In case we need to inject variables into HTML
serverConfig: JSON.stringify({
gameEnv: isProduction ? env.GAME_ENV : "Dev",
numWorkers: isProduction ? parseInt(env.NUM_WORKERS, 10) : 2,
gitCommit: isProduction ? env.GIT_COMMIT : "DEV",
}),
},
},
}),
@@ -71,19 +75,6 @@ export default defineConfig(({ mode }) => {
tailwindcss(),
],
define: {
"process.env.WEBSOCKET_URL": JSON.stringify(
isProduction ? "" : "localhost:3000",
),
"process.env.GAME_ENV": JSON.stringify(isProduction ? "prod" : "dev"),
"process.env.GIT_COMMIT": JSON.stringify(gitCommit),
"process.env.STRIPE_PUBLISHABLE_KEY": JSON.stringify(
env.STRIPE_PUBLISHABLE_KEY,
),
"process.env.API_DOMAIN": JSON.stringify(env.API_DOMAIN),
// Add other process.env variables if needed, OR migrate code to import.meta.env
},
build: {
outDir: "static", // Webpack outputs to 'static', assuming we want to keep this.
emptyOutDir: true,