Skip to content

Commit 5e738fa

Browse files
authored
Merge pull request #665 from lyjjl/main
feat: 支持 Arch Linux 环境并优化启动脚本逻辑
2 parents b859261 + d80291d commit 5e738fa

File tree

1 file changed

+119
-113
lines changed

1 file changed

+119
-113
lines changed

script/start-linux.sh

Lines changed: 119 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,146 @@
11
#!/bin/bash
2+
23
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4+
export PATH=$PATH:/usr/bin:/usr/local/bin
5+
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
36

4-
# 检测是否为 Debian 系列系统(通过 apt 命令)
5-
if ! command -v apt &> /dev/null; then
6-
echo "错误:本脚本只支持使用 apt 包管理器的系统(如 Debian、Ubuntu 等)"
7-
exit 1
8-
fi
7+
log() { echo -e "${GREEN}>>> $1${NC}"; }
8+
warn() { echo -e "${YELLOW}>>> $1${NC}"; }
9+
error() { echo -e "${RED}错误: $1${NC}"; exit 1; }
10+
11+
confirm() {
12+
read -n 1 -s -r -p "$1 (Y/n) " key
13+
echo ""
14+
[[ "$key" == "Y" || "$key" == "y" || "$key" == "" ]]
15+
}
16+
17+
find_port() {
18+
local port=$1
19+
while [ $port -lt 65535 ]; do
20+
if ! ss -tuln | grep -q ":$port "; then echo $port; return 0; fi
21+
((port++))
22+
done
23+
return 1
24+
}
925

10-
# 检测系统架构
11-
ARCH=$(uname -m)
12-
if [ "$ARCH" == "x86_64" ]; then
13-
ARCH_TYPE="amd64"
14-
elif [ "$ARCH" == "aarch64" ]; then
15-
ARCH_TYPE="arm64"
26+
if command -v pacman &> /dev/null; then
27+
DISTRO="arch"
28+
elif command -v apt &> /dev/null; then
29+
DISTRO="debian"
1630
else
17-
echo "错误:不支持的系统架构: $ARCH"
18-
echo "本脚本只支持 x86_64 (x64) 和 aarch64 (arm64) 架构"
19-
exit 1
31+
error "只支持 apt 或 pacman 包管理器"
2032
fi
33+
log "检测到系统: $DISTRO"
34+
35+
install_arch() {
36+
log "检查 Arch 依赖..."
37+
sudo pacman -S --needed --noconfirm base-devel git ffmpeg xorg-server-xvfb libvips imagemagick dbus xorg-xhost fcitx5-im wget
38+
39+
if [ ! -f "/opt/QQ/qq" ] && confirm "未检测到 QQ,是否通过 AUR 安装?"; then
40+
if ! command -v yay &> /dev/null; then
41+
warn "未检测到 yay,尝试安装..."
42+
if ! sudo pacman -S --needed --noconfirm yay 2>/dev/null; then
43+
warn "pacman 安装失败,切换源码编译..."
44+
rm -rf /tmp/yay_install && git clone https://aur.archlinux.org/yay.git /tmp/yay_install
45+
(cd /tmp/yay_install && makepkg -si --noconfirm) || error "yay 编译失败"
46+
rm -rf /tmp/yay_install
47+
fi
48+
fi
49+
yay -S --noconfirm linuxqq || error "LinuxQQ 安装失败"
50+
fi
51+
}
2152

