koishi-plugin-bilibili-notify 1.0.13 → 1.1.0-alpha.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/lib/biliAPI.d.ts CHANGED
@@ -12,8 +12,10 @@ declare class BiliAPI extends Service {
12
12
  client: any;
13
13
  loginData: any;
14
14
  loginNotifier: Notifier;
15
+ refreshCookieTimer: Function;
15
16
  constructor(ctx: Context);
16
17
  protected start(): void | Promise<void>;
18
+ test_refresh_token(): Promise<void>;
17
19
  getServerUTCTime(): Promise<number>;
18
20
  getTimeNow(): Promise<any>;
19
21
  getUserSpaceDynamic(mid: string): Promise<any>;
@@ -24,6 +26,7 @@ declare class BiliAPI extends Service {
24
26
  getLoginStatus(qrcodeKey: string): Promise<any>;
25
27
  getLiveRoomInfo(roomId: string): Promise<any>;
26
28
  getMasterInfo(mid: string): Promise<any>;
29
+ enableRefreshCookiesDetect(refreshToken: string, csrf?: string): void;
27
30
  disposeNotifier(): void;
28
31
  createNewClient(): void;
29
32
  getCookies(): string;
package/lib/biliAPI.js CHANGED
@@ -25,6 +25,7 @@ class BiliAPI extends koishi_1.Service {
25
25
  client;
26
26
  loginData;
27
27
  loginNotifier;
28
+ refreshCookieTimer;
28
29
  constructor(ctx) {
29
30
  super(ctx, 'biliAPI');
30
31
  }
@@ -35,6 +36,50 @@ class BiliAPI extends koishi_1.Service {
35
36
  this.loadCookiesFromDatabase();
36
37
  // this.logger.info('BiliAPI已被注册到Context中')
37
38
  }
39
+ async test_refresh_token() {
40
+ const publicKey = await crypto.subtle.importKey("jwk", {
41
+ kty: "RSA",
42
+ n: "y4HdjgJHBlbaBN04VERG4qNBIFHP6a3GozCl75AihQloSWCXC5HDNgyinEnhaQ_4-gaMud_GF50elYXLlCToR9se9Z8z433U3KjM-3Yx7ptKkmQNAMggQwAVKgq3zYAoidNEWuxpkY_mAitTSRLnsJW-NCTa0bqBFF6Wm1MxgfE",
43
+ e: "AQAB",
44
+ }, { name: "RSA-OAEP", hash: "SHA-256" }, true, ["encrypt"]);
45
+ async function getCorrespondPath(timestamp) {
46
+ const data = new TextEncoder().encode(`refresh_${timestamp}`);
47
+ const encrypted = new Uint8Array(await crypto.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data));
48
+ return encrypted.reduce((str, c) => str + c.toString(16).padStart(2, "0"), "");
49
+ }
50
+ const ts = Date.now();
51
+ const correspondPath = await getCorrespondPath(ts);
52
+ const { data } = await this.client.get(`https://www.bilibili.com/correspond/1/${correspondPath}`);
53
+ // 创建一个虚拟的DOM元素
54
+ const { document } = new jsdom_1.JSDOM(data).window;
55
+ // 提取标签name为1-name的内容
56
+ const targetElement = document.getElementById('1-name');
57
+ const refresh_csrf = targetElement ? targetElement.textContent : null;
58
+ // 获取csrf
59
+ let csrf;
60
+ const cookies = JSON.parse(this.getCookies());
61
+ cookies.forEach(cookie => {
62
+ if (cookie.key === 'bili_jct')
63
+ csrf = cookie.value;
64
+ });
65
+ // 读取数据库获取cookies
66
+ const database = (await this.ctx.database.get('loginBili', 1))[0];
67
+ // 获取refreshToken
68
+ const refresh_token = this.ctx.wbi.decrypt(database.bili_refresh_token);
69
+ // 发送请求
70
+ // const { data: refreshData } = await this.client.post(`https://passport.bilibili.com/x/passport-login/web/cookie/refresh?csrf=${csrf}&refresh_csrf=${refresh_csrf}&source=main_web&refresh_token=${refresh_token}`)
71
+ const { data: refreshData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/cookie/refresh', {
72
+ csrf,
73
+ refresh_csrf,
74
+ source: 'main_web',
75
+ refresh_token
76
+ }, {
77
+ headers: {
78
+ 'Content-Type': 'application/x-www-form-urlencoded',
79
+ }
80
+ });
81
+ console.log(refreshData);
82
+ }
38
83
  async getServerUTCTime() {
39
84
  try {
40
85
  const { data } = await this.client.get(GET_SERVER_UTC_TIME);
@@ -135,13 +180,33 @@ class BiliAPI extends koishi_1.Service {
135
180
  throw new Error('网络异常,本次请求失败!');
136
181
  }
137
182
  }
183
+ enableRefreshCookiesDetect(refreshToken, csrf) {
184
+ // 获取cookies
185
+ const cookies = JSON.parse(this.getCookies());
186
+ // 获取csrf
187
+ if (!csrf) {
188
+ cookies.find(cookie => {
189
+ // 获取key为bili_jct的值
190
+ if (cookie.key === 'bili_jct') {
191
+ csrf = cookie.value;
192
+ return true;
193
+ }
194
+ });
195
+ }
196
+ // 判断之前是否启动检测
197
+ this.refreshCookieTimer && this.refreshCookieTimer();
198
+ // Open scheduled tasks and check if token need refresh
199
+ this.refreshCookieTimer = this.ctx.setInterval(() => {
200
+ this.checkIfTokenNeedRefresh(refreshToken, csrf);
201
+ }, 43200000);
202
+ }
138
203
  disposeNotifier() { this.loginNotifier && this.loginNotifier.dispose(); }
139
204
  createNewClient() {
140
205
  this.jar = new tough_cookie_1.CookieJar();
141
206
  this.client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({
142
207
  jar: this.jar,
143
208
  headers: {
144
- 'Content-Type': 'application/json; charset=utf-8',
209
+ 'Content-Type': 'application/json',
145
210
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
146
211
  'Origin': 'https://www.bilibili.com',
147
212
  'Referer': 'https://www.bilibili.com/'
@@ -203,13 +268,27 @@ class BiliAPI extends koishi_1.Service {
203
268
  });
204
269
  // restart plugin check
205
270
  this.checkIfTokenNeedRefresh(decryptedRefreshToken, csrf);
206
- // Open scheduled tasks and check if token need refresh
207
- this.ctx.setInterval(() => {
208
- this.checkIfTokenNeedRefresh(decryptedRefreshToken, csrf);
209
- }, 43200000);
271
+ // enable refresh cookies detect
272
+ this.enableRefreshCookiesDetect(decryptedRefreshToken, csrf);
210
273
  }
211
274
  async checkIfTokenNeedRefresh(refreshToken, csrf, times = 0) {
275
+ // 定义数据
212
276
  let data;
277
+ // 定义方法
278
+ const notifyAndError = (info) => {
279
+ // 设置控制台通知
280
+ this.loginNotifier = this.ctx.notifier.create({
281
+ type: 'warning',
282
+ content: info
283
+ });
284
+ // 重置为未登录状态
285
+ this.createNewClient();
286
+ // 关闭定时器
287
+ this.refreshCookieTimer();
288
+ // 抛出错误
289
+ throw new Error(info);
290
+ };
291
+ // 尝试获取Cookieinfo
213
292
  try {
214
293
  const { data: cookieData } = await this.getCookieInfo(refreshToken);
215
294
  data = cookieData;
@@ -227,17 +306,21 @@ class BiliAPI extends koishi_1.Service {
227
306
  // 不需要刷新,直接返回
228
307
  if (!data.refresh)
229
308
  return;
309
+ // 定义Key
230
310
  const publicKey = await crypto.subtle.importKey("jwk", {
231
311
  kty: "RSA",
232
312
  n: "y4HdjgJHBlbaBN04VERG4qNBIFHP6a3GozCl75AihQloSWCXC5HDNgyinEnhaQ_4-gaMud_GF50elYXLlCToR9se9Z8z433U3KjM-3Yx7ptKkmQNAMggQwAVKgq3zYAoidNEWuxpkY_mAitTSRLnsJW-NCTa0bqBFF6Wm1MxgfE",
233
313
  e: "AQAB",
234
314
  }, { name: "RSA-OAEP", hash: "SHA-256" }, true, ["encrypt"]);
315
+ // 定义获取CorrespondPath方法
235
316
  async function getCorrespondPath(timestamp) {
236
317
  const data = new TextEncoder().encode(`refresh_${timestamp}`);
237
318
  const encrypted = new Uint8Array(await crypto.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data));
238
319
  return encrypted.reduce((str, c) => str + c.toString(16).padStart(2, "0"), "");
239
320
  }
240
- const correspondPath = await getCorrespondPath(data.timestamp);
321
+ // 获取CorrespondPath
322
+ const ts = Date.now();
323
+ const correspondPath = await getCorrespondPath(ts);
241
324
  // 获取refresh_csrf
242
325
  const { data: refreshCsrfHtml } = await this.client.get(`https://www.bilibili.com/correspond/1/${correspondPath}`);
243
326
  // 创建一个虚拟的DOM元素
@@ -247,19 +330,15 @@ class BiliAPI extends koishi_1.Service {
247
330
  const refresh_csrf = targetElement ? targetElement.textContent : null;
248
331
  // 发送刷新请求
249
332
  const { data: refreshData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/cookie/refresh', {
250
- csrf: csrf.trim(),
333
+ csrf,
251
334
  refresh_csrf,
252
335
  source: 'main_web',
253
336
  refresh_token: refreshToken
337
+ }, {
338
+ headers: {
339
+ 'Content-Type': 'application/x-www-form-urlencoded',
340
+ }
254
341
  });
255
- const notifyAndError = (info) => {
256
- // 设置控制台通知
257
- this.loginNotifier = this.ctx.notifier.create({
258
- type: 'warning',
259
- content: info
260
- });
261
- throw new Error(info);
262
- };
263
342
  // 检查是否有其他问题
264
343
  switch (refreshData.code) {
265
344
  // 账号未登录
@@ -274,7 +353,7 @@ class BiliAPI extends koishi_1.Service {
274
353
  }
275
354
  }
276
355
  // 更新 新的cookies和refresh_token
277
- const encryptedCookies = this.ctx.wbi.encrypt(this.ctx.biliAPI.getCookies());
356
+ const encryptedCookies = this.ctx.wbi.encrypt(this.getCookies());
278
357
  const encryptedRefreshToken = this.ctx.wbi.encrypt(refreshData.data.refresh_token);
279
358
  await this.ctx.database.upsert('loginBili', [{
280
359
  id: 1,
@@ -283,12 +362,6 @@ class BiliAPI extends koishi_1.Service {
283
362
  }]);
284
363
  // Get new csrf from cookies
285
364
  let newCsrf;
286
- /* this.jar.store.getAllCookies((err, c) => {
287
- if (err) throw err;
288
- c.forEach(cookie => {
289
- if (cookie.key === 'bili_jct') newCsrf = cookie.value
290
- });
291
- }) */
292
365
  this.jar.serializeSync().cookies.forEach(cookie => {
293
366
  if (cookie.key === 'bili_jct')
294
367
  newCsrf = cookie.value;
@@ -297,6 +370,10 @@ class BiliAPI extends koishi_1.Service {
297
370
  const { data: aceeptData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/confirm/refresh', {
298
371
  csrf: newCsrf,
299
372
  refresh_token: refreshToken
373
+ }, {
374
+ headers: {
375
+ 'Content-Type': 'application/x-www-form-urlencoded',
376
+ }
300
377
  });
301
378
  // 检查是否有其他问题
302
379
  switch (aceeptData.code) {
@@ -20,6 +20,7 @@ declare class ComRegister {
20
20
  qqBot: Bot<Context>;
21
21
  qqguildBot: Bot<Context>;
22
22
  oneBot: Bot<Context>;
23
+ redBot: Bot<Context>;
23
24
  constructor(ctx: Context, config: ComRegister.Config);
24
25
  dynamicDetect(ctx: Context, bot: Bot<Context>, guildId: string, uid: string): () => Promise<void>;
25
26
  liveDetect(ctx: Context, bot: Bot<Context>, guildId: string, roomId: string): () => Promise<string[]>;
@@ -33,6 +34,7 @@ declare class ComRegister {
33
34
  declare namespace ComRegister {
34
35
  interface Config {
35
36
  unlockSubLimits: boolean;
37
+ liveStartAtAll: boolean;
36
38
  pushTime: number;
37
39
  liveLoopTime: number;
38
40
  dynamicLoopTime: number;
@@ -27,15 +27,20 @@ class ComRegister {
27
27
  qqguildBot;
28
28
  // OneBot机器人
29
29
  oneBot;
30
+ // Red机器人
31
+ redBot;
30
32
  constructor(ctx, config) {
31
33
  this.logger = ctx.logger('commandRegister');
32
34
  this.config = config;
33
- // 拿到QQ群机器人
34
- this.qqBot = ctx.bots.find(bot => bot.platform === 'qq');
35
- // 拿到QQ频道机器人
36
- this.qqguildBot = ctx.bots.find(bot => bot.platform === 'qqguild');
37
- // 拿到OneBot机器人
38
- this.oneBot = ctx.bots.find(bot => bot.platform === 'onebot');
35
+ // 拿到各类机器人
36
+ ctx.bots.forEach(bot => {
37
+ switch (bot.platform) {
38
+ case 'qq': this.qqBot = bot;
39
+ case 'qqguild': this.qqguildBot = bot;
40
+ case 'onebot': this.oneBot = bot;
41
+ case ' red': this.redBot = bot;
42
+ }
43
+ });
39
44
  // 从数据库获取订阅
40
45
  this.getSubFromDatabase(ctx);
41
46
  /* const testCom = ctx.command('test', { hidden: true, permissions: ['authority:5'] })
@@ -45,7 +50,7 @@ class ComRegister {
45
50
  .action(async () => {
46
51
  this.logger.info('调用test cookies指令')
47
52
  // await ctx.biliAPI.loadCookiesFromDatabase()
48
- console.log(ctx.biliAPI.getCookies());
53
+ console.log(JSON.parse(ctx.biliAPI.getCookies()));
49
54
  })
50
55
 
51
56
  testCom
@@ -120,6 +125,14 @@ class ComRegister {
120
125
  .example('test utc')
121
126
  .action(async ({ session }) => {
122
127
  session.send((await ctx.biliAPI.getServerUTCTime()).toString())
128
+ })
129
+
130
+ testCom
131
+ .subcommand('.refresh')
132
+ .usage('测试cookie刷新方法')
133
+ .example('test refresh')
134
+ .action(async ({ session }) => {
135
+ ctx.biliAPI.test_refresh_token()
123
136
  }) */
124
137
  const biliCom = ctx.command('bili', 'bili-notify插件相关指令', { permissions: ['authority:3'] });
125
138
  biliCom.subcommand('.login', '登录B站之后才可以进行之后的操作')
@@ -154,43 +167,57 @@ class ComRegister {
154
167
  });
155
168
  // 检查之前是否存在登录定时器
156
169
  this.loginTimer && this.loginTimer();
170
+ // 设置flag
171
+ let flag = true;
157
172
  // 发起登录请求检查登录状态
158
173
  this.loginTimer = ctx.setInterval(async () => {
159
- let loginContent;
160
174
  try {
161
- loginContent = await ctx.biliAPI.getLoginStatus(content.data.qrcode_key);
162
- }
163
- catch (e) {
164
- this.logger.error(e);
165
- return;
166
- }
167
- if (loginContent.code !== 0) {
168
- this.loginTimer();
169
- return await session.send('登录失败请联系管理员解决');
170
- }
171
- if (loginContent.data.code === 86038) {
172
- this.loginTimer();
173
- return await session.send('二维码已失效,请重新登录');
175
+ // 判断上一个循环是否完成
176
+ if (!flag)
177
+ return;
178
+ flag = false;
179
+ // 获取登录信息
180
+ let loginContent;
181
+ try {
182
+ loginContent = await ctx.biliAPI.getLoginStatus(content.data.qrcode_key);
183
+ }
184
+ catch (e) {
185
+ this.logger.error(e);
186
+ return;
187
+ }
188
+ if (loginContent.code !== 0) {
189
+ this.loginTimer();
190
+ return await session.send('登录失败请重试');
191
+ }
192
+ if (loginContent.data.code === 86038) {
193
+ this.loginTimer();
194
+ return await session.send('二维码已失效,请重新登录');
195
+ }
196
+ if (loginContent.data.code === 0) { // 登录成功
197
+ const encryptedCookies = ctx.wbi.encrypt(ctx.biliAPI.getCookies());
198
+ const encryptedRefreshToken = ctx.wbi.encrypt(loginContent.data.refresh_token);
199
+ await ctx.database.upsert('loginBili', [{
200
+ id: 1,
201
+ bili_cookies: encryptedCookies,
202
+ bili_refresh_token: encryptedRefreshToken
203
+ }]);
204
+ // 销毁定时器
205
+ this.loginTimer();
206
+ // 订阅之前的订阅
207
+ await this.getSubFromDatabase(ctx);
208
+ // 清除控制台通知
209
+ ctx.biliAPI.disposeNotifier();
210
+ // 发送成功登录推送
211
+ await session.send('登录成功');
212
+ // bili show
213
+ await session.execute('bili show');
214
+ // 开启cookies刷新检测
215
+ ctx.biliAPI.enableRefreshCookiesDetect(loginContent.data.refresh_token);
216
+ return;
217
+ }
174
218
  }
175
- if (loginContent.data.code === 0) { // 登录成功
176
- const encryptedCookies = ctx.wbi.encrypt(ctx.biliAPI.getCookies());
177
- const encryptedRefreshToken = ctx.wbi.encrypt(loginContent.data.refresh_token);
178
- await ctx.database.upsert('loginBili', [{
179
- id: 1,
180
- bili_cookies: encryptedCookies,
181
- bili_refresh_token: encryptedRefreshToken
182
- }]);
183
- // 销毁定时器
184
- this.loginTimer();
185
- // 订阅之前的订阅
186
- await this.getSubFromDatabase(ctx);
187
- // 清除控制台通知
188
- ctx.biliAPI.disposeNotifier();
189
- // 发送成功登录推送
190
- await session.send('登录成功');
191
- // bili show
192
- await session.execute('bili show');
193
- return;
219
+ finally {
220
+ flag = true;
194
221
  }
195
222
  }, 1000);
196
223
  });
@@ -315,11 +342,12 @@ class ComRegister {
315
342
  if (!liveMsg && !dynamicMsg) {
316
343
  return '您未订阅该UP的任何消息';
317
344
  }
318
- // 设置群号
319
- if (!guildId) { // 没有输入群号,默认当前聊天环境
345
+ // 设置频道号
346
+ if (!guildId) { // 没有输入频道号,默认当前聊天环境
320
347
  switch (session.event.platform) {
321
- case 'qqguild':
348
+ case 'red':
322
349
  case 'onebot':
350
+ case 'qqguild':
323
351
  guildId = session.event.channel.id;
324
352
  break;
325
353
  case 'qq':
@@ -413,6 +441,9 @@ class ComRegister {
413
441
  case 'onebot':
414
442
  bot = this.oneBot;
415
443
  break;
444
+ case 'red':
445
+ bot = this.redBot;
446
+ break;
416
447
  default: return '非法调用';
417
448
  }
418
449
  // 开始循环检测
@@ -451,6 +482,9 @@ class ComRegister {
451
482
  case 'onebot':
452
483
  bot = this.oneBot;
453
484
  break;
485
+ case 'red':
486
+ bot = this.redBot;
487
+ break;
454
488
  default: return '非法调用';
455
489
  }
456
490
  // 开始循环检测
@@ -753,6 +787,11 @@ class ComRegister {
753
787
  uData = userData;
754
788
  // 发送直播通知卡片
755
789
  sendLiveNotifyCard(data, uData, LiveType.StartBroadcasting);
790
+ // 判断是否需要@全体成员
791
+ if (this.config.liveStartAtAll) {
792
+ // 发送@全体成员通知
793
+ bot.sendMessage(guildId, (0, jsx_runtime_1.jsx)("at", { type: "all" }));
794
+ }
756
795
  }
757
796
  else { // 还在直播
758
797
  if (this.config.pushTime > 0) {
@@ -881,6 +920,9 @@ class ComRegister {
881
920
  case 'onebot':
882
921
  bot = this.oneBot;
883
922
  break;
923
+ case 'red':
924
+ bot = this.redBot;
925
+ break;
884
926
  default: {
885
927
  // 本条数据被篡改,删除该条订阅
886
928
  ctx.database.remove('bilibili', { id: sub.id });
@@ -1040,6 +1082,7 @@ class ComRegister {
1040
1082
  (function (ComRegister) {
1041
1083
  ComRegister.Config = koishi_1.Schema.object({
1042
1084
  unlockSubLimits: koishi_1.Schema.boolean().required(),
1085
+ liveStartAtAll: koishi_1.Schema.boolean().required(),
1043
1086
  pushTime: koishi_1.Schema.number().required(),
1044
1087
  liveLoopTime: koishi_1.Schema.number().default(10),
1045
1088
  dynamicLoopTime: koishi_1.Schema.number().default(60),
package/lib/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface Config {
6
6
  key: string;
7
7
  basicSettings: {};
8
8
  unlockSubLimits: boolean;
9
+ liveStartAtAll: boolean;
9
10
  pushTime: number;
10
11
  dynamicCheckNumber: number;
11
12
  dynamicLoopTime: '1分钟' | '2分钟' | '3分钟' | '5分钟';
package/lib/index.js CHANGED
@@ -49,6 +49,10 @@ exports.Config = koishi_1.Schema.object({
49
49
  unlockSubLimits: koishi_1.Schema.boolean()
50
50
  .default(false)
51
51
  .description('解锁3个订阅限制,默认只允许订阅3位UP主。订阅过多用户可能有导致IP暂时被封禁的风险'),
52
+ liveStartAtAll: koishi_1.Schema.boolean()
53
+ .default(false)
54
+ .experimental()
55
+ .description('直播开始时艾特全体成员,默认关闭'),
52
56
  pushTime: koishi_1.Schema.number()
53
57
  .min(0)
54
58
  .max(12)
@@ -61,7 +65,7 @@ exports.Config = koishi_1.Schema.object({
61
65
  .role('slider')
62
66
  .step(1)
63
67
  .default(5)
64
- .description('设定每次检查动态的数量。若订阅的UP主经常在短时间内连着发多条动态可以将该值提高,若订阅的UP主有置顶动态,在计算该值时应-1。默认值为5条'),
68
+ .description('设定每次检查动态的数量。若订阅的UP主经常在短时间内连着发多条动态可以将该值提高,若订阅的UP主有置顶动态,在计算该值时应+1。默认值为5条'),
65
69
  dynamicLoopTime: koishi_1.Schema.union(['1分钟', '2分钟', '3分钟', '5分钟'])
66
70
  .role('')
67
71
  .default('2分钟')
@@ -163,6 +167,7 @@ function apply(ctx, config) {
163
167
  // ctx.plugin(Authority)
164
168
  ctx.plugin(comRegister_1.default, {
165
169
  unlockSubLimits: config.unlockSubLimits,
170
+ liveStartAtAll: config.liveStartAtAll,
166
171
  pushTime: config.pushTime,
167
172
  dynamicCheckNumber: config.dynamicCheckNumber,
168
173
  dynamicLoopTime
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-bilibili-notify",
3
3
  "description": "Koishi bilibili notify plugin",
4
- "version": "1.0.13",
4
+ "version": "1.1.0-alpha.0",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
package/readme.md CHANGED
@@ -81,14 +81,16 @@
81
81
  - ver 1.0.3 修复了一些bug,提供用户自己选择推送卡片字体样式的选项
82
82
  - ver 1.0.4 修复了重复推送的bug,提供用户选择推送卡片渲染方式的选项
83
83
  - ver 1.0.5 修复了用户非法篡改数据库内容可能导致程序异常运行的bug,修复了UP主开播动态推送空白卡片的bug
84
- - ver 1.0.6 修复了转发动态转发信息出现undefinedbug,修复了再次登录订阅显示错误的bug,优化了动态推送的逻辑
85
- - ver 1.0.7 修复了在已登录情况下,再次登录会导致重复订阅和提示用户未订阅任何UP主的提示(实际上已订阅)的bug,新增了订阅对象在控制台的显示,优化了bili show指令的逻辑
84
+ - ver 1.0.6 修复了转发动态转发信息出现`undefined`的bug,修复了再次登录订阅显示错误的bug,优化了动态推送的逻辑
85
+ - ver 1.0.7 修复了在已登录情况下,再次登录会导致重复订阅和提示用户未订阅任何UP主的提示(实际上已订阅)的bug,新增了订阅对象在控制台的显示,优化了`bili show`指令的逻辑
86
86
  - ver 1.0.8 修复了取消订阅的bug
87
87
  - ver 1.0.9 更新请求客户端header信息。优化了动态推送卡片的页面布局,增加了字体大小。提供用户开放订阅数量限制的选项,提供用户移除推送卡片边框的选项。在控制台页面增加订阅信息提示
88
- - ver 1.0.10 增加对onebot的支持,添加动态关键字屏蔽功能
89
- - ver 1.0.11 修复了render渲染模式下,动态重复推送的问题,修复了没有订阅时,控制台空白提示的问题。优化了视频动态缩略图显示不全的问题,优化了部分逻辑。增强容错和增加错误提示
88
+ - ver 1.0.10 增加对`onebot`的支持,添加动态关键字屏蔽功能
89
+ - ver 1.0.11 修复了`render`渲染模式下,动态重复推送的问题,修复了没有订阅时,控制台空白提示的问题。优化了视频动态缩略图显示不全的问题,优化了部分逻辑。增强容错和增加错误提示
90
90
  - ver 1.0.12 提供用户选择动态推送卡片字体增大的选项
91
91
  - ver 1.0.13 修复了直播通知卡片连续发三次的bug,修复了多次调用指令 `bili login` 产生的bug
92
+ - ver 1.0.14 修复了获取二维码,二维码失效后会多次发送提示的bug,新增对`red`的支持,新增开播艾特全体成员功能,优化了部分逻辑
93
+ - ver 1.1.0-alpha.0 修复了直播订阅一段时间过后提示房间不存在的bug,修复了自动登录刷新错误的bug
92
94
 
93
95
  ## 感谢
94
96