dsh-qq-stack 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.js +7 -2
- package/index.js +15 -3
- package/install.sh +36 -3
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -48,7 +48,8 @@ window.__ModuleLoader__.load({
|
|
|
48
48
|
.fs-login{display:flex;flex-direction:column;gap:10px}
|
|
49
49
|
.fs-field{width:100%;box-sizing:border-box;border:0;border-bottom:1px solid rgba(127,127,127,.28);background:transparent;color:inherit;padding:10px 2px;font-size:15px;outline:none}
|
|
50
50
|
.fs-wide{padding:11px}
|
|
51
|
-
.fs-sep{text-align:center;font-size:12px;opacity:.5;margin-top:6px}
|
|
51
|
+
.fs-sep{text-align:center;font-size:12px;opacity:.5;margin-top:6px}
|
|
52
|
+
.fs-install{font-size:14px;font-weight:600;margin-bottom:6px}`
|
|
52
53
|
|
|
53
54
|
function Panel() {
|
|
54
55
|
const [st, setSt] = react.useState(null)
|
|
@@ -78,11 +79,15 @@ window.__ModuleLoader__.load({
|
|
|
78
79
|
row('OneBot 端口', !!st?.qq, st?.qq ? '已监听' : '未监听'),
|
|
79
80
|
row('登录状态', logged, logged ? `已登录 ${st?.nickname || ''} ${st?.uin || ''}` : '未登录'),
|
|
80
81
|
),
|
|
81
|
-
!logged ? h('div', { className: 'fs-card fs-center' },
|
|
82
|
+
(st?.installed !== false && !st?.installing && !logged) ? h('div', { className: 'fs-card fs-center' },
|
|
82
83
|
st?.qrAt
|
|
83
84
|
? h('img', { className: 'fs-qr', src: qrUrl, alt: '登录二维码' })
|
|
84
85
|
: h('div', { className: 'fs-hint' }, '正在生成二维码…'),
|
|
85
86
|
) : null,
|
|
87
|
+
(st && (!st.installed || st.installing)) ? h('div', { className: 'fs-card' },
|
|
88
|
+
h('div', { className: 'fs-install' }, st.installing ? '正在安装 QQ 运行环境…' : '运行环境未就绪'),
|
|
89
|
+
h('div', { className: 'fs-hint' }, st.installTail || '首次安装约 250MB,请稍候'),
|
|
90
|
+
) : null,
|
|
86
91
|
logged ? h('div', { className: 'fs-card fs-account' },
|
|
87
92
|
h('img', {
|
|
88
93
|
className: 'fs-avatar',
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, statSync, readdirSync, unlinkSync, mkdirSync } from 'node:fs'
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, statSync, readdirSync, unlinkSync, mkdirSync, openSync } from 'node:fs'
|
|
3
3
|
import { readFileSync as rf } from 'node:fs'
|
|
4
4
|
|
|
5
5
|
export const name = 'dsh-qq-stack'
|
|
@@ -154,7 +154,10 @@ function applyInner(ctx, pluginConfig = {}) {
|
|
|
154
154
|
if (!existsSync(installer)) { log('[qq-stack] 找不到 install.sh'); return }
|
|
155
155
|
log('[qq-stack] 首次安装开始(LinuxQQ + NapCat,约 250MB)')
|
|
156
156
|
try {
|
|
157
|
-
|
|
157
|
+
mkdirSync(`${cfg.root}/logs`, { recursive: true })
|
|
158
|
+
const fd = openSync(`${cfg.root}/logs/install.log`, 'a')
|
|
159
|
+
const child = spawnSafe('bash', [installer], { cwd: cfg.root, detached: true, stdio: ['ignore', fd, fd], env })
|
|
160
|
+
if (child?.pid) { try { writeFileSync(`${cfg.root}/install.pid`, String(child.pid)) } catch {} }
|
|
158
161
|
} catch (e) { log(`[qq-stack] 安装启动失败:${e?.message ?? e}`) }
|
|
159
162
|
}
|
|
160
163
|
|
|
@@ -223,6 +226,15 @@ function applyInner(ctx, pluginConfig = {}) {
|
|
|
223
226
|
const pidM = statSync(`${cfg.root}/qq.pid`).mtimeMs
|
|
224
227
|
if (qrM >= pidM) qrAt = Math.floor(qrM)
|
|
225
228
|
} catch {}
|
|
229
|
+
let installing = false
|
|
230
|
+
try { installing = alive(Number(readFileSync(`${cfg.root}/install.pid`, 'utf8').trim())) } catch {}
|
|
231
|
+
let installed = existsSync(`${cfg.root}/opt/opt/QQ/qq`)
|
|
232
|
+
let installTail = ''
|
|
233
|
+
try {
|
|
234
|
+
const raw = readFileSync(`${cfg.root}/logs/install.log`, 'utf8')
|
|
235
|
+
const lines = raw.split(/[\r\n]+/).map((x) => x.trim()).filter(Boolean)
|
|
236
|
+
installTail = lines.slice(-2).join(' ').slice(-160)
|
|
237
|
+
} catch {}
|
|
226
238
|
const login = qq ? await probeLogin(Number(envFile.DSH_QQ_WS_PORT || cfg.wsPort || 3001), envFile.DSH_QQ_TOKEN || cfg.token) : { loggedIn: false, nickname: '' }
|
|
227
239
|
if (login.loggedIn) {
|
|
228
240
|
const qqUin = detectedUin || envFile.DSH_QQ_UIN || ''
|
|
@@ -245,7 +257,7 @@ function applyInner(ctx, pluginConfig = {}) {
|
|
|
245
257
|
writeFileSync(`${cfg.root}/config.env`, Object.entries(e2).map(([k, x]) => `${k}=${x}`).join('\n') + '\n')
|
|
246
258
|
} catch {}
|
|
247
259
|
}
|
|
248
|
-
return json({ ok: true, qq, loggedIn: !!login.loggedIn, nickname: login.nickname, uin: login.loggedIn ? login.uin : (envFile.DSH_QQ_UIN || detectedUin), port: envFile.DSH_QQ_WS_PORT || '3001', token: envFile.DSH_QQ_TOKEN || '', qrAt })
|
|
260
|
+
return json({ ok: true, qq, loggedIn: !!login.loggedIn, nickname: login.nickname, uin: login.loggedIn ? login.uin : (envFile.DSH_QQ_UIN || detectedUin), installed, installing, installTail, port: envFile.DSH_QQ_WS_PORT || '3001', token: envFile.DSH_QQ_TOKEN || '', qrAt })
|
|
249
261
|
}
|
|
250
262
|
if (req.method === 'GET' && p === '/qr.png') {
|
|
251
263
|
let detectedUin = ''
|
package/install.sh
CHANGED
|
@@ -32,9 +32,20 @@ QQ_DEB_URL="https://qqdl.gtimg.cn/qqfile/QQNT/9.9.36/beta/9ee04bef/linuxqq_${QQ_
|
|
|
32
32
|
NAPCAT_ZIP="https://github.com/NapNeko/NapCatQQ/releases/latest/download/NapCat.Shell.zip"
|
|
33
33
|
|
|
34
34
|
missing=""
|
|
35
|
-
for p in xvfb libnss3 libgbm1 libasound2t64 libgtk-3-0 dbus-x11 unzip curl; do
|
|
36
|
-
dpkg -s "$p" >/dev/null 2>&1 ||
|
|
35
|
+
for p in xvfb libnss3 libgbm1 libasound2t64 libasound2 libgtk-3-0 libgtk-3-0t64 dbus-x11 unzip curl; do
|
|
36
|
+
dpkg -s "$p" >/dev/null 2>&1 || continue
|
|
37
|
+
case "$p" in
|
|
38
|
+
libasound2) miss="$miss libasound2" ;;
|
|
39
|
+
libasound2t64) [ -n "${miss##*libasound2 }" ] && miss="$miss libasound2t64" ;;
|
|
40
|
+
libgtk-3-0) miss="$miss libgtk-3-0" ;;
|
|
41
|
+
libgtk-3-0t64) miss="$miss libgtk-3-0t64" ;;
|
|
42
|
+
*) miss="$miss $p" ;;
|
|
43
|
+
esac
|
|
37
44
|
done
|
|
45
|
+
# 成对包只留一个(t64 与旧名并存,供不同发行版)
|
|
46
|
+
case " $miss " in *" libasound2 "*) miss=$(echo "$miss" | sed 's/ libasound2t64 / /g') ;; *) miss=$(echo "$miss" | sed 's/ libasound2 / /g') ;; esac
|
|
47
|
+
case " $miss " in *" libgtk-3-0t64 "*) miss=$(echo "$miss" | sed 's/ libgtk-3-0 / /g') ;; *) miss=$(echo "$miss" | sed 's/ libgtk-3-0t64 / /g') ;; esac
|
|
48
|
+
missing="$miss"
|
|
38
49
|
if [ -n "$missing" ]; then
|
|
39
50
|
say "安装依赖:$missing"
|
|
40
51
|
export DEBIAN_FRONTEND=noninteractive
|
|
@@ -52,6 +63,29 @@ fi
|
|
|
52
63
|
|
|
53
64
|
QQ_APP="$ROOT/opt/opt/QQ/resources/app"
|
|
54
65
|
|
|
66
|
+
ensure_deps() {
|
|
67
|
+
need=0
|
|
68
|
+
command -v xvfb-run >/dev/null 2>&1 || need=1
|
|
69
|
+
command -v dbus-run-session >/dev/null 2>&1 || need=1
|
|
70
|
+
if [ -x "$ROOT/opt/opt/QQ/qq" ] && ldd "$ROOT/opt/opt/QQ/qq" 2>/dev/null | grep -q "not found"; then
|
|
71
|
+
need=1
|
|
72
|
+
fi
|
|
73
|
+
[ "$need" = 0 ] && return 0
|
|
74
|
+
say "补齐运行依赖"
|
|
75
|
+
export DEBIAN_FRONTEND=noninteractive
|
|
76
|
+
apt-get update -qq || true
|
|
77
|
+
pkgs=""
|
|
78
|
+
for p in xvfb dbus-x11 libnss3 libgbm1 libasound2t64 libasound2 libgtk-3-0t64 libgtk-3-0 \
|
|
79
|
+
libxss1 libxtst6 libdrm2 libxkbcommon0 libcups2 libpango-1.0-0 libcairo2 \
|
|
80
|
+
libatk1.0-0 libatk-bridge2.0-0 libxdamage1 libxrandr2 libatspi2.0-0 libnspr4 \
|
|
81
|
+
libxcomposite1 libxfixes3 libxrender1; do
|
|
82
|
+
apt-cache show "$p" >/dev/null 2>&1 && pkgs="$pkgs $p"
|
|
83
|
+
done
|
|
84
|
+
apt-get install -y $pkgs || { say "依赖安装失败"; exit 1; }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ensure_deps
|
|
88
|
+
|
|
55
89
|
if [ ! -f "$QQ_APP/app_launcher/napcat/napcat.mjs" ]; then
|
|
56
90
|
say "下载 NapCat"
|
|
57
91
|
if [ -f /tmp/NapCat.Shell.zip ] && unzip -t /tmp/NapCat.Shell.zip >/dev/null 2>&1; then
|
|
@@ -160,4 +194,3 @@ fi
|
|
|
160
194
|
chmod +x "$ROOT"/*.sh
|
|
161
195
|
say "安装完成,启动 QQ"
|
|
162
196
|
bash "$ROOT/start-qq.sh"
|
|
163
|
-
say "完成(首次需要扫码,之后启动会走 ${UIN:-未设置账号} 的快速登录)"
|