koishi-plugin-steam-info-check 1.0.9 → 1.1.0
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/dist/index.d.ts +1 -0
- package/dist/index.js +109 -40
- package/dist/locales/zh-CN.d.ts +25 -0
- package/dist/locales/zh-CN.js +25 -0
- package/nonebot-plugin-steam-info-main/.github/actions/setup-python/action.yml +21 -0
- package/nonebot-plugin-steam-info-main/.github/workflows/release.yml +37 -0
- package/nonebot-plugin-steam-info-main/LICENSE +21 -0
- package/nonebot-plugin-steam-info-main/README.md +117 -0
- package/nonebot-plugin-steam-info-main/fonts/MiSans-Bold.ttf +0 -0
- package/nonebot-plugin-steam-info-main/fonts/MiSans-Light.ttf +0 -0
- package/nonebot-plugin-steam-info-main/fonts/MiSans-Regular.ttf +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/__init__.py +487 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/config.py +19 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/data_source.py +264 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/draw.py +921 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/models.py +82 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/bg_dots.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/busy.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/default_achievement_image.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/default_header_image.jpg +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/friends_search.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/gaming.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/parent_status.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/unknown_avatar.jpg +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/zzz_gaming.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/res/zzz_online.png +0 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/steam.py +259 -0
- package/nonebot-plugin-steam-info-main/nonebot_plugin_steam_info/utils.py +112 -0
- package/nonebot-plugin-steam-info-main/pdm.lock +966 -0
- package/nonebot-plugin-steam-info-main/preview.png +0 -0
- package/nonebot-plugin-steam-info-main/preview_1.png +0 -0
- package/nonebot-plugin-steam-info-main/preview_2.png +0 -0
- package/nonebot-plugin-steam-info-main/pyproject.toml +29 -0
- package/package.json +1 -1
- package/src/index.ts +83 -42
- package/src/locales/zh-CN.ts +25 -0
- package/src/locales/zh-CN.yml +2 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
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
|
+
logForwardTarget?: string
|
|
16
17
|
fonts: {
|
|
17
18
|
regular: string
|
|
18
19
|
light: string
|
|
@@ -36,6 +37,7 @@ export const Config: Schema<Config> = Schema.object({
|
|
|
36
37
|
steamRequestInterval: Schema.number().default(300).description('轮询间隔(秒)'),
|
|
37
38
|
steamBroadcastType: Schema.union(['all', 'part', 'none']).default('part').description('播报类型:all(全部图片列表)、part(仅开始游戏时图片)、none(仅文字)'),
|
|
38
39
|
steamDisableBroadcastOnStartup: Schema.boolean().default(false).description('启动时禁用首次播报(仅预热缓存)'),
|
|
40
|
+
logForwardTarget: Schema.string().description('将所有日志转发到的目标用户 QQ(可选)'),
|
|
39
41
|
fonts: Schema.object({
|
|
40
42
|
regular: Schema.string().default('fonts/MiSans-Regular.ttf'),
|
|
41
43
|
light: Schema.string().default('fonts/MiSans-Light.ttf'),
|
|
@@ -71,6 +73,34 @@ export function apply(ctx: Context, config: Config) {
|
|
|
71
73
|
ctx.plugin(SteamService, config)
|
|
72
74
|
ctx.plugin(DrawService, config)
|
|
73
75
|
|
|
76
|
+
// 日志转发(可选)
|
|
77
|
+
if (config.logForwardTarget) {
|
|
78
|
+
const target = config.logForwardTarget
|
|
79
|
+
const sendToTarget = async (level: string, message: any) => {
|
|
80
|
+
try {
|
|
81
|
+
const bots = Object.values(ctx.bots)
|
|
82
|
+
const bot: any = bots[0]
|
|
83
|
+
if (!bot) return
|
|
84
|
+
const text = `[${name}][${level}] ${typeof message === 'string' ? message : JSON.stringify(message)}`
|
|
85
|
+
await bot.sendMessage(target, text)
|
|
86
|
+
} catch {
|
|
87
|
+
// 忽略转发失败,避免影响主流程
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const ld: any = logger as any
|
|
92
|
+
const wrap = (orig: Function, level: string) => (...args: any[]) => {
|
|
93
|
+
try { orig(...args) } catch {}
|
|
94
|
+
try { sendToTarget(level, args.map(a => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ')) } catch {}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
ld.debug = wrap(ld.debug?.bind(ld) || (() => {}), 'DEBUG')
|
|
98
|
+
ld.info = wrap(ld.info?.bind(ld) || (() => {}), 'INFO')
|
|
99
|
+
ld.warn = wrap(ld.warn?.bind(ld) || (() => {}), 'WARN')
|
|
100
|
+
ld.error = wrap(ld.error?.bind(ld) || (() => {}), 'ERROR')
|
|
101
|
+
;(ld as any).fatal = wrap((ld as any).fatal?.bind(ld) || (() => {}), 'FATAL')
|
|
102
|
+
}
|
|
103
|
+
|
|
74
104
|
// Database
|
|
75
105
|
ctx.model.extend('steam_bind', {
|
|
76
106
|
id: 'unsigned',
|
|
@@ -291,55 +321,67 @@ async function ensureChannelMeta(ctx: Context, session: Session) {
|
|
|
291
321
|
}
|
|
292
322
|
// OneBot 群名补充
|
|
293
323
|
if (!name && session.platform?.includes('onebot') && session.bot?.internal?.getGroupInfo) {
|
|
294
|
-
//
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
{ group_id: { group_id: channelId } },
|
|
298
|
-
{ group_id: Number(channelId) },
|
|
299
|
-
{ group_id: { group_id: Number(channelId) } },
|
|
300
|
-
]
|
|
301
|
-
|
|
302
|
-
for (const args of argVariants) {
|
|
324
|
+
// 先尝试原始(primitive)参数,许多 adapter/napcat 期望直接的字符串或数字
|
|
325
|
+
const primitiveVariants = [channelId, Number(channelId)]
|
|
326
|
+
for (const arg of primitiveVariants) {
|
|
303
327
|
try {
|
|
304
|
-
logger.error(`getGroupInfo 尝试 args=${JSON.stringify(
|
|
305
|
-
const info = await session.bot.internal.getGroupInfo(
|
|
328
|
+
logger.error(`getGroupInfo 尝试 args=${JSON.stringify(arg)}`)
|
|
329
|
+
const info = await session.bot.internal.getGroupInfo(arg as any)
|
|
306
330
|
logger.error(`getGroupInfo 返回: ${JSON.stringify(info)}`)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
name = info.group_name
|
|
313
|
-
break
|
|
331
|
+
if (info) {
|
|
332
|
+
if ((info as any).group_name) { name = (info as any).group_name; break }
|
|
333
|
+
if ((info as any).data && (info as any).data.group_name) { name = (info as any).data.group_name; break }
|
|
334
|
+
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 }
|
|
335
|
+
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 }
|
|
314
336
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (info.data && info.data.group && info.data.group.group_name) {
|
|
320
|
-
name = info.data.group.group_name
|
|
321
|
-
break
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// 某些实现会把返回包在 ret.data 或直接在 ret
|
|
325
|
-
if (info.ret && info.ret.data && info.ret.data.group_name) {
|
|
326
|
-
name = info.ret.data.group_name
|
|
327
|
-
break
|
|
337
|
+
} catch (err) {
|
|
338
|
+
logger.error('getGroupInfo 原始参数调用失败,arg=' + JSON.stringify(arg) + ',错误:' + String(err) + ' EEE')
|
|
339
|
+
if (err && (err as any).message) {
|
|
340
|
+
logger.error('getGroupInfo 原始错误信息: ' + String((err as any).message))
|
|
328
341
|
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
329
344
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
345
|
+
// 如果 primitive 未成功,再尝试对象参数包裹形式
|
|
346
|
+
if (!name) {
|
|
347
|
+
const argVariants = [
|
|
348
|
+
{ group_id: channelId },
|
|
349
|
+
{ group_id: { group_id: channelId } },
|
|
350
|
+
{ group_id: Number(channelId) },
|
|
351
|
+
{ group_id: { group_id: Number(channelId) } },
|
|
352
|
+
]
|
|
353
|
+
for (const args of argVariants) {
|
|
334
354
|
try {
|
|
335
|
-
logger.error(
|
|
336
|
-
|
|
337
|
-
logger.error(
|
|
355
|
+
logger.error(`getGroupInfo 尝试 args=${JSON.stringify(args)}`)
|
|
356
|
+
const info = await session.bot.internal.getGroupInfo(args)
|
|
357
|
+
logger.error(`getGroupInfo 返回: ${JSON.stringify(info)}`)
|
|
358
|
+
|
|
359
|
+
if (!info) continue
|
|
360
|
+
|
|
361
|
+
if ((info as any).group_name) { name = (info as any).group_name; break }
|
|
362
|
+
if ((info as any).data && (info as any).data.group_name) { name = (info as any).data.group_name; break }
|
|
363
|
+
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 }
|
|
364
|
+
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 }
|
|
365
|
+
|
|
366
|
+
logger.error('getGroupInfo 返回了未识别结构(尝试 参数:' + JSON.stringify(args) + '): ' + JSON.stringify(info) + ' EEE')
|
|
367
|
+
} catch (err) {
|
|
368
|
+
try {
|
|
369
|
+
logger.error('getGroupInfo 调用失败,args=' + JSON.stringify(args) + ',错误:' + String(err) + ' EEE')
|
|
370
|
+
if (err && (err as any).message) {
|
|
371
|
+
logger.error('getGroupInfo 原始错误信息: ' + String((err as any).message))
|
|
372
|
+
}
|
|
373
|
+
} catch (e) {
|
|
374
|
+
logger.error('getGroupInfo 调用失败但记录 args 时出错:' + String(e) + ' EEE')
|
|
375
|
+
}
|
|
338
376
|
}
|
|
339
|
-
// 如果错误中包含 retcode,记录方便排查
|
|
340
|
-
// 继续尝试下一个参数变体
|
|
341
377
|
}
|
|
342
378
|
}
|
|
379
|
+
|
|
380
|
+
// 所有尝试失败,记录最终失败并使用回退值
|
|
381
|
+
if (!name) {
|
|
382
|
+
logger.error('getGroupInfo 所有尝试均失败,使用回退群名: ' + channelId + ' EEE')
|
|
383
|
+
name = channelId
|
|
384
|
+
}
|
|
343
385
|
}
|
|
344
386
|
|
|
345
387
|
let avatar = current.avatar
|
|
@@ -410,11 +452,10 @@ async function broadcast(ctx: Context, config: Config) {
|
|
|
410
452
|
const newGame = current.gameextrainfo
|
|
411
453
|
const name = bind.nickname || current.personaname
|
|
412
454
|
|
|
455
|
+
// 只在玩家开始游戏或从一个游戏切换到另一个游戏时推送
|
|
413
456
|
if (newGame && !oldGame) {
|
|
414
457
|
msgs.push(`${name} 开始玩 ${newGame} 了`)
|
|
415
458
|
startGamingPlayers.push({ ...current, nickname: bind.nickname })
|
|
416
|
-
} else if (!newGame && oldGame) {
|
|
417
|
-
msgs.push(`${name} 玩了 ${oldGame} 后不玩了`)
|
|
418
459
|
} else if (newGame && oldGame && newGame !== oldGame) {
|
|
419
460
|
msgs.push(`${name} 停止玩 ${oldGame},开始玩 ${newGame} 了`)
|
|
420
461
|
}
|
package/src/locales/zh-CN.ts
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
export default {
|
|
2
|
+
'steam-info': {
|
|
3
|
+
config: {
|
|
4
|
+
steamApiKey: 'Steam API Key(支持多个)',
|
|
5
|
+
proxy: '代理地址,例如 http://127.0.0.1:7890',
|
|
6
|
+
steamRequestInterval: '轮询间隔(秒)',
|
|
7
|
+
steamBroadcastType: '播报类型:all(全部图片列表)、part(仅开始游戏时图片)、none(仅文字)',
|
|
8
|
+
steamDisableBroadcastOnStartup: '启动时禁用首次播报(仅预热缓存)',
|
|
9
|
+
logForwardTarget: '日志转发目标 QQ(填写 QQ 号)',
|
|
10
|
+
fonts: {
|
|
11
|
+
regular: '常规字体路径',
|
|
12
|
+
light: '细体字体路径',
|
|
13
|
+
bold: '粗体字体路径',
|
|
14
|
+
},
|
|
15
|
+
commandAuthority: {
|
|
16
|
+
bind: '绑定命令权限',
|
|
17
|
+
unbind: '解绑命令权限',
|
|
18
|
+
info: '查看资料命令权限',
|
|
19
|
+
check: '查看状态命令权限',
|
|
20
|
+
enable: '启用播报命令权限',
|
|
21
|
+
disable: '禁用播报命令权限',
|
|
22
|
+
update: '更新群信息命令权限',
|
|
23
|
+
nickname: '设置昵称命令权限',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
2
27
|
commands: {
|
|
3
28
|
steam: {
|
|
4
29
|
bind: {
|
package/src/locales/zh-CN.yml
CHANGED