22-
echo "检测到系统架构: $ARCH_TYPE"
53+
install_debian() {
54+
local ARCH_MAP=( ["x86_64"]="amd64" ["aarch64"]="arm64" )
55+
local ARCH=${ARCH_MAP[$(uname -m)]}
56+
[ -z "$ARCH" ] && error "不支持的架构: $(uname -m)"
2357

24-
# 检测 QQ 是否已安装
25-
if [ ! -f "/opt/QQ/qq" ]; then
26-
echo "未检测到 QQ 安装 (/opt/QQ/qq 不存在)"
27-
echo "是否需要安装 QQ?(Y/n)"
28-
read -n 1 -s -r key
29-
echo ""
30-
if [[ "$key" == "Y" || "$key" == "y" || "$key" == "" ]]; then
31-
echo "正在下载 QQ ($ARCH_TYPE 版本)..."
32-
QQ_DEB="/tmp/qq_linux_$ARCH_TYPE.deb"
33-
sudo apt-get update
34-
sudo apt-get install wget
35-
wget -O "$QQ_DEB" "https://dldir1v6.qq.com/qqfile/qq/QQNT/ec800879/linuxqq_3.2.20-40990_$ARCH_TYPE.deb"
36-
if [ $? -ne 0 ]; then
37-
echo "错误:QQ 下载失败"
38-
exit 1
39-
fi
40-
echo "正在安装 QQ..."
58+
if [ ! -f "/opt/QQ/qq" ] && confirm "未检测到 QQ,是否安装?"; then
59+
log "下载并安装 QQ ($ARCH)..."
60+
sudo apt-get update && sudo apt-get install -y wget
61+
local DEB="/tmp/qq.deb"
62+
wget -O "$DEB" "https://dldir1v6.qq.com/qqfile/qq/QQNT/ec800879/linuxqq_3.2.20-41768_$ARCH.deb" || error "下载失败"
4163

42-
sudo apt install -y "$QQ_DEB"
43-
if [ $? -ne 0 ]; then
44-
echo "错误:QQ 安装失败"
45-
exit 1
46-
fi
47-
echo "QQ 安装完成"
48-
rm -f "$QQ_DEB"
49-
echo "进行安装 QQ 相关依赖"
50-
# 检测 libasound 包名(新系统用 libasound2t64,旧系统用 libasound2)
51-
# 使用 apt-cache policy 检测包是否真正可安装
52-
if apt-cache policy libasound2t64 2>/dev/null | grep -q "Candidate:"; then
53-
LIBASOUND_PKG="libasound2t64"
54-
elif apt-cache policy libasound2 2>/dev/null | grep -q "Candidate:"; then
55-
LIBASOUND_PKG="libasound2"
56-
else
57-
# 如果都不可用,尝试安装 alsa-utils 作为替代(会拉取正确的 libasound 依赖)
58-
LIBASOUND_PKG="alsa-utils"
59-
fi
60-
echo "使用 ALSA 库包: $LIBASOUND_PKG"
61-
62-
sudo apt-get install -y \
63-
x11-utils \
64-
libgtk-3-0 \
65-
libxcb-xinerama0 \
66-
libgl1-mesa-dri \
67-
libnotify4 \
68-
libnss3 \
69-
xdg-utils \
70-
libsecret-1-0 \
71-
libappindicator3-1 \
72-
libgbm1 \
73-
$LIBASOUND_PKG \
74-
fonts-noto-cjk \
75-
libxss1
76-
else
77-
echo "跳过 QQ 安装,退出脚本"
78-
exit 0
79-
fi
80-
fi
64+
# 依赖判断
65+
local LIB_SND="alsa-utils"
66+
apt-cache policy libasound2t64 2>/dev/null | grep -q "Candidate:" && LIB_SND="libasound2t64"
67+
apt-cache policy libasound2 2>/dev/null | grep -q "Candidate:" && LIB_SND="libasound2"
8168

82-
chmod +x $SCRIPT_DIR/llbot/node
83-
chmod +x $SCRIPT_DIR/llbot/pmhq
69+
echo "使用 ALSA 库包: $LIB_SND"
8470

85-
# 检测 FFmpeg 是否已安装
86-
if ! command -v ffmpeg &> /dev/null; then
87-
echo "未检测到 FFmpeg,正在安装..."
88-
sudo apt-get install -y ffmpeg
89-
if [ $? -ne 0 ]; then
90-
echo "警告:FFmpeg 安装失败,音视频处理功能可能受限"
91-
else
92-
echo "FFmpeg 安装完成"
71+
sudo apt install -y "$DEB" x11-utils libgtk-3-0 libxcb-xinerama0 libgl1-mesa-dri libnotify4 libnss3 xdg-utils libsecret-1-0 libappindicator3-1 libgbm1 $LIB_SND fonts-noto-cjk libxss1
72+
rm -f "$DEB"
9373
fi
94-
fi
9574

96-
# 寻找可用端口(从 13000 开始)
97-
find_available_port() {
98-
local port=$1
99-
while [ $port -lt 65535 ]; do
100-
if ! ss -tuln | grep -q ":$port "; then
101-
echo $port
102-
return 0
103-
fi
104-
port=$((port + 1))
75+
for pkg in ffmpeg xvfb; do
76+
command -v $pkg &> /dev/null || sudo apt-get install -y $pkg
10577
done
106-
echo ""
107-
return 1
10878
}
10979

110-
AVAILABLE_PORT=$(find_available_port 13000)
111-
if [ -z "$AVAILABLE_PORT" ]; then
112-
echo "错误:无法找到可用端口"
113-
exit 1
114-
fi
80+
[ "$DISTRO" == "arch" ] && install_arch || install_debian
11581

82+
chmod +x "$SCRIPT_DIR/llbot/node" "$SCRIPT_DIR/llbot/pmhq" 2>/dev/null
83+
[ "$DISTRO" == "arch" ] && sudo chown -R $(whoami):$(whoami) "$SCRIPT_DIR/llbot"
11684

117-
# 检测 xvfb-run 命令是否存在
118-
USE_XVFB=1
119-
if ! command -v xvfb-run &> /dev/null; then
120-
echo "未找到 xvfb-run 命令"
121-
echo "如果你是桌面环境,按 Y 继续运行"
122-
echo "如果不是桌面环境,按其他键进行安装 xvfb"
123-
read -n 1 -s -r key
124-
echo ""
125-
if [[ "$key" == "Y" || "$key" == "y" ]]; then
126-
USE_XVFB=0
85+
PORT=$(find_port 13000)
86+
[ -z "$PORT" ] && error "无法找到可用端口"
87+
log "使用端口: $PORT"
88+
89+
HAS_DISPLAY=0
90+
[[ -n "$DISPLAY" || -n "$WAYLAND_DISPLAY" ]] && HAS_DISPLAY=1
91+
92+
echo "------------------------------------------------"
93+
echo "1) GUI 模式"
94+
echo "2) Shell 模式"
95+
echo "------------------------------------------------"
96+
DEFAULT_CHOICE=$([ $HAS_DISPLAY -eq 1 ] && echo "1" || echo "2")
97+
read -p "请选择 [1/2] (默认 $DEFAULT_CHOICE): " MODE_CHOICE
98+
MODE_CHOICE=${MODE_CHOICE:-$DEFAULT_CHOICE}
99+
USE_XVFB=$([ "$MODE_CHOICE" == "2" ] && echo 1 || echo 0)
100+
101+
# 授权 X11
102+
if [ $USE_XVFB -eq 0 ]; then
103+
if command -v xauth &> /dev/null; then
104+
export XAUTHORITY=${XAUTHORITY:-$HOME/.Xauthority}
127105
else
128-
sudo apt install -y xvfb
106+
warn "未检测到 xauth,使用临时 xhost 授权"
107+
xhost +local:$(whoami) > /dev/null 2>&1
108+
trap "xhost -local:$(whoami) > /dev/null 2>&1" EXIT
129109
fi
130110
fi
131111

132-
SUB_CMD="$SCRIPT_DIR/llbot/node --enable-source-maps $SCRIPT_DIR/llbot/llbot.js -- --pmhq-port=$AVAILABLE_PORT"
112+
IM_ENV=""
113+
EXTRA_FLAGS=""
133114

134-
if [ $USE_XVFB -eq 1 ]; then
135-
sudo xvfb-run $SCRIPT_DIR/llbot/pmhq --port=$AVAILABLE_PORT --sub-cmd="$SUB_CMD"
115+
if [[ "$XDG_SESSION_TYPE" == "wayland" || -n "$WAYLAND_DISPLAY" ]]; then
116+
log "环境: Wayland"
117+
IM_ENV="XMODIFIERS=@im=fcitx"
118+
EXTRA_FLAGS="--enable-features=UseOzonePlatform --ozone-platform=wayland --enable-wayland-ime"
136119
else
137-
sudo $SCRIPT_DIR/llbot/pmhq --port=$AVAILABLE_PORT --sub-cmd="$SUB_CMD"
120+
log "环境: X11"
121+
IM_ENV="GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitx XMODIFIERS=@im=fcitx SDL_IM_MODULE=fcitx GLFW_IM_MODULE=ibus"
138122
fi
139123

124+
NODE_BIN="$SCRIPT_DIR/llbot/node"
125+
LLBOT_JS="$SCRIPT_DIR/llbot/llbot.js"
126+
PMHQ_BIN="$SCRIPT_DIR/llbot/pmhq"
127+
128+
run_llbot() {
129+
if [ "$DISTRO" == "arch" ]; then
130+
export LD_PRELOAD="/usr/lib/libstdc++.so.6:/usr/lib/libgcc_s.so.1"
131+
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
132+
fi
133+
134+
local sub_cmd="$NODE_BIN --enable-source-maps $LLBOT_JS -- --pmhq-port=$PORT --no-sandbox $EXTRA_FLAGS"
135+
136+
log "启动中... (模式: $([ $USE_XVFB -eq 1 ] && echo "Headless" || echo "GUI"))"
137+
138+
if [ $USE_XVFB -eq 1 ]; then
139+
env $IM_ENV xvfb-run -a "$PMHQ_BIN" --port="$PORT" --sub-cmd="$sub_cmd"
140+
else
141+
[ "$DISTRO" != "arch" ] && xhost +local:$(whoami) > /dev/null 2>&1
142+
env $IM_ENV "$PMHQ_BIN" --port="$PORT" --sub-cmd="$sub_cmd"
143+
fi
144+
}
140145

146+
run_llbot

0 commit comments

Comments
 (0)