koishi-plugin-steam-info-check 1.0.10 → 1.1.1

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 (37) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +75 -56
  3. package/dist/locales/zh-CN.d.ts +3 -0
  4. package/dist/locales/zh-CN.js +3 -0
  5. package/nonebot-plugin-steam-info-main/.github/actions/setup-python/action.yml +21 -0
  6. package/nonebot-plugin-steam-info-main/.github/workflows/release.yml +37 -0
  7. package/nonebot-plugin-steam-info-main/LICENSE +21 -0
  8. package/nonebot-plugin-steam-info-main/README.md +117 -0
  9. package/nonebot-plugin-steam-info-main/fonts/MiSans-Bold.ttf +0 -0
  10. package/nonebot-plugin-steam-info-main/fonts/MiSans-Light.ttf +0 -0
  11. package/nonebot-plugin-steam-info-main/fonts/MiSans-Regular.ttf +0 -0
  12. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/__init__.py +487 -0
  13. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/config.py +19 -0
  14. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/data_source.py +264 -0
  15. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/draw.py +921 -0
  16. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/models.py +82 -0
  17. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/bg_dots.png +0 -0
  18. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/busy.png +0 -0
  19. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/default_achievement_image.png +0 -0
  20. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/default_header_image.jpg +0 -0
  21. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/friends_search.png +0 -0
  22. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/gaming.png +0 -0
  23. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/parent_status.png +0 -0
  24. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/unknown_avatar.jpg +0 -0
  25. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/zzz_gaming.png +0 -0
  26. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/zzz_online.png +0 -0
  27. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/steam.py +259 -0
  28. package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/utils.py +112 -0
  29. package/nonebot-plugin-steam-info-main/pdm.lock +966 -0
  30. package/nonebot-plugin-steam-info-main/preview.png +0 -0
  31. package/nonebot-plugin-steam-info-main/preview_1.png +0 -0
  32. package/nonebot-plugin-steam-info-main/preview_2.png +0 -0
  33. package/nonebot-plugin-steam-info-main/pyproject.toml +29 -0
  34. package/package.json +1 -1
  35. package/src/index.ts +58 -58
  36. package/src/locales/zh-CN.ts +3 -0
  37. package/src/locales/zh-CN.yml +2 -1
