-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/repack appimage improvements (#170)
* feat: arm64支持, 在线下载支持, AppRun 优化 - arm64 架构支持 - 变量 LITELOADERQQNT_PROFILE 支持自定义 - 在线下载 qq appimage * fix: qq appimage download error * fix: add dependencies for appimage.yml * fix: update deprecated content in workflow * fix: add missing quotes in output * fix: GITHUB_OUTPUT usage error * chore: rename workflow steps in appimage.yml * fix: fix detection section in appimage.yml workflow * feat: 手动提取 squashfs 内容以支持 arm64 架构 - 使用 wget 替换 curl - 通过特征值 "68 73 71 73" 获取 squashfs 在 appimage 文件中的偏移值以提取 squashfs 文件 * fix: remove debug code and fix typos
- Loading branch information
Showing
2 changed files
with
187 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,171 @@ | ||
#!/bin/bash | ||
|
||
# 修补 index.js 的函数,创建 *.js 文件,并修改 package.json | ||
function patch_index_js() { | ||
local path=$1 | ||
local file_name="ml_install.js" # 这里的文件名可以随意设置 | ||
|
||
echo "正在创建 $path/$file_name..." | ||
os_arch=${ARCH:=$(uname -m)} | ||
|
||
[ "$os_arch" = "x86_64" ] && _arch="$os_arch" || _arch="aarch64" | ||
runtime_url="https://github.com/AppImage/AppImageKit/releases/download/13/runtime-$_arch" | ||
|
||
echo "正在获取 LiteLoaderQQNT 版本..." | ||
liteloaderqqnt_check_url="https://github.com/LiteLoaderQQNT/LiteLoaderQQNT/releases/latest" | ||
liteloaderqqnt_version=$(basename "$(wget -t3 -T3 --spider "$liteloaderqqnt_check_url" 2>&1 | grep -m1 -o 'https://.*releases/tag[^ ]*')") | ||
liteloaderqqnt_url="https://github.com/LiteLoaderQQNT/LiteLoaderQQNT/releases/latest/download/LiteLoaderQQNT.zip" | ||
echo "最新 LiteLoaderQQNT 版本:$liteloaderqqnt_version" | ||
|
||
workdir="$PWD" | ||
|
||
# 创建并切换至临时目录 | ||
temp_dir=$(mktemp -d) | ||
echo "临时目录创建成功: $temp_dir" | ||
cd "$temp_dir" || exit 1 | ||
|
||
cleanup() { | ||
echo "清理临时目录: $temp_dir" | ||
rm -rf "$temp_dir" | ||
} | ||
trap cleanup EXIT | ||
|
||
# 修补 resources,创建 *.js 文件,并修改 package.json | ||
function patch_resources() { | ||
local app_path=$1 | ||
local jsfile_name="ml_install.js" # 这里的文件名可以随意设置 | ||
local jsfile_path="$app_path/app_launcher/$jsfile_name" | ||
|
||
# 写入 require(String.raw`*`) 到 *.js 文件 | ||
echo 'require("./LiteLoader");' > "$path/$file_name" | ||
echo "已创建 $path/$file_name,内容为 require("./LiteLoader")" | ||
echo "正在将 'require(\"./LiteLoader\");' 写入 $jsfile_path" | ||
echo 'require("./LiteLoader");' > "$jsfile_path" | ||
echo "写入成功" | ||
|
||
# 检查 package.json 文件是否存在 | ||
local package_json="$path/../package.json" | ||
local package_json="$app_path/package.json" | ||
if [ -f "$package_json" ]; then | ||
echo "正在修改 $package_json 的 main 字段..." | ||
|
||
# 修改 package.json 中的 main 字段为 ./app_launcher/launcher.js | ||
$sudo_cmd sed -i 's|"main":.*|"main": "./app_launcher/'"$file_name"'",|' "$package_json" | ||
echo "已将 $package_json 中的 main 字段修改为 ./app_launcher/$file_name" | ||
echo "正在修改 $package_json 的 main 字段为 './app_launcher/$jsfile_name'" | ||
sed -i 's|"main":.*|"main": "./app_launcher/'"$jsfile_name"'",|' "$package_json" | ||
echo "修改成功" | ||
else | ||
echo "未找到 $path/../package.json,跳过修改" | ||
echo "未找到 $package_json,跳过修改" | ||
fi | ||
} | ||
|
||
if [ $# -eq 0 ]; then | ||
echo "未提供 QQ.AppImage 文件的路径,默认使用当前目录下的 QQ.AppImage" | ||
appimage_path="$PWD/QQ.AppImage" | ||
else | ||
appimage_path="$1" | ||
fi | ||
# 获取qq appimage 最新链接 | ||
function get_qqnt_appimage_url() { | ||
[ "$os_arch" != "x86_64" ] && os_arch="arm64" | ||
check_url="$(wget -t3 -T3 -q -O- https://im.qq.com/linuxqq/index.shtml| grep -o 'https://.*linuxQQDownload.js?[^"]*')" | ||
appimage_url=$(wget -t3 -T3 -q -O- "$check_url" | grep -o 'https://[^,]*AppImage' | grep "$os_arch") | ||
|
||
qq_path=$(dirname "$appimage_path") | ||
[ -z "$appimage_url" ] && { echo "获取qq下载链接失败"; exit 1; } | ||
echo "$appimage_url" | ||
} | ||
|
||
if [ -f "$appimage_path" ]; then | ||
echo "当前 QQ.AppImage 路径: $appimage_path" | ||
cp "$appimage_path" QQ.AppImage.bak | ||
chmod +x "$appimage_path" | ||
else | ||
echo "未找到指定的 QQ.AppImage 文件" | ||
exit 1 | ||
fi | ||
echo "处理原AppImage" | ||
chmod +x $appimage_path | ||
$appimage_path --appimage-extract >/dev/null | ||
rm "$appimage_path" | ||
|
||
cd $qq_path/squashfs-root | ||
target_dir="$qq_path/squashfs-root" | ||
install_dir="$target_dir/resources/app/app_launcher" | ||
config_file="$target_dir/AppRun" | ||
plugin_dir="\$HOME/.config/QQ/LiteLoader" | ||
echo "当前target_dir:$target_dir" | ||
|
||
# 检查是否已存在LITELOADERQQNT_PROFILE | ||
if grep -q "export LITELOADERQQNT_PROFILE=" "$config_file"; then | ||
sed -i 's|export LITELOADERQQNT_PROFILE=.*|export LITELOADERQQNT_PROFILE="'$plugin_dir'"|' "$config_file" | ||
else | ||
# 如果不存在,则添加新的行 | ||
echo 'export LITELOADERQQNT_PROFILE="'$plugin_dir'"' >> "$config_file" | ||
echo "已添加 LITELOADERQQNT_PROFILE: $plugin_dir" | ||
fi | ||
function download_url() { | ||
local url=$1 | ||
local output=$2 | ||
echo "开始下载 $output: $url" | ||
if wget -t3 -T3 -q -O "$output" "$url"; then | ||
echo "下载成功:$output" | ||
else | ||
echo "下载失败:$url" && exit 1 | ||
fi | ||
} | ||
|
||
cd /tmp | ||
echo "正在拉取最新版本的仓库..." | ||
rm -rf LiteLoader | ||
git clone https://github.com/LiteLoaderQQNT/LiteLoaderQQNT.git LiteLoader | ||
# 计算 squashfs 偏移值 | ||
function calc_appimage_offset() { | ||
local appimage_file="$1" | ||
local magic_number="68 73 71 73" #hsqs | ||
|
||
# 移动到安装目录 | ||
echo "拉取完成,正在安装LiteLoader..." | ||
[ ! -f "$appimage_file" ] && { echo "Error: '$appimage_file' not found!"; exit 1; } | ||
|
||
# 移动LiteLoader | ||
mv -f LiteLoader "$install_dir/LiteLoader" | ||
# 查找魔数并计算偏移值 | ||
lineno=$(od -A n -t x1 -v -w4 "$appimage_file" | awk "/^ $magic_number/ {print NR; exit}") | ||
[ -z "$lineno" ] && { echo "Error: 未找到 squashfs"; exit 1; } | ||
|
||
# 修改index.js | ||
echo "正在修补index.js... $install_dir" | ||
echo "$(( (lineno-1)*4 ))" | ||
} | ||
|
||
patch_index_js "$install_dir" | ||
# 提取 appimage 内容 | ||
function extract_appimage() { | ||
local appimage_file="$1" | ||
if ! ./"$appimage_file" --appimage-extract >/dev/null 2>&1; then | ||
echo "执行 --appimage-extract 失败,尝试手动提取..." | ||
offset=$(calc_appimage_offset "$appimage_file") | ||
output="out.squashfs" | ||
echo "squashfs偏移值:$offset" | ||
rm -rf squashfs-root | ||
|
||
echo "开始写出 squashfs 文件至 $output" | ||
tail -c +"$((offset+1))" "$appimage_file" > "$output" | ||
echo "写出成功:$output" | ||
|
||
echo "开始提取 squashfs 内容" | ||
unsquashfs "$output" >/dev/null | ||
[ ! -d "squashfs-root" ] && { echo "文件提取失败: $output"; exit 1; } | ||
echo "文件提取成功" | ||
rm "$output" && echo "临时文件 $output 已移除" | ||
fi | ||
} | ||
|
||
# 修改 AppRun 文件以支持变量 LITELOADERQQNT_PROFILE | ||
function patch_appimage_apprun() { | ||
apprun_file="$1/AppRun" | ||
profile_dir="\$HOME/.config/QQ/LiteLoader" | ||
|
||
chmod -R 0777 $install_dir | ||
# 检查是否已存在 LITELOADERQQNT_PROFILE | ||
if grep -q "export LITELOADERQQNT_PROFILE=" "$apprun_file"; then | ||
sed -i "s|export LITELOADERQQNT_PROFILE=.*|export LITELOADERQQNT_PROFILE=\${LITELOADERQQNT_PROFILE:=$profile_dir}|" "$apprun_file" | ||
else | ||
# 如果不存在,则添加新的行 | ||
echo "export LITELOADERQQNT_PROFILE=\${LITELOADERQQNT_PROFILE:=$profile_dir}" >> "$apprun_file" | ||
echo "已添加 LITELOADERQQNT_PROFILE: $profile_dir" | ||
fi | ||
} | ||
|
||
cd "$target_dir/.." | ||
echo "正在重打包" | ||
mksquashfs squashfs-root tmp.squashfs -root-owned -noappend >/dev/null | ||
cat runtime-x86_64 >> QQ.AppImage | ||
cat tmp.squashfs >> QQ.AppImage | ||
chmod a+x QQ.AppImage | ||
echo "注意,插件与配置文件将放在 $plugin_dir" | ||
# 重新打包 appimage 文件 | ||
function repack_appimage() { | ||
local appdir="$1" | ||
local output="$2" | ||
echo "正在重新打包" | ||
mksquashfs "$appdir" tmp.squashfs -root-owned -noappend >/dev/null | ||
cat "$runtime_filename" >> "$output" | ||
cat "tmp.squashfs" >> "$output" | ||
rm -rf "tmp.squashfs" | ||
chmod a+x "$output" | ||
echo "打包完成:$output" | ||
} | ||
|
||
echo "清理临时文件" | ||
# 清理临时文件 | ||
rm -rf /tmp/LiteLoader | ||
rm -rf tmp.squashfs | ||
rm -r $target_dir | ||
# 修改 appimage 文件 | ||
function patch_appiamge() { | ||
local appimage="$1" | ||
echo "正在对 AppImage 文件进行补丁操作: $appimage" | ||
chmod +x "$appimage" | ||
extract_appimage "$appimage" | ||
patch_appimage_apprun "squashfs-root" | ||
patch_resources "squashfs-root/resources/app" | ||
|
||
install_dir="squashfs-root/resources/app/app_launcher/LiteLoader" | ||
unzip -q "$liteloaderqqnt_filename" -d "$install_dir" | ||
# chmod -R 0777 "$install_dir" | ||
repack_appimage "squashfs-root" "$new_qq_filename" | ||
rm -rf "squashfs-root" | ||
} | ||
|
||
# 错误处理. | ||
if [ $? -ne 0 ]; then | ||
echo "发生错误,安装失败" | ||
exit 1 | ||
# 使用指定 appimage 或从网络获取 | ||
qq_url=$(get_qqnt_appimage_url) | ||
if [ $# -eq 0 ]; then | ||
echo "未提供 QQ.AppImage 文件的路径,默认从官网下载最新版" | ||
qq_filename=$(basename "$qq_url") | ||
download_url "$qq_url" "$qq_filename" | ||
appimage_path=$(realpath "$qq_filename") | ||
else | ||
qq_filename=$(basename "$1") | ||
appimage_path="$(cd "$workdir" || exit; realpath "$1")" | ||
fi | ||
|
||
exit 0 | ||
new_qq_filename=${qq_filename//.AppImage/_patch-${liteloaderqqnt_version}.AppImage} | ||
runtime_filename=$(basename "$runtime_url") | ||
liteloaderqqnt_filename=$(basename "$liteloaderqqnt_url") | ||
|
||
download_url "$runtime_url" "$runtime_filename" | ||
download_url "$liteloaderqqnt_url" "$liteloaderqqnt_filename" | ||
|
||
patch_appiamge "$appimage_path" | ||
cp "$new_qq_filename" "$workdir" |