Skip to content

Commit 758f571

Browse files
committed
Merge branch 'dev' of github.com:LLOneBot/LLOneBot into dev
2 parents 2c10ec2 + 9aced66 commit 758f571

File tree

161 files changed

+426
-312
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+426
-312
lines changed

.github/ISSUE_TEMPLATE/bug_report.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ body:
3535
id: onebot-client-version
3636
attributes:
3737
label: OneBot 客户端
38-
description: 连接至 LLOneBot 的客户端版本信息
38+
description: 连接至 LLBot 的客户端版本信息
3939
placeholder: Overflow 2.16.0-2cf7991-SNAPSHOT
4040
- type: textarea
4141
id: what-happened

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
## Stargazers over time
1414

15-
[![Stargazers over time](https://starchart.cc/LLOneBot/LLOneBot.svg?variant=adaptive)](https://starchart.cc/LLOneBot/LLOneBot)
15+
[![Stargazers over time](https://starchart.cc/LLOneBot/LuckyLilliaBot.svg?variant=adaptive)](https://starchart.cc/LLOneBot/LuckyLilliaBot)
1616

1717
TG Group:<https://t.me/+nLZEnpne-pQ1OWFl>
1818

doc/更新日志.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ V7.3.1
1010
* WebQQ 添加已撤回消息的提示
1111
* Linux CLI 启动脚本优化
1212
* OneBot 修复老版本 QQ 无法使用闪传相关接口
13+
* OneBot 修复 Docker 环境下可能无法发送合并转发图片
14+
* OneBot 修复获取合并转发内视频网址可能失败
15+
* Milky 修复 API `get_history_messages` 可能获取到空消息
16+
* Milky 修复 API `get_history_messages` 返回的 `next_message_seq` 不正确
1317

14-
18+
=================
1519
V7.3.0
1620
更新时间 2025-12-28
1721

docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ COPY docker/startup.sh /startup.sh
2626

2727
RUN chmod +x /startup.sh
2828

29-
RUN wget https://github.com/LLOneBot/LLOneBot/releases/download/v$LLBOT_VERSION/LLBot.zip -O /app/llbot.zip
29+
RUN wget https://github.com/LLOneBot/LuckyLilliaBot/releases/download/v$LLBOT_VERSION/LLBot.zip -O /app/llbot.zip
3030

3131
#COPY /dist/llonebot.zip /app/llonebot.zip
3232

script/start-linux.sh

Lines changed: 140 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,114 @@
22

33
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
44
export PATH=$PATH:/usr/bin:/usr/local/bin
5+
56
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
67

8+
CLEANING=0
9+
PMHQ_PID=""
10+
USE_XVFB=0
11+
DISTRO=""
12+
713
log() { echo -e "${GREEN}>>> $1${NC}"; }
814
warn() { echo -e "${YELLOW}>>> $1${NC}"; }
915
error() { echo -e "${RED}错误: $1${NC}"; exit 1; }
1016

17+
check_sudo() {
18+
log "验证 Sudo 权限..."
19+
if ! sudo -v; then
20+
error "Sudo 验证失败或被取消,脚本终止。"
21+
fi
22+
}
23+
24+
cleanup() {
25+
# 防止用户对 Ctrl+C 突然产生某种异样的迷恋然后狂按 Ctrl+C
26+
[ "$CLEANING" -eq 1 ] && return
27+
CLEANING=1
28+
29+
# 防止日志挡交互
30+
if [ -n "$PMHQ_PID" ] && kill -0 "$PMHQ_PID" 2>/dev/null; then
31+
kill -STOP -"$PMHQ_PID" 2>/dev/null
32+
fi
33+
34+
echo ""
35+
warn "收到退出信号 (进程已挂起) <<<"
36+
37+
local kill_qq=1
38+
local choice=""
39+
40+
if [ -n "$PMHQ_PID" ]; then
41+
if read -t 5 -n 1 -r -p "是否关闭 QQ 及相关进程? [Y/n] (5秒后默认关闭): " choice < /dev/tty; then
42+
echo ""
43+
else
44+
echo ""
45+
log "等待超时,执行默认关闭操作。"
46+
fi
47+
48+
if [[ "$choice" == "n" || "$choice" == "N" ]]; then
49+
kill_qq=0
50+
fi
51+
fi
52+
53+
if [ $kill_qq -eq 1 ]; then
54+
warn "正在停止服务..."
55+
56+
kill -CONT -"$PMHQ_PID" 2>/dev/null
57+
58+
kill -TERM -"$PMHQ_PID" 2>/dev/null
59+
pkill -15 -f "$PMHQ_BIN" 2>/dev/null
60+
pkill -15 -f "/opt/QQ/qq" 2>/dev/null
61+
62+
local wait_count=0
63+
64+
while kill -0 "$PMHQ_PID" 2>/dev/null || \
65+
pgrep -f "$PMHQ_BIN" > /dev/null || \
66+
pgrep -f "/opt/QQ/qq" > /dev/null; do
67+
sleep 0.5
68+
((wait_count++))
69+
if [ $wait_count -ge 6 ]; then
70+
warn "检测到残留进程,执行强制清理..."
71+
# 气死我了,总有点关不掉进程的毛病,累了,跟我 pkill -9 说去吧
72+
# 期待大手子修复
73+
kill -KILL -"$PMHQ_PID" 2>/dev/null
74+
pkill -9 -f "$PMHQ_BIN" 2>/dev/null
75+
pkill -9 -f "/opt/QQ/qq" 2>/dev/null
76+
break
77+
fi
78+
done
79+
80+
# 环境清理
81+
if [ "$DISTRO" != "arch" ] && [ "$USE_XVFB" -eq 0 ]; then
82+
if command -v xhost &> /dev/null; then
83+
xhost -local:$(whoami) > /dev/null 2>&1
84+
fi
85+
fi
86+
log "所有进程已清理完毕。"
87+
else
88+
# 选择不关闭时必须恢复进程运行
89+
kill -CONT -"$PMHQ_PID" 2>/dev/null
90+
log "已恢复后台进程运行 (PGID: $PMHQ_PID)"
91+
warn "注意:它们已脱离脚本控制,后续请手动管理"
92+
fi
93+
94+
exit 0
95+
}
96+
97+
trap cleanup SIGINT SIGTERM
98+
1199
confirm() {
12100
read -n 1 -s -r -p "$1 (Y/n) " key
13101
echo ""
14102
[[ "$key" == "Y" || "$key" == "y" || "$key" == "" ]]
15103
}
16104

17105
find_port() {
18-
# 让系统自动分配可用端口
106+
# 优先尝试让系统自动分配
19107
local port=$(python3 -c 'import socket; s=socket.socket(); s.bind(("",0)); print(s.getsockname()[1]); s.close()' 2>/dev/null)
20108
if [ -n "$port" ]; then
21109
echo $port
22110
return 0
23111
fi
24-
# 回退方案:从指定端口开始查找
112+
# 回退方案:扫描可用端口
25113
local port=$1
26114
while [ $port -lt 65535 ]; do
27115
if ! ss -tuln 2>/dev/null | grep -q ":$port " && ! netstat -tuln 2>/dev/null | grep -q ":$port "; then
@@ -38,19 +126,20 @@ if command -v pacman &> /dev/null; then
38126
elif command -v apt &> /dev/null; then
39127
DISTRO="debian"
40128
else
41-
error "只支持 apt 或 pacman 包管理器"
129+
error "当前只支持 apt 或 pacman 包管理器"
42130
fi
43131
log "检测到系统: $DISTRO"
44132

45133
install_arch() {
134+
check_sudo
46135
log "检查 Arch 依赖..."
47-
sudo pacman -S --needed --noconfirm base-devel git ffmpeg xorg-server-xvfb libvips imagemagick dbus xorg-xhost fcitx5-im wget
136+
sudo pacman -S --needed --noconfirm base-devel git ffmpeg xorg-server-xvfb libvips imagemagick dbus xorg-xhost fcitx5-im wget || error "基础依赖安装失败"
48137

49138
if [ ! -f "/opt/QQ/qq" ] && confirm "未检测到 QQ,是否通过 AUR 安装?"; then
50139
if ! command -v yay &> /dev/null; then
51140
warn "未检测到 yay,尝试安装..."
52141
if ! sudo pacman -S --needed --noconfirm yay 2>/dev/null; then
53-
warn "pacman 安装失败,切换源码编译..."
142+
warn "pacman 安装 yay 失败,切换源码编译..."
54143
rm -rf /tmp/yay_install && git clone https://aur.archlinux.org/yay.git /tmp/yay_install
55144
(cd /tmp/yay_install && makepkg -si --noconfirm) || error "yay 编译失败"
56145
rm -rf /tmp/yay_install
@@ -61,6 +150,7 @@ install_arch() {
61150
}
62151

63152
install_debian() {
153+
check_sudo
64154
local MACHINE=$(uname -m)
65155
local ARCH=""
66156
case "$MACHINE" in
@@ -71,78 +161,88 @@ install_debian() {
71161

72162
if [ ! -f "/opt/QQ/qq" ] && confirm "未检测到 QQ,是否安装?"; then
73163
log "下载并安装 QQ ($ARCH)..."
74-
sudo apt-get update && sudo apt-get install -y wget
164+
sudo apt-get update && sudo apt-get install -y wget || error "apt update 或 wget 安装失败"
165+
75166
local DEB="/tmp/qq.deb"
76-
wget -O "$DEB" "https://dldir1v6.qq.com/qqfile/qq/QQNT/ab90fdfa/linuxqq_3.2.20-40768_$ARCH.deb" || error "下载失败"
167+
wget -O "$DEB" "https://dldir1v6.qq.com/qqfile/qq/QQNT/ab90fdfa/linuxqq_3.2.20-40768_$ARCH.deb" || error "QQ 安装包下载失败"
77168

78-
# 依赖判断 (新版 Ubuntu 24.04+ 用 libasound2t64,旧版用 libasound2)
79169
local LIB_SND="libasound2"
80170
if apt-cache show libasound2t64 &>/dev/null; then
81171
LIB_SND="libasound2t64"
82172
fi
173+
log "使用 ALSA 库包名: $LIB_SND"
83174

84-
echo "使用 ALSA 库包: $LIB_SND"
85-
86-
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
175+
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 || error "QQ 依赖安装失败"
87176
rm -f "$DEB"
88177
fi
89178

179+
# 检查其他工具
180+
local missing_pkgs=""
90181
for pkg in ffmpeg xvfb; do
91-
command -v $pkg &> /dev/null || sudo apt-get install -y $pkg
182+
if ! command -v $pkg &> /dev/null; then
183+
missing_pkgs="$missing_pkgs $pkg"
184+
fi
92185
done
186+
187+
if [ -n "$missing_pkgs" ]; then
188+
log "安装缺失工具: $missing_pkgs"
189+
sudo apt-get install -y $missing_pkgs || error "工具安装失败"
190+
fi
93191
}
94192

95-
[ "$DISTRO" == "arch" ] && install_arch || install_debian
193+
# 执行安装
194+
if [ "$DISTRO" == "arch" ]; then
195+
install_arch
196+
else
197+
install_debian
198+
fi
96199

97200
chmod +x "$SCRIPT_DIR/llbot/node" "$SCRIPT_DIR/llbot/pmhq" 2>/dev/null
98-
[ "$DISTRO" == "arch" ] && sudo chown -R $(whoami):$(whoami) "$SCRIPT_DIR/llbot"
201+
202+
sudo chown -R $(whoami):$(whoami) "$SCRIPT_DIR/llbot" 2>/dev/null
99203

100204
PORT=$(find_port 13000)
101205
[ -z "$PORT" ] && error "无法找到可用端口"
102-
log "使用端口: $PORT"
103-
104-
HAS_DISPLAY=0
105-
[[ -n "$DISPLAY" || -n "$WAYLAND_DISPLAY" ]] && HAS_DISPLAY=1
206+
log "分配端口: $PORT"
106207

107208
echo "------------------------------------------------"
108-
echo "1) GUI 模式"
109-
echo "2) Shell 模式 (默认)"
209+
echo "1) GUI 模式 (有界面)"
210+
echo "2) Shell 模式 (无界面/Headless,默认)"
110211
echo "------------------------------------------------"
111212

112213
MODE_CHOICE=""
113214
TIMEOUT=5
114215
while [ $TIMEOUT -gt 0 ]; do
115-
printf "\r请选择 [1/2] (${TIMEOUT}秒后默认选择 Shell): "
216+
printf "\r请选择 [1/2] (${TIMEOUT}秒后自动选择 Shell): "
116217
if read -t 1 -n 1 MODE_CHOICE; then
117218
echo ""
118219
break
119220
fi
120221
((TIMEOUT--))
121222
done
122-
[ $TIMEOUT -eq 0 ] && echo "" && log "超时,使用默认 Shell 模式"
223+
[ $TIMEOUT -eq 0 ] && echo "" && log "超时,自动选择 Shell 模式"
224+
123225
MODE_CHOICE=${MODE_CHOICE:-2}
124226
USE_XVFB=$([ "$MODE_CHOICE" == "2" ] && echo 1 || echo 0)
125227

126-
# 授权 X11
127228
if [ $USE_XVFB -eq 0 ]; then
128229
if command -v xauth &> /dev/null; then
129230
export XAUTHORITY=${XAUTHORITY:-$HOME/.Xauthority}
130231
else
131232
warn "未检测到 xauth,使用临时 xhost 授权"
132233
xhost +local:$(whoami) > /dev/null 2>&1
133-
trap "xhost -local:$(whoami) > /dev/null 2>&1" EXIT
134234
fi
135235
fi
136236

137237
IM_ENV=""
138238
EXTRA_FLAGS=""
139239

140240
if [[ "$XDG_SESSION_TYPE" == "wayland" || -n "$WAYLAND_DISPLAY" ]]; then
141-
log "环境: Wayland"
241+
log "检测到 Wayland 环境"
142242
IM_ENV="XMODIFIERS=@im=fcitx"
143243
EXTRA_FLAGS="--enable-features=UseOzonePlatform --ozone-platform=wayland --enable-wayland-ime"
144244
else
145-
log "环境: X11"
245+
log "检测到 X11 环境"
146246
IM_ENV="GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitx XMODIFIERS=@im=fcitx SDL_IM_MODULE=fcitx GLFW_IM_MODULE=ibus"
147247
fi
148248

@@ -151,21 +251,31 @@ LLBOT_JS="$SCRIPT_DIR/llbot/llbot.js"
151251
PMHQ_BIN="$SCRIPT_DIR/llbot/pmhq"
152252

153253
run_llbot() {
254+
set -m
255+
154256
if [ "$DISTRO" == "arch" ]; then
155257
export LD_PRELOAD="/usr/lib/libstdc++.so.6:/usr/lib/libgcc_s.so.1"
156258
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
157259
fi
158260

159261
local sub_cmd="$NODE_BIN --enable-source-maps $LLBOT_JS -- --pmhq-port=$PORT --no-sandbox $EXTRA_FLAGS"
160262

161-
log "启动中... (模式: $([ $USE_XVFB -eq 1 ] && echo "Headless" || echo "GUI"))"
263+
log "正在启动 LLBot... (模式: $([ $USE_XVFB -eq 1 ] && echo "Headless" || echo "GUI"))"
264+
log "按 Ctrl+C 可停止运行"
162265

163266
if [ $USE_XVFB -eq 1 ]; then
164-
env $IM_ENV xvfb-run -a "$PMHQ_BIN" --port="$PORT" --sub-cmd="$sub_cmd"
267+
env $IM_ENV xvfb-run -a "$PMHQ_BIN" --port="$PORT" --sub-cmd="$sub_cmd" &
165268
else
166-
[ "$DISTRO" != "arch" ] && xhost +local:$(whoami) > /dev/null 2>&1
167-
env $IM_ENV "$PMHQ_BIN" --port="$PORT" --sub-cmd="$sub_cmd"
269+
if [ "$DISTRO" != "arch" ]; then
270+
xhost +local:$(whoami) > /dev/null 2>&1
271+
fi
272+
env $IM_ENV "$PMHQ_BIN" --port="$PORT" --sub-cmd="$sub_cmd" &
168273
fi
274+
275+
PMHQ_PID=$!
276+
277+
# 阻塞等待进程结束
278+
wait "$PMHQ_PID" || true
169279
}
170280

171281
run_llbot

src/common/utils/file.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,10 @@ export async function uri2local(ctx: Context, uri: string, needExt?: boolean): P
129129

130130
if (type === FileUriType.FileURL) {
131131
const filePath = fileURLToPath(uri)
132+
if (!fs.existsSync(filePath)) {
133+
return { success: false, errMsg: '路径不存在', fileName: '', path: '', isLocal: false }
134+
}
132135
const fileName = path.basename(filePath)
133-
// console.log('fileURLToPath', filePath)
134-
// console.log('fileName', fileName)
135136
return { success: true, errMsg: '', fileName, path: filePath, isLocal: true }
136137
}
137138

@@ -239,6 +240,6 @@ export async function getFileType(filePath: string) {
239240
}
240241
}
241242

242-
export async function getImageSize(path: string){
243+
export async function getImageSize(path: string) {
243244
return await imageSizeFromFile(path)
244245
}

src/common/utils/port.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import getPort from 'get-port'
2-
import path from 'node:path'
3-
import { getFixedDataDir } from '@/common/globalVars'
4-
import fs from 'node:fs/promises'
52

63
export async function getAvailablePort(startPort: number, range: number = 100) {
74
const ports = Array.from({ length: range }, (_, i) => startPort + i)

0 commit comments

Comments
 (0)