From b40db8c6f2285e489c71100c80d3c9845a9feb62 Mon Sep 17 00:00:00 2001 From: Isaac Thoman <49598528+IsaacThoman@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:43:43 -0500 Subject: [PATCH 1/4] ci: cache NPM and Deno dependencies in Dockerfile --- Dockerfile | 35 ++++++++++++++++++++++------------- deno.json | 4 +++- import_map.json | 8 ++++++++ 3 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 import_map.json diff --git a/Dockerfile b/Dockerfile index c40912c..262580a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,33 @@ -FROM denoland/deno:2.1.2 -LABEL authors="Candiru " +# Build stage +FROM denoland/deno:2.1.2 AS builder +WORKDIR /app + +# Copy all source files +COPY . . + +# Cache dependencies +RUN deno cache --import-map=import_map.json main.ts + +# Build the application +RUN deno task build -# Set working directory +# Runtime stage +FROM denoland/deno:2.1.2 WORKDIR /app -# Install curl +# Install curl for runtime USER root RUN apt-get update && apt-get install -y curl -# Copy the project files -COPY . . +# Copy ALL source files and build artifacts +COPY --from=builder /app/ ./ + +# Copy the Deno cache +COPY --from=builder /deno-dir/ /deno-dir/ -# Ensure the deno user has ownership of the necessary files and directories +# Set permissions RUN chown -R deno:deno /app -# Switch back to deno user USER deno - -# Expose the port EXPOSE 3000 - -# Run the task -CMD ["task", "start"] +CMD ["task", "startnobuild"] diff --git a/deno.json b/deno.json index b99aba1..934073e 100644 --- a/deno.json +++ b/deno.json @@ -2,9 +2,11 @@ "tasks": { "dev": "deno run -A --node-modules-dir npm:vite", "build": "deno run -A --node-modules-dir npm:vite build", + "cache": "deno cache --import-map=import_map.json main.ts", "preview": "deno run -A --node-modules-dir npm:vite preview", "serve": "deno run --allow-net --allow-read jsr:@std/http@1/file-server dist/", - "start": "deno task build && deno run --allow-read --allow-env --allow-net --allow-write main.ts" + "start": "deno task build && deno run --allow-read --allow-env --allow-net --allow-write main.ts", + "startnobuild": "deno run --allow-read --allow-env --allow-net --allow-write main.ts" }, "compilerOptions": { "lib": ["ES2020", "DOM", "DOM.Iterable", "deno.ns"] diff --git a/import_map.json b/import_map.json new file mode 100644 index 0000000..6037fe6 --- /dev/null +++ b/import_map.json @@ -0,0 +1,8 @@ +{ + "imports": { + "@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0", + "@oak/oak": "jsr:@oak/oak@^17.1.3", + "@std/http": "jsr:@std/http@^1.0.10", + "vite": "npm:vite@^5.4.8" + } +} From 09e9d5c7f05f0f6a03064d68e95e4b7bc101aca4 Mon Sep 17 00:00:00 2001 From: Isaac Thoman <49598528+IsaacThoman@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:46:34 -0500 Subject: [PATCH 2/4] nodeModulesDir to auto --- deno.json | 1 + 1 file changed, 1 insertion(+) diff --git a/deno.json b/deno.json index 934073e..9a1e12c 100644 --- a/deno.json +++ b/deno.json @@ -1,4 +1,5 @@ { + "nodeModulesDir": "auto", "tasks": { "dev": "deno run -A --node-modules-dir npm:vite", "build": "deno run -A --node-modules-dir npm:vite build", From e4f5ed11054b50a2c3efcec68c9ab3a6b8e0d979 Mon Sep 17 00:00:00 2001 From: Isaac Thoman <49598528+IsaacThoman@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:53:37 -0500 Subject: [PATCH 3/4] undo auto nodeModulesDir --- deno.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deno.json b/deno.json index 9a1e12c..3e29414 100644 --- a/deno.json +++ b/deno.json @@ -1,5 +1,5 @@ { - "nodeModulesDir": "auto", + "nodeModulesDir": "manual", "tasks": { "dev": "deno run -A --node-modules-dir npm:vite", "build": "deno run -A --node-modules-dir npm:vite build", From d6702a1d3dd5f98144d68bb627425ea38457531c Mon Sep 17 00:00:00 2001 From: Isaac Thoman <49598528+IsaacThoman@users.noreply.github.com> Date: Mon, 27 Jan 2025 23:06:13 -0500 Subject: [PATCH 4/4] types: remove implicit any --- deno.json | 2 +- src/client/core/AssetManager.ts | 10 +++++----- src/client/core/RemotePlayerRenderer.ts | 14 +++++++------- src/client/items/BananaGun.ts | 4 ++-- src/client/items/FishGun.ts | 4 ++-- src/client/items/FlagItem.ts | 4 ++-- src/client/items/ItemBase.ts | 4 ++-- src/client/items/Pipe.ts | 6 +++--- src/client/ui/DirectionIndicator.ts | 2 +- src/client/ui/HealthIndicator.ts | 2 +- src/client/ui/IndicatorBase.ts | 6 +++--- 11 files changed, 29 insertions(+), 29 deletions(-) diff --git a/deno.json b/deno.json index 3e29414..9a1e12c 100644 --- a/deno.json +++ b/deno.json @@ -1,5 +1,5 @@ { - "nodeModulesDir": "manual", + "nodeModulesDir": "auto", "tasks": { "dev": "deno run -A --node-modules-dir npm:vite", "build": "deno run -A --node-modules-dir npm:vite build", diff --git a/src/client/core/AssetManager.ts b/src/client/core/AssetManager.ts index 6acfa9c..0b29d7c 100644 --- a/src/client/core/AssetManager.ts +++ b/src/client/core/AssetManager.ts @@ -1,4 +1,4 @@ -import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; +import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; import * as THREE from 'three'; @@ -31,11 +31,11 @@ export class AssetManager { private cloneWithNewMaterials(scene: THREE.Group): THREE.Group { const clonedScene = scene.clone(); - clonedScene.traverse((node) => { + clonedScene.traverse((node: THREE.Object3D) => { if ((node as THREE.Mesh).isMesh) { const mesh = node as THREE.Mesh; if (Array.isArray(mesh.material)) { - mesh.material = mesh.material.map((mat) => mat.clone()); + mesh.material = mesh.material.map((mat: THREE.Material) => mat.clone()); } else { mesh.material = mesh.material.clone(); } @@ -60,7 +60,7 @@ export class AssetManager { this.assets.set(url, { scene: new THREE.Group(), isLoaded: false, callbacks: [callback] }); this.gltfLoader.load( url, - (gltf) => { + (gltf: GLTF) => { const assetEntry = this.assets.get(url)!; assetEntry.scene = gltf.scene; assetEntry.isLoaded = true; @@ -72,7 +72,7 @@ export class AssetManager { assetEntry.callbacks = []; }, undefined, - (error) => { + (error: Error) => { console.error(`Error loading asset ${url}:`, error); }, ); diff --git a/src/client/core/RemotePlayerRenderer.ts b/src/client/core/RemotePlayerRenderer.ts index 978944b..85122cd 100644 --- a/src/client/core/RemotePlayerRenderer.ts +++ b/src/client/core/RemotePlayerRenderer.ts @@ -1,6 +1,6 @@ import * as THREE from 'three'; import { Networking } from './Networking.ts'; -import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; +import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree } from 'three-mesh-bvh'; import { Player, PlayerData } from '../../shared/Player.ts'; @@ -74,7 +74,7 @@ export class RemotePlayerRenderer { this.possumMesh = undefined; this.loader.load( 'models/simplified_possum.glb', - (gltf) => { + (gltf: GLTF) => { console.time('Computing possum BVH'); ( gltf.scene.children[0]).geometry.computeBoundsTree(); console.timeEnd('Computing possum BVH'); @@ -412,7 +412,7 @@ export class RemotePlayerRenderer { const wallIntersects = this.raycaster.intersectObjects([RemotePlayerRenderer.map]); this.raycaster.firstHitOnly = false; - const filteredIntersects = playerIntersects.filter((playerIntersect) => { + const filteredIntersects = playerIntersects.filter((playerIntersect: THREE.Intersection) => { for (const wallIntersect of wallIntersects) { if (wallIntersect.distance < playerIntersect.distance) { return false; @@ -424,7 +424,7 @@ export class RemotePlayerRenderer { return true; }); - return filteredIntersects.map((intersect) => intersect.object); + return filteredIntersects.map((intersect: THREE.Intersection) => intersect.object); } public getPlayerSpheresInCrosshairWithWalls(): THREE.Object3D[] { @@ -437,7 +437,7 @@ export class RemotePlayerRenderer { const wallIntersects = this.raycaster.intersectObjects([RemotePlayerRenderer.map]); this.raycaster.firstHitOnly = false; - const filteredIntersects = playerIntersects.filter((playerIntersect) => { + const filteredIntersects = playerIntersects.filter((playerIntersect: THREE.Intersection) => { for (const wallIntersect of wallIntersects) { if (wallIntersect.distance < playerIntersect.distance) { return false; @@ -446,7 +446,7 @@ export class RemotePlayerRenderer { return true; }); - return filteredIntersects.map((intersect) => intersect.object); + return filteredIntersects.map((intersect: THREE.Intersection) => intersect.object); } public getShotVectorsToPlayersWithOffset( @@ -467,7 +467,7 @@ export class RemotePlayerRenderer { this.raycaster.firstHitOnly = false; // Filter player intersections based on wall intersections - const filteredPlayerIntersects = playerIntersects.filter((playerIntersect) => { + const filteredPlayerIntersects = playerIntersects.filter((playerIntersect: THREE.Intersection) => { for (const wallIntersect of wallIntersects) { if (wallIntersect.distance < playerIntersect.distance) { return false; // A wall is blocking the player diff --git a/src/client/items/BananaGun.ts b/src/client/items/BananaGun.ts index 37002dd..61bf049 100644 --- a/src/client/items/BananaGun.ts +++ b/src/client/items/BananaGun.ts @@ -38,12 +38,12 @@ export class BananaGun extends ItemBase { AssetManager.getInstance().loadAsset('models/simplified_banana_1.glb', (scene) => { this.object = scene; if (this.itemType === ItemType.InventoryItem) { - this.object.traverse((child) => { + this.object.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { child.renderOrder = 999; const mesh = child as THREE.Mesh; if (Array.isArray(mesh.material)) { - mesh.material.forEach((mat) => mat.depthTest = false); + mesh.material.forEach((mat: THREE.Material) => mat.depthTest = false); } else { mesh.material.depthTest = false; } diff --git a/src/client/items/FishGun.ts b/src/client/items/FishGun.ts index b4d4854..c3ab042 100644 --- a/src/client/items/FishGun.ts +++ b/src/client/items/FishGun.ts @@ -39,12 +39,12 @@ export class FishGun extends ItemBase { AssetManager.getInstance().loadAsset('models/simplified_fish.glb', (scene) => { this.object = scene; if (this.itemType === ItemType.InventoryItem) { - this.object.traverse((child) => { + this.object.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { child.renderOrder = 999; const mesh = child as THREE.Mesh; if (Array.isArray(mesh.material)) { - mesh.material.forEach((mat) => mat.depthTest = false); + mesh.material.forEach((mat: THREE.Material) => mat.depthTest = false); } else { mesh.material.depthTest = false; } diff --git a/src/client/items/FlagItem.ts b/src/client/items/FlagItem.ts index bafab14..287d1d0 100644 --- a/src/client/items/FlagItem.ts +++ b/src/client/items/FlagItem.ts @@ -31,12 +31,12 @@ export class FlagItem extends ItemBase { AssetManager.getInstance().loadAsset('models/simplified_pizza.glb', (scene) => { this.object = scene; if (this.itemType === ItemType.InventoryItem) { - this.object.traverse((child) => { + this.object.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { child.renderOrder = 999; const mesh = child as THREE.Mesh; if (Array.isArray(mesh.material)) { - mesh.material.forEach((mat) => mat.depthTest = false); + mesh.material.forEach((mat: THREE.Material) => mat.depthTest = false); } else { mesh.material.depthTest = false; } diff --git a/src/client/items/ItemBase.ts b/src/client/items/ItemBase.ts index 54f0070..e4dba89 100644 --- a/src/client/items/ItemBase.ts +++ b/src/client/items/ItemBase.ts @@ -38,10 +38,10 @@ export class ItemBase { this.inventoryMenuObject = this.object.clone(); if (this.itemType === ItemType.InventoryItem) { - this.object.traverse((child) => { + this.object.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { child.renderOrder = 999; - const applyDepthTest = (material: THREE.Material | THREE.Material[]) => { + const applyDepthTest = (material: THREE.Material | THREE.Material[]): void => { if (Array.isArray(material)) { material.forEach((mat) => applyDepthTest(mat)); // Recursively handle array elements } else { diff --git a/src/client/items/Pipe.ts b/src/client/items/Pipe.ts index f517784..e52ddcb 100644 --- a/src/client/items/Pipe.ts +++ b/src/client/items/Pipe.ts @@ -38,14 +38,14 @@ export class Pipe extends ItemBase { public override init() { AssetManager.getInstance().loadAsset('models/simplified_rusty_pipe.glb', (scene) => { - this.object = scene; + this.object = scene; // if (this.itemType === ItemType.InventoryItem) { - this.object.traverse((child) => { + this.object.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { child.renderOrder = 999; const mesh = child as THREE.Mesh; if (Array.isArray(mesh.material)) { - mesh.material.forEach((mat) => mat.depthTest = false); + mesh.material.forEach((mat: THREE.Material) => mat.depthTest = false); } else { mesh.material.depthTest = false; } diff --git a/src/client/ui/DirectionIndicator.ts b/src/client/ui/DirectionIndicator.ts index 81d1d1b..8eb3496 100644 --- a/src/client/ui/DirectionIndicator.ts +++ b/src/client/ui/DirectionIndicator.ts @@ -24,7 +24,7 @@ export class DirectionIndicator extends IndicatorBase { this.loadModel('models/arrow.glb') .then((model) => { this.directionObject = model; - this.directionObject.traverse((child) => { + this.directionObject.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { (child as THREE.Mesh).renderOrder = 999; this.applyDepthTestToMesh(child as THREE.Mesh); diff --git a/src/client/ui/HealthIndicator.ts b/src/client/ui/HealthIndicator.ts index ecbaf4d..31530ef 100644 --- a/src/client/ui/HealthIndicator.ts +++ b/src/client/ui/HealthIndicator.ts @@ -31,7 +31,7 @@ export class HealthIndicator extends IndicatorBase { this.loadModel('models/simplified_possum.glb') .then((model) => { this.possumObject = model; - this.possumObject.traverse((child) => { + this.possumObject.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { (child as THREE.Mesh).renderOrder = 999; this.applyDepthTest(child as THREE.Mesh); diff --git a/src/client/ui/IndicatorBase.ts b/src/client/ui/IndicatorBase.ts index 6a89e65..aeaafc7 100644 --- a/src/client/ui/IndicatorBase.ts +++ b/src/client/ui/IndicatorBase.ts @@ -1,5 +1,5 @@ import * as THREE from 'three'; -import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; +import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; import { Player } from '../../shared/Player.ts'; import { Networking } from '../core/Networking.ts'; @@ -87,9 +87,9 @@ export abstract class IndicatorBase { return new Promise((resolve, reject) => { loader.load( modelPath, - (gltf) => { + (gltf: GLTF) => { const object = gltf.scene; - object.traverse((child) => { + object.traverse((child: THREE.Object3D) => { if ((child as THREE.Mesh).isMesh) { (child as THREE.Mesh).renderOrder = 999; this.applyDepthTest(child as THREE.Mesh);