@@ -0,0 +1,29 @@
1
+ [project]
2
+ name = "nonebot-plugin-steam-info"
3
+ version = "1.3.5"
4
+ description = "Steam 好友状态播报 NoneBot 插件"
5
+ authors = [
6
+ {name = "zhaomaoniu", email = "2667292003@qq.com"},
7
+ ]
8
+ dependencies = [
9
+ "nonebot2>=2.2.0",
10
+ "nonebot-plugin-alconna>=0.54.2",
11
+ "Pillow>=10.2.0",
12
+ "nonebot-plugin-apscheduler>=0.4.0",
13
+ "nonebot-plugin-localstore>=0.6.0",
14
+ "httpx<0.28.0,>=0.27.0",
15
+ "numpy>=1.24.4",
16
+ "beautifulsoup4>=4.12.3",
17
+ "pytz>=2024.2",
18
+ ]
19
+ requires-python = ">=3.9"
20
+ readme = "README.md"
21
+ license = {text = "MIT"}
22
+
23
+ [build-system]
24
+ requires = ["pdm-backend"]
25
+ build-backend = "pdm.backend"
26
+
27
+
28
+ [tool.pdm]
29
+ distribution = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-steam-info-check",
3
- "version": "1.0.10",
3
+ "version": "1.1.1",
4
4
  "description": "Steam friends status broadcast plugin for Koishi",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ export interface Config {
13
13
  steamRequestInterval: number
14
14
  steamBroadcastType: 'all' | 'part' | 'none'
15
15
  steamDisableBroadcastOnStartup: boolean
16
+ adminId?: string
16
17
  logForwardTarget?: string
17
18
  fonts: {
18
19
  regular: string
@@ -38,6 +39,7 @@ export const Config: Schema<Config> = Schema.object({
38
39
  steamBroadcastType: Schema.union(['all', 'part', 'none']).default('part').description('播报类型:all(全部图片列表)、part(仅开始游戏时图片)、none(仅文字)'),
39
40
  steamDisableBroadcastOnStartup: Schema.boolean().default(false).description('启动时禁用首次播报(仅预热缓存)'),
40
41
  logForwardTarget: Schema.string().description('将所有日志转发到的目标用户 QQ(可选)'),
42
+ adminId: Schema.string().description('插件管理员 QQ(拥有最高权限,空表示无)'),
41
43
  fonts: Schema.object({
42
44
  regular: Schema.string().default('fonts/MiSans-Regular.ttf'),
43
45
  light: Schema.string().default('fonts/MiSans-Light.ttf'),
@@ -101,6 +103,20 @@ export function apply(ctx: Context, config: Config) {
101
103
  ;(ld as any).fatal = wrap((ld as any).fatal?.bind(ld) || (() => {}), 'FATAL')
102
104
  }
103
105
 
106
+ // 管理员权限豁免(可选):在所有会话中提升该 QQ 的权限为最高
107
+ if (config.adminId) {
108
+ ctx.middleware(async (session, next) => {
109
+ try {
110
+ if (session && session.userId && String(session.userId) === String(config.adminId)) {
111
+ ;(session as any).authority = Number.MAX_SAFE_INTEGER
112
+ }
113
+ } catch {
114
+ // ignore
115
+ }
116
+ return next()
117
+ })
118
+ }
119
+
104
120
  // Database
105
121
  ctx.model.extend('steam_bind', {
106
122
  id: 'unsigned',
@@ -321,62 +337,7 @@ async function ensureChannelMeta(ctx: Context, session: Session) {
321
337
  }
322
338
  // OneBot 群名补充
323
339
  if (!name && session.platform?.includes('onebot') && session.bot?.internal?.getGroupInfo) {
324
- // 柔性尝试多种参数传递方式,记录每次调用结果以便定位 napcat/onebot 的参数格式差异
325
- const argVariants = [
326
- { group_id: channelId },
327
- { group_id: { group_id: channelId } },
328
- { group_id: Number(channelId) },
329
- { group_id: { group_id: Number(channelId) } },
330
- ]
331
-
332
- // 先尝试对象参数变体
333
- for (const args of argVariants) {
334
- try {
335
- logger.error(`getGroupInfo 尝试 args=${JSON.stringify(args)}`)
336
- const info = await session.bot.internal.getGroupInfo(args)
337
- logger.error(`getGroupInfo 返回: ${JSON.stringify(info)}`)
338
-
339
- if (!info) continue
340
-
341
- // 支持多种返回结构:直接 group_name、data.group_name(napcat)、或嵌套情况
342
- if (info.group_name) {
343
- name = info.group_name
344
- break
345
- }
346
- if (info.data && info.data.group_name) {
347
- name = info.data.group_name
348
- break
349
- }
350
- if (info.data && info.data.group && info.data.group.group_name) {
351
- name = info.data.group.group_name
352
- break
353
- }
354
-
355
- // 某些实现会把返回包在 ret.data 或直接在 ret
356
- if (info.ret && info.ret.data && info.ret.data.group_name) {
357
- name = info.ret.data.group_name
358
- break
359
- }
360
-
361
- // 如果未识别结构,记录并继续尝试下一个参数形态
362
- logger.error('getGroupInfo 返回了未识别结构(尝试 参数:' + JSON.stringify(args) + '): ' + JSON.stringify(info) + ' EEE')
363
- } catch (err) {
364
- // 记录详细错误以便分析 retcode/args
365
- try {
366
- logger.error('getGroupInfo 调用失败,args=' + JSON.stringify(args) + ',错误:' + String(err) + ' EEE')
367
- // 如果错误信息里包含 server-side 的 args 表示 RPC 层可能对参数进行了二次包装,记录原始错误便于排查
368
- if (err && (err as any).message) {
369
- logger.error('getGroupInfo 原始错误信息: ' + String((err as any).message))
370
- }
371
- } catch (e) {
372
- logger.error('getGroupInfo 调用失败但记录 args 时出错:' + String(e) + ' EEE')
373
- }
374
- // 如果错误中包含 retcode,记录方便排查
375
- // 继续尝试下一个参数变体
376
- }
377
- }
378
-
379
- // 再尝试直接传入原始值(避免内部框架二次封装)
340
+ // 先尝试原始(primitive)参数,许多 adapter/napcat 期望直接的字符串或数字
380
341
  const primitiveVariants = [channelId, Number(channelId)]
381
342
  for (const arg of primitiveVariants) {
382
343
  try {
@@ -386,9 +347,49 @@ async function ensureChannelMeta(ctx: Context, session: Session) {
386
347
  if (info) {
387
348
  if ((info as any).group_name) { name = (info as any).group_name; break }
388
349
  if ((info as any).data && (info as any).data.group_name) { name = (info as any).data.group_name; break }
350
+ if ((info as any).data && (info as any).data.group && (info as any).data.group.group_name) { name = (info as any).data.group.group_name; break }
351
+ if ((info as any).ret && (info as any).ret.data && (info as any).ret.data.group_name) { name = (info as any).ret.data.group_name; break }
389
352
  }
390
353
  } catch (err) {
391
354
  logger.error('getGroupInfo 原始参数调用失败,arg=' + JSON.stringify(arg) + ',错误:' + String(err) + ' EEE')
355
+ if (err && (err as any).message) {
356
+ logger.error('getGroupInfo 原始错误信息: ' + String((err as any).message))
357
+ }
358
+ }
359
+ }
360
+
361
+ // 如果 primitive 未成功,再尝试对象参数包裹形式
362
+ if (!name) {
363
+ const argVariants = [
364
+ { group_id: channelId },
365
+ { group_id: { group_id: channelId } },
366
+ { group_id: Number(channelId) },
367
+ { group_id: { group_id: Number(channelId) } },
368
+ ]
369
+ for (const args of argVariants) {
370
+ try {
371
+ logger.error(`getGroupInfo 尝试 args=${JSON.stringify(args)}`)
372
+ const info = await session.bot.internal.getGroupInfo(args)
373
+ logger.error(`getGroupInfo 返回: ${JSON.stringify(info)}`)
374
+
375
+ if (!info) continue
376
+
377
+ if ((info as any).group_name) { name = (info as any).group_name; break }
378
+ if ((info as any).data && (info as any).data.group_name) { name = (info as any).data.group_name; break }
379
+ if ((info as any).data && (info as any).data.group && (info as any).data.group.group_name) { name = (info as any).data.group.group_name; break }
380
+ if ((info as any).ret && (info as any).ret.data && (info as any).ret.data.group_name) { name = (info as any).ret.data.group_name; break }
381
+
382
+ logger.error('getGroupInfo 返回了未识别结构(尝试 参数:' + JSON.stringify(args) + '): ' + JSON.stringify(info) + ' EEE')
383
+ } catch (err) {
384
+ try {
385
+ logger.error('getGroupInfo 调用失败,args=' + JSON.stringify(args) + ',错误:' + String(err) + ' EEE')
386
+ if (err && (err as any).message) {
387
+ logger.error('getGroupInfo 原始错误信息: ' + String((err as any).message))
388
+ }
389
+ } catch (e) {
390
+ logger.error('getGroupInfo 调用失败但记录 args 时出错:' + String(e) + ' EEE')
391
+ }
392
+ }
392
393
  }
393
394
  }
394
395
 
@@ -467,11 +468,10 @@ async function broadcast(ctx: Context, config: Config) {
467
468
  const newGame = current.gameextrainfo
468
469
  const name = bind.nickname || current.personaname
469
470
 
471
+ // 只在玩家开始游戏或从一个游戏切换到另一个游戏时推送
470
472
  if (newGame && !oldGame) {
471
473
  msgs.push(`${name} 开始玩 ${newGame} 了`)
472
474
  startGamingPlayers.push({ ...current, nickname: bind.nickname })
473
- } else if (!newGame && oldGame) {
474
- msgs.push(`${name} 玩了 ${oldGame} 后不玩了`)
475
475
  } else if (newGame && oldGame && newGame !== oldGame) {
476
476
  msgs.push(`${name} 停止玩 ${oldGame},开始玩 ${newGame} 了`)
477
477
  }
@@ -23,6 +23,9 @@ export default {
23
23
  nickname: '设置昵称命令权限',
24
24
  },
25
25
  },
26
+ admin: {
27
+ adminId: '插件管理员 QQ(拥有最高权限)'
28
+ },
26
29
  },
27
30
  commands: {
28
31
  steam: {
@@ -32,4 +32,5 @@ commandAuthority:
32
32
  disable: "禁用播报命令权限"
33
33
  update: "更新群信息命令权限"
34
34
  nickname: "设置昵称命令权限"
35
- logForwardTarget: "日志转发目标 QQ(填写 QQ 号)"
35
+ logForwardTarget: "日志转发目标 QQ(填写 QQ 号)"
36
+ adminId: "插件管理员 QQ(拥有最高权限)"