android: build.sh installs and syncs the game files when a phone is attached
After building the APK, android/build.sh now picks the attached device (ANDROID_SERIAL for several), installs the APK (reinstalling on a signature mismatch), syncs the zh client into files/Client and, with --launch, wakes the phone and starts the app. Without a device it only builds. push-client.sh is now incremental (android/sync_client.py): the device keeps files/Client/.mt_sync (size, mtime, path of what the last sync wrote), so later syncs send only new and changed files as one tar streamed through `adb shell -T run-as` (no copy in /data/local/tmp) and delete the ones gone locally. Only game resources are synced; settings and logs the app writes there are kept. --locale zh rebuilds build/zh-locale/Client first when its inputs changed. android/adb_env.sh picks adb and falls back to server port 5038 when :5037 cannot bind. Verified against a fake adb device: first sync (1.4 GB, byte-identical), no-op resync, changed files, deletions, locale switch, --full, the install/launch path and the no-device path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f9cd63713f
commit
cd9e5b259d
+59
-11
@@ -1,20 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the native (SDL3 + Vulkan) 40250 client as an Android arm64 APK.
|
||||
# ./android/build.sh [Debug|Release] [--install]
|
||||
# Build the native (SDL3 + Vulkan) 40250 client as an Android arm64 APK and, when a phone is attached,
|
||||
# install it and bring its game files up to date, so the app is ready to play.
|
||||
# ./android/build.sh [Debug|Release] [--no-deploy] [--no-push] [--locale XX] [--full-push] [--launch]
|
||||
# Output: android/app/build/outputs/apk/debug/app-debug.apk
|
||||
# The 1.4 GB Client/ directory is not in the APK; push it once with ./android/push-client.sh.
|
||||
# Deploy (skipped when no device is ready; ANDROID_SERIAL picks one of several):
|
||||
# adb install -r, then ./android/push-client.sh --locale XX (default zh), which sends only the game
|
||||
# files changed since the last push (the first push is the whole 1.4 GB client). --no-push installs
|
||||
# only, --full-push resends everything, --launch wakes the phone and starts the app afterwards.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
REPO="$PWD"
|
||||
|
||||
CONFIG=Release
|
||||
INSTALL=0
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
Debug|Release) CONFIG="$a" ;;
|
||||
--install) INSTALL=1 ;;
|
||||
*) echo "usage: $0 [Debug|Release] [--install]" >&2; exit 2 ;;
|
||||
DEPLOY=1
|
||||
PUSH=1
|
||||
LOCALE=zh
|
||||
FULL_PUSH=0
|
||||
LAUNCH=0
|
||||
usage="usage: $0 [Debug|Release] [--no-deploy] [--no-push] [--locale XX] [--full-push] [--launch]"
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
Debug|Release) CONFIG="$1" ;;
|
||||
--install) ;; # the default now; kept for old command lines
|
||||
--no-deploy) DEPLOY=0 ;;
|
||||
--no-push) PUSH=0 ;;
|
||||
--locale) LOCALE="${2:?--locale needs a locale code}"; shift ;;
|
||||
--full-push) FULL_PUSH=1 ;;
|
||||
--launch) LAUNCH=1 ;;
|
||||
*) echo "$usage" >&2; exit 2 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
API=24
|
||||
OUT="$REPO/build/android"
|
||||
@@ -84,6 +99,39 @@ variant=Debug # debug-signed either way (sideload); CONFIG picks the native opt
|
||||
APK="$REPO/android/app/build/outputs/apk/debug/app-debug.apk"
|
||||
ls -la "$APK"
|
||||
|
||||
if [ "$INSTALL" = 1 ]; then
|
||||
adb install -r "$APK"
|
||||
[ "$DEPLOY" = 1 ] || exit 0
|
||||
. android/adb_env.sh
|
||||
if ! adb_device; then
|
||||
echo "APK built; install and push skipped. Attach the phone and rerun (or ./android/push-client.sh)."
|
||||
exit 0
|
||||
fi
|
||||
echo "device: $DEVICE ($("$ADB" shell getprop ro.product.model | tr -d '\r'))"
|
||||
if ! out=$("$ADB" install -r "$APK" 2>&1); then
|
||||
echo "$out" >&2
|
||||
case "$out" in
|
||||
*INSTALL_FAILED_UPDATE_INCOMPATIBLE*|*INSTALL_FAILED_VERSION_DOWNGRADE*)
|
||||
# Signed by another machine's debug key (or a newer build): only a reinstall helps. That drops the
|
||||
# app's data, so the push below starts over with the whole client.
|
||||
echo "reinstalling $PKG (the installed copy has another signature; its data is removed)"
|
||||
"$ADB" uninstall "$PKG" >/dev/null
|
||||
"$ADB" install "$APK" ;;
|
||||
*)
|
||||
echo "install failed; on some phones USB installs must be allowed in developer options and confirmed on screen" >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
echo "installed $PKG"
|
||||
if [ "$PUSH" = 1 ]; then
|
||||
push_args=(--locale "$LOCALE")
|
||||
[ "$FULL_PUSH" = 1 ] && push_args+=(--full)
|
||||
python3 android/sync_client.py "${push_args[@]}"
|
||||
fi
|
||||
if [ "$LAUNCH" = 1 ]; then
|
||||
# The app exits with a Vulkan surface error when started behind the lock screen.
|
||||
"$ADB" shell input keyevent KEYCODE_WAKEUP
|
||||
if "$ADB" shell dumpsys window | grep -qE 'mDreamingLockscreen=true|isKeyguardShowing=true|mKeyguardShowing=true'; then
|
||||
echo "the phone is locked: unlock it, then start Metin2 from the launcher" >&2
|
||||
else
|
||||
"$ADB" shell am start -n "$PKG/.MainActivity" >/dev/null && echo "started $PKG"
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user