Files
metin2-client/scripts/package_mac_app.sh
T
2026-09-30 17:14:30 -07:00

86 lines
4.5 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"
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"
# Clone private assets on APFS; fall back to an ordinary copy on other filesystems.
cp -cR "$client" "$stage/Contents/Resources/Client" 2>/dev/null || ditto "$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/>
</dict></plist>
PLIST
for library in "$stage"/Contents/Frameworks/*.dylib; do codesign --force --sign - "$library"; done
codesign --force --sign - "$stage/Contents/MacOS/mt_native_render"
codesign --force --deep --sign - "$stage"
codesign --verify --deep --strict "$stage"
# Publish only after validating the complete replacement bundle.
rm -rf "$out"
mv "$stage" "$out"
trap - EXIT
echo "$out"