soul-browser/scripts/compile-userscript-page.sh
KaKi87 6b75f103b0 Fix Userscripts command button clicks on MyButtonImage.
Initialize the press paint via setBgPreColor so touches reach the
listener, and size the command list so it is not collapsed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-11 15:00:40 +02:00

98 lines
3.7 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SRC="${ROOT_DIR}/sources/java/com/mycompany/app/web/UserscriptPageHelper.java"
STUBS="${ROOT_DIR}/sources/userscript-page/stubs"
OUT_SMALI="${ROOT_DIR}/app/smali_classes3/com/mycompany/app/web"
TOOLS="${ROOT_DIR}/tools"
ANDROID_HOME="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-${HOME}/android-sdk}}"
ANDROID_JAR="$(ls -1 "${ANDROID_HOME}/platforms"/android-*/android.jar 2>/dev/null | sort -V | tail -1)"
D8="$(find "${ANDROID_HOME}/build-tools" -name d8 -type f 2>/dev/null | sort -V | tail -1)"
DEX_TOOLS_ZIP="${TOOLS}/dex-tools-v2.4.zip"
DEX_TOOLS_DIR="${TOOLS}/dex-tools-v2.4"
BAKSMALI_JAR="${TOOLS}/baksmali.jar"
mkdir -p "${TOOLS}" "${OUT_SMALI}"
if [[ ! -f "${ANDROID_JAR}" ]]; then
echo "error: android.jar not found" >&2
exit 1
fi
if [[ -z "${D8}" ]]; then
echo "error: d8 not found" >&2
exit 1
fi
if [[ ! -f "${DEX_TOOLS_DIR}/d2j-baksmali.sh" ]]; then
if [[ ! -f "${DEX_TOOLS_ZIP}" ]]; then
echo "Downloading dex-tools v2.4..."
curl -fsSL -o "${DEX_TOOLS_ZIP}" \
"https://github.com/pxb1988/dex2jar/releases/download/v2.4/dex-tools-v2.4.zip"
fi
unzip -qo "${DEX_TOOLS_ZIP}" -d "${TOOLS}"
fi
chmod +x "${DEX_TOOLS_DIR}/"*.sh "${DEX_TOOLS_DIR}/d2j_invoke.sh" 2>/dev/null || true
if [[ ! -f "${BAKSMALI_JAR}" ]]; then
echo "Downloading baksmali 2.5.2..."
curl -fsSL -o "${BAKSMALI_JAR}" \
"https://repo1.maven.org/maven2/org/smali/baksmali/2.5.2/baksmali-2.5.2.jar"
fi
STAGE="$(mktemp -d)"
cleanup() { rm -rf "${STAGE}"; }
trap cleanup EXIT
echo "Compiling UserscriptPageHelper.java..."
javac --release 8 -classpath "${ANDROID_JAR}" -d "${STAGE}/classes" \
$(find "${STUBS}" -name '*.java') \
"${SRC}"
echo "Dexing..."
mkdir -p "${STAGE}/out"
"${D8}" --release --output "${STAGE}/out" \
"${STAGE}/classes/com/mycompany/app/web/UserscriptPageHelper.class" \
"${STAGE}/classes/com/mycompany/app/web/UserscriptPageHelper"\$*.class 2>/dev/null || \
"${D8}" --release --output "${STAGE}/out" \
"${STAGE}/classes/com/mycompany/app/web/"UserscriptPageHelper*.class
echo "Disassembling to smali..."
if [[ -x "${DEX_TOOLS_DIR}/d2j-baksmali.sh" ]]; then
bash "${DEX_TOOLS_DIR}/d2j-baksmali.sh" -f -o "${STAGE}/smali" "${STAGE}/out/classes.dex"
else
java -cp "${BAKSMALI_JAR}" org.jf.baksmali.Main d "${STAGE}/out/classes.dex" -o "${STAGE}/smali"
fi
rm -f "${OUT_SMALI}"/UserscriptPageHelper*.smali
cp -f "${STAGE}/smali/com/mycompany/app/web/"UserscriptPageHelper*.smali "${OUT_SMALI}/"
# Inherited fields a/b live on ScriptId in the APK.
# d2j-baksmali emits abbreviated const/high16; apktool wants full 32-bit values.
OUT_SMALI="${OUT_SMALI}" python3 - <<'PY'
from pathlib import Path
import os, re
out = Path(os.environ["OUT_SMALI"])
fixes = {
'16256': '0x3f800000', # 1.0f
'16768': '0x41800000', # 16.0f
'260': '0x1040000', # android.R.string.cancel
'-256': '-0x1000000', # 0xFF000000
'8448': '0x21000000', # light press color
}
for f in out.glob("UserscriptPageHelper*.smali"):
t = f.read_text()
t = t.replace(
"Lcom/mycompany/app/script/Script;->a:",
"Lcom/mycompany/app/script/ScriptId;->a:",
)
t = t.replace(
"Lcom/mycompany/app/script/Script;->b:",
"Lcom/mycompany/app/script/ScriptId;->b:",
)
for half, full in fixes.items():
t = re.sub(rf"const/high16 (\w+), {re.escape(half)}\b", rf"const/high16 \1, {full}", t)
t = t.replace("const p1, 1051931443", "const p1, 0x3eb33333") # 0.35f
f.write_text(t)
print("normalized", len(list(out.glob('UserscriptPageHelper*.smali'))), "smali files")
PY
echo "Wrote $(ls "${OUT_SMALI}"/UserscriptPageHelper*.smali | wc -l) smali file(s) to ${OUT_SMALI}"