Compare commits

51 Commits
v2.0 ... v2.5

Author SHA1 Message Date
KOWX712
e192fcc916 v2.5 2024-11-22 00:23:08 +08:00
KOWX712
7a2c87b365 minor ui change x2 2024-11-22 00:15:51 +08:00
KOWX712
a1f4d8fc72 minor layout change 2024-11-21 23:51:26 +08:00
KOWX712
7f7c124b25 Add more detail x2 2024-11-21 23:24:38 +08:00
KOWX712
90696c5c5d Update update.json 2024-11-21 23:09:01 +08:00
KOWX712
9cbb73bab0 Add more detail
Add more detail in help menu and clarity keybox operation prompt.
2024-11-21 23:04:38 +08:00
KOWX712
d9eb97cb3c fix webui installation skip
Magisk action.sh: On next installation, prompt webui again if rejected.
2024-11-21 23:04:13 +08:00
KOWX712
e848da327b change kb logic 2024-11-20 15:05:37 +08:00
KOWX712
67581ae941 Update .extra 2024-11-20 13:56:15 +08:00
KOWX712
91dea027ce Create .extra 2024-11-20 13:40:27 +08:00
KOWX712
5806ab16d7 v2.4 2024-11-20 00:52:21 +08:00
KOWX712
0736f4ea38 Add app name display
try to display app name in webui
2024-11-20 00:44:28 +08:00
KOWX712
ff8a768a00 Add aapt bianry
prepare for app name feature
2024-11-19 23:26:27 +08:00
KOWX712
af3f8b88c0 Update changelog.md 2024-11-18 22:02:31 +08:00
KOWX712
40f1e8d69e v2.3 2024-11-18 21:59:17 +08:00
KOWX712
82d803c2db v2.3 2024-11-18 21:37:46 +08:00
KOWX712
68158796dc v2.3
update boot_hash path
2024-11-18 21:17:23 +08:00
KOWX712
3015fd44ba finalize 2024-11-18 21:04:30 +08:00
KOWX712
605a4c8c90 Update more-excldue.json 2024-11-18 20:59:09 +08:00
KOWX712
439ae0332a Update UpdateTargetList.sh 2024-11-18 20:54:28 +08:00
KOWX712
6f7108543f cleanup residue
cleanup residue during remove module
2024-11-18 20:33:37 +08:00
KOWX712
596c92ba18 Read app from DenlyList
For Magisk only
2024-11-18 20:19:40 +08:00
KOWX712
1f3c1e960a Migrate boot hash to /data/adb
prevent ksu/apatch overwrite
2024-11-18 18:56:07 +08:00
KOWX712
383a7eeb5f Update action button
Abandon action.sh in KernelSU and Apatch. Magisk: redirect to WebUI with action button if installed KSU WebUI. Add KSU WebUI standalone automated installation script (optional).
2024-11-18 18:36:51 +08:00
KOWX712
2e71b6512b Update more-excldue.json 2024-11-17 00:14:21 +08:00
KOWX712
bcfb8c12ad remove curl binary
use busybox wget binary instead of curl binary to fetch exclude-list
2024-11-14 21:44:31 +08:00
KOWX712
e9346303ac prevent tspa overwrite 2024-11-14 21:37:32 +08:00
KOWX712
cc77b95f5c v2.2 2024-11-13 01:18:25 +08:00
KOWX712
685a6b89ef v2.2
update description, changelog and version code
2024-11-13 00:34:17 +08:00
KOWX712
face2fe644 ui change
no connection prompt, help menu overlay transition. Better readability installation script.
2024-11-13 00:15:38 +08:00
KOWX712
584ad2f2df spacing format 2024-11-10 01:22:32 +08:00
KOWX712
47e383bf69 Update more-excldue.json
add link
2024-11-10 01:19:29 +08:00
KOWX712
a02ed06557 Update index.js
Better unsuccessful prompt
2024-11-10 01:06:55 +08:00
KOWX712
eb8666f79e Update more-excldue.json 2024-11-10 00:57:01 +08:00
KOWX712
9883922927 Add help menu 2024-11-10 00:50:06 +08:00
KOWX712
fcfa723052 better logic
now can show app that excluded by keyword as deselected.
2024-11-09 03:22:48 +08:00
KOWX712
c347392792 fix typo 2024-11-09 02:53:58 +08:00
KOWX712
cfa795034e exclude more than only xposed
added option to exclude more root related app other than xposed module
2024-11-09 02:40:25 +08:00
KOWX712
d16611ddc1 minor UI enhance, new exclude list
introduce new exclude list to exclude unnecessary app from tricky store target.
2024-11-09 02:15:03 +08:00
KOWX712
b1f75d012e Create more-excldue.json
for more exclude package name
2024-11-08 02:10:31 +08:00
KOWX712
3f19e0bee5 Update README.md 2024-11-08 01:34:02 +08:00
KOWX712
bd38e1a615 Update README.md 2024-11-08 01:33:35 +08:00
KOWX712
bfb4c3293e Merge branch 'master' of https://github.com/KOWX712/Tricky-Addon-Update-Target-List 2024-11-08 01:30:08 +08:00
KOWX712
5591a3ed14 Minor UI change
change icon, enhanced UI experience
2024-11-08 01:30:05 +08:00
KOWX712
9d0d1c7e46 Update changelog.md 2024-11-06 20:29:51 +08:00
KOWX712
6bab7df285 Update index.js 2024-11-06 20:24:55 +08:00
KOWX712
5d14680bb9 Update update.json 2024-11-06 20:21:38 +08:00
KOWX712
3201f9ee16 minor fix
search function enhancement
2024-11-06 20:03:00 +08:00
KOWX712
8a0ab7c56d v2.1
Add curl binary to fetch Xposed module package name list. WebUI bug fix and new feature: exclude Xposed module, better ui experience and more user friendly.
2024-11-06 19:39:37 +08:00
KOWX712
55406e377a fine tune UI 2024-11-04 23:42:15 +08:00
KOWX712
4a9650bd54 fix abnormal color in dark mode 2024-11-04 23:37:44 +08:00
25 changed files with 1188 additions and 338 deletions

