#!/usr/bin/env bash # 步骤 1:打包 — 单一运行时包,本地与 CDN 完全一致 # # bash tools/package-for-project.sh # # 产物: # build/mstest5/ 运行时包(← 本地 import + OSS 上传,内容相同) # build/deploy/ 上传清单(不进 OSS / static) # build/standalone-player/ 独立调试页(可选,不进 OSS / static) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" BUILD_DIR="$PROJECT_DIR/build/web-desktop" MODE="cdn" OUT_DIR="$PROJECT_DIR/build/mstest5" DEPLOY_DIR="$PROJECT_DIR/build/deploy" CDN_BASE="" PKG_EXTRA=() CDN_REF="${COCOS_CDN_UNITY_REF:-$HOME/tfrh/竞赛/mstest5}" SKIP_MANIFEST=0 MAKE_ZIP=0 usage() { echo "步骤 1 - 打包(单一运行时包)" >&2 echo "" >&2 echo "用法: $0 [options]" >&2 echo " --build DIR Cocos 构建目录(默认 build/web-desktop)" >&2 echo " --out DIR 运行时包目录(默认 build/mstest5)" >&2 echo " --mode cdn|flat cdn=默认; flat=旧扁平包(不推荐)" >&2 echo " --cdn-base URL 写入 deploy/UPLOAD-MANIFEST.txt" >&2 echo " --skip-manifest 不生成 deploy/ 清单" >&2 echo " --zip 额外生成 build/mstest5-runtime.zip" >&2 echo "" >&2 echo "默认分包: assets_all 首屏含 level-prefabs 壳;每关独立 bundle 进关按需" >&2 echo " MERGE_LEVELS=1 合并 level-prefabs 进 assets_all(不推荐)" >&2 echo "运行时包结构(本地 static/unity = OSS unitycdndir):" >&2 echo " Build/ StreamingAssets/ levels-database.json(.br)" >&2 echo "" >&2 echo "步骤 2: scratch-gui/static/unity/import-to-unity.sh" >&2 } while [[ $# -gt 0 ]]; do case "$1" in --build) BUILD_DIR="$2"; shift 2 ;; --out) OUT_DIR="$2"; shift 2 ;; --mode) MODE="$2"; shift 2 ;; --cdn-base) CDN_BASE="$2"; shift 2 ;; --skip-manifest) SKIP_MANIFEST=1; shift ;; --zip) MAKE_ZIP=1; shift ;; --brotli-db) PKG_EXTRA+=(--brotli-db); shift ;; --preload-resources) PKG_EXTRA+=(--preload-resources); shift ;; --no-minify-db) PKG_EXTRA+=(--no-minify-db); shift ;; -h|--help) usage; exit 0 ;; *) echo "未知参数: $1" >&2; usage; exit 1 ;; esac done [[ -f "$BUILD_DIR/index.js" || -f "$BUILD_DIR/index.html" ]] || { echo "错误: 请先 Cocos 构建 Web Desktop: $BUILD_DIR" >&2 exit 1 } DB="$PROJECT_DIR/assets/level-data/levels-database.json" if [[ ! -f "$DB" ]] || [[ "$(python3 -c "import json; d=json.load(open('$DB')); print(len(d.get('levels',{})))" 2>/dev/null || echo 0)" -lt 100 ]]; then echo "==> 从 Cocos 导出关卡库" bash "$SCRIPT_DIR/sync-level-db.sh" fi case "$MODE" in cdn) CDN_REF="$(cd "$CDN_REF" 2>/dev/null && pwd || true)" if [[ -z "$CDN_REF" || ! -f "$CDN_REF/StreamingAssets/aa/catalog.json" ]]; then echo "错误: 缺少 Unity 参考包: $CDN_REF" >&2 exit 1 fi # 移除旧的双份产物 rm -rf "$PROJECT_DIR/build/cdn-upload" "$PROJECT_DIR/build/cdn-upload.zip" 2>/dev/null || true echo "==> [1/2] 打运行时包" bash "$SCRIPT_DIR/verify-split-build.sh" "$BUILD_DIR" node "$SCRIPT_DIR/package-for-cdn.js" "$BUILD_DIR" "$OUT_DIR" "$CDN_REF" if [[ "$SKIP_MANIFEST" -eq 0 ]]; then echo "==> [2/2] 生成 OSS 上传清单(build/deploy/,不复制包)" MANIFEST_ARGS=("$OUT_DIR" --manifest-dir "$DEPLOY_DIR") [[ -n "$CDN_BASE" ]] && MANIFEST_ARGS+=(--cdn-base "$CDN_BASE") [[ "$MAKE_ZIP" -eq 1 ]] && MANIFEST_ARGS+=(--zip) node "$SCRIPT_DIR/write-deploy-manifest.js" "${MANIFEST_ARGS[@]}" fi ;; flat) OUT_DIR="${OUT_DIR:-$PROJECT_DIR/build/unity-runtime}" echo "==> [警告] flat 模式与 CDN 不一致" >&2 if ((${#PKG_EXTRA[@]} > 0)); then node "$SCRIPT_DIR/package-for-project.js" "$BUILD_DIR" "$OUT_DIR" "${PKG_EXTRA[@]}" else node "$SCRIPT_DIR/package-for-project.js" "$BUILD_DIR" "$OUT_DIR" fi ;; *) echo "错误: --mode 须为 cdn 或 flat" >&2 exit 1 ;; esac echo "" echo "==> 运行时包: $OUT_DIR" echo " 本地: import-to-unity.sh" echo " CDN: 上传 $OUT_DIR/ 全部 → unitycdndir" [[ "$SKIP_MANIFEST" -eq 0 && "$MODE" == "cdn" ]] && echo " 清单: $DEPLOY_DIR/UPLOAD-MANIFEST.txt"