diff options
-rw-r--r-- | .SRCINFO | 24 | ||||
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | PKGBUILD | 30 | ||||
-rwxr-xr-x | _start.sh | 41 | ||||
-rw-r--r-- | linuxqq-nt-bwrap.install | 3 | ||||
-rw-r--r-- | resolv.conf | 1 | ||||
-rwxr-xr-x | start.sh | 121 |
7 files changed, 176 insertions, 48 deletions
@@ -1,7 +1,7 @@ pkgbase = linuxqq-nt-bwrap pkgdesc = New Linux QQ based on Electron, with bubblewrap sandbox and some tweaks - pkgver = 3.2.7_240412 - pkgrel = 3 + pkgver = 3.2.8_23873 + pkgrel = 4 url = https://im.qq.com/linuxqq/index.shtml install = linuxqq-nt-bwrap.install arch = x86_64 @@ -25,6 +25,8 @@ pkgbase = linuxqq-nt-bwrap depends = openslide depends = autoconf depends = libunwind + depends = slirp4netns + depends = socat optdepends = libappindicator-gtk3: 以显示托盘图标 optdepends = gjs: 提供 GNOME Wayland 下的截图支持 provides = qq @@ -32,16 +34,20 @@ pkgbase = linuxqq-nt-bwrap conflicts = linuxqq options = !emptydirs source = start.sh + source = _start.sh source = config.json + source = resolv.conf source = xdg-open.sh - sha256sums = bf956210c3feef339efbec3a7663dcc061a3066f038d74b1e8bd3eede780d1a5 + sha256sums = 92f5cd9f279dd998af3cd63643aa8591bed8afd203dff09ae518417a965d2c38 + sha256sums = 3c78b576aa5d07e4cacde95d1088530503478bb0d43d19371c5da56f675d9861 sha256sums = bb2ec0f104da4da7422d9b0f51c71d0ab38ed2a21764a7a643ab42689e098e4b + sha256sums = cc002ee0eb2e8702c97d16f4ce628841cd5fe10195875a075432e92248741424 sha256sums = f1c778b5a8b23bc77fd8e5e89056fea07309794c9a44ec38134a176cf1f7b675 - source_x86_64 = https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240412_amd64_01.deb - sha256sums_x86_64 = 83d564e1cc58ec0c114a8fedbbc8d63ff06d97ab780844333600a4971f975203 - source_aarch64 = https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240412_arm64_01.deb - sha256sums_aarch64 = 561c0b5031cdeafeb07510e7bdc49500686c3b8a9d20aa29d1eb7b9b8b8d1706 - source_loong64 = https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240412_loongarch64_01.deb - sha256sums_loong64 = a2a46d62dc151a65bebce18b5ce83c0f4f7004b15ec41982ed0d0fd7d52a29d2 + source_x86_64 = https://dldir1.qq.com/qqfile/qq/QQNT/96fbb21f/linuxqq_3.2.8-23873_amd64.deb + sha256sums_x86_64 = d23e212d26cf80a40e3eab44499aa76586eade3fc260d1b9f171294fb507393f + source_aarch64 = https://dldir1.qq.com/qqfile/qq/QQNT/96fbb21f/linuxqq_3.2.8-23873_arm64.deb + sha256sums_aarch64 = a92bfb1aa9d7be9f08161de4adc2652a17919f8b05e1caf8f9922d776cbc2548 + source_loong64 = https://dldir1.qq.com/qqfile/qq/QQNT/96fbb21f/linuxqq_3.2.8-23873_loongarch64.deb + sha256sums_loong64 = 56ec7abcaa5c96b8bd718096ed84f76b558ab815079e9e6e84f6bd37863b4ac6 pkgname = linuxqq-nt-bwrap diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..876ffd2d0339 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +pkg/ +src/ +linuxqq*.deb +linuxqq*.pkg.tar.zst @@ -2,11 +2,12 @@ # Maintainer: sukanka _pkgname=linuxqq -_base_pkgver=3.2.7_240412 +_base_pkgver=3.2.8-23873 _update_pkgver=${_base_pkgver} +_md5=96fbb21f pkgname=linuxqq-nt-bwrap pkgver="${_update_pkgver//-/_}" -pkgrel=3 +pkgrel=4 pkgdesc="New Linux QQ based on Electron, with bubblewrap sandbox and some tweaks" arch=('x86_64' 'aarch64' 'loong64') url='https://im.qq.com/linuxqq/index.shtml' @@ -15,6 +16,7 @@ depends=('at-spi2-core' 'alsa-lib' 'desktop-file-utils' 'gtk3' 'gtk-update-icon- 'gnutls' 'bubblewrap' 'xdg-user-dirs' 'flatpak-xdg-utils' 'snapd-xdg-open-git' 'libvips' 'openslide' 'autoconf' 'libunwind' + 'slirp4netns' 'socat' ) makedepends=('p7zip') optdepends=('libappindicator-gtk3: 以显示托盘图标' @@ -23,16 +25,18 @@ provides=('qq' 'linuxqq') conflicts=('linuxqq') options=('!emptydirs') install="${pkgname}.install" -source_x86_64=("https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_${_base_pkgver}_amd64_01.deb") -source_aarch64=("https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_${_base_pkgver}_arm64_01.deb") -source_loong64=("https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_${_base_pkgver}_loongarch64_01.deb") -source=('start.sh' 'config.json' 'xdg-open.sh') -sha256sums=('bf956210c3feef339efbec3a7663dcc061a3066f038d74b1e8bd3eede780d1a5' - 'bb2ec0f104da4da7422d9b0f51c71d0ab38ed2a21764a7a643ab42689e098e4b' - 'f1c778b5a8b23bc77fd8e5e89056fea07309794c9a44ec38134a176cf1f7b675') -sha256sums_x86_64=('83d564e1cc58ec0c114a8fedbbc8d63ff06d97ab780844333600a4971f975203') -sha256sums_aarch64=('561c0b5031cdeafeb07510e7bdc49500686c3b8a9d20aa29d1eb7b9b8b8d1706') -sha256sums_loong64=('a2a46d62dc151a65bebce18b5ce83c0f4f7004b15ec41982ed0d0fd7d52a29d2') +source_x86_64=("https://dldir1.qq.com/qqfile/qq/QQNT/${_md5}/linuxqq_${_base_pkgver}_amd64.deb") +source_aarch64=("https://dldir1.qq.com/qqfile/qq/QQNT/${_md5}/linuxqq_${_base_pkgver}_arm64.deb") +source_loong64=("https://dldir1.qq.com/qqfile/qq/QQNT/${_md5}/linuxqq_${_base_pkgver}_loongarch64.deb") +source=('start.sh' '_start.sh' 'config.json' 'resolv.conf' 'xdg-open.sh') +sha256sums=('92f5cd9f279dd998af3cd63643aa8591bed8afd203dff09ae518417a965d2c38' # start.sh + '3c78b576aa5d07e4cacde95d1088530503478bb0d43d19371c5da56f675d9861' # _start.sh + 'bb2ec0f104da4da7422d9b0f51c71d0ab38ed2a21764a7a643ab42689e098e4b' # config.json + 'cc002ee0eb2e8702c97d16f4ce628841cd5fe10195875a075432e92248741424' # resolv.conf + 'f1c778b5a8b23bc77fd8e5e89056fea07309794c9a44ec38134a176cf1f7b675') # xdg-open.sh +sha256sums_x86_64=('d23e212d26cf80a40e3eab44499aa76586eade3fc260d1b9f171294fb507393f') +sha256sums_aarch64=('a92bfb1aa9d7be9f08161de4adc2652a17919f8b05e1caf8f9922d776cbc2548') +sha256sums_loong64=('56ec7abcaa5c96b8bd718096ed84f76b558ab815079e9e6e84f6bd37863b4ac6') prepare() { local base_ver=${_base_pkgver} @@ -53,6 +57,7 @@ package() { mkdir -p "${pkgdir}/opt/QQ/workarounds" install -Dm755 "xdg-open.sh" "${pkgdir}/opt/QQ/workarounds/xdg-open.sh" cp "${srcdir}/config.json" "${pkgdir}/opt/QQ/workarounds/config.json" + cp "${srcdir}/resolv.conf" "${pkgdir}/opt/QQ/workarounds/resolv.conf" # 将 LICENSE 移动到正确位置 mkdir -p "${pkgdir}/usr/share/licenses/${_pkgname}" @@ -64,6 +69,7 @@ package() { # 对 desktop 文件做处理,使其使用正确的图标,启动 start.sh cp "${srcdir}/start.sh" "${pkgdir}/opt/QQ/start.sh" + cp "${srcdir}/_start.sh" "${pkgdir}/opt/QQ/_start.sh" sed -i "s|/opt/QQ/qq|/opt/QQ/start.sh|" "${pkgdir}/usr/share/applications/qq.desktop" sed -i "s|Icon=/usr/share/icons/hicolor/512x512/apps/qq.png|Icon=qq|" "${pkgdir}/usr/share/applications/qq.desktop" diff --git a/_start.sh b/_start.sh new file mode 100755 index 000000000000..d40a92e138cb --- /dev/null +++ b/_start.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Source: https://alampy.com/2024/05/15/fix-mac-for-linux-qq/ + +trap 'kill $(jobs -p)' EXIT + +echo $$ > "${INFO_FILE}" +echo "PID written." + +# wait for the file to be deleted +while [ -f "${INFO_FILE}" ]; do + sleep 0.01 +done +# clear proxy settings +unset http_proxy +unset https_proxy +unset ftp_proxy +unset all_proxy +socat tcp-listen:94301,reuseaddr,fork tcp:127.0.0.1:4301 & +socat tcp-listen:94310,reuseaddr,fork tcp:127.0.0.1:4310 & +/opt/QQ/electron --no-proxy-server "$@" + +# 移除无用崩溃报告和日志 +# 如果需要向腾讯反馈 bug,请注释掉如下几行 +rm -rf ${QQ_APP_DIR}/crash_files +touch ${QQ_APP_DIR}/crash_files +if [ -d "${QQ_APP_DIR}/log" ]; then + rm -rf "${QQ_APP_DIR}/log" +fi +for nt_qq_userdata in "${QQ_APP_DIR}/nt_qq_"*; do + if [ -d "${nt_qq_userdata}/log" ]; then + rm -rf "${nt_qq_userdata}/log" + fi + if [ -d "${nt_qq_userdata}/log-cache" ]; then + rm -rf "${nt_qq_userdata}/log-cache" + fi +done +if [ -d "${QQ_APP_DIR}/Crashpad" ]; then + rm -rf "${QQ_APP_DIR}/Crashpad" +fi + +exit $? diff --git a/linuxqq-nt-bwrap.install b/linuxqq-nt-bwrap.install index d7d3570df130..3694ed9be238 100644 --- a/linuxqq-nt-bwrap.install +++ b/linuxqq-nt-bwrap.install @@ -10,7 +10,8 @@ blue="${bold}$(tput setaf 4)" yellow="${bold}$(tput setaf 3)" post_install() { - note "要传递给 electron 的自定义参数应该写在: ~/.config/qq-electron-flags.conf" + note "要传递给 bwrap 的自定义参数应该写在 ~/.config/qq-bwrap-flags.conf,可在此文件中设置自定义挂载目录。" + note "要传递给 electron 的自定义参数应该写在 ~/.config/qq-electron-flags.conf。" note "如果要在 QQ 中下载文件,请先在「设置」->「存储管理」中把下载文件夹更改为系统的“下载”/“Downloads”文件夹。" } diff --git a/resolv.conf b/resolv.conf new file mode 100644 index 000000000000..27a94c07e56a --- /dev/null +++ b/resolv.conf @@ -0,0 +1 @@ +nameserver 10.0.2.3 @@ -43,19 +43,41 @@ fi # 从 flags 文件中加载参数 set -euo pipefail -flags_file="${XDG_CONFIG_HOME}/qq-electron-flags.conf" -declare -a flags -if [[ -f "${flags_file}" ]]; then - mapfile -t <"${flags_file}" +electron_flags_file="${XDG_CONFIG_HOME}/qq-electron-flags.conf" +declare -a electron_flags +if [[ -f "${electron_flags_file}" ]]; then + mapfile -t ELECTRON_FLAGS_MAPFILE <"${electron_flags_file}" fi - -for line in "${MAPFILE[@]}"; do +for line in "${ELECTRON_FLAGS_MAPFILE[@]}"; do if [[ ! "${line}" =~ ^[[:space:]]*#.* ]]; then - flags+=("${line}") + electron_flags+=("${line}") fi done +bwrap_flags_file="${XDG_CONFIG_HOME}/qq-bwrap-flags.conf" +declare -a bwrap_flags +if [[ -f "${bwrap_flags_file}" ]]; then + while IFS= read -r line; do + if [[ ! "${line}" =~ ^[[:space:]]*# ]] && [[ -n "${line}" ]]; then + eval "expanded_line=\"$line\"" + read -ra parts <<< "$expanded_line" + for part in "${parts[@]}"; do + bwrap_flags+=("$part") + done + fi + done < "${bwrap_flags_file}" +fi + + +# read the mac address from .qq_mac, if not exist, generate a random one +if [ -f "${QQ_APP_DIR}/.qq_mac" ]; then + qq_mac=$(cat "${QQ_APP_DIR}/.qq_mac") +else + qq_mac=00\:$(hexdump -n5 -e '/1 ":%02X"' /dev/random | sed s/^://g) + echo $qq_mac > "${QQ_APP_DIR}/.qq_mac" +fi + QQ_HOTUPDATE_DIR="${QQ_APP_DIR}/versions" # 在「下载」目录不存在的时候,自动使用 ~/Downloads @@ -90,7 +112,14 @@ if [ "$is_hotupdated_version" == "0" ]; then cp "/opt/QQ/workarounds/config.json" "${QQ_HOTUPDATE_DIR}/config.json" fi -bwrap --new-session --cap-drop ALL --unshare-user-try --unshare-pid --unshare-cgroup-try \ +INFO_DIR=$(mktemp -d) +INFO_FILE=$INFO_DIR/info + +bwrap --new-session --unshare-user-try --unshare-cgroup-try \ + --unshare-user \ + --uid "$(id -u)" --gid "$(id -g)" \ + --unshare-net \ + --cap-add CAP_NET_ADMIN,CAP_NET_RAW,CAP_SYS_ADMIN \ --symlink usr/lib /lib \ --symlink usr/lib64 /lib64 \ --symlink usr/bin /bin \ @@ -105,7 +134,7 @@ bwrap --new-session --cap-drop ALL --unshare-user-try --unshare-pid --unshare-cg --ro-bind /etc/passwd /etc/passwd \ --ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \ --ro-bind-try /run/systemd/userdb /run/systemd/userdb \ - --ro-bind /etc/resolv.conf /etc/resolv.conf \ + --ro-bind /opt/QQ/workarounds/resolv.conf /etc/resolv.conf \ --ro-bind /etc/localtime /etc/localtime \ --proc /proc \ --dev-bind /run/dbus /run/dbus \ @@ -115,6 +144,7 @@ bwrap --new-session --cap-drop ALL --unshare-user-try --unshare-pid --unshare-cg --bind-try "${HOME}/.pki" "${HOME}/.pki" \ --ro-bind-try "${XAUTHORITY}" "${XAUTHORITY}" \ --bind-try "${QQ_DOWNLOAD_DIR}" "${QQ_DOWNLOAD_DIR}" \ + --setenv QQ_APP_DIR "${QQ_APP_DIR}" \ --bind "${QQ_APP_DIR}" "${QQ_APP_DIR}" \ --ro-bind-try "${FONTCONFIG_HOME}" "${FONTCONFIG_HOME}" \ --ro-bind-try "${HOME}/.icons" "${HOME}/.icons" \ @@ -126,23 +156,62 @@ bwrap --new-session --cap-drop ALL --unshare-user-try --unshare-pid --unshare-cg --setenv IBUS_USE_PORTAL 1 \ --setenv QQNTIM_HOME "${QQ_APP_DIR}/QQNTim" \ --setenv LITELOADERQQNT_PROFILE "${QQ_APP_DIR}/LiteLoaderQQNT" \ - /opt/QQ/electron "${flags[@]}" "$@" /opt/QQ/resources/app - -# 移除无用崩溃报告和日志 -# 如果需要向腾讯反馈 bug,请注释掉如下几行 -rm -rf ${QQ_APP_DIR}/crash_files -touch ${QQ_APP_DIR}/crash_files -if [ -d "${QQ_APP_DIR}/log" ]; then - rm -rf "${QQ_APP_DIR}/log" + --bind "${INFO_DIR}" "${INFO_DIR}" \ + --setenv INFO_FILE "${INFO_FILE}" \ + "${bwrap_flags[@]}" \ + /opt/QQ/_start.sh "${electron_flags[@]}" "$@" /opt/QQ/resources/app & + +if [ "$?" -ne 0 ]; then + rm "$INFO_FILE" + echo "bwrap failed" + exit 1 fi -for nt_qq_userdata in "${QQ_APP_DIR}/nt_qq_"*; do - if [ -d "${nt_qq_userdata}/log" ]; then - rm -rf "${nt_qq_userdata}/log" - fi - if [ -d "${nt_qq_userdata}/log-cache" ]; then - rm -rf "${nt_qq_userdata}/log-cache" - fi +while [ ! -s "$INFO_FILE" ]; do + sleep 0.01 +done + +PID="$(cat "$INFO_FILE")" +echo "SubProcess PID: $PID" + +SLIRP_API_SOCKET=$INFO_DIR/slirp.sock +slirp4netns --configure --mtu=65520 --disable-host-loopback --enable-ipv6 "$PID" eth0 --macaddress "$qq_mac" --api-socket "$SLIRP_API_SOCKET" & +SLIRP_PID=$! + +while [ ! -S "$SLIRP_API_SOCKET" ]; do + sleep 0.01 done -if [ -d "${QQ_APP_DIR}/Crashpad" ]; then - rm -rf "${QQ_APP_DIR}/Crashpad" + +if [ "$?" -ne 0 ]; then + echo "slirp4netns failed" + kill "$PID" + rm -rf "${INFO_DIR:?}" + exit 1 fi +add_hostfwd() { + local proto=$1 + local guest_port=$2 + shift 2 + local ports=("$@") + for port in "${ports[@]}"; do + result=$(echo -n "{\"execute\": \"add_hostfwd\", \"arguments\": {\"proto\": \"$proto\", \"host_addr\": \"127.0.0.1\", \"host_port\": $port, \"guest_port\": $guest_port}}" | socat UNIX-CONNECT:$SLIRP_API_SOCKET -) + if [[ $result != *"error"* ]]; then + echo "$proto forwarding setup on port $port" + return 0 + fi + done + echo "Failed to setup $proto forwarding." + return 1 +} +https_ports=(4301 4303 4305 4307 4309) +http_ports=(4310 4308 4306 4304 4302) +add_hostfwd "tcp" 94301 "${https_ports[@]}" +add_hostfwd "tcp" 94310 "${http_ports[@]}" +rm "$INFO_FILE" +# 启动步骤结束 +tail --pid="$PID" -f /dev/null +echo "Cleaning up..." +set +e +kill -TERM "$SLIRP_PID" +wait "$SLIRP_PID" +rm -rf "${INFO_DIR:?}" +exit 0 |