1
.extra Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
# **Tricky Addon - Update Target List** # **Tricky Addon - Update Target List**
An addon module for tricky store A **KSU WebUI** to configure tricky store target.txt
--- ---
## Description ## Description
@@ -11,19 +11,18 @@ An addon module for tricky store
- [Tricky store](https://github.com/5ec1cff/TrickyStore) module installed - [Tricky store](https://github.com/5ec1cff/TrickyStore) module installed
## Custom Configuration ## Custom Configuration
- ADDITION and EXCLUDE in `/data/adb/tricky_store/target_list_config` - Configuration target list with **KSU WebUI**
- EXCLUDE for removing unnecessary apps - For Magisk users, first attempt perform action button can install KSU WebUI (optional).
- ADDITION for adding back system app excluded by default - Advance configure: ADDITION and EXCLUDE in `/data/adb/tricky_store/target_list_config`
- Configuration list with **KSU WebUI** (For KernelSU and Apatch, )
## Instructions ## Instructions
### Automatic update ### Automatic update
- On boot - On boot
### Manually update ### Manually update
**Action button method** **KSU WebUI**
- Use action button to update tricky store target list. - Configure target list
- Available for Magisk 27008+, KernelSU 11981+, Apatch 10927+ - Save and Update
**Manual script method** **Manual script method**
- Run `UpdateTargetList.sh` under `/data/adb/tricky_store` manually. - Run `UpdateTargetList.sh` under `/data/adb/tricky_store` manually.
@@ -31,7 +30,7 @@ An addon module for tricky store
## More ## More
**Support to pass abnormal boot state** **Support to pass abnormal boot state**
- Put Verfied Boot Hash to `boot_hash` in `/data/adb/modules/TA_utl`, reboot. - Paste Verfied Boot Hash to `boot_hash` in `/data/adb/`, reboot.
## Acknowledgement ## Acknowledgement
- [j-hc/zygisk-detach](https://github.com/j-hc/zygisk-detach) - KSU WebUI template - [j-hc/zygisk-detach](https://github.com/j-hc/zygisk-detach) - KSU WebUI template

View File

@@ -1,15 +1,52 @@
### Tricky Addon: Update Target List ### Tricky Addon: Update Target List
Automated script to update tricky store target.txt A **KSU WebUI** to configure tricky store target.txt
Requirement: Tricky Store module installed Requirement: Tricky Store module installed
Manually add VerifiedBootHash to /data/adb/modules/TA_utl/boot_hash (optional) Manually add VerifiedBootHash to /data/adb/boot_hash (optional)
GitHub release: [Tricky Addon: Update Target List](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest) GitHub release: [Tricky Addon: Update Target List](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest)
Telegram channel: [KOW's Little World](https://t.me/kowchannel) Telegram channel: [KOW's Little World](https://t.me/kowchannel)
Starting from v2.4, WebUI will take longer time to load due to reading app name from every base.apk. The more apps installed, the longer time it takes to load the WebUI.
## Changelog ## Changelog
### v2.5
- Remove kb prompt on installation, moved into WebUI
- Restore to AOSP keybox during uninstallation
### v2.4
- Added aapt binary for app name display
**KSU WebUI**
- Added app name display
### v2.3
- Removed curl binary
- Moved boot_hash to /data/adb to prevent overwrite
- Stop TSP-A auto target to prevent overwrite
- Abandoned action button in KernelSU and Apatch
- Magisk action button: open WebUI, automatic download if not installed (optional)
**KSU WebUI**
- Option to select app from DenyList (Magisk)
### v2.2
**KSU WebUI:**
- Added help menu
- Added extra [unnecessary app](https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/more-excldue.json) exclude option
- Added no Internet connection prompt
### v2.1
- Added curl binary to fetch Xposed module package name from LSPosed webside
- **KSU WebUI:**
- Added feature to exclude Xposed module package name
- Fixed abnormal color in dark mode
- Combined save config and update target.txt button
- Fixed some more known bugs
### v2.0 ### v2.0
- Added WebUI for configuration - Added WebUI for configuration

View File

@@ -4,6 +4,9 @@
- Recommend to run with MT manager - Recommend to run with MT manager
## Changelog ## Changelog
### v2.1, v2.2, v2.3, v2.4, v2.5
- Remain same with v2.0
### v2.0 ### v2.0
- More clarify remark in code - More clarify remark in code
- Remove useless code - Remove useless code

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# Tricky Addon Lite: Update Target List Script v2.0 # Tricky Addon Lite: Update Target List Script v2.5
# GitHub Repository: https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/master/lite-script_only/README.md # GitHub Repository: https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/master/lite-script_only/README.md
# Telegram channel: https://t.me/kowchannel # Telegram channel: https://t.me/kowchannel
@@ -14,6 +14,7 @@
EXCLUDE=" EXCLUDE="
oneplus oneplus
coloros coloros
miui
com.android.patch com.android.patch
me.bmax.apatch me.bmax.apatch
me.garfieldhan.apatch.next" me.garfieldhan.apatch.next"

View File

@@ -1,18 +1,33 @@
MODPATH="${0%/*}"
COMPATH="$MODPATH/common"
SCRIPT_DIR="/data/adb/tricky_store" SCRIPT_DIR="/data/adb/tricky_store"
echo "**********************************************" . "$COMPATH/util_func.sh"
echo "- Staring script..."
echo " "
if [ ! -f "$SCRIPT_DIR/UpdateTargetList.sh" ]; then if pm list packages | grep -q "$PACKAGE_NAME"; then
echo "! Script missing, please install module again" echo "- Launching KSU WebUI..."
echo "**********************************************" am start -n "${PACKAGE_NAME}/.WebUIActivity" -e id "$MODID"
exit 1
else else
. "$SCRIPT_DIR/UpdateTargetList.sh" SKIP_FILE="$SCRIPT_DIR/target_list_config/skipwebui"
fi if [ ! -f "$SKIP_FILE" ]; then
echo "**********************************************"
echo "- Do you want to install KSU WebUI standalone?"
echo " VOL [+]: YES"
echo " VOL [-]: NO"
echo "**********************************************"
echo "**********************************************" key_check
echo "\(__All set!__)/" if [[ "$keycheck" == "KEY_VOLUMEUP" ]]; then
echo "Exiting in 2 seconds..." echo "- Installing KSU WebUI..."
sleep 2 . "$COMPATH/get_WebUI.sh"
else
echo "- Skipping WebUI installation..."
touch "$SKIP_FILE"
echo "- Skip WebUI check until next installation."
echo ""
update_script
fi
else
update_script
fi
fi

BIN
module/bin/arm64-v8a/aapt Normal file

Binary file not shown.

BIN
module/bin/armeabi-v7a/aapt Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -4,6 +4,7 @@
# Each app package name should be on a new line # Each app package name should be on a new line
oneplus oneplus
coloros coloros
miui
com.android.patch com.android.patch
me.bmax.apatch me.bmax.apatch
me.garfieldhan.apatch.next me.garfieldhan.apatch.next

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# This script will put all non-system app into /data/adb/tricky_store/target.txt # This script will put non-system app into /data/adb/tricky_store/target.txt
CONFIG_DIR="/data/adb/tricky_store/target_list_config" CONFIG_DIR="/data/adb/tricky_store/target_list_config"
echo "- Checking config files..." echo "- Checking config files..."
@@ -20,14 +20,23 @@ else
echo " " echo " "
fi fi
EXCLUDE=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/EXCLUDE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
ADDITION=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/ADDITION" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
for app in $ADDITION; do
app=$(echo "$app" | tr -d '[:space:]')
if grep -Fq "$app" "$CONFIG_DIR/EXCLUDE"; then
sed -i "\|^$app$|d" "$CONFIG_DIR/EXCLUDE"
fi
done
EXCLUDE=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/EXCLUDE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr '\n' '|' | sed 's/|$//') EXCLUDE=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/EXCLUDE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr '\n' '|' | sed 's/|$//')
ADDITION=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/ADDITION")
echo "- Adding apps into /data/adb/tricky_store/target.txt..." echo "- Adding apps into /data/adb/tricky_store/target.txt..."
echo " " echo " "
su -c pm list packages -3 </dev/null 2>&1 | cat | awk -F: '{print $2}' | grep -Ev "$EXCLUDE" > /data/adb/tricky_store/target.txt pm list packages -3 </dev/null 2>&1 | awk -F: '{print $2}' | grep -Ev "$EXCLUDE" > /data/adb/tricky_store/target.txt
echo "- Adding addition app... " echo "- Adding addition app..."
echo " " echo " "
for app in $ADDITION; do for app in $ADDITION; do
app=$(echo "$app" | tr -d '[:space:]') app=$(echo "$app" | tr -d '[:space:]')

View File

@@ -0,0 +1,28 @@
URL="https://github.com/5ec1cff/KsuWebUIStandalone/releases/download/v1.0/KsuWebUI-1.0-34-release.apk"
APK_DIR="$COMPATH"
LOG_FILE="$COMPATH/webuiError.log"
find_busybox
check_wget
echo "- Downloading the WebUI apk..."
download_webui
echo "- Download complete."
APK_PATH=$(find "$APK_DIR" -type f -name "*.apk" | head -n 1)
if [ -z "$APK_PATH" ]; then
echo "Error: No APK file found in $APK_DIR."
exit 1
fi
echo "- Installing..."
install_webui
echo "- Done."
rm -f "$APK_PATH"
echo "- Launching..."
am start -n "${PACKAGE_NAME}/.WebUIActivity" -e id "$MODID" </dev/null 2>&1 | cat
if [ $? -ne 0 ]; then
echo "Error: Failed to start application."
exit 1
fi
echo "- Application launched successfully."

View File

@@ -0,0 +1,32 @@
#!/system/bin/sh
MODPATH=${0%/*}
OUTPUT="$MODPATH/exclude-list"
KBOUTPUT="$MODPATH/.extra"
. $MODPATH/util_func.sh
find_busybox
check_wget
# Fetch Xposed module package names
wget --no-check-certificate -q -O - "https://modules.lsposed.org/modules.json" 2>/dev/null | \
grep -o '"name":"[^"]*","description":' | \
awk -F'"' '{print $4}' > "$OUTPUT"
# Fetch additional package names
wget --no-check-certificate -q -O - "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/more-excldue.json" 2>/dev/null | \
grep -o '"package-name": *"[^"]*"' | \
awk -F'"' '{print $4}' >> "$OUTPUT"
if [ ! -s "$OUTPUT" ]; then
echo "Error: Failed to fetch data." > "$OUTPUT"
rm -f "$KBOUTPUT"
exit 1
fi
wget --no-check-certificate -qO "$KBOUTPUT" "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/.extra"
if [ ! -s "$KBOUTPUT" ]; then
rm -f "$KBOUTPUT"
fi

View File

@@ -0,0 +1,84 @@
PACKAGE_NAME="io.github.a13e300.ksuwebui"
MODID="set-id"
BBPATH="/data/adb/modules/busybox-ndk/system/*/busybox \
/data/adb/magisk/busybox \
/data/adb/ksu/bin/busybox \
/data/adb/ap/bin/busybox"
find_busybox() {
for path in $BBPATH; do
if [ -f "$path" ]; then
BUSYBOX="$path"
return 0
fi
done
return 1
}
check_wget() {
if ! command -v wget >/dev/null || grep -q "wget-curl" "$(command -v wget)"; then
if find_busybox; then
wget() { "$BUSYBOX" wget "$@"; }
else
echo "Error: busybox not found." > "$OUTPUT"
exit 1
fi
fi
}
download_webui() {
wget --no-check-certificate -P "$APK_DIR" "$URL"
if [ $? -ne 0 ]; then
echo "Error: APK download failed."
exit 1
fi
}
install_webui() {
pm install -r "$APK_PATH" </dev/null 2>&1 | cat
if [ $? -ne 0 ]; then
echo "Error: APK installation failed."
rm -f "$APK_PATH"
exit 1
fi
}
key_check() {
while true; do
key_check=$(/system/bin/getevent -qlc 1)
key_event=$(echo "$key_check" | awk '{ print $3 }' | grep 'KEY_')
key_status=$(echo "$key_check" | awk '{ print $4 }')
if [[ "$key_event" == *"KEY_"* && "$key_status" == "DOWN" ]]; then
keycheck="$key_event"
break
fi
done
while true; do
key_check=$(/system/bin/getevent -qlc 1)
key_event=$(echo "$key_check" | awk '{ print $3 }' | grep 'KEY_')
key_status=$(echo "$key_check" | awk '{ print $4 }')
if [[ "$key_event" == *"KEY_"* && "$key_status" == "UP" ]]; then
break
fi
done
}
update_script() {
echo "**********************************************"
echo "- Starting script..."
echo ""
if [[ ! -f "$SCRIPT_DIR/UpdateTargetList.sh" ]]; then
echo "! Script missing, please install module again."
echo "**********************************************"
exit 1
else
. "$SCRIPT_DIR/UpdateTargetList.sh"
fi
echo "**********************************************"
echo ""
echo "\(__All set!__)/"
echo "Exiting in 2 seconds..."
sleep 2
}

View File

@@ -1,11 +1,20 @@
SKIPUNZIP=0 SKIPUNZIP=0
DEBUG=false DEBUG=false
COMPATH="$MODPATH/common"
TS="/data/adb/modules/tricky_store"
SCRIPT_DIR="/data/adb/tricky_store"
CONFIG_DIR="$SCRIPT_DIR/target_list_config"
MODID=`grep_prop id $TMPDIR/module.prop`
ORG_DIR="/data/adb/modules/$MODID"
kb="$COMPATH/.default"
ui_print " "; ui_print " ";
if [ "$APATCH" ]; then if [ "$APATCH" ]; then
ui_print "- APatch:$APATCH_VER$APATCH_VER_CODE" ui_print "- APatch:$APATCH_VER$APATCH_VER_CODE"
ACTION=false
elif [ "$KSU" ]; then elif [ "$KSU" ]; then
ui_print "- KSU:$KSU_KERNEL_VER_CODE$KSU_VER_CODE" ui_print "- KSU:$KSU_KERNEL_VER_CODE$KSU_VER_CODE"
ACTION=false
elif [ "$MAGISK_VER_CODE" ]; then elif [ "$MAGISK_VER_CODE" ]; then
ui_print "- Magisk:$MAGISK_VER$MAGISK_VER_CODE" ui_print "- Magisk:$MAGISK_VER$MAGISK_VER_CODE"
else else
@@ -14,134 +23,21 @@ else
abort " "; abort " ";
fi fi
COMPATH="$MODPATH/common" if [ ! -d "$TS" ]; then
TS="/data/adb/modules/tricky_store"
SCRIPT_DIR="/data/adb/tricky_store"
CONFIG_DIR="$SCRIPT_DIR/target_list_config"
MODNAME=$(grep '^id=' "$MODPATH/module.prop" | awk -F= '{print $2}' | xargs)
ORG_DIR="/data/adb/modules/$MODNAME"
kb="$COMPATH/.default"
if [ -d "$TS" ]; then
ui_print "- Tricky store module installed"
else
ui_print "! Tricky store module is not installed" ui_print "! Tricky store module is not installed"
abort " " abort
fi fi
key_check() { . "$MODPATH/install_func.sh"
while true; do
key_check=$(/system/bin/getevent -qlc 1)
key_event=$(echo "$key_check" | awk '{ print $3 }' | grep 'KEY_')
key_status=$(echo "$key_check" | awk '{ print $4 }')
if [[ "$key_event" == *"KEY_"* && "$key_status" == "DOWN" ]]; then
keycheck="$key_event"
break
fi
done
while true; do
key_check=$(/system/bin/getevent -qlc 1)
key_event=$(echo "$key_check" | awk '{ print $3 }' | grep 'KEY_')
key_status=$(echo "$key_check" | awk '{ print $4 }')
if [[ "$key_event" == *"KEY_"* && "$key_status" == "UP" ]]; then
break
fi
done
}
add_exclude() {
EXCLUDE=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/EXCLUDE")
for app in $EXCLUDE; do
app=$(echo "$app" | tr -d '[:space:]')
if ! grep -Fq "$app" $COMPATH/EXCLUDE; then
echo "$app" >> $COMPATH/EXCLUDE
fi
done
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
}
add_addition() {
ADDITION=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/ADDITION")
for app in $ADDITION; do
app=$(echo "$app" | tr -d '[:space:]')
if ! grep -Fq "$app" $COMPATH/ADDITION; then
echo "$app" >> $COMPATH/ADDITION
fi
done
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
}
ui_print "- Installing..." ui_print "- Installing..."
initialize
if [ -f "$SCRIPT_DIR/UpdateTargetList.sh" ]; then ui_print "- Creating config directory..."
rm -f "$SCRIPT_DIR/UpdateTargetList.sh" find_config
fi migrate_old_boot_hash
cp "$MODPATH/module.prop" "$COMPATH/module.prop.orig"
mv "$COMPATH/UpdateTargetList.sh" "$SCRIPT_DIR/UpdateTargetList.sh"
set_perm $SCRIPT_DIR/UpdateTargetList.sh 0 2000 0755 rm -f "$MODPATH/install_func.sh"
if [ -d "$CONFIG_DIR" ]; then
if [ ! -f "$CONFIG_DIR/EXCLUDE" ] && [ ! -f "$CONFIG_DIR/ADDITION" ]; then
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
elif [ ! -f "$CONFIG_DIR/ADDITION" ]; then
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
add_exclude
elif [ ! -f "$CONFIG_DIR/EXCLUDE" ]; then
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
add_addition
else
add_exclude
add_addition
fi
ui_print "- Migrating old config data"
else
ui_print "- Creating config folder $CONFIG_DIR"
mkdir -p "$CONFIG_DIR"
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
fi
if [ ! -f "$ORG_DIR/boot_hash" ]; then
mv "$COMPATH/boot_hash" "$MODPATH/boot_hash"
else
rm -f "$COMPATH/boot_hash"
mv "$ORG_DIR/boot_hash" "$MODPATH/boot_hash"
fi
# Migrate from old version setup
if [ -f "$ORG_DIR/system.prop" ]; then
hash_value=$(sed -n 's/^ro.boot.vbmeta.digest=//p' "$ORG_DIR/system.prop")
if [ -n "$hash_value" ]; then
echo -e "\n$hash_value" >> "$MODPATH/boot_hash"
fi
fi
ui_print "*********************************************"
ui_print "- Do you want to replace tricky store keybox?"
ui_print " VOL [+]: YES"
ui_print " VOL [-]: NO"
ui_print "*********************************************"
key_check
if [[ "$keycheck" == "KEY_VOLUMEUP" ]]; then
ui_print "*********************************************"
ui_print "- Backing up original keybox..."
ui_print "- Replacing keybox..."
ui_print "*********************************************"
if [ -f "$ORG_DIR/common/origkeybox" ]; then
mv "$ORG_DIR/common/origkeybox" "$COMPATH/origkeybox"
else
mv "$SCRIPT_DIR/keybox.xml" "$COMPATH/origkeybox"
fi
mv "$kb" "$SCRIPT_DIR/keybox.xml"
else
if [ -f "$ORG_DIR/common/origkeybox" ]; then
mv "$ORG_DIR/common/origkeybox" "$COMPATH/origkeybox"
else
rm -f "$kb"
fi
fi
ui_print "- Installation completed successfully! " ui_print "- Installation completed successfully! "
ui_print " " ui_print " "

96
module/install_func.sh Normal file
View File

@@ -0,0 +1,96 @@
initialize() {
if [ -f "$SCRIPT_DIR/UpdateTargetList.sh" ]; then
rm -f "$SCRIPT_DIR/UpdateTargetList.sh"
fi
if [ -f "$CONFIG_DIR/skipwebui" ]; then
rm -f "$CONFIG_DIR/skipwebui"
fi
cp "$MODPATH/module.prop" "$COMPATH/module.prop.orig"
mv "$COMPATH/UpdateTargetList.sh" "$SCRIPT_DIR/UpdateTargetList.sh"
sed -i "s|\"set-path\"|\"/data/adb/modules/$MODID/common/\"|" "$MODPATH/webroot/index.js" || {
ui_print "! Failed to set path"
abort
}
sed -i "s|\"set-id\"|\"$MODID\"|" "$COMPATH/util_func.sh" || {
ui_print "! Failed to set id"
abort
}
mkdir -p "$MODPATH/system/bin"
mv "$MODPATH/bin/$(getprop ro.product.cpu.abi)/aapt" "$COMPATH/aapt"
rm -rf "$MODPATH/bin"
set_perm $COMPATH/aapt 0 2000 0755
set_perm $SCRIPT_DIR/UpdateTargetList.sh 0 2000 0755
set_perm $COMPATH/get_extra.sh 0 2000 0755
set_perm $COMPATH/get_WebUI.sh 0 2000 0755
if [ "$ACTION" = "false" ]; then
rm -f "$MODPATH/action.sh"
rm -f "$COMPATH/get_WebUI.sh"
fi
}
add_exclude() {
EXCLUDE=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/EXCLUDE")
for app in $EXCLUDE; do
app=$(echo "$app" | tr -d '[:space:]')
if ! grep -Fq "$app" $COMPATH/EXCLUDE; then
echo "$app" >> $COMPATH/EXCLUDE
fi
done
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
}
add_addition() {
ADDITION=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' "$CONFIG_DIR/ADDITION")
for app in $ADDITION; do
app=$(echo "$app" | tr -d '[:space:]')
if ! grep -Fq "$app" $COMPATH/ADDITION; then
echo "$app" >> $COMPATH/ADDITION
fi
done
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
}
find_config() {
if [ -d "$CONFIG_DIR" ]; then
if [ ! -f "$CONFIG_DIR/EXCLUDE" ] && [ ! -f "$CONFIG_DIR/ADDITION" ]; then
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
elif [ ! -f "$CONFIG_DIR/ADDITION" ]; then
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
add_exclude
elif [ ! -f "$CONFIG_DIR/EXCLUDE" ]; then
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
add_addition
else
add_exclude
add_addition
fi
else
mkdir -p "$CONFIG_DIR"
mv "$COMPATH/EXCLUDE" "$CONFIG_DIR/EXCLUDE"
mv "$COMPATH/ADDITION" "$CONFIG_DIR/ADDITION"
fi
}
migrate_old_boot_hash() {
if [ ! -f "/data/adb/boot_hash" ]; then
if [ -f "$ORG_DIR/boot_hash" ]; then
mv "$ORG_DIR/boot_hash" "/data/adb/boot_hash"
fi
mv "$COMPATH/boot_hash" "/data/adb/boot_hash"
else
rm -f "$COMPATH/boot_hash"
fi
# Migrate from old version setup
if [ -f "$ORG_DIR/system.prop" ]; then
hash_value=$(sed -n 's/^ro.boot.vbmeta.digest=//p' "$ORG_DIR/system.prop")
if [ -n "$hash_value" ]; then
echo -e "\n$hash_value" >> "/data/adb/boot_hash"
fi
fi
}

View File

@@ -1,7 +1,7 @@
id=TA_utl id=TA_utl
name=Tricky Addon - Update Target List name=Tricky Addon - Update Target List
version=v2.0 version=v2.5
versionCode=200 versionCode=250
author=KOWX712 author=KOWX712
description=Update tricky store target list with action button. Custom config: ADDITION and EXCLUDE in /data/adb/tricky_store/target_list_config description=A WebUI to conifgure tricky store target.txt
updateJson=https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/update.json updateJson=https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/update.json

View File

@@ -1,12 +1,20 @@
MODPATH=${0%/*} MODPATH=${0%/*}
TS="/data/adb/modules/tricky_store" TS="/data/adb/modules/tricky_store"
SCRIPT_DIR="/data/adb/tricky_store" SCRIPT_DIR="/data/adb/tricky_store"
TSPA="/data/adb/modules/tsupport-advance"
hash_value=$(grep -v '^#' "$MODPATH/boot_hash" | tr -d '[:space:]') hash_value=$(grep -v '^#' "/data/adb/boot_hash" | tr -d '[:space:]')
if [ -n "$hash_value" ]; then if [ -n "$hash_value" ]; then
resetprop -n ro.boot.vbmeta.digest "$hash_value" resetprop -n ro.boot.vbmeta.digest "$hash_value"
fi fi
# Disable TSupport-A auto update target to prevent overwrite
if [ -d "$TSPA" ]; then
touch "/storage/emulated/0/stop-tspa-auto-target"
elif [ ! -d "$TSPA" ] && [ -f "/storage/emulated/0/stop-tspa-auto-target" ]; then
rm -f "/storage/emulated/0/stop-tspa-auto-target"
fi
if [ ! -f "$MODPATH/common/module.prop.orig" ]; then if [ ! -f "$MODPATH/common/module.prop.orig" ]; then
sed -i 's/^description=.*/description=Module is corrupted, please reinstall module./' "$MODPATH/module.prop" sed -i 's/^description=.*/description=Module is corrupted, please reinstall module./' "$MODPATH/module.prop"
touch "$MODPATH/disable" touch "$MODPATH/disable"

View File

@@ -1,10 +1,13 @@
MODPATH=${0%/*} MODPATH=${0%/*}
SCRIPT_DIR="/data/adb/tricky_store" SCRIPT_DIR="/data/adb/tricky_store"
# Remove residue and restore original keybox. # Enable back TSupport-A auto update
if [ -f "/storage/emulated/0/stop-tspa-auto-target" ]; then
rm -f "/storage/emulated/0/stop-tspa-auto-target"
fi
# Remove residue and restore aosp keybox.
rm -rf "$SCRIPT_DIR/target_list_config" rm -rf "$SCRIPT_DIR/target_list_config"
rm -f "$SCRIPT_DIR/UpdateTargetList.sh" rm -f "$SCRIPT_DIR/UpdateTargetList.sh"
if [ -f "$MODPATH/common/origkeybox" ]; then rm -f "/data/adb/boot_hash"
rm -f "$SCRIPT_DIR/keybox.xml" xxd -r -p "$MODPATH/common/.default" | base64 -d > "$SCRIPT_DIR/keybox.xml"
mv "$MODPATH/common/origkeybox" "$SCRIPT_DIR/keybox.xml"
fi

View File

@@ -1,44 +1,121 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title> <title>Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="/styles.css" type="text/css"> <link rel="stylesheet" href="/styles.css" type="text/css">
<script type="module" crossorigin src="/index.js"></script> <script type="module" crossorigin src="/index.js"></script>
</head> </head>
<body> <body>
<div id="title">Tricky Addon - Update Target List</div> <div class="title-container">
<div class="search-card"> <div id="title">Tricky Addon - Update Target List</div>
<input type="text" class="search-input" id="search" placeholder="Search"> <button id="help-button" class="help-button"><i class="fa fa-question-circle"></i></button>
<div class="no-connection">
<img src="wifi-slash.svg" alt="No Connection Icon" class="wifi-icon">
</div>
</div> </div>
<div class="menu"> <div id="help-overlay" class="help-overlay">
<input type="checkbox" id="menu-toggle" class="menu-toggle" style="display: none;"> <div class="help-menu">
<label for="menu-toggle" id="menu-button"></label> <button id="close-help" class="close-help">&#x2715;</button>
<div id="menu-options" class="menu-options"> <div class="help-content">
<ul> <p>Instructions</p>
<li id="refresh">Refresh</li> <ul>
<li id="select-all">Select All</li> <li>Save and Update
<li id="deselect-all">Deselect All</li> <ul>
<li id="update">Update Target List</li> <li>Save the current configuration and update target.txt immediately.</li>
</ul> <li><br></li>
</ul>
</li>
<li>Refresh
<ul>
<li>Refresh app list and exclude list.</li>
<li><br></li>
</ul>
</li>
<li>Select All & Deselect All
<ul>
<li>Select or deselect all apps in the current interface.</li>
<li><br></li>
</ul>
</li>
<li>Select From DenyList
<ul>
<li>Available in Magisk only, select apps that in the DenyList. Recommended.</li>
<li><br></li>
</ul>
</li>
<li>Deselect Unnecessary
<ul>
<li>Unnecessary category: Xposed module, root manager, root-related apps, and general apps
that never check bootloader status. This option requrie Internet connection.</li>
<ul>
<li>Contribute to <a
href="https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/more-excldue.json"
target="_blank">unnecessary app list</a>? Create an <a
href="https://github.com/KOWX712/Tricky-Addon-Update-Target-List/issues"
target="_blank">issue</a> or <a
href="https://github.com/KOWX712/Tricky-Addon-Update-Target-List/pulls"
target="_blank">pull request</a>.</li>
</ul>
<li><br></li>
</ul>
</li>
<li>Set AOSP & Valid Keybox
<ul>
<li>Replace tricky store keybox.xml<br><strong>AOSP keybox:</strong> Device
Integrity.<br><strong>Valid keybox:</strong> Strong Integrity, fallback to Basic
Integrity if revoked.<br>AOSP keybox will be replaced if there's no more valid keybox.
Valid keybox option require Internet connection.</li>
<li><br></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="search-menu-container">
<div class="search-card">
<span class="search-icon"><i class="fa fa-search"></i></span>
<input type="text" class="search-input" id="search" placeholder="Search">
<button class="clear-btn" id="clear-btn">&#x2715;</button>
</div>
<div class="menu">
<input type="checkbox" id="menu-toggle" class="menu-toggle">
<label for="menu-toggle" id="menu-button">
<span class="menu-icon"><i class="fa fa-bars"></i></span>
</label>
<div id="menu-options" class="menu-options">
<ul>
<li id="refresh">Refresh</li>
<li id="select-all">Select All</li>
<li id="deselect-all">Deselect All</li>
<li id="select-denylist">Select From DenyList</li>
<li id="deselect-unnecessary">Deselect Unnecessary</li>
<li id="aospkb">Set AOSP Keybox</li>
<li id="extrakb">Set Valid Keybox</li>
</ul>
</div>
</div> </div>
</div> </div>
<div id="apps-list"></div> <div id="apps-list"></div>
<div class="floating-card"> <div class="floating-card">
<button class="floating-btn" id="save">Save Config</button> <button class="floating-btn" id="save">Save and Update</button>
</div> </div>
<template id="app-template"> <template id="app-template">
<div class="card" onclick="toggleCheckbox(event)"> <div class="card" onclick="toggleCheckbox(event)">
<div class="content"> <div class="content" data-package="">
<p class="name"></p> <p class="name"></p>
<input type="checkbox" class="checkbox" checked> <input type="checkbox" class="checkbox" checked>
</div> </div>
</div> </div>
</template> </template>
<div class="acknowledgment"> <div class="loading">Loading...</div>
Credit to j-hc/zygisk-detach WebUI <div class="acknowledgment">Credit to j-hc/zygisk-detach WebUI</div>
</div>
<div id="prompt" class="prompt"></div> <div id="prompt" class="prompt"></div>
</body> </body>
</html> </html>

View File

@@ -1,7 +1,22 @@
let e = 0; let e = 0;
const appTemplate = document.getElementById("app-template").content; const appTemplate = document.getElementById("app-template").content;
const appListContainer = document.getElementById("apps-list"); const appListContainer = document.getElementById("apps-list");
const loadingIndicator = document.querySelector(".loading");
const searchMenuContainer = document.querySelector('.search-menu-container');
const searchInput = document.getElementById("search");
const clearBtn = document.getElementById("clear-btn");
const title = document.querySelector('.title-container');
const noConnection = document.querySelector(".no-connection");
const helpButton = document.getElementById("help-button");
const helpOverlay = document.getElementById("help-overlay");
const closeHelp = document.getElementById("close-help");
const searchCard = document.querySelector('.search-card');
const menu = document.querySelector('.menu');
const selectDenylistElement = document.getElementById("select-denylist");
const floatingBtn = document.querySelector('.floating-btn');
const basePath = "set-path";
let excludeList = []; let excludeList = [];
let isRefreshing = false;
// Function to execute shell commands // Function to execute shell commands
async function execCommand(command) { async function execCommand(command) {
@@ -36,101 +51,240 @@ async function readExcludeFile() {
} }
} }
// Function to fetch the app list using the package manager // Helper function to check if an app name should be excluded
function isExcluded(appName) {
return excludeList.some(excludeItem => appName.includes(excludeItem));
}
// Function to fetch, sort, and render the app list with app names
async function fetchAppList() { async function fetchAppList() {
try { try {
const result = await execCommand("pm list packages -3 </dev/null 2>&1 | cat"); await readExcludeFile();
return result.split("\n").map(line => line.replace("package:", "").trim()).filter(Boolean); const result = await execCommand(`
pm list packages -3 | while read -r line; do
PACKAGE=$(echo "$line" | awk -F: '{print $2}')
APK_PATH=$(pm path "$PACKAGE" | grep "base.apk" | awk -F: '{print $2}' | tr -d '\\r')
if [ -n "$APK_PATH" ]; then
APP_NAME=$( ${basePath}aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g" )
echo "$APP_NAME|$PACKAGE"
else
echo "Unknown App|$PACKAGE"
fi
done
`);
const appEntries = result.split("\n").map(line => {
const [appName, packageName] = line.split("|").map(item => item.trim());
return { appName, packageName };
}).filter(entry => entry.packageName); // Remove invalid entries
const sortedApps = appEntries.sort((a, b) => {
const aInExclude = isExcluded(a.packageName);
const bInExclude = isExcluded(b.packageName);
return aInExclude === bInExclude ? a.appName.localeCompare(b.appName) : aInExclude ? 1 : -1;
});
appListContainer.innerHTML = ""; // Clear the container before rendering
sortedApps.forEach(({ appName, packageName }) => {
const appElement = document.importNode(appTemplate, true);
const contentElement = appElement.querySelector(".content");
contentElement.setAttribute("data-package", packageName);
const nameElement = appElement.querySelector(".name");
nameElement.innerHTML = `<strong>${appName || "Unknown App"}</strong><br>${packageName}`;
const checkbox = appElement.querySelector(".checkbox");
checkbox.checked = !isExcluded(packageName);
appListContainer.appendChild(appElement);
});
console.log("App list with names and packages rendered successfully.");
} catch (error) { } catch (error) {
console.error("Failed to fetch app list:", error); console.error("Failed to fetch or render app list with names:", error);
return []; }
floatingBtn.style.transform = "translateY(-100px)";
}
// Function to refresh app list
async function refreshAppList() {
isRefreshing = true;
title.style.transform = 'translateY(0)';
searchMenuContainer.style.transform = 'translateY(0)';
floatingBtn.style.transform = 'translateY(0)';
searchInput.value = '';
clearBtn.style.display = "none";
appListContainer.innerHTML = '';
loadingIndicator.style.display = 'flex';
await new Promise(resolve => setTimeout(resolve, 500));
window.scrollTo(0, 0);
if (noConnection.style.display === "flex") {
await runExtraScript();
}
await fetchAppList();[]
loadingIndicator.style.display = 'none';
isRefreshing = false;
}
// Function to select all visible apps
function selectAllApps() {
document.querySelectorAll(".card").forEach(card => {
if (card.style.display !== "none") {
card.querySelector(".checkbox").checked = true;
}
});
}
// Function to deselect all visible apps
function deselectAllApps() {
document.querySelectorAll(".card").forEach(card => {
if (card.style.display !== "none") {
card.querySelector(".checkbox").checked = false;
}
});
}
// Function to run the extra script
async function runExtraScript() {
try {
const scriptPath = `${basePath}get_extra.sh`;
await execCommand(scriptPath);
console.log("Extra script executed successfully.");
noConnection.style.display = "none";
} catch (error) {
console.error("Failed to execute Extra script:", error);
showPrompt("Please check your Internet connection", false);
noConnection.style.display = "flex";
} }
} }
// Function to render apps // Function to read the exclude list and uncheck corresponding apps
async function renderAppList() { async function deselectUnnecessaryApps() {
await readExcludeFile(); try {
const apps = await fetchAppList(); const result = await execCommand(`cat ${basePath}exclude-list`);
const sortedApps = apps.sort((a, b) => { const UnnecessaryApps = result.split("\n").map(app => app.trim()).filter(Boolean);
const aInExclude = excludeList.includes(a); const apps = document.querySelectorAll(".card");
const bInExclude = excludeList.includes(b); apps.forEach(app => {
return aInExclude === bInExclude ? a.localeCompare(b) : aInExclude ? 1 : -1; const contentElement = app.querySelector(".content");
}); const packageName = contentElement.getAttribute("data-package");
appListContainer.innerHTML = ""; const checkbox = app.querySelector(".checkbox");
sortedApps.forEach(appName => { if (UnnecessaryApps.includes(packageName)) {
const appElement = document.importNode(appTemplate, true); checkbox.checked = false; // Uncheck if found in more-exclude list
appElement.querySelector(".name").textContent = appName; }
const checkbox = appElement.querySelector(".checkbox"); });
checkbox.checked = !excludeList.includes(appName); console.log("unnecessary apps deselected successfully.");
appListContainer.appendChild(appElement); } catch (error) {
}); console.error("Failed to deselect unnecessary apps:", error);
}
} }
// Function to refresh the app list and clear the search input // Function to check if Magisk
async function refreshAppList() { async function checkMagisk() {
const searchInput = document.getElementById("search"); try {
searchInput.value = ''; const hasDenylistCondition = await execCommand(`
const apps = appListContainer.querySelectorAll(".card"); if [ ! -f "/data/adb/apd" ] && [ ! -f "/data/adb/ksud" ]; then
apps.forEach(app => app.style.display = "block"); echo "OK"
await renderAppList(); else
echo ""
fi
`);
if (hasDenylistCondition.trim() === "OK") {
console.log("Denylist conditions met, displaying element.");
selectDenylistElement.style.display = "flex";
} else {
console.log("ksud or apd detected, leaving denylist element hidden.");
}
} catch (error) {
console.error("Error while checking denylist conditions:", error);
}
} }
// Function to select all apps // Function to read the denylist and check corresponding apps
function selectAllApps() { async function selectDenylistApps() {
document.querySelectorAll(".checkbox").forEach(checkbox => checkbox.checked = true); try {
const result = await execCommand(`
magisk --denylist ls 2>/dev/null | \
awk -F'|' '{print $1}' | \
grep -v "isolated" | \
sort | uniq
`);
const denylistApps = result.split("\n").map(app => app.trim()).filter(Boolean);
const apps = document.querySelectorAll(".card");
await deselectAllApps();
apps.forEach(app => {
const contentElement = app.querySelector(".content");
const packageName = contentElement.getAttribute("data-package");
const checkbox = app.querySelector(".checkbox");
if (denylistApps.includes(packageName)) {
checkbox.checked = true; // Select the app if found in denylist
}
});
console.log("Denylist apps selected successfully.");
} catch (error) {
console.error("Failed to select Denylist apps:", error);
}
} }
// Function to deselect all apps // Function to replace aosp kb
function deselectAllApps() { async function aospkb() {
document.querySelectorAll(".checkbox").forEach(checkbox => checkbox.checked = false); try {
const sourcePath = `${basePath}.default`;
const destinationPath = "/data/adb/tricky_store/keybox.xml";
await execCommand(`xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
console.log("AOSP keybox copied successfully.");
showPrompt("AOSP keybox set successfully.");
} catch (error) {
console.error("Failed to copy AOSP keybox:", error);
showPrompt("Failed to update keybox.", false);
}
} }
let promptTimeout; // Variable to store the current timeout // Function to replace valid kb
async function extrakb() {
const sourcePath = `${basePath}.extra`;
const destinationPath = "/data/adb/tricky_store/keybox.xml";
try {
const fileExists = await execCommand(`[ -f ${sourcePath} ] && echo "exists"`);
if (fileExists.trim() !== "exists") {
throw new Error(".extra file not found");
}
await execCommand(`xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
console.log("Valid keybox copied successfully.");
showPrompt("Valid keybox set successfully.");
} catch (error) {
console.error("Failed to copy valid keybox:", error);
await aospkb();
showPrompt("No valid keybox found, replaced with AOSP keybox.", false);
}
}
// Function to show the prompt with a success or error message // Function to show the prompt with a success or error message
function showPrompt(message, isSuccess = true) { function showPrompt(message, isSuccess = true) {
const prompt = document.getElementById('prompt'); const prompt = document.getElementById('prompt');
prompt.textContent = message; prompt.textContent = message;
prompt.classList.toggle('error', !isSuccess); // Apply error class if not success prompt.classList.toggle('error', !isSuccess);
prompt.style.display = 'block'; if (window.promptTimeout) {
clearTimeout(window.promptTimeout);
if (promptTimeout) {
clearTimeout(promptTimeout);
} }
setTimeout(() => {
promptTimeout = setTimeout(() => { prompt.classList.add('visible');
prompt.style.display = 'none'; prompt.classList.remove('hidden');
}, 2000); window.promptTimeout = setTimeout(() => {
prompt.classList.remove('visible');
prompt.classList.add('hidden');
}, 3000);
}, 500);
} }
// Function to update the target list by executing a script // Function to toggle menu option
async function updateTargetList() {
try {
await execCommand("/data/adb/tricky_store/UpdateTargetList.sh");
showPrompt("Successfully updated target.txt");
} catch (error) {
console.error("Failed to update target list:", error);
showPrompt("Failed to update target.txt !", false);
}
}
// Menu toggle functionality
function setupMenuToggle() { function setupMenuToggle() {
const menuButton = document.getElementById('menu-button'); const menuButton = document.getElementById('menu-button');
const menuIcon = menuButton.querySelector('.menu-icon');
const menuOptions = document.getElementById('menu-options'); const menuOptions = document.getElementById('menu-options');
let menuOpen = false;
let menuAnimating = false;
menuButton.addEventListener('click', (event) => { menuButton.addEventListener('click', (event) => {
if (menuAnimating) return;
event.stopPropagation(); event.stopPropagation();
if (menuOptions.classList.contains('visible')) { if (menuOptions.classList.contains('visible')) {
closeMenu(); closeMenu();
} else { } else {
menuOptions.style.display = 'block'; openMenu();
setTimeout(() => {
menuOptions.classList.remove('hidden');
menuOptions.classList.add('visible');
menuButton.classList.add('menu-open');
menuButton.classList.remove('menu-closed');
}, 10);
} }
}); });
@@ -140,7 +294,13 @@ function setupMenuToggle() {
} }
}); });
const closeMenuItems = ['refresh', 'select-all', 'deselect-all', 'update']; window.addEventListener('scroll', () => {
if (menuOptions.classList.contains('visible')) {
closeMenu();
}
});
const closeMenuItems = ['refresh', 'select-all', 'deselect-all', 'select-denylist', 'deselect-unnecessary', 'aospkb', 'extrakb'];
closeMenuItems.forEach(id => { closeMenuItems.forEach(id => {
const item = document.getElementById(id); const item = document.getElementById(id);
if (item) { if (item) {
@@ -151,92 +311,169 @@ function setupMenuToggle() {
} }
}); });
function openMenu() {
menuAnimating = true;
menuOptions.style.display = 'block';
setTimeout(() => {
menuOptions.classList.remove('hidden');
menuOptions.classList.add('visible');
menuIcon.classList.add('menu-open');
menuIcon.classList.remove('menu-closed');
menuOpen = true;
menuAnimating = false;
}, 10);
}
function closeMenu() { function closeMenu() {
if (menuOptions.classList.contains('visible')) { if (menuOptions.classList.contains('visible')) {
menuAnimating = true;
menuOptions.classList.remove('visible'); menuOptions.classList.remove('visible');
menuOptions.classList.add('hidden'); menuOptions.classList.add('hidden');
menuButton.classList.remove('menu-open'); menuIcon.classList.remove('menu-open');
menuButton.classList.add('menu-closed'); menuIcon.classList.add('menu-closed');
setTimeout(() => { setTimeout(() => {
menuOptions.style.display = 'none'; menuOptions.style.display = 'none';
}, 300); menuOpen = false;
menuAnimating = false;
}, 200);
} }
} }
} }
// Focus on search input when search card is clicked
searchCard.addEventListener("click", () => {
searchInput.focus();
});
// Search functionality // Search functionality
document.getElementById("search").addEventListener("input", (e) => { searchInput.addEventListener("input", (e) => {
const searchQuery = e.target.value.toLowerCase(); const searchQuery = e.target.value.toLowerCase();
const apps = appListContainer.querySelectorAll(".card"); const apps = appListContainer.querySelectorAll(".card");
apps.forEach(app => { apps.forEach(app => {
const name = app.querySelector(".name").textContent.toLowerCase(); const name = app.querySelector(".name").textContent.toLowerCase();
app.style.display = name.includes(searchQuery) ? "block" : "none"; app.style.display = name.includes(searchQuery) ? "block" : "none";
window.scrollTo(0, 0);
});
if (searchQuery !== "") {
clearBtn.style.display = "block";
} else {
clearBtn.style.display = "none";
}
});
// Clear search input
clearBtn.addEventListener("click", () => {
searchInput.value = "";
clearBtn.style.display = "none";
window.scrollTo(0, 0);
const apps = appListContainer.querySelectorAll(".card");
apps.forEach(app => {
app.style.display = "block";
}); });
}); });
// Add button click event to update EXCLUDE file // Add button click event to update EXCLUDE file and run UpdateTargetList.sh
document.getElementById("save").addEventListener("click", async () => { document.getElementById("save").addEventListener("click", async () => {
await readExcludeFile(); await readExcludeFile();
const deselectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:not(:checked)")) const deselectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:not(:checked)"))
.map(checkbox => checkbox.closest(".card").querySelector(".name").textContent); .map(checkbox => checkbox.closest(".card").querySelector(".content").getAttribute("data-package"));
const selectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:checked")) const selectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:checked"))
.map(checkbox => checkbox.closest(".card").querySelector(".name").textContent); .map(checkbox => checkbox.closest(".card").querySelector(".content").getAttribute("data-package"));
// Add deselected apps to EXCLUDE list
for (const app of deselectedApps) { for (const packageName of deselectedApps) {
if (!excludeList.includes(app)) { if (!excludeList.includes(packageName)) {
excludeList.push(app); excludeList.push(packageName);
console.log("Added to EXCLUDE list:", app); console.log("Added to EXCLUDE list:", packageName);
} else { } else {
console.log("App already in EXCLUDE file, skipping:", app); console.log("Package already in EXCLUDE file, skipping:", packageName);
} }
} }
// Remove selected apps from EXCLUDE list
if (selectedApps.length > 0) { if (selectedApps.length > 0) {
selectedApps.forEach(app => { selectedApps.forEach(packageName => {
excludeList = excludeList.filter(excludedApp => excludedApp !== app); excludeList = excludeList.filter(excludedPackage => excludedPackage !== packageName);
console.log("Removed from EXCLUDE list:", app); console.log("Removed from EXCLUDE list:", packageName);
}); });
} }
try { try {
// Save the EXCLUDE file
const updatedExcludeContent = excludeList.join("\n"); const updatedExcludeContent = excludeList.join("\n");
await execCommand(`echo "${updatedExcludeContent}" > /data/adb/tricky_store/target_list_config/EXCLUDE`); await execCommand(`echo "${updatedExcludeContent}" > /data/adb/tricky_store/target_list_config/EXCLUDE`);
console.log("EXCLUDE file updated successfully."); console.log("EXCLUDE file updated successfully.");
showPrompt("Config saved successfully");
// Execute UpdateTargetList.sh
try {
await execCommand("/data/adb/tricky_store/UpdateTargetList.sh");
showPrompt("Config and target.txt updated");
} catch (error) {
console.error("Failed to update target list:", error);
showPrompt("Config saved, but failed to update target list", false);
}
} catch (error) { } catch (error) {
console.error("Failed to update EXCLUDE file:", error); console.error("Failed to update EXCLUDE file:", error);
showPrompt("Failed to save config", false); showPrompt("Failed to save config", false);
} }
await readExcludeFile(); await readExcludeFile();
await refreshAppList();
}); });
// Event listener for the "Update Target List" menu option
document.getElementById('update').addEventListener('click', updateTargetList);
// Initial load // Initial load
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', async () => {
setupMenuToggle(); setupMenuToggle();
document.getElementById("refresh").addEventListener("click", refreshAppList); document.getElementById("refresh").addEventListener("click", refreshAppList);
document.getElementById("select-all").addEventListener("click", selectAllApps); document.getElementById("select-all").addEventListener("click", selectAllApps);
document.getElementById("deselect-all").addEventListener("click", deselectAllApps); document.getElementById("deselect-all").addEventListener("click", deselectAllApps);
renderAppList(); document.getElementById("select-denylist").addEventListener("click", selectDenylistApps);
document.getElementById("deselect-unnecessary").addEventListener("click", deselectUnnecessaryApps);
document.getElementById("aospkb").addEventListener("click", aospkb);
document.getElementById("extrakb").addEventListener("click", extrakb);
await fetchAppList();
checkMagisk();
runExtraScript();
loadingIndicator.style.display = "none";
}); });
// Scroll event // Scroll event
let lastScrollY = window.scrollY; let lastScrollY = window.scrollY;
const title = document.getElementById('title'); const scrollThreshold = 35;
const searchCard = document.querySelector('.search-card');
const menu = document.querySelector('.menu');
window.addEventListener('scroll', () => { window.addEventListener('scroll', () => {
if (window.scrollY > lastScrollY) { if (isRefreshing) return;
if (window.scrollY > lastScrollY && window.scrollY > scrollThreshold) {
title.style.transform = 'translateY(-100%)'; title.style.transform = 'translateY(-100%)';
searchCard.style.transform = 'translateY(-40px)'; searchMenuContainer.style.transform = 'translateY(-35px)';
menu.style.transform = 'translateY(-40px)'; floatingBtn.style.transform = 'translateY(0)';
} else { } else if (window.scrollY < lastScrollY) {
title.style.transform = 'translateY(0)'; title.style.transform = 'translateY(0)';
searchCard.style.transform = 'translateY(0)'; searchMenuContainer.style.transform = 'translateY(0)';
menu.style.transform = 'translateY(0)'; floatingBtn.style.transform = 'translateY(-100px)';
} }
lastScrollY = window.scrollY; lastScrollY = window.scrollY;
}); });
// Show help overlay
helpButton.addEventListener("click", () => {
helpOverlay.classList.remove("hide");
helpOverlay.style.display = "flex";
requestAnimationFrame(() => {
helpOverlay.classList.add("show");
});
document.body.classList.add("no-scroll");
});
// Hide help overlay
const hideHelpOverlay = () => {
helpOverlay.classList.remove("show");
helpOverlay.classList.add("hide");
document.body.classList.remove("no-scroll");
setTimeout(() => {
helpOverlay.style.display = "none";
}, 200);
};
// Hide when clicking on close button or outside of the overlay content
closeHelp.addEventListener("click", hideHelpOverlay);
helpOverlay.addEventListener("click", (event) => {
if (event.target === helpOverlay) {
hideHelpOverlay();
}
});

View File

@@ -2,58 +2,194 @@ body {
background-color: #F5F5F5; background-color: #F5F5F5;
} }
#title { .no-scroll {
overflow: hidden;
}
.title-container {
display: flex;
align-items: center;
justify-content: space-between;
position: fixed;
top: 0;
height: 40px;
width: calc(100% - 17px);
background-color: #F5F5F5; background-color: #F5F5F5;
border: none; transition: transform 0.3s ease;
z-index: 1000;
}
#title {
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
left: 0; padding-left: 10px;
padding: 7px 25px; }
.no-connection {
display: none;
align-items: center;
color: #7E7E7E;
}
.no-connection .wifi-icon {
width: 20px;
height: 20px;
margin-right: 5px;
filter: invert(0.6) sepia(0) saturate(0) hue-rotate(180deg) brightness(0.8) contrast(1);
}
.help-button {
margin-right: auto;
padding: 0 10px;
background: none;
border: none;
font-size: 24px;
align-items: center;
justify-content: center;
}
.help-overlay {
display: none;
position: fixed; position: fixed;
text-align: left;
top: 0; top: 0;
transition: transform 0.3s ease; left: 0;
width: 100%; width: 100vw;
z-index: 1000; height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
z-index: 2000;
justify-content: center;
align-items: center;
opacity: 0;
transition: opacity 0.2s ease;
}
.help-overlay.show {
display: flex;
opacity: 1;
}
.help-overlay.hide {
opacity: 0;
}
.help-menu {
position: relative;
width: 75vw;
max-width: 800px;
background-color: white;
padding: 0 10px;
border-radius: 15px;
text-align: left;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.close-help {
position: absolute;
top: 15px;
right: 12px;
background: none;
border: none;
font-size: 20px;
color: #ccc;
}
.help-content {
max-height: 85vh;
padding: 0 20px;
overflow-y: auto;
}
.help-content p {
font-size: 26px;
}
.help-content ul {
padding-left: 0;
list-style-type: none;
}
.help-content ul li {
font-weight: bold;
font-size: 18px;
}
.help-content ul ul li {
font-weight: normal;
font-size: 16px;
}
.help-content ul ul ul li {
color: #777777;
font-weight: normal;
font-size: 14px;
}
.help-content ul ul ul li a {
color: inherit;
} }
#apps-list { #apps-list {
margin-top: 100px; margin-top: 100px;
} }
.search-menu-container {
display: flex;
position: fixed;
top: 40px;
height: 50px;
width: calc(100% - 17px);
z-index: 1000;
transition: transform 0.3s ease;
}
.search-card { .search-card {
background-color: white; background-color: white;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 25px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
display: flex; display: flex;
align-items: center; align-items: center;
padding: 10px; border-radius: 50px;
position: fixed; left: 0;
top: 40px; height: calc(100% - 2px);
transition: transform 0.3s ease; width: calc(100% - 60px);
width: calc(100% - 100px); position: absolute;
}
.search-icon {
position: absolute;
left: 18px;
font-size: 15px;
z-index: 1000; z-index: 1000;
} }
.search-input { .search-input {
background-color: #fff; position: absolute;
border: none; border: none;
box-sizing: border-box; font-size: 17px;
font-size: 14px;
outline: none; outline: none;
padding: 5px 15px; left: 10px;
text-align: left; padding: 0 30px;
width: 100%; width: calc(100% - 10);
}
.clear-btn {
position: absolute;
color: #ccc;
right: 10px;
border: none;
background: none;
font-size: 18px;
cursor: pointer;
display: none;
z-index: 10;
} }
.menu { .menu {
display: flex; display: flex;
position: fixed; right: 0;
top: 40px; position: absolute;
right: 10px; height: 100%;
z-index: 1000;
transition: transform 0.3s ease;
} }
.menu-toggle { .menu-toggle {
@@ -63,11 +199,25 @@ body {
#menu-button { #menu-button {
background-color: white; background-color: white;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 25px; border-radius: 50%;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
padding: 13px 17px; width: 48px;
text-align: center; display: flex;
transition: transform 0.3s ease; justify-content: center;
align-items: center;
}
.menu-icon {
display: inline-block;
transition: transform 0.2s ease;
}
.menu-icon.menu-open {
transform: rotate(90deg);
}
.menu-icon.menu-closed {
transform: rotate(0deg);
} }
.menu-options { .menu-options {
@@ -77,11 +227,17 @@ body {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
display: none; display: none;
position: absolute; position: absolute;
padding: 5px;
top: 110%; top: 110%;
right: 0; right: 0;
transform: translateX(100%); transform: translateX(120%);
transition: transform 0.3s ease; transition: transform 0.2s ease;
width: 170px; width: auto;
white-space: nowrap;
}
#select-denylist {
display: none;
} }
.menu-options.visible { .menu-options.visible {
@@ -90,7 +246,7 @@ body {
} }
.menu-options.hidden { .menu-options.hidden {
transform: translateX(110%); transform: translateX(140%);
} }
.menu-options ul { .menu-options ul {
@@ -100,19 +256,11 @@ body {
} }
.menu-options li { .menu-options li {
cursor: pointer; cursor: default;
padding: 15px 16px; padding: 15px 12px;
text-align: left; text-align: left;
} }
.menu-open {
transform: rotate(90deg);
}
.menu-closed {
transform: rotate(0deg);
}
.card { .card {
background-color: white; background-color: white;
border: none; border: none;
@@ -141,29 +289,66 @@ body {
} }
.prompt { .prompt {
position: fixed;
bottom: 0;
left: 10px;
background-color: #4CAF50; background-color: #4CAF50;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
color: white; color: white;
display: none;
font-size: 15px; font-size: 15px;
left: 10px;
padding: 5px 15px; padding: 5px 15px;
position: fixed;
bottom: 15px;
z-index: 1000; z-index: 1000;
transition: opacity 1s ease; transform: translateY(100%);
transition: transform 0.5s ease;
white-space: nowrap;
}
.prompt.visible {
animation: YbounceIn 0.4s forwards;
}
.prompt.hidden {
animation: YbounceOut 0.4s forwards;
} }
.prompt.error { .prompt.error {
background-color: #f44336; background-color: #f44336;
} }
@keyframes YbounceIn {
0% {
transform: translateY(100%);
}
50% {
transform: translateY(-80%);
}
100% {
transform: translateY(-60%);
}
}
@keyframes YbounceOut {
0% {
transform: translateY(-60%);
}
50% {
transform: translateY(-80%);
}
100% {
transform: translateY(100%);
}
}
.floating-card { .floating-card {
display: flex; display: flex;
justify-content: center; justify-content: center;
position: fixed; position: fixed;
bottom: 45px; bottom: -50px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
z-index: 3; z-index: 3;
@@ -172,15 +357,27 @@ body {
.floating-btn { .floating-btn {
background-color: #007bff; background-color: #007bff;
border: none; border: none;
border-radius: 24px;
box-shadow: 0 4px 8px #0003; box-shadow: 0 4px 8px #0003;
color: #fff; color: #fff;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 10px 20px; padding: 12px 17px;
font-size: 16px; font-size: 17px;
transition: transform .3s ease-in-out; transition: transform 0.3s ease-in-out;
border-top-left-radius: 50px;
border-top-right-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
}
.loading {
color: #6E6E6E;
display: flex;
justify-content: center;
align-items: center;
height: calc(100vh - 164px);
font-size: 24px;
} }
.acknowledgment { .acknowledgment {
@@ -196,10 +393,15 @@ body {
color: #eee; color: #eee;
} }
#title { .title-container {
background-color: #121212; background-color: #121212;
} }
.help-button {
color: #fff;
}
.help-menu,
.card, .card,
.search-input, .search-input,
.search-card { .search-card {
@@ -210,6 +412,10 @@ body {
border: 1px solid #6E6E6E; border: 1px solid #6E6E6E;
} }
.search-input {
color: white;
}
.menu-options, .menu-options,
#menu-button { #menu-button {
background-color: #343434; background-color: #343434;

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.92,5.51h0L3.71,2.29A1,1,0,0,0,2.29,3.71L4.56,6A15.21,15.21,0,0,0,1.4,8.39a1,1,0,0,0,0,1.41,1,1,0,0,0,.71.3,1,1,0,0,0,.7-.29A13.07,13.07,0,0,1,6.05,7.46L7.54,9a10.78,10.78,0,0,0-3.32,2.27,1,1,0,1,0,1.42,1.4,8.8,8.8,0,0,1,3.45-2.12l1.62,1.61a7.07,7.07,0,0,0-3.66,1.94,1,1,0,1,0,1.42,1.4A5,5,0,0,1,12,14a4.13,4.13,0,0,1,.63.05l7.66,7.66a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42ZM12,16a3,3,0,1,0,3,3A3,3,0,0,0,12,16Zm0,4a1,1,0,1,1,1-1A1,1,0,0,1,12,20ZM22.61,8.39A15,15,0,0,0,10.29,4.1a1,1,0,1,0,.22,2A13.07,13.07,0,0,1,21.2,9.81a1,1,0,0,0,1.41-1.42Zm-4.25,4.24a1,1,0,0,0,1.42-1.4,10.75,10.75,0,0,0-4.84-2.82,1,1,0,1,0-.52,1.92A8.94,8.94,0,0,1,18.36,12.63Z"/></svg>

After

Width:  |  Height:  |  Size: 725 B

116
more-excldue.json Normal file
View File

@@ -0,0 +1,116 @@
{
"description": "Unnecessary app list",
"repo-link": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List",
"json-link": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/more-excldue.json",
"data": [
{
"info": "Root manager",
"apps": [
{
"name": "Magisk",
"package-name": "com.topjohnwu.magisk"
},
{
"name": "Magisk Alpha",
"package-name": "io.github.vvb2060.magisk"
},
{
"name": "Kitsune Mask",
"package-name": "io.github.huskydg.magisk"
},
{
"name": "KernelSU",
"package-name": "me.weishu.kernelsu"
},
{
"name": "Apatch",
"package-name": "me.bmax.apatch"
},
{
"name": "Apatch Next",
"package-name": "me.garfieldhan.apatch.next"
}
]
},
{
"info": "Root related app that won't detect bootloader",
"apps": [
{
"name": "LSPosed Manager",
"package-name": "org.lsposed.manager"
},
{
"name": "Termux",
"package-name": "com.termux"
},
{
"name": "MT Manager",
"package-name": "bin.mt.plus"
},
{
"name": "MT Manager clone",
"package-name": "bin.mt.plus.canary"
},
{
"name": "KonaBess",
"package-name": "xzr.konabess"
},
{
"name": "KsuWebUI",
"package-name": "io.github.a13e300.ksuwebui"
},
{
"name": "ShortX",
"package-name": "tornaco.apps.shortx"
}
]
},
{
"info": "General app that won't detect bootloader",
"apps": [
{
"name": "Scene",
"package-name": "com.omarea.vtools"
},
{
"name": "Swift Backup",
"package-name": "org.swiftapps.swiftbackup"
},
{
"name": "Google Docs",
"package-name": "com.google.android.apps.docs.editors.docs"
},
{
"name": "Google Sheets",
"package-name": "com.google.android.apps.docs.editors.sheets"
},
{
"name": "Google Slides",
"package-name": "com.google.android.apps.docs.editors.slides"
},
{
"name": "Google Maps",
"package-name": "com.google.android.apps.maps"
},
{
"name": "Google Earth",
"package-name": "com.google.earth"
},
{
"name": "Google Translate",
"package-name": "com.google.android.apps.translate"
},
{
"name": "Chrome",
"package-name": "com.android.chrome"
}
]
}
],
"Add more app into this list?": [
{
"issue": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/issues",
"pull-request": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/pulls"
}
]
}

View File

@@ -1,6 +1,6 @@
{ {
"versionCode": 200, "versionCode": 250,
"version": "v2.0", "version": "v2.5",
"zipUrl": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/download/v2.0/TrickyAddonModule-v2.0.zip", "zipUrl": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/download/v2.5/TrickyAddonModule-v2.5.zip",
"changelog": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/refs/heads/master/changelog.md" "changelog": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/changelog.md"
} }