koishi-plugin-steam-info-check 1.0.0 → 1.0.2

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.
@@ -10,6 +10,8 @@ export interface SteamChannel {
10
10
  enable: boolean;
11
11
  name?: string;
12
12
  avatar?: string;
13
+ platform?: string;
14
+ assignee?: string;
13
15
  }
14
16
  declare module 'koishi' {
15
17
  interface Tables {
package/dist/index.js CHANGED
@@ -1,12 +1,16 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.logger = exports.Config = exports.inject = exports.name = void 0;
4
7
  exports.apply = apply;
5
8
  const koishi_1 = require("koishi");
6
9
  const service_1 = require("./service");
7
10
  const drawer_1 = require("./drawer");
11
+ const zh_CN_1 = __importDefault(require("./locales/zh-CN"));
8
12
  exports.name = 'steam-info';
9
- exports.inject = ['model', 'http', 'puppeteer', 'database'];
13
+ exports.inject = ['model', 'http', 'puppeteer', 'database', 'steam', 'drawer'];
10
14
  exports.Config = koishi_1.Schema.object({
11
15
  steamApiKey: koishi_1.Schema.array(String).required().description('Steam API Key (supports multiple)'),
12
16
  proxy: koishi_1.Schema.string().description('Proxy URL (e.g., http://127.0.0.1:7890)'),
@@ -32,7 +36,7 @@ exports.Config = koishi_1.Schema.object({
32
36
  exports.logger = new koishi_1.Logger('steam-info');
33
37
  function apply(ctx, config) {
34
38
  // Localization
35
- ctx.i18n.define('zh-CN', require('./locales/zh-CN'));
39
+ ctx.i18n.define('zh-CN', zh_CN_1.default);
36
40
  // Services
37
41
  ctx.plugin(service_1.SteamService, config);
38
42
  ctx.plugin(drawer_1.DrawService, config);
@@ -52,6 +56,8 @@ function apply(ctx, config) {
52
56
  enable: 'boolean',
53
57
  name: 'string',
54
58
  avatar: 'string',
59
+ platform: 'string',
60
+ assignee: 'string',
55
61
  }, {
56
62
  primary: 'id',
57
63
  });
@@ -92,60 +98,81 @@ function apply(ctx, config) {
92
98
  .action(async ({ session }, target) => {
93
99
  if (!session)
94
100
  return;
95
- let steamId = null;
96
- if (target) {
97
- // Check if target is mention
98
- const [platform, userId] = session.resolve(target);
99
- if (userId) {
100
- const bind = await ctx.database.get('steam_bind', { userId, channelId: session.channelId });
101
+ try {
102
+ let steamId = null;
103
+ if (target) {
104
+ try {
105
+ const [, userId] = session.resolve(target);
106
+ if (userId) {
107
+ const bind = await ctx.database.get('steam_bind', { userId, channelId: session.channelId });
108
+ if (bind.length)
109
+ steamId = bind[0].steamId;
110
+ }
111
+ }
112
+ catch {
113
+ /* ignore resolve errors */
114
+ }
115
+ if (!steamId && /^\d+$/.test(target)) {
116
+ steamId = await ctx.steam.getSteamId(target);
117
+ }
118
+ }
119
+ else {
120
+ const bind = await ctx.database.get('steam_bind', { userId: session.userId, channelId: session.channelId });
101
121
  if (bind.length)
102
122
  steamId = bind[0].steamId;
103
123
  }
104
- else if (/^\d+$/.test(target)) {
105
- steamId = await ctx.steam.getSteamId(target);
106
- }
124
+ if (!steamId)
125
+ return session.text('.user_not_found');
126
+ const profile = await ctx.steam.getUserData(steamId);
127
+ const image = await ctx.drawer.drawPlayerStatus(profile, steamId);
128
+ if (typeof image === 'string')
129
+ return session.send(image);
130
+ return session.send(koishi_1.h.image(image, 'image/png'));
107
131
  }
108
- else {
109
- const bind = await ctx.database.get('steam_bind', { userId: session.userId, channelId: session.channelId });
110
- if (bind.length)
111
- steamId = bind[0].steamId;
132
+ catch (err) {
133
+ exports.logger.error(err);
134
+ return session.text('.error');
112
135
  }
113
- if (!steamId)
114
- return session.text('.user_not_found');
115
- const profile = await ctx.steam.getUserData(steamId);
116
- const image = await ctx.drawer.drawPlayerStatus(profile, steamId);
117
- if (typeof image === 'string')
118
- return session.send(image);
119
- return session.send(koishi_1.h.image(image, 'image/png'));
120
136
  });
121
137
  ctx.command('steam.check', 'Check Friends Status', { authority: config.commandAuthority.check })
122
138
  .alias('steamcheck', '查看steam', '查steam')
123
139
  .action(async ({ session }) => {
124
140
  if (!session)
125
141
  return;
126
- const binds = await ctx.database.get('steam_bind', { channelId: session.channelId });
127
- if (binds.length === 0)
128
- return session.text('.no_binds');
129
- const steamIds = binds.map(b => b.steamId);
130
- const summaries = await ctx.steam.getPlayerSummaries(steamIds);
131
- if (summaries.length === 0)
132
- return session.text('.api_error');
133
- const channelInfo = await ctx.database.get('steam_channel', { id: session.channelId });
134
- const parentAvatar = channelInfo[0]?.avatar
135
- ? Buffer.from(channelInfo[0].avatar, 'base64')
136
- : await ctx.drawer.getDefaultAvatar();
137
- const parentName = channelInfo[0]?.name || session.channelId || 'Unknown';
138
- const image = await ctx.drawer.drawFriendsStatus(parentAvatar, parentName, summaries, binds);
139
- if (typeof image === 'string')
140
- return session.send(image);
141
- return session.send(koishi_1.h.image(image, 'image/png'));
142
+ try {
143
+ const binds = await ctx.database.get('steam_bind', { channelId: session.channelId });
144
+ if (binds.length === 0)
145
+ return session.text('.no_binds');
146
+ const steamIds = binds.map(b => b.steamId);
147
+ const summaries = await ctx.steam.getPlayerSummaries(steamIds);
148
+ if (summaries.length === 0)
149
+ return session.text('.api_error');
150
+ const channelInfo = await ctx.database.get('steam_channel', { id: session.channelId });
151
+ const parentAvatar = channelInfo[0]?.avatar
152
+ ? Buffer.from(channelInfo[0].avatar, 'base64')
153
+ : await ctx.drawer.getDefaultAvatar();
154
+ const parentName = channelInfo[0]?.name || session.channelId || 'Unknown';
155
+ const image = await ctx.drawer.drawFriendsStatus(parentAvatar, parentName, summaries, binds);
156
+ if (typeof image === 'string')
157
+ return session.send(image);
158
+ return session.send(koishi_1.h.image(image, 'image/png'));
159
+ }
160
+ catch (err) {
161
+ exports.logger.error(err);
162
+ return session.text('.error');
163
+ }
142
164
  });
143
165
  ctx.command('steam.enable', 'Enable Broadcast', { authority: config.commandAuthority.enable })
144
166
  .alias('steamenable', '启用steam')
145
167
  .action(async ({ session }) => {
146
168
  if (!session)
147
169
  return;
148
- await ctx.database.upsert('steam_channel', [{ id: session.channelId, enable: true }]);
170
+ await ctx.database.upsert('steam_channel', [{
171
+ id: session.channelId,
172
+ enable: true,
173
+ platform: session.platform,
174
+ assignee: session.selfId,
175
+ }]);
149
176
  return session.text('.enable_success');
150
177
  });
151
178
  ctx.command('steam.disable', 'Disable Broadcast', { authority: config.commandAuthority.disable })
@@ -153,7 +180,12 @@ function apply(ctx, config) {
153
180
  .action(async ({ session }) => {
154
181
  if (!session)
155
182
  return;
156
- await ctx.database.upsert('steam_channel', [{ id: session.channelId, enable: false }]);
183
+ await ctx.database.upsert('steam_channel', [{
184
+ id: session.channelId,
185
+ enable: false,
186
+ platform: session.platform,
187
+ assignee: session.selfId,
188
+ }]);
157
189
  return session.text('.disable_success');
158
190
  });
159
191
  ctx.command('steam.update [name:string] [avatar:image]', 'Update Group Info', { authority: config.commandAuthority.update })
@@ -170,7 +202,7 @@ function apply(ctx, config) {
170
202
  }
171
203
  if (!name && !avatarBase64)
172
204
  return session.text('.args_missing');
173
- const update = { id: session.channelId };
205
+ const update = { id: session.channelId, platform: session.platform, assignee: session.selfId };
174
206
  if (name)
175
207
  update.name = name;
176
208
  if (avatarBase64)
@@ -190,13 +222,29 @@ function apply(ctx, config) {
190
222
  return session.text('.nickname_set', [nickname]);
191
223
  });
192
224
  // Scheduler
225
+ let skipFirstBroadcast = config.steamDisableBroadcastOnStartup;
193
226
  ctx.setInterval(async () => {
194
- await broadcast(ctx);
227
+ if (skipFirstBroadcast) {
228
+ await seedStatusCache(ctx);
229
+ skipFirstBroadcast = false;
230
+ return;
231
+ }
232
+ await broadcast(ctx, config);
195
233
  }, config.steamRequestInterval * 1000);
196
234
  }
197
235
  // Broadcast Logic
198
236
  const statusCache = new Map();
199
- async function broadcast(ctx) {
237
+ async function seedStatusCache(ctx) {
238
+ const binds = await ctx.database.get('steam_bind', {});
239
+ if (!binds.length)
240
+ return;
241
+ const steamIds = [...new Set(binds.map(b => b.steamId))];
242
+ const summaries = await ctx.steam.getPlayerSummaries(steamIds);
243
+ for (const player of summaries) {
244
+ statusCache.set(player.steamid, player);
245
+ }
246
+ }
247
+ async function broadcast(ctx, config) {
200
248
  const channels = await ctx.database.get('steam_channel', { enable: true });
201
249
  if (channels.length === 0)
202
250
  return;
@@ -233,13 +281,14 @@ async function broadcast(ctx) {
233
281
  }
234
282
  }
235
283
  if (msgs.length > 0) {
236
- const bot = ctx.bots[0];
284
+ const botKey = channel.platform && channel.assignee ? `${channel.platform}:${channel.assignee}` : undefined;
285
+ const bot = botKey ? ctx.bots[botKey] : Object.values(ctx.bots)[0];
237
286
  if (!bot)
238
287
  continue;
239
- if (ctx.config.steamBroadcastType === 'none') {
288
+ if (config.steamBroadcastType === 'none') {
240
289
  await bot.sendMessage(channel.id, msgs.join('\n'));
241
290
  }
242
- else if (ctx.config.steamBroadcastType === 'part') {
291
+ else if (config.steamBroadcastType === 'part') {
243
292
  if (startGamingPlayers.length > 0) {
244
293
  const images = await Promise.all(startGamingPlayers.map(p => ctx.drawer.drawStartGaming(p, p.nickname)));
245
294
  const combined = await ctx.drawer.concatImages(images);
@@ -250,7 +299,7 @@ async function broadcast(ctx) {
250
299
  await bot.sendMessage(channel.id, msgs.join('\n'));
251
300
  }
252
301
  }
253
- else if (ctx.config.steamBroadcastType === 'all') {
302
+ else if (config.steamBroadcastType === 'all') {
254
303
  const channelPlayers = channelBinds.map(b => currentMap.get(b.steamId)).filter(Boolean);
255
304
  const parentAvatar = channel.avatar ? Buffer.from(channel.avatar, 'base64') : await ctx.drawer.getDefaultAvatar();
256
305
  const image = await ctx.drawer.drawFriendsStatus(parentAvatar, channel.name || channel.id, channelPlayers, channelBinds);
@@ -0,0 +1,61 @@
1
+ declare const _default: {
2
+ commands: {
3
+ steam: {
4
+ bind: {
5
+ messages: {
6
+ invalid_id: string;
7
+ id_not_found: string;
8
+ bind_success: string;
9
+ error: string;
10
+ };
11
+ };
12
+ unbind: {
13
+ messages: {
14
+ unbind_success: string;
15
+ not_bound: string;
16
+ error: string;
17
+ };
18
+ };
19
+ info: {
20
+ messages: {
21
+ user_not_found: string;
22
+ error: string;
23
+ };
24
+ };
25
+ check: {
26
+ messages: {
27
+ no_binds: string;
28
+ api_error: string;
29
+ error: string;
30
+ };
31
+ };
32
+ enable: {
33
+ messages: {
34
+ enable_success: string;
35
+ error: string;
36
+ };
37
+ };
38
+ disable: {
39
+ messages: {
40
+ disable_success: string;
41
+ error: string;
42
+ };
43
+ };
44
+ update: {
45
+ messages: {
46
+ args_missing: string;
47
+ update_success: string;
48
+ error: string;
49
+ };
50
+ };
51
+ nickname: {
52
+ messages: {
53
+ not_bound: string;
54
+ nickname_set: string;
55
+ error: string;
56
+ };
57
+ };
58
+ };
59
+ };
60
+ };
61
+ export default _default;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ commands: {
5
+ steam: {
6
+ bind: {
7
+ messages: {
8
+ invalid_id: '请输入有效的 Steam ID。',
9
+ id_not_found: '无法找到该 Steam ID。',
10
+ bind_success: '绑定成功!Steam ID: {0}',
11
+ error: '发生错误。',
12
+ },
13
+ },
14
+ unbind: {
15
+ messages: {
16
+ unbind_success: '解绑成功。',
17
+ not_bound: '你还没有绑定 Steam ID。',
18
+ error: '发生错误。',
19
+ },
20
+ },
21
+ info: {
22
+ messages: {
23
+ user_not_found: '未找到用户信息。',
24
+ error: '发生错误。',
25
+ },
26
+ },
27
+ check: {
28
+ messages: {
29
+ no_binds: '本群尚无绑定用户。',
30
+ api_error: '连接 Steam API 失败。',
31
+ error: '发生错误。',
32
+ },
33
+ },
34
+ enable: {
35
+ messages: {
36
+ enable_success: '已开启本群播报。',
37
+ error: '发生错误。',
38
+ },
39
+ },
40
+ disable: {
41
+ messages: {
42
+ disable_success: '已关闭本群播报。',
43
+ error: '发生错误。',
44
+ },
45
+ },
46
+ update: {
47
+ messages: {
48
+ args_missing: '参数缺失。',
49
+ update_success: '更新群信息成功。',
50
+ error: '发生错误。',
51
+ },
52
+ },
53
+ nickname: {
54
+ messages: {
55
+ not_bound: '你还没有绑定 Steam ID。',
56
+ nickname_set: '昵称已设置为 {0}。',
57
+ error: '发生错误。',
58
+ },
59
+ },
60
+ },
61
+ },
62
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-steam-info-check",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Steam friends status broadcast plugin for Koishi",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -53,4 +53,4 @@
53
53
  "typescript": "^5.0.0",
54
54
  "koishi": "^4.16.0"
55
55
  }
56
- }
56
+ }
package/src/database.ts CHANGED
@@ -11,6 +11,8 @@ export interface SteamChannel {
11
11
  enable: boolean
12
12
  name?: string
13
13
  avatar?: string
14
+ platform?: string
15
+ assignee?: string
14
16
  }
15
17
 
16
18
  declare module 'koishi' {
package/src/index.ts CHANGED
@@ -2,9 +2,10 @@ import { Context, Schema, Logger, Service, Session, h } from 'koishi'
2
2
  import { SteamService } from './service'
3
3
  import { DrawService } from './drawer'
4
4
  import { SteamBind, SteamChannel } from './database'
5
+ import zhCN from './locales/zh-CN'
5
6
 
6
7
  export const name = 'steam-info'
7
- export const inject = ['model', 'http', 'puppeteer', 'database']
8
+ export const inject = ['model', 'http', 'puppeteer', 'database', 'steam', 'drawer']
8
9
 
9
10
  export interface Config {
10
11
  steamApiKey: string[]
@@ -63,7 +64,7 @@ declare module 'koishi' {
63
64
 
64
65
  export function apply(ctx: Context, config: Config) {
65
66
  // Localization
66
- ctx.i18n.define('zh-CN', require('./locales/zh-CN'))
67
+ ctx.i18n.define('zh-CN', zhCN)
67
68
 
68
69
  // Services
69
70
  ctx.plugin(SteamService, config)
@@ -86,6 +87,8 @@ export function apply(ctx: Context, config: Config) {
86
87
  enable: 'boolean',
87
88
  name: 'string',
88
89
  avatar: 'string',
90
+ platform: 'string',
91
+ assignee: 'string',
89
92
  }, {
90
93
  primary: 'id',
91
94
  })
@@ -128,57 +131,77 @@ export function apply(ctx: Context, config: Config) {
128
131
  .alias('steaminfo', 'steam信息')
129
132
  .action(async ({ session }, target) => {
130
133
  if (!session) return
131
- let steamId: string | null = null
132
- if (target) {
133
- // Check if target is mention
134
- const [platform, userId] = session.resolve(target)
135
- if (userId) {
136
- const bind = await ctx.database.get('steam_bind', { userId, channelId: session.channelId })
137
- if (bind.length) steamId = bind[0].steamId
138
- } else if (/^\d+$/.test(target)) {
139
- steamId = await ctx.steam.getSteamId(target)
134
+ try {
135
+ let steamId: string | null = null
136
+ if (target) {
137
+ try {
138
+ const [, userId] = session.resolve(target)
139
+ if (userId) {
140
+ const bind = await ctx.database.get('steam_bind', { userId, channelId: session.channelId })
141
+ if (bind.length) steamId = bind[0].steamId
142
+ }
143
+ } catch {
144
+ /* ignore resolve errors */
145
+ }
146
+
147
+ if (!steamId && /^\d+$/.test(target)) {
148
+ steamId = await ctx.steam.getSteamId(target)
149
+ }
150
+ } else {
151
+ const bind = await ctx.database.get('steam_bind', { userId: session.userId, channelId: session.channelId })
152
+ if (bind.length) steamId = bind[0].steamId
140
153
  }
141
- } else {
142
- const bind = await ctx.database.get('steam_bind', { userId: session.userId, channelId: session.channelId })
143
- if (bind.length) steamId = bind[0].steamId
144
- }
145
154
 
146
- if (!steamId) return session.text('.user_not_found')
155
+ if (!steamId) return session.text('.user_not_found')
147
156
 
148
- const profile = await ctx.steam.getUserData(steamId)
149
- const image = await ctx.drawer.drawPlayerStatus(profile, steamId)
150
- if (typeof image === 'string') return session.send(image)
151
- return session.send(h.image(image, 'image/png'))
157
+ const profile = await ctx.steam.getUserData(steamId)
158
+ const image = await ctx.drawer.drawPlayerStatus(profile, steamId)
159
+ if (typeof image === 'string') return session.send(image)
160
+ return session.send(h.image(image, 'image/png'))
161
+ } catch (err) {
162
+ logger.error(err)
163
+ return session.text('.error')
164
+ }
152
165
  })
153
166
 
154
167
  ctx.command('steam.check', 'Check Friends Status', { authority: config.commandAuthority.check })
155
168
  .alias('steamcheck', '查看steam', '查steam')
156
169
  .action(async ({ session }) => {
157
170
  if (!session) return
158
- const binds = await ctx.database.get('steam_bind', { channelId: session.channelId })
159
- if (binds.length === 0) return session.text('.no_binds')
171
+ try {
172
+ const binds = await ctx.database.get('steam_bind', { channelId: session.channelId })
173
+ if (binds.length === 0) return session.text('.no_binds')
160
174
 
161
- const steamIds = binds.map(b => b.steamId)
162
- const summaries = await ctx.steam.getPlayerSummaries(steamIds)
163
-
164
- if (summaries.length === 0) return session.text('.api_error')
165
-
166
- const channelInfo = await ctx.database.get('steam_channel', { id: session.channelId })
167
- const parentAvatar = channelInfo[0]?.avatar
168
- ? Buffer.from(channelInfo[0].avatar, 'base64')
169
- : await ctx.drawer.getDefaultAvatar()
170
- const parentName = channelInfo[0]?.name || session.channelId || 'Unknown'
171
-
172
- const image = await ctx.drawer.drawFriendsStatus(parentAvatar, parentName, summaries, binds)
173
- if (typeof image === 'string') return session.send(image)
174
- return session.send(h.image(image, 'image/png'))
175
+ const steamIds = binds.map(b => b.steamId)
176
+ const summaries = await ctx.steam.getPlayerSummaries(steamIds)
177
+
178
+ if (summaries.length === 0) return session.text('.api_error')
179
+
180
+ const channelInfo = await ctx.database.get('steam_channel', { id: session.channelId })
181
+ const parentAvatar = channelInfo[0]?.avatar
182
+ ? Buffer.from(channelInfo[0].avatar, 'base64')
183
+ : await ctx.drawer.getDefaultAvatar()
184
+ const parentName = channelInfo[0]?.name || session.channelId || 'Unknown'
185
+
186
+ const image = await ctx.drawer.drawFriendsStatus(parentAvatar, parentName, summaries, binds)
187
+ if (typeof image === 'string') return session.send(image)
188
+ return session.send(h.image(image, 'image/png'))
189
+ } catch (err) {
190
+ logger.error(err)
191
+ return session.text('.error')
192
+ }
175
193
  })
176
194
 
177
195
  ctx.command('steam.enable', 'Enable Broadcast', { authority: config.commandAuthority.enable })
178
196
  .alias('steamenable', '启用steam')
179
197
  .action(async ({ session }) => {
180
198
  if (!session) return
181
- await ctx.database.upsert('steam_channel', [{ id: session.channelId, enable: true }])
199
+ await ctx.database.upsert('steam_channel', [{
200
+ id: session.channelId,
201
+ enable: true,
202
+ platform: session.platform,
203
+ assignee: session.selfId,
204
+ }])
182
205
  return session.text('.enable_success')
183
206
  })
184
207
 
@@ -186,7 +209,12 @@ export function apply(ctx: Context, config: Config) {
186
209
  .alias('steamdisable', '禁用steam')
187
210
  .action(async ({ session }) => {
188
211
  if (!session) return
189
- await ctx.database.upsert('steam_channel', [{ id: session.channelId, enable: false }])
212
+ await ctx.database.upsert('steam_channel', [{
213
+ id: session.channelId,
214
+ enable: false,
215
+ platform: session.platform,
216
+ assignee: session.selfId,
217
+ }])
190
218
  return session.text('.disable_success')
191
219
  })
192
220
 
@@ -205,7 +233,7 @@ export function apply(ctx: Context, config: Config) {
205
233
 
206
234
  if (!name && !avatarBase64) return session.text('.args_missing')
207
235
 
208
- const update: any = { id: session.channelId }
236
+ const update: any = { id: session.channelId, platform: session.platform, assignee: session.selfId }
209
237
  if (name) update.name = name
210
238
  if (avatarBase64) update.avatar = avatarBase64
211
239
 
@@ -225,15 +253,31 @@ export function apply(ctx: Context, config: Config) {
225
253
  })
226
254
 
227
255
  // Scheduler
256
+ let skipFirstBroadcast = config.steamDisableBroadcastOnStartup
228
257
  ctx.setInterval(async () => {
229
- await broadcast(ctx)
258
+ if (skipFirstBroadcast) {
259
+ await seedStatusCache(ctx)
260
+ skipFirstBroadcast = false
261
+ return
262
+ }
263
+ await broadcast(ctx, config)
230
264
  }, config.steamRequestInterval * 1000)
231
265
  }
232
266
 
233
267
  // Broadcast Logic
234
268
  const statusCache = new Map<string, any>()
235
269
 
236
- async function broadcast(ctx: Context) {
270
+ async function seedStatusCache(ctx: Context) {
271
+ const binds = await ctx.database.get('steam_bind', {})
272
+ if (!binds.length) return
273
+ const steamIds = [...new Set(binds.map(b => b.steamId))]
274
+ const summaries = await ctx.steam.getPlayerSummaries(steamIds)
275
+ for (const player of summaries) {
276
+ statusCache.set(player.steamid, player)
277
+ }
278
+ }
279
+
280
+ async function broadcast(ctx: Context, config: Config) {
237
281
  const channels = await ctx.database.get('steam_channel', { enable: true })
238
282
  if (channels.length === 0) return
239
283
 
@@ -274,12 +318,13 @@ async function broadcast(ctx: Context) {
274
318
  }
275
319
 
276
320
  if (msgs.length > 0) {
277
- const bot = ctx.bots[0]
321
+ const botKey = channel.platform && channel.assignee ? `${channel.platform}:${channel.assignee}` : undefined
322
+ const bot = botKey ? ctx.bots[botKey] : Object.values(ctx.bots)[0]
278
323
  if (!bot) continue
279
324
 
280
- if (ctx.config.steamBroadcastType === 'none') {
325
+ if (config.steamBroadcastType === 'none') {
281
326
  await bot.sendMessage(channel.id, msgs.join('\n'))
282
- } else if (ctx.config.steamBroadcastType === 'part') {
327
+ } else if (config.steamBroadcastType === 'part') {
283
328
  if (startGamingPlayers.length > 0) {
284
329
  const images = await Promise.all(startGamingPlayers.map(p => ctx.drawer.drawStartGaming(p, p.nickname)))
285
330
  const combined = await ctx.drawer.concatImages(images)
@@ -288,7 +333,7 @@ async function broadcast(ctx: Context) {
288
333
  } else {
289
334
  await bot.sendMessage(channel.id, msgs.join('\n'))
290
335
  }
291
- } else if (ctx.config.steamBroadcastType === 'all') {
336
+ } else if (config.steamBroadcastType === 'all') {
292
337
  const channelPlayers = channelBinds.map(b => currentMap.get(b.steamId)).filter(Boolean) as any[]
293
338
  const parentAvatar = channel.avatar ? Buffer.from(channel.avatar, 'base64') : await ctx.drawer.getDefaultAvatar()
294
339
  const image = await ctx.drawer.drawFriendsStatus(parentAvatar, channel.name || channel.id, channelPlayers, channelBinds)
@@ -0,0 +1,60 @@
1
+ export default {
2
+ commands: {
3
+ steam: {
4
+ bind: {
5
+ messages: {
6
+ invalid_id: '请输入有效的 Steam ID。',
7
+ id_not_found: '无法找到该 Steam ID。',
8
+ bind_success: '绑定成功!Steam ID: {0}',
9
+ error: '发生错误。',
10
+ },
11
+ },
12
+ unbind: {
13
+ messages: {
14
+ unbind_success: '解绑成功。',
15
+ not_bound: '你还没有绑定 Steam ID。',
16
+ error: '发生错误。',
17
+ },
18
+ },
19
+ info: {
20
+ messages: {
21
+ user_not_found: '未找到用户信息。',
22
+ error: '发生错误。',
23
+ },
24
+ },
25
+ check: {
26
+ messages: {
27
+ no_binds: '本群尚无绑定用户。',
28
+ api_error: '连接 Steam API 失败。',
29
+ error: '发生错误。',
30
+ },
31
+ },
32
+ enable: {
33
+ messages: {
34
+ enable_success: '已开启本群播报。',
35
+ error: '发生错误。',
36
+ },
37
+ },
38
+ disable: {
39
+ messages: {
40
+ disable_success: '已关闭本群播报。',
41
+ error: '发生错误。',
42
+ },
43
+ },
44
+ update: {
45
+ messages: {
46
+ args_missing: '参数缺失。',
47
+ update_success: '更新群信息成功。',
48
+ error: '发生错误。',
49
+ },
50
+ },
51
+ nickname: {
52
+ messages: {
53
+ not_bound: '你还没有绑定 Steam ID。',
54
+ nickname_set: '昵称已设置为 {0}。',
55
+ error: '发生错误。',
56
+ },
57
+ },
58
+ },
59
+ },
60
+ }