From 001722bd59a86dfeb7713ef054eebd1bbc0e08b9 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Tue, 13 Aug 2024 20:07:20 -0700 Subject: [PATCH] added deployment --- Dockerfile | 4 +- TODO.txt | 4 +- package-lock.json | 8 +++ package.json | 3 +- src/client/Client.ts | 6 ++- src/client/ClientGame.ts | 3 +- src/core/PseudoRandom.ts | 4 ++ src/core/Util.ts | 6 --- src/server/GameManager.ts | 8 +-- update-deploy.sh | 8 +-- webpack.config.js | 106 ++++++++++++++++++++------------------ 11 files changed, 90 insertions(+), 70 deletions(-) mode change 100644 => 100755 update-deploy.sh diff --git a/Dockerfile b/Dockerfile index d74977628..6615cfdf1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,11 +13,11 @@ RUN npm install # Copy the rest of the application code COPY . . -# Build the application +# Build the client-side application RUN npm run build-prod # Expose the port the app runs on EXPOSE 3000 # Define the command to run the app -CMD [ "node", "dist/server/server.js" ] \ No newline at end of file +CMD ["npm", "run", "start:server"] \ No newline at end of file diff --git a/TODO.txt b/TODO.txt index f37945945..cd885c41b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -15,10 +15,10 @@ * improve front page DONE 8/12/2024 * attacks cancel out DONE 8/13/2024 * upload and start server -* fix enemy islands when attacking * better algorithm for name render placement * make boats larger * have boats not get close to shore * make coasts look better * add shader to dim border -* remove player.info() \ No newline at end of file +* remove player.info() +* fix enemy islands when attacking diff --git a/package-lock.json b/package-lock.json index 4bcb6bfdc..bec3e91e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "@types/express": "^4.17.21", "@types/jimp": "^0.2.28", "colord": "^2.9.3", + "crypto": "^1.0.1", "express": "^4.19.2", "jimp": "^0.22.12", "node-addon-api": "^8.1.0", @@ -5170,6 +5171,13 @@ "node": ">= 8" } }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.", + "license": "ISC" + }, "node_modules/css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", diff --git a/package.json b/package.json index 511ef8099..e8b7cbdf2 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@types/express": "^4.17.21", "@types/jimp": "^0.2.28", "colord": "^2.9.3", + "crypto": "^1.0.1", "express": "^4.19.2", "jimp": "^0.22.12", "node-addon-api": "^8.1.0", @@ -52,4 +53,4 @@ "zod": "^3.23.8" }, "type": "module" -} \ No newline at end of file +} diff --git a/src/client/Client.ts b/src/client/Client.ts index f05a4fe4a..f6cf2d29d 100644 --- a/src/client/Client.ts +++ b/src/client/Client.ts @@ -1,8 +1,8 @@ import {defaultConfig} from "../core/configuration/DefaultConfig"; import {TerrainMap} from "../core/Game"; +import {PseudoRandom} from "../core/PseudoRandom"; import {ServerMessage, ServerMessageSchema} from "../core/Schemas"; import {loadTerrainMap} from "../core/TerrainMapLoader"; -import {generateUniqueID} from "../core/Util"; import {ClientGame, createClientGame} from "./ClientGame"; import {v4 as uuidv4} from 'uuid'; @@ -18,6 +18,8 @@ class Client { private lobbiesContainer: HTMLElement | null; private lobbiesInterval: NodeJS.Timeout | null = null; + private random = new PseudoRandom(1234) + constructor() { this.lobbiesContainer = document.getElementById('lobbies-container'); @@ -84,7 +86,7 @@ class Client { if (this.game != null) { return } - this.game = createClientGame(getUsername(), generateUniqueID(), lobbyID, defaultConfig, map) + this.game = createClientGame(getUsername(), this.random.nextID(), lobbyID, defaultConfig, map) this.game.joinLobby() }) } diff --git a/src/client/ClientGame.ts b/src/client/ClientGame.ts index 7d37dc0b9..e8b1c9aad 100644 --- a/src/client/ClientGame.ts +++ b/src/client/ClientGame.ts @@ -60,7 +60,8 @@ export class ClientGame { ) { } public joinLobby() { - this.socket = new WebSocket(`ws://localhost:3000`) + const wsHost = process.env.WEBSOCKET_URL || window.location.host; + this.socket = new WebSocket(`ws://${wsHost}`) this.socket.onopen = () => { console.log('Connected to game server!'); this.socket.send( diff --git a/src/core/PseudoRandom.ts b/src/core/PseudoRandom.ts index 6ddd18fc2..6dc7eb391 100644 --- a/src/core/PseudoRandom.ts +++ b/src/core/PseudoRandom.ts @@ -30,4 +30,8 @@ export class PseudoRandom { nextFloat(min: number, max: number): number { return this.next() * (max - min) + min; } + + nextID(): string { + return this.nextInt(0, 1000000).toString(36).padStart(5, '0'); + } } \ No newline at end of file diff --git a/src/core/Util.ts b/src/core/Util.ts index 49a684f48..914fc3b38 100644 --- a/src/core/Util.ts +++ b/src/core/Util.ts @@ -1,11 +1,5 @@ import {Cell} from "./Game"; -export function generateUniqueID(): string { - const array = new Uint8Array(16); - crypto.getRandomValues(array); - return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join(''); -} - export function manhattanDist(c1: Cell, c2: Cell): number { return Math.abs(c1.x - c2.x) + Math.abs(c1.y - c2.y); } \ No newline at end of file diff --git a/src/server/GameManager.ts b/src/server/GameManager.ts index 3be081a3d..e00fef40b 100644 --- a/src/server/GameManager.ts +++ b/src/server/GameManager.ts @@ -3,8 +3,8 @@ import {Client} from "./Client"; import {Lobby} from "./Lobby"; import {GameServer} from "./GameServer"; import {Config} from "../core/configuration/Config"; -import {generateUniqueID} from "../core/Util"; import {defaultConfig} from "../core/configuration/DefaultConfig"; +import {PseudoRandom} from "../core/PseudoRandom"; export class GameManager { @@ -14,6 +14,8 @@ export class GameManager { private games: Map = new Map() + private random = new PseudoRandom(123) + constructor(private settings: Config) { } @@ -42,7 +44,7 @@ export class GameManager { } startGame(lobby: Lobby) { - const gs = new GameServer(generateUniqueID(), lobby.clients, defaultConfig) + const gs = new GameServer(this.random.nextID(), lobby.clients, defaultConfig) this.games.set(gs.id, gs) gs.start() } @@ -61,7 +63,7 @@ export class GameManager { if (now > this.lastNewLobby + this.settings.lobbyCreationRate()) { this.lastNewLobby = now - this.addLobby(new Lobby(generateUniqueID(), this.settings.lobbyLifetime())) + this.addLobby(new Lobby(this.random.nextID(), this.settings.lobbyLifetime())) } } } \ No newline at end of file diff --git a/update-deploy.sh b/update-deploy.sh old mode 100644 new mode 100755 index ea352f08a..07bba29e5 --- a/update-deploy.sh +++ b/update-deploy.sh @@ -1,20 +1,20 @@ #!/bin/bash # Ensure you're authenticated with Google Cloud -gcloud auth configure-docker +gcloud auth configure-docker us-central1-docker.pkg.dev # Build the new Docker image docker build -t openfrontio . # Tag the new image (use a version number or 'latest') -docker tag openfrontio gcr.io/[YOUR-PROJECT-ID]/openfrontio:latest +docker tag openfrontio us-central1-docker.pkg.dev/openfrontio/openfrontio/game-server:latest # Push the new image to Google Container Registry -docker push gcr.io/[YOUR-PROJECT-ID]/openfrontio:latest +docker push us-central1-docker.pkg.dev/openfrontio/openfrontio/game-server:latest # Update the GCE instance with the new container image gcloud compute instances update-container openfrontio-instance \ - --container-image us-central1-docker.pkg.dev/openfrontio/openfrontio:latest \ + --container-image us-central1-docker.pkg.dev/openfrontio/openfrontio/game-server:latest \ --zone=us-central1-a echo "Deployment complete. New version should be live soon." \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index fabde4cd7..3231c475a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,59 +1,67 @@ import path from 'path'; import {fileURLToPath} from 'url'; import HtmlWebpackPlugin from 'html-webpack-plugin'; +import webpack from 'webpack'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -export default { - entry: './src/client/Client.ts', - output: { - filename: 'bundle.js', - path: path.resolve(__dirname, 'out'), - }, - module: { - rules: [ - { - test: /\.ts$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - { - test: /\.(png|jpe?g|gif)$/i, - type: 'asset/resource', - generator: { - filename: 'images/[hash][ext][query]' - } - } - ], - }, - resolve: { - extensions: ['.ts', '.js'], - }, - plugins: [ - new HtmlWebpackPlugin({ - template: './src/client/index.html', - filename: 'index.html' - }), - ], - devServer: { - static: { - directory: path.join(__dirname, 'out'), +export default (env, argv) => { + const isProduction = argv.mode === 'production'; + + return { + entry: './src/client/Client.ts', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'out'), }, - compress: true, - port: 9000, - proxy: [ - { - context: ['/socket'], - target: 'ws://localhost:3000', - ws: true, - }, - { - context: ['/lobbies', '/join_game', '/join_lobby'], // Add any other API endpoints here - target: 'http://localhost:3000', - secure: false, - changeOrigin: true, - } + module: { + rules: [ + { + test: /\.ts$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /\.(png|jpe?g|gif)$/i, + type: 'asset/resource', + generator: { + filename: 'images/[hash][ext][query]' + } + } + ], + }, + resolve: { + extensions: ['.ts', '.js'], + }, + plugins: [ + new HtmlWebpackPlugin({ + template: './src/client/index.html', + filename: 'index.html' + }), + new webpack.DefinePlugin({ + 'process.env.WEBSOCKET_URL': JSON.stringify(isProduction ? '' : 'localhost:3000') + }), ], - }, + devServer: isProduction ? {} : { + static: { + directory: path.join(__dirname, 'out'), + }, + compress: true, + port: 9000, + proxy: [ + { + context: ['/socket'], + target: 'ws://localhost:3000', + ws: true, + }, + { + context: ['/lobbies', '/join_game', '/join_lobby'], + target: 'http://localhost:3000', + secure: false, + changeOrigin: true, + } + ], + }, + }; }; \ No newline at end of file