dsh-qq-stack 0.1.2 → 0.1.3

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.
Files changed (2) hide show
  1. package/index.js +19 -11
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { spawn } from 'node:child_process'
2
- import { existsSync, readFileSync, writeFileSync, statSync, readdirSync, unlinkSync } from 'node:fs'
2
+ import { existsSync, readFileSync, writeFileSync, statSync, readdirSync, unlinkSync, mkdirSync } from 'node:fs'
3
3
  import { readFileSync as rf } from 'node:fs'
4
4
 
5
5
  export const name = 'dsh-qq-stack'
@@ -102,6 +102,16 @@ async function probeLogin(port, token, force) {
102
102
  return probeCache
103
103
  }
104
104
 
105
+
106
+ function spawnSafe(cmd, args, opts) {
107
+ try {
108
+ const child = spawn(cmd, args, opts)
109
+ child.on('error', () => {})
110
+ child.unref()
111
+ return child
112
+ } catch { return null }
113
+ }
114
+
105
115
  function alive(pid) {
106
116
  if (!pid) return false
107
117
  try { process.kill(pid, 0); return true } catch { return false }
@@ -113,6 +123,7 @@ export function apply(ctx, pluginConfig = {}) {
113
123
 
114
124
  function applyInner(ctx, pluginConfig = {}) {
115
125
  const cfg = resolveConfig(pluginConfig)
126
+ try { mkdirSync(cfg.root, { recursive: true }) } catch {}
116
127
  const log = (msg) => { try { ctx.logger?.info?.(msg); if (process.env.DSH_QQ_DEBUG) console.log(msg) } catch {} }
117
128
  log(`[qq-stack] 激活 root=${cfg.root} uin=${cfg.uin || '(空)'} autoInstall=${cfg.autoInstall}`)
118
129
 
@@ -131,8 +142,7 @@ function applyInner(ctx, pluginConfig = {}) {
131
142
  if (alive(pid)) return
132
143
  const script = `${cfg.root}/start-qq.sh`
133
144
  if (!existsSync(script)) return
134
- const child = spawn('bash', [script], { cwd: cfg.root, detached: true, stdio: 'ignore', env })
135
- child.unref()
145
+ const child = spawnSafe('bash', [script], { cwd: cfg.root, detached: true, stdio: 'ignore', env })
136
146
  log('[qq-stack] 拉起 QQ')
137
147
  } catch (e) { log(`[qq-stack] 启动失败:${e?.message ?? e}`) }
138
148
  }
@@ -144,8 +154,7 @@ function applyInner(ctx, pluginConfig = {}) {
144
154
  if (!existsSync(installer)) { log('[qq-stack] 找不到 install.sh'); return }
145
155
  log('[qq-stack] 首次安装开始(LinuxQQ + NapCat,约 250MB)')
146
156
  try {
147
- const child = spawn('bash', [installer], { cwd: cfg.root, detached: true, stdio: 'ignore', env })
148
- child.unref()
157
+ const child = spawnSafe('bash', [installer], { cwd: cfg.root, detached: true, stdio: 'ignore', env })
149
158
  } catch (e) { log(`[qq-stack] 安装启动失败:${e?.message ?? e}`) }
150
159
  }
151
160
 
@@ -155,8 +164,7 @@ function applyInner(ctx, pluginConfig = {}) {
155
164
  let pid = 0
156
165
  try { pid = Number(readFileSync(watchPid, 'utf8').trim()) || 0 } catch {}
157
166
  if (alive(pid)) return
158
- const child = spawn(process.execPath, [`${SELF}watch.mjs`, SELF, cfg.root], { detached: true, stdio: 'ignore' })
159
- child.unref()
167
+ const child = spawnSafe(process.execPath, [`${SELF}watch.mjs`, SELF, cfg.root], { detached: true, stdio: 'ignore' })
160
168
  try { writeFileSync(watchPid, String(child.pid)) } catch {}
161
169
  } catch (e) { log(`[qq-stack] 卸载清理器启动失败:${e?.message ?? e}`) }
162
170
  }, 'dsh-qq-stack: uninstall-watch')
@@ -177,7 +185,7 @@ function applyInner(ctx, pluginConfig = {}) {
177
185
  if (healed && Date.now() - lastHealAt > 90000) {
178
186
  lastHealAt = Date.now()
179
187
  log('[qq-stack] 补齐 OneBot 配置,重启 QQ')
180
- try { spawn('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' }).unref() } catch {}
188
+ spawnSafe('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' })
181
189
  }
182
190
  } catch (e) { log(`[qq-stack] 巡检失败:${e?.message ?? e}`) }
183
191
  }, 60000)
@@ -228,7 +236,7 @@ function applyInner(ctx, pluginConfig = {}) {
228
236
  const healed = ensureOnebot(cfg.root, portNum, tokenVal)
229
237
  if (healed && !login.loggedIn && Date.now() - lastHealAt > 90000) {
230
238
  lastHealAt = Date.now()
231
- try { spawn('bash', ['-c', `bash stop-qq.sh; bash start-qq.sh`], { cwd: cfg.root, detached: true, stdio: 'ignore' }).unref() } catch {}
239
+ spawnSafe('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' })
232
240
  }
233
241
  const probeFresh = Date.now() - (probeCache.at || 0) < 6000
234
242
  if (login.loggedIn && login.uin && probeFresh && envFile.DSH_QQ_UIN !== login.uin) {
@@ -283,11 +291,11 @@ function applyInner(ctx, pluginConfig = {}) {
283
291
  if (existsSync(auth)) unlinkSync(auth)
284
292
  } catch {}
285
293
  probeCache = { at: 0, loggedIn: false, nickname: '', uin: '' }
286
- try { spawn('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' }).unref() } catch {}
294
+ spawnSafe('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' })
287
295
  return json({ ok: true })
288
296
  }
289
297
  if (req.method === 'POST' && p === '/restart') {
290
- try { spawn('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' }).unref() } catch {}
298
+ spawnSafe('bash', ['-c', 'bash stop-qq.sh; bash start-qq.sh'], { cwd: cfg.root, detached: true, stdio: 'ignore' })
291
299
  return json({ ok: true })
292
300
  }
293
301
  json({ ok: false }, 404)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-qq-stack",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "description": "DeepSeek Harness 的 QQ 协议端底座:LinuxQQ + NapCat 随引擎自启,扫码一次后自动快登。",