91 lines
4.8 KiB
Bash
Executable File
91 lines
4.8 KiB
Bash
Executable File
#!/bin/zsh
|
|
# Portable local macOS bundle with private Client assets and the validated 2x UI archive.
|
|
# scripts/package_mac_app.sh [BUILD_DIR] [CLIENT_DIR] [OUT] [HD_UI_PAK]
|
|
set -euo pipefail
|
|
repo=${0:A:h:h}
|
|
build=${1:-$repo/build/release}
|
|
client=${2:-$repo/build/zh-locale/Client}
|
|
out=${3:-$repo/dist/Metin2.app}
|
|
pak=${4:-${MT_HD_UI_PAK:-$repo/build/hd-ui/hd_ui.pak}}
|
|
bin=$build/src/host/mt_native_render
|
|
[[ -x "$bin" ]] || { echo "missing native executable: $bin" >&2; exit 1; }
|
|
[[ -d "$client/pack" ]] || { echo "missing Client/pack: $client" >&2; exit 1; }
|
|
[[ -f "$pak" ]] || { echo "missing HD UI archive: $pak (run scripts/build_hd_ui.py first)" >&2; exit 1; }
|
|
python3 "$repo/scripts/verify_hd_ui.py" "$pak"
|
|
signing_identity=${MT_CODESIGN_IDENTITY:--}
|
|
version=$(git -C "$repo" describe --always --dirty 2>/dev/null || echo dev)
|
|
mkdir -p "${out:A:h}"
|
|
stage=$(mktemp -d "${out:A}.tmp.XXXXXX")
|
|
trap 'rm -rf "$stage"' EXIT
|
|
mkdir -p "$stage/Contents/MacOS" "$stage/Contents/Resources" "$stage/Contents/Frameworks"
|
|
cp "$bin" "$stage/Contents/MacOS/mt_native_render"
|
|
cp "$build/src/host/native.vert.spv" "$build/src/host/native.frag.spv" "$build/src/host/python27.zip" "$stage/Contents/Resources/"
|
|
cp "$repo/branding/icon/macos/AppIcon.icns" "$stage/Contents/Resources/"
|
|
cp "$pak" "$stage/Contents/Resources/hd_ui.pak"
|
|
# Materialize source links so the bundle is portable; clone asset data on APFS.
|
|
cp -cRL "$client" "$stage/Contents/Resources/Client" 2>/dev/null || {
|
|
mkdir -p "$stage/Contents/Resources/Client"
|
|
rsync -aL "$client/" "$stage/Contents/Resources/Client/"
|
|
}
|
|
for lib in libvulkan.1.dylib libSDL3.0.dylib; do
|
|
dependency=$(otool -L "$bin" | awk -v name="$lib" '$1 ~ name "$" {print $1; exit}')
|
|
[[ -f "$dependency" ]] || { echo "cannot resolve $lib: $dependency" >&2; exit 1; }
|
|
cp "$dependency" "$stage/Contents/Frameworks/$lib"
|
|
install_name_tool -change "$dependency" "@rpath/$lib" "$stage/Contents/MacOS/mt_native_render"
|
|
install_name_tool -id "@rpath/$lib" "$stage/Contents/Frameworks/$lib"
|
|
done
|
|
for rpath in ${(f)"$(otool -l "$bin" | awk '/LC_RPATH/ {getline; getline; print $2}')"}; do
|
|
install_name_tool -delete_rpath "$rpath" "$stage/Contents/MacOS/mt_native_render"
|
|
done
|
|
install_name_tool -add_rpath '@executable_path/../Frameworks' "$stage/Contents/MacOS/mt_native_render"
|
|
molten=${MT_MOLTENVK:-/opt/homebrew/opt/molten-vk/lib/libMoltenVK.dylib}
|
|
[[ -f "$molten" ]] || molten=/usr/local/opt/molten-vk/lib/libMoltenVK.dylib
|
|
[[ -f "$molten" ]] || { echo "missing MoltenVK (set MT_MOLTENVK)" >&2; exit 1; }
|
|
cp "$molten" "$stage/Contents/Frameworks/libMoltenVK.dylib"
|
|
cat > "$stage/Contents/Resources/MoltenVK_icd.json" <<'JSON'
|
|
{"file_format_version":"1.0.0","ICD":{"library_path":"../Frameworks/libMoltenVK.dylib","api_version":"1.2.0","is_portability_driver":true}}
|
|
JSON
|
|
cat > "$stage/Contents/MacOS/Metin2" <<'SH'
|
|
#!/bin/sh
|
|
set -eu
|
|
CONTENTS_DIR="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
RESOURCES_DIR="$CONTENTS_DIR/Resources"
|
|
export VK_ICD_FILENAMES="$RESOURCES_DIR/MoltenVK_icd.json"
|
|
# Resource lookup also works when Finder starts us with cwd=/ or Client is overridden.
|
|
: "${MT_HD_UI_PAK:=$RESOURCES_DIR/hd_ui.pak}"
|
|
export MT_HD_UI_PAK
|
|
cd "$RESOURCES_DIR"
|
|
exec "$CONTENTS_DIR/MacOS/mt_native_render" --login-screen \
|
|
--live-client "${MT_CLIENT_DIR:-$RESOURCES_DIR/Client}" \
|
|
--live-server "${MT_SERVER:-192.168.21.203:11000:13000}" \
|
|
--width 1280 --height 800 "$@"
|
|
SH
|
|
chmod +x "$stage/Contents/MacOS/Metin2"
|
|
cat > "$stage/Contents/Info.plist" <<PLIST
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0"><dict>
|
|
<key>CFBundleName</key><string>Metin2</string>
|
|
<key>CFBundleDisplayName</key><string>Metin2</string>
|
|
<key>CFBundleIdentifier</key><string>org.metin2port.client</string>
|
|
<key>CFBundleExecutable</key><string>Metin2</string>
|
|
<key>CFBundleIconFile</key><string>AppIcon</string>
|
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
<key>CFBundleShortVersionString</key><string>0.1</string>
|
|
<key>CFBundleVersion</key><string>$version</string>
|
|
<key>LSMinimumSystemVersion</key><string>12.0</string>
|
|
<key>LSApplicationCategoryType</key><string>public.app-category.role-playing-games</string>
|
|
<key>NSHighResolutionCapable</key><true/>
|
|
<key>NSLocalNetworkUsageDescription</key><string>连接局域网中的 Metin2 游戏服务器,查询频道状态并登录游戏。</string>
|
|
</dict></plist>
|
|
PLIST
|
|
for library in "$stage"/Contents/Frameworks/*.dylib; do codesign --force --sign "$signing_identity" "$library"; done
|
|
codesign --force --sign "$signing_identity" --identifier org.metin2port.client.renderer "$stage/Contents/MacOS/mt_native_render"
|
|
codesign --force --deep --sign "$signing_identity" "$stage"
|
|
codesign --verify --deep --strict "$stage"
|
|
# Publish only after validating the complete replacement bundle.
|
|
rm -rf "$out"
|
|
mv "$stage" "$out"
|
|
trap - EXIT
|
|
echo "$out"
|