diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0abccc8..50fb2079 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,12 +108,7 @@ jobs: run: | source emsdk/emsdk_env.sh cd assets - python3 base.py \ - --root https://static.sourga.me/blobs/6481/.index.source \ - --models \ - --download \ - --outdir dist \ - complex dust2 turbine + ./ci - name: Upload uses: actions/upload-artifact@v4 diff --git a/assets/.gitignore b/assets/.gitignore index 316ef7d6..330106c1 100644 --- a/assets/.gitignore +++ b/assets/.gitignore @@ -6,3 +6,4 @@ __pycache__ quadropolis *.tar.gz cache/** +/dist diff --git a/assets/base.py b/assets/base.py index d9503e9b..2c8bd7ab 100644 --- a/assets/base.py +++ b/assets/base.py @@ -272,6 +272,7 @@ def expand_hudguns(prefix: str) -> List[str]: for model in fps_models: print(model) model_files = package.dump_sour("model", model, params.roots) + for mapping in model_files: if mapping[1] in fps_mounted: continue @@ -292,15 +293,25 @@ def expand_hudguns(prefix: str) -> List[str]: def _build_map(_map: str) -> Optional[BuildResult]: return build_map(params, outdir, _map) - with Pool(cpu_count()) as pool: - for result in track(pool.imap_unordered( - _build_map, - maps, - ), "building maps", total=len(maps)): + # TODO pool.imap_unordered is failing in local macOS dev + if package.IS_MACOS: + for map_ in maps: + result = _build_map(map_) if not result: continue p.assets = p.assets | result.assets p.maps += result.maps p.bundles += result.bundles + else: + with Pool(cpu_count()) as pool: + for result in track(pool.imap_unordered( + _build_map, + maps, + ), "building maps", total=len(maps)): + if not result: + continue + p.assets = p.assets | result.assets + p.maps += result.maps + p.bundles += result.bundles p.dump_index(args.prefix) diff --git a/assets/ci b/assets/ci index b41aeb11..5fcb0d55 100755 --- a/assets/ci +++ b/assets/ci @@ -16,17 +16,9 @@ mkdir -p cache outdir=${ASSET_OUTPUT_DIR:-output} -echo "building desktop" python3 base.py \ - --root https://static.sourga.me/blobs/6481/.index.source \ - --download \ - --outdir $outdir/desktop \ - complex dust2 turbine - -echo "building mobile" -python3 base.py \ - --root https://static.sourga.me/blobs/6481/.index.source \ - --download \ - --mobile \ - --outdir $outdir/mobile \ - none + --root https://static.sourga.me/blobs/6481/.index.source \ + --models \ + --download \ + --outdir dist \ + complex dust2 turbine diff --git a/assets/package.py b/assets/package.py index 997e50c8..b75b287f 100644 --- a/assets/package.py +++ b/assets/package.py @@ -19,6 +19,7 @@ # Example: ("/home/cfoust/Downloads/blah.ogz", "packages/base/blah.ogz") Mapping = Tuple[str, str] +IS_MACOS = sys.platform == 'darwin' class Asset(NamedTuple): # The hash of the asset's file contents. Also used as a unique reference. @@ -82,8 +83,9 @@ def hash_string(string: str) -> str: def hash_files(files: List[str]) -> str: + sha256 = 'sha256sum' if not IS_MACOS else 'sha3-256sum' if len(files) == 1: - sha = subprocess.check_output(['sha256sum', files[0]]) + sha = subprocess.check_output([sha256, files[0]]) return sha.decode('utf-8').split(' ')[0] tar = subprocess.Popen([ @@ -98,7 +100,7 @@ def hash_files(files: List[str]) -> str: "--numeric-owner", *files, ], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) - sha = subprocess.check_output(['sha256sum'], stdin=tar.stdout) + sha = subprocess.check_output([sha256], stdin=tar.stdout) tar.wait() return sha.decode('utf-8').split(' ')[0] diff --git a/client/package.json b/client/package.json index 6120a4e7..bb8d8075 100644 --- a/client/package.json +++ b/client/package.json @@ -7,7 +7,7 @@ "license": "MIT", "scripts": { "serve": "./scripts/serve", - "serve:site": "yarn run parcel watch --target default -p 1239", + "serve:site": "yarn run parcel watch --target package -p 1239", "build": "yarn run parcel build --target default" }, "devDependencies": { @@ -39,6 +39,11 @@ "source": "./src/index.tsx", "context": "browser", "distDir": "./dist" + }, + "package": { + "source": "./src/index.tsx", + "context": "browser", + "distDir": "../pkg/server/static/site" } } } diff --git a/client/scripts/serve b/client/scripts/serve index 24814ba3..3d244077 100755 --- a/client/scripts/serve +++ b/client/scripts/serve @@ -17,17 +17,12 @@ ensure_link() { } SITE_DIR="$SCRIPT_DIR/../../pkg/server/static/site" - -if [ -d "$SITE_DIR" ]; then - rm -rf "$SITE_DIR" -fi mkdir -p "$SITE_DIR" cd "$SCRIPT_DIR/../" -yarn build cp "$SRC_DIR/index.html" "$SITE_DIR/index.html" cp "$SRC_DIR/favicon.ico" "$SITE_DIR/favicon.ico" cp "$SRC_DIR/background.png" "$SITE_DIR/background.png" cp -r "$SRC_DIR/../../game/dist/game" "$SITE_DIR" -cp "$DIST_DIR"/* "$SITE_DIR" +yarn serve:site diff --git a/cmd/sour/http.go b/cmd/sour/http.go new file mode 100644 index 00000000..3b652391 --- /dev/null +++ b/cmd/sour/http.go @@ -0,0 +1,19 @@ +package main + +import ( + "net/http" + "strings" +) + +// SkipIndex is an http.Handler that disables the browser cache for .source +// files. +func SkipIndex(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Set cache-control to none if url contains ".source" + if strings.Contains(r.URL.Path, ".source") { + w.Header().Set("Cache-Control", "no-store") + } + + h.ServeHTTP(w, r) + }) +} diff --git a/cmd/sour/serve.go b/cmd/sour/serve.go index 5475b023..09c2ea00 100644 --- a/cmd/sour/serve.go +++ b/cmd/sour/serve.go @@ -226,14 +226,16 @@ func serveCommand(configs []string) error { mux.Handle("/api/", cluster) for i, dir := range fsRoots { + log.Info().Msgf("%s -> /assets/%d", dir, i) prefix := fmt.Sprintf("/assets/%d/", i) - mux.Handle( + + handler := http.FileServer(http.Dir(dir)) + handler = http.StripPrefix( prefix, - http.StripPrefix( - prefix, - http.FileServer(http.Dir(dir)), - ), + handler, ) + handler = SkipIndex(handler) + mux.Handle(prefix, handler) } errc <- http.ListenAndServe( diff --git a/dev.yaml b/dev.yaml new file mode 100644 index 00000000..f670d203 --- /dev/null +++ b/dev.yaml @@ -0,0 +1,67 @@ +# This configuration can be used for local development. +server: + assets: + - "fs:./assets/dist/.index.source" + presets: + - name: "ffa-duel" + virtual: true + config: + defaultMode: "ffa" + defaultMap: "turbine" + - name: "insta-duel" + virtual: true + config: + defaultMode: "insta" + defaultMap: "turbine" + - name: "default" + default: true + config: + defaultMode: "coop" + defaultMap: "xmwhub" + - name: "ffa" + config: + defaultMode: "ffa" + defaultMap: "complex" + maps: + - "turbine" + - "complex" + - "dust2" + - name: "insta" + config: + defaultMode: "insta" + defaultMap: "complex" + maps: + - "turbine" + - "complex" + - "dust2" + - name: "explore" + config: + matchLength: 180 + + ingress: + desktop: + - port: 28785 + target: ffa + serverInfo: + enabled: true + server: true + web: + port: 29999 + + matchmaking: + duel: + - name: "ffa" + preset: "ffa-duel" + forceRespawn: "dead" + default: true + - name: "insta" + preset: "insta-duel" + forceRespawn: "dead" + + spaces: + - preset: ffa + config: + alias: lobby + - preset: insta + config: + alias: insta