yz-yuki-plugin 2.0.5-12 → 2.0.5-13
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/CHANGELOG.md +1 -0
- package/lib/apps/bilibili.js +13 -10
- package/lib/models/bilibili/bilibili.main.api.js +277 -0
- package/lib/models/bilibili/bilibili.main.models.js +36 -217
- package/lib/models/bilibili/bilibili.risk.buid.fp.js +277 -72
- package/lib/models/bilibili/bilibili.risk.wbi.js +49 -8
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
package/lib/apps/bilibili.js
CHANGED
|
@@ -5,7 +5,7 @@ import { BiliQuery } from '../models/bilibili/bilibili.main.query.js';
|
|
|
5
5
|
import { BiliTask } from '../models/bilibili/bilibili.main.task.js';
|
|
6
6
|
import Config from '../utils/config.js';
|
|
7
7
|
import { BiliGetWebData } from '../models/bilibili/bilibili.main.get.web.data.js';
|
|
8
|
-
import { applyLoginQRCode, pollLoginQRCode, saveLoginCookie, postGateway, exitBiliLogin, checkBiliLogin, readSavedCookieItems, saveLocalBiliCk, readSyncCookie, getNewTempCk,
|
|
8
|
+
import { applyLoginQRCode, pollLoginQRCode, saveLoginCookie, postGateway, exitBiliLogin, checkBiliLogin, readSavedCookieItems, saveLocalBiliCk, readSyncCookie, getNewTempCk, saveTempCk } from '../models/bilibili/bilibili.main.models.js';
|
|
9
9
|
|
|
10
10
|
const message = new Messages('message');
|
|
11
11
|
let biliPushData = Config.getConfigData('config', 'bilibili', 'push');
|
|
@@ -171,9 +171,6 @@ message.use(async (e) => {
|
|
|
171
171
|
try {
|
|
172
172
|
const token = await applyLoginQRCode(e);
|
|
173
173
|
let biliLoginCk = await pollLoginQRCode(e, token);
|
|
174
|
-
//let _uuid = readSavedCookieItems(biliLoginCk, ['_uuid'])
|
|
175
|
-
//const buvid_fp = await get_buvid_fp(_uuid);
|
|
176
|
-
//biliLoginCk = buvid_fp + biliLoginCk;
|
|
177
174
|
if (lodash.trim(biliLoginCk).length != 0) {
|
|
178
175
|
await saveLoginCookie(e, biliLoginCk);
|
|
179
176
|
e.reply(`get bilibili LoginCk:成功!`);
|
|
@@ -257,9 +254,7 @@ message.use(async (e) => {
|
|
|
257
254
|
return;
|
|
258
255
|
}
|
|
259
256
|
//筛选ck
|
|
260
|
-
localBiliCookie = await readSavedCookieItems(localBiliCookie, ['buvid3', 'buvid4', '_uuid', 'SESSDATA', 'DedeUserID', 'DedeUserID__ckMd5', 'bili_jct', 'b_nut', 'b_lsid'], false);
|
|
261
|
-
//const buvid_fp = await get_buvid_fp(param._uuid)
|
|
262
|
-
//localBiliCookie = buvid_fp + localBiliCookie; //添加buvid_fp值
|
|
257
|
+
localBiliCookie = await readSavedCookieItems(localBiliCookie, ['buvid3', 'buvid4', '_uuid', 'SESSDATA', 'DedeUserID', 'DedeUserID__ckMd5', 'bili_jct', 'b_nut', 'b_lsid', 'buvid_fp', 'sid'], false);
|
|
263
258
|
await saveLocalBiliCk(localBiliCookie);
|
|
264
259
|
logger.mark(`${e.logFnc} 保存B站cookie成功 [UID:${param.DedeUserID}]`);
|
|
265
260
|
let uidMsg = [`好耶~绑定B站cookie成功:\n${param.DedeUserID}`];
|
|
@@ -322,9 +317,17 @@ message.use(async (e) => {
|
|
|
322
317
|
/** 删除并刷新redis缓存的临时B站ck */
|
|
323
318
|
message.use(async (e) => {
|
|
324
319
|
try {
|
|
325
|
-
await getNewTempCk();
|
|
326
|
-
|
|
327
|
-
|
|
320
|
+
const newTempCk = await getNewTempCk();
|
|
321
|
+
if (newTempCk) {
|
|
322
|
+
await saveTempCk(newTempCk);
|
|
323
|
+
const result = await postGateway(newTempCk);
|
|
324
|
+
const data = await result.data; // 解析校验结果
|
|
325
|
+
if (data?.code !== 0) {
|
|
326
|
+
logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
|
|
327
|
+
}
|
|
328
|
+
else if (data?.code === 0) {
|
|
329
|
+
logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
|
|
330
|
+
}
|
|
328
331
|
e.reply(`~yuki-plugin:\n临时b站ck刷新成功~❤~\n接下来如果获取动态失败,请重启bot(手动或发送指令 #重启)刷新状态~\n如果重启续仍不可用,请考虑 #优纪添加b站登录 吧~`);
|
|
329
332
|
}
|
|
330
333
|
else {
|
|
@@ -23,6 +23,8 @@ class BiliApi {
|
|
|
23
23
|
// 将静态常量赋值给实例属性
|
|
24
24
|
get BILIBIL_API() {
|
|
25
25
|
return {
|
|
26
|
+
//获取服务器端RTC时间戳
|
|
27
|
+
biliServerTimeStamp: 'https://api.live.bilibili.com/xlive/open-interface/v1/rtc/getTimestamp',
|
|
26
28
|
//获取动态资源列表 wbi/无wbi parama = { host_mid: uid, timezone_offset: -480, platform: 'web', features: 'itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote', web_location: "333.999", ...getDmImg(), "x-bili-device-req-json": { "platform": "web", "device": "pc" }, "x-bili-web-req-json": { "spm_id": "333.999" }, w_rid, wts }
|
|
27
29
|
biliDynamicInfoList: `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space`,
|
|
28
30
|
//获取关注数与粉丝数 parama = { vmid: uid }
|
|
@@ -119,6 +121,281 @@ class BiliApi {
|
|
|
119
121
|
'User-Agent': this.USER_AGENT
|
|
120
122
|
};
|
|
121
123
|
}
|
|
124
|
+
/**返回GatWay payload */
|
|
125
|
+
async BILIBILI_BROWSER_DATA(_uuid) {
|
|
126
|
+
return {
|
|
127
|
+
'3064': 1, // ptype, mobile => 2, others => 1
|
|
128
|
+
'5062': `${Date.now()}`, // timestamp
|
|
129
|
+
'03bf': 'https://www.bilibili.com/', // url accessed
|
|
130
|
+
'39c8': '333.999.fp.risk',
|
|
131
|
+
'34f1': '', // target_url, default empty now
|
|
132
|
+
'd402': '', // screenx, default empty
|
|
133
|
+
'654a': '', // screeny, default empty
|
|
134
|
+
'6e7c': '878x1066', // browser_resolution, window.innerWidth || document.body && document.body.clientWidth + "x" + window.innerHeight || document.body && document.body.clientHeight
|
|
135
|
+
'3c43': {
|
|
136
|
+
// 3c43 => msg
|
|
137
|
+
'2673': 0, // hasLiedResolution, window.screen.width < window.screen.availWidth || window.screen.height < window.screen.availHeight
|
|
138
|
+
'5766': 24, // colorDepth, window.screen.colorDepth
|
|
139
|
+
'6527': 0, // addBehavior, !!window.HTMLElement.prototype.addBehavior, html5 api
|
|
140
|
+
'7003': 1, // indexedDb, !!window.indexedDB, html5 api
|
|
141
|
+
'807e': 1, // cookieEnabled, navigator.cookieEnabled
|
|
142
|
+
'b8ce': this.USER_AGENT, // ua "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0",
|
|
143
|
+
'641c': 0, // webdriver, navigator.webdriver, like Selenium
|
|
144
|
+
'07a4': 'zh-CN', // language
|
|
145
|
+
'1c57': 'not available', // deviceMemory in GB, navigator.deviceMemory
|
|
146
|
+
'0bd0': 16, // hardwareConcurrency, navigator.hardwareConcurrency
|
|
147
|
+
'748e': [1920, 1200], // window.screen.width window.screen.height
|
|
148
|
+
'd61f': [1920, 1152], // window.screen.availWidth window.screen.availHeight
|
|
149
|
+
'fc9d': -480, // timezoneOffset, (new Date).getTimezoneOffset()
|
|
150
|
+
'6aa9': 'Asia/Shanghai', //Intl.DateTimeFormat().resolvedOptions().timeZone, // timezone, (new window.Intl.DateTimeFormat).resolvedOptions().timeZone
|
|
151
|
+
'75b8': 1, // sessionStorage, window.sessionStorage, html5 api
|
|
152
|
+
'3b21': 1, // localStorage, window.localStorage, html5 api
|
|
153
|
+
'8a1c': 0, // openDatabase, window.openDatabase, html5 api
|
|
154
|
+
'd52f': 'not available', // cpuClass, navigator.cpuClass
|
|
155
|
+
'adca': this.USER_AGENT.includes('Windows') ? 'Win32' : 'Linux', // platform, navigator.platform
|
|
156
|
+
'80c9': [
|
|
157
|
+
[
|
|
158
|
+
'PDF Viewer',
|
|
159
|
+
'Portable Document Format',
|
|
160
|
+
[
|
|
161
|
+
['application/pdf', 'pdf'],
|
|
162
|
+
['text/pdf', 'pdf']
|
|
163
|
+
]
|
|
164
|
+
],
|
|
165
|
+
[
|
|
166
|
+
'Chrome PDF Viewer',
|
|
167
|
+
'Portable Document Format',
|
|
168
|
+
[
|
|
169
|
+
['application/pdf', 'pdf'],
|
|
170
|
+
['text/pdf', 'pdf']
|
|
171
|
+
]
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
'Chromium PDF Viewer',
|
|
175
|
+
'Portable Document Format',
|
|
176
|
+
[
|
|
177
|
+
['application/pdf', 'pdf'],
|
|
178
|
+
['text/pdf', 'pdf']
|
|
179
|
+
]
|
|
180
|
+
],
|
|
181
|
+
[
|
|
182
|
+
'Microsoft Edge PDF Viewer',
|
|
183
|
+
'Portable Document Format',
|
|
184
|
+
[
|
|
185
|
+
['application/pdf', 'pdf'],
|
|
186
|
+
['text/pdf', 'pdf']
|
|
187
|
+
]
|
|
188
|
+
],
|
|
189
|
+
[
|
|
190
|
+
'WebKit built-in PDF',
|
|
191
|
+
'Portable Document Format',
|
|
192
|
+
[
|
|
193
|
+
['application/pdf', 'pdf'],
|
|
194
|
+
['text/pdf', 'pdf']
|
|
195
|
+
]
|
|
196
|
+
]
|
|
197
|
+
], // plugins
|
|
198
|
+
'13ab': 'f3YAAAAASUVORK5CYII=', // canvas fingerprint
|
|
199
|
+
'bfe9': 'kABYpRAGAVYzWJooB9Bf4P+UortSvxRY0AAAAASUVORK5CYII=', // webgl_str
|
|
200
|
+
'a3c1': [
|
|
201
|
+
'extensions:ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_sRGB;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_provoking_vertex',
|
|
202
|
+
'webgl aliased line width range:[1, 1]',
|
|
203
|
+
'webgl aliased point size range:[1, 1024]',
|
|
204
|
+
'webgl alpha bits:8',
|
|
205
|
+
'webgl antialiasing:yes',
|
|
206
|
+
'webgl blue bits:8',
|
|
207
|
+
'webgl depth bits:24',
|
|
208
|
+
'webgl green bits:8',
|
|
209
|
+
'webgl max anisotropy:16',
|
|
210
|
+
'webgl max combined texture image units:32',
|
|
211
|
+
'webgl max cube map texture size:16384',
|
|
212
|
+
'webgl max fragment uniform vectors:1024',
|
|
213
|
+
'webgl max render buffer size:16384',
|
|
214
|
+
'webgl max texture image units:16',
|
|
215
|
+
'webgl max texture size:16384',
|
|
216
|
+
'webgl max varying vectors:30',
|
|
217
|
+
'webgl max vertex attribs:16',
|
|
218
|
+
'webgl max vertex texture image units:16',
|
|
219
|
+
'webgl max vertex uniform vectors:4096',
|
|
220
|
+
'webgl max viewport dims:[32767, 32767]',
|
|
221
|
+
'webgl red bits:8',
|
|
222
|
+
'webgl renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar',
|
|
223
|
+
'webgl shading language version:WebGL GLSL ES 1.0',
|
|
224
|
+
'webgl stencil bits:0',
|
|
225
|
+
'webgl vendor:Mozilla',
|
|
226
|
+
'webgl version:WebGL 1.0',
|
|
227
|
+
'webgl unmasked vendor:Google Inc. (Intel)',
|
|
228
|
+
'webgl unmasked renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar',
|
|
229
|
+
'webgl vertex shader high float precision:23',
|
|
230
|
+
'webgl vertex shader high float precision rangeMin:127',
|
|
231
|
+
'webgl vertex shader high float precision rangeMax:127',
|
|
232
|
+
'webgl vertex shader medium float precision:23',
|
|
233
|
+
'webgl vertex shader medium float precision rangeMin:127',
|
|
234
|
+
'webgl vertex shader medium float precision rangeMax:127',
|
|
235
|
+
'webgl vertex shader low float precision:23',
|
|
236
|
+
'webgl vertex shader low float precision rangeMin:127',
|
|
237
|
+
'webgl vertex shader low float precision rangeMax:127',
|
|
238
|
+
'webgl fragment shader high float precision:23',
|
|
239
|
+
'webgl fragment shader high float precision rangeMin:127',
|
|
240
|
+
'webgl fragment shader high float precision rangeMax:127',
|
|
241
|
+
'webgl fragment shader medium float precision:23',
|
|
242
|
+
'webgl fragment shader medium float precision rangeMin:127',
|
|
243
|
+
'webgl fragment shader medium float precision rangeMax:127',
|
|
244
|
+
'webgl fragment shader low float precision:23',
|
|
245
|
+
'webgl fragment shader low float precision rangeMin:127',
|
|
246
|
+
'webgl fragment shader low float precision rangeMax:127',
|
|
247
|
+
'webgl vertex shader high int precision:0',
|
|
248
|
+
'webgl vertex shader high int precision rangeMin:31',
|
|
249
|
+
'webgl vertex shader high int precision rangeMax:30',
|
|
250
|
+
'webgl vertex shader medium int precision:0',
|
|
251
|
+
'webgl vertex shader medium int precision rangeMin:31',
|
|
252
|
+
'webgl vertex shader medium int precision rangeMax:30',
|
|
253
|
+
'webgl vertex shader low int precision:0',
|
|
254
|
+
'webgl vertex shader low int precision rangeMin:31',
|
|
255
|
+
'webgl vertex shader low int precision rangeMax:30',
|
|
256
|
+
'webgl fragment shader high int precision:0',
|
|
257
|
+
'webgl fragment shader high int precision rangeMin:31',
|
|
258
|
+
'webgl fragment shader high int precision rangeMax:30',
|
|
259
|
+
'webgl fragment shader medium int precision:0',
|
|
260
|
+
'webgl fragment shader medium int precision rangeMin:31',
|
|
261
|
+
'webgl fragment shader medium int precision rangeMax:30',
|
|
262
|
+
'webgl fragment shader low int precision:0',
|
|
263
|
+
'webgl fragment shader low int precision rangeMin:31',
|
|
264
|
+
'webgl fragment shader low int precision rangeMax:30'
|
|
265
|
+
], // webgl_params, cab be set to [] if webgl is not supported
|
|
266
|
+
'6bc5': 'Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar', // webglVendorAndRenderer
|
|
267
|
+
'ed31': 0,
|
|
268
|
+
'72bd': 0,
|
|
269
|
+
'097b': 0,
|
|
270
|
+
'52cd': [0, 0, 0],
|
|
271
|
+
'a658': [
|
|
272
|
+
'Arial',
|
|
273
|
+
'Arial Black',
|
|
274
|
+
'Calibri',
|
|
275
|
+
'Cambria',
|
|
276
|
+
'Cambria Math',
|
|
277
|
+
'Comic Sans MS',
|
|
278
|
+
'Consolas',
|
|
279
|
+
'Courier',
|
|
280
|
+
'Courier New',
|
|
281
|
+
'Georgia',
|
|
282
|
+
'Helvetica',
|
|
283
|
+
'Impact',
|
|
284
|
+
'Lucida Console',
|
|
285
|
+
'Lucida Sans Unicode',
|
|
286
|
+
'Microsoft Sans Serif',
|
|
287
|
+
'MS Gothic',
|
|
288
|
+
'MS PGothic',
|
|
289
|
+
'MS Sans Serif',
|
|
290
|
+
'MS Serif',
|
|
291
|
+
'Palatino Linotype',
|
|
292
|
+
'Segoe Print',
|
|
293
|
+
'Segoe Script',
|
|
294
|
+
'Segoe UI',
|
|
295
|
+
'Segoe UI Light',
|
|
296
|
+
'Segoe UI Symbol',
|
|
297
|
+
'Tahoma',
|
|
298
|
+
'Times',
|
|
299
|
+
'Times New Roman',
|
|
300
|
+
'Trebuchet MS',
|
|
301
|
+
'Verdana',
|
|
302
|
+
'Wingdings'
|
|
303
|
+
],
|
|
304
|
+
'd02f': '35.749972093850374'
|
|
305
|
+
},
|
|
306
|
+
'54ef': {
|
|
307
|
+
'in_new_ab ': true,
|
|
308
|
+
'ab_version ': {
|
|
309
|
+
'waterfall_article ': 'SHOW '
|
|
310
|
+
},
|
|
311
|
+
'ab_split_num ': {
|
|
312
|
+
'waterfall_article ': 0
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
'8b94': '',
|
|
316
|
+
'df35': `${_uuid}`, // _uuid, set from cookie, generated by client side(algorithm remains unknown)
|
|
317
|
+
'07a4': 'zh-CN',
|
|
318
|
+
'5f45': null,
|
|
319
|
+
'db46': 0
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
/**返回Bilibili Fingerprint data */
|
|
323
|
+
BILIBILI_FINGERPRINT_DATA(_uuid) {
|
|
324
|
+
return {
|
|
325
|
+
userAgent: this.USER_AGENT, // 用户代理
|
|
326
|
+
webdriver: false, // 是否是 WebDriver(例如 Selenium)
|
|
327
|
+
language: 'zh-CN', // 浏览器语言
|
|
328
|
+
colorDepth: 24, // 屏幕颜色深度
|
|
329
|
+
deviceMemory: 'not available', // 设备内存(GB)
|
|
330
|
+
pixelRatio: 2, // 设备像素比
|
|
331
|
+
hardwareConcurrency: 8, // 处理器核心数量
|
|
332
|
+
screenResolution: '1920x1200', // 屏幕分辨率
|
|
333
|
+
availableScreenResolution: '1920x1152', // 可用屏幕分辨率
|
|
334
|
+
timezoneOffset: -480, // 时区偏移,单位为分钟
|
|
335
|
+
timezone: 'Asia/Shanghai', // 时区
|
|
336
|
+
sessionStorage: true, // 是否支持 sessionStorage
|
|
337
|
+
localStorage: true, // 是否支持 localStorage
|
|
338
|
+
indexedDb: true, // 是否支持 IndexedDB
|
|
339
|
+
addBehavior: false, // 是否支持 addBehavior
|
|
340
|
+
openDatabase: false, // 是否支持 openDatabase
|
|
341
|
+
cpuClass: 'not available', // CPU 类型amd 或 intel 或 not available
|
|
342
|
+
platform: this.USER_AGENT.includes('Windows') ? 'Win32' : 'Linux', // 操作系统平台,例如 Windows,Linux,Mac
|
|
343
|
+
doNotTrack: null, // DNT 设置,通常是 `navigator.doNotTrack`
|
|
344
|
+
plugins: [
|
|
345
|
+
{ name: 'PDF Viewer', description: 'Portable Document Format', mimeTypes: [['application/pdf', 'pdf']] },
|
|
346
|
+
{ name: 'Chrome PDF Viewer', description: 'Portable Document Format', mimeTypes: [['application/pdf', 'pdf']] },
|
|
347
|
+
{ name: 'Chromium PDF Viewer', description: 'Portable Document Format', mimeTypes: [['application/pdf', 'pdf']] },
|
|
348
|
+
{ name: 'Microsoft Edge PDF Viewer', description: 'Portable Document Format', mimeTypes: [['application/pdf', 'pdf']] },
|
|
349
|
+
{ name: 'WebKit built-in PDF', description: 'Portable Document Format', mimeTypes: [['application/pdf', 'pdf']] }
|
|
350
|
+
],
|
|
351
|
+
canvas: 'f3YAAAAASUVORK5CYII=', // Canvas 指纹
|
|
352
|
+
webgl: 'kABYpRAGAVYzWJooB9Bf4P+UortSvxRY0AAAAASUVORK5CYII=', // WebGL 参数
|
|
353
|
+
webglVendorAndRenderer: 'Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar', // WebGL 的厂商和渲染器信息
|
|
354
|
+
adBlock: false, // 是否检测到广告拦截器
|
|
355
|
+
hasLiedLanguages: false, // 是否谎称语言
|
|
356
|
+
hasLiedResolution: false, // 是否谎称分辨率
|
|
357
|
+
hasLiedOs: false, // 是否谎称操作系统
|
|
358
|
+
hasLiedBrowser: false, // 是否谎称浏览器
|
|
359
|
+
touchSupport: 0, // 支持的触摸点数
|
|
360
|
+
fonts: [
|
|
361
|
+
'Arial',
|
|
362
|
+
'Arial Black',
|
|
363
|
+
'Calibri',
|
|
364
|
+
'Cambria',
|
|
365
|
+
'Cambria Math',
|
|
366
|
+
'Comic Sans MS',
|
|
367
|
+
'Consolas',
|
|
368
|
+
'Courier',
|
|
369
|
+
'Courier New',
|
|
370
|
+
'Georgia',
|
|
371
|
+
'Helvetica',
|
|
372
|
+
'Impact',
|
|
373
|
+
'Lucida Console',
|
|
374
|
+
'Lucida Sans Unicode',
|
|
375
|
+
'Microsoft Sans Serif',
|
|
376
|
+
'MS Gothic',
|
|
377
|
+
'MS PGothic',
|
|
378
|
+
'MS Sans Serif',
|
|
379
|
+
'MS Serif',
|
|
380
|
+
'Palatino Linotype',
|
|
381
|
+
'Segoe Print',
|
|
382
|
+
'Segoe Script',
|
|
383
|
+
'Segoe UI',
|
|
384
|
+
'Segoe UI Light',
|
|
385
|
+
'Segoe UI Symbol',
|
|
386
|
+
'Tahoma',
|
|
387
|
+
'Times',
|
|
388
|
+
'Times New Roman',
|
|
389
|
+
'Trebuchet MS',
|
|
390
|
+
'Verdana',
|
|
391
|
+
'Wingdings'
|
|
392
|
+
],
|
|
393
|
+
fontsFlash: false, // Flash 插件是否安装
|
|
394
|
+
audio: '35.749972093850374', // 音频指纹
|
|
395
|
+
enumerateDevices: [`id=${_uuid};gid=groupId1;kind=videoinput;label=Camera1`, `id=${_uuid};gid=groupId2;kind=audioinput;label=Microphone1`]
|
|
396
|
+
// 枚举设备指纹,Unreliable on Windows, see https://github.com/fingerprintjs/fingerprintjs/issues/375
|
|
397
|
+
};
|
|
398
|
+
}
|
|
122
399
|
}
|
|
123
400
|
var BiliApi$1 = new BiliApi();
|
|
124
401
|
|
|
@@ -61,8 +61,8 @@ async function applyLoginQRCode(e) {
|
|
|
61
61
|
return qrcodeKey;
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
|
-
e.reply(`获取B站登录二维码失败: ${res.data
|
|
65
|
-
throw new Error(`获取B站登录二维码失败: ${res.data
|
|
64
|
+
e.reply(`获取B站登录二维码失败: ${JSON.stringify(res.data)}`);
|
|
65
|
+
throw new Error(`获取B站登录二维码失败: ${JSON.stringify(res.data)}`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
/**处理扫码结果 */
|
|
@@ -81,8 +81,17 @@ async function pollLoginQRCode(e, qrcodeKey) {
|
|
|
81
81
|
if (data.data.code === 0) {
|
|
82
82
|
// 登录成功,获取 cookie
|
|
83
83
|
const LoginCookie = response.headers.get('set-cookie');
|
|
84
|
+
let loginCk = '';
|
|
85
|
+
try {
|
|
86
|
+
const nomalCk = await getNewTempCk();
|
|
87
|
+
loginCk = `${nomalCk}${LoginCookie}`;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
loginCk = LoginCookie;
|
|
91
|
+
logger.debug(`优纪插件: 获取B站登录ck缺失部分: ${error}`);
|
|
92
|
+
}
|
|
84
93
|
e.reply(`~B站登陆成功~`);
|
|
85
|
-
return
|
|
94
|
+
return loginCk;
|
|
86
95
|
}
|
|
87
96
|
else if (data.data.code === 86101) {
|
|
88
97
|
// 未扫码
|
|
@@ -245,7 +254,22 @@ async function saveLocalBiliCk(data) {
|
|
|
245
254
|
async function readTempCk() {
|
|
246
255
|
const CK_KEY = 'Yz:yuki:bili:tempCookie';
|
|
247
256
|
const tempCk = await Redis.get(CK_KEY);
|
|
248
|
-
|
|
257
|
+
if (!tempCk) {
|
|
258
|
+
const newTempCk = await getNewTempCk();
|
|
259
|
+
await saveTempCk(newTempCk);
|
|
260
|
+
const result = await postGateway(newTempCk);
|
|
261
|
+
const data = await result.data; // 解析校验结果
|
|
262
|
+
if (data?.code !== 0) {
|
|
263
|
+
logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
|
|
264
|
+
}
|
|
265
|
+
else if (data?.code === 0) {
|
|
266
|
+
logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
|
|
267
|
+
}
|
|
268
|
+
return newTempCk;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
return tempCk;
|
|
272
|
+
}
|
|
249
273
|
}
|
|
250
274
|
/**保存tempCK*/
|
|
251
275
|
async function saveTempCk(newTempCk) {
|
|
@@ -362,231 +386,26 @@ async function getBuvid3_4(uuid) {
|
|
|
362
386
|
/**获取新的tempCK*/
|
|
363
387
|
async function getNewTempCk() {
|
|
364
388
|
const uuid = await genUUID();
|
|
389
|
+
const b_nut = `b_nut=${Date.now() / 1000};`;
|
|
365
390
|
const buvid3_buvid4 = await getBuvid3_4(uuid);
|
|
366
391
|
const b_lsid = await gen_b_lsid();
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
await saveTempCk(newTempCk);
|
|
370
|
-
const result = await postGateway(newTempCk);
|
|
371
|
-
const data = await result.data; // 解析校验结果
|
|
372
|
-
if (data?.code !== 0) {
|
|
373
|
-
logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
|
|
374
|
-
}
|
|
375
|
-
else if (data?.code === 0) {
|
|
376
|
-
logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
|
|
377
|
-
}
|
|
392
|
+
const buvid_fp = await get_buvid_fp(uuid);
|
|
393
|
+
return `${uuid}${buvid3_buvid4}${b_lsid}${buvid_fp}${b_nut}`;
|
|
378
394
|
}
|
|
379
395
|
/**
|
|
380
396
|
* *******************************************************************
|
|
381
397
|
* 风控相关函数
|
|
382
398
|
* *******************************************************************
|
|
383
399
|
*/
|
|
384
|
-
/**获取GatWay payload */
|
|
385
|
-
async function getPayload(cookie) {
|
|
386
|
-
const payloadOriginData = {
|
|
387
|
-
'3064': 1, // ptype, mobile => 2, others => 1
|
|
388
|
-
'5062': `${Date.now()}`, // timestamp
|
|
389
|
-
'03bf': 'https://www.bilibili.com/', // url accessed
|
|
390
|
-
'39c8': '333.999.fp.risk',
|
|
391
|
-
'34f1': '', // target_url, default empty now
|
|
392
|
-
'd402': '', // screenx, default empty
|
|
393
|
-
'654a': '', // screeny, default empty
|
|
394
|
-
'6e7c': '878x1066', // browser_resolution, window.innerWidth || document.body && document.body.clientWidth + "x" + window.innerHeight || document.body && document.body.clientHeight
|
|
395
|
-
'3c43': {
|
|
396
|
-
// 3c43 => msg
|
|
397
|
-
'2673': 0, // hasLiedResolution, window.screen.width < window.screen.availWidth || window.screen.height < window.screen.availHeight
|
|
398
|
-
'5766': 24, // colorDepth, window.screen.colorDepth
|
|
399
|
-
'6527': 0, // addBehavior, !!window.HTMLElement.prototype.addBehavior, html5 api
|
|
400
|
-
'7003': 1, // indexedDb, !!window.indexedDB, html5 api
|
|
401
|
-
'807e': 1, // cookieEnabled, navigator.cookieEnabled
|
|
402
|
-
'b8ce': BiliApi.BILIBILI_HEADERS['User-Agent'], // ua "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0",
|
|
403
|
-
'641c': 0, // webdriver, navigator.webdriver, like Selenium
|
|
404
|
-
'07a4': 'zh-CN', // language
|
|
405
|
-
'1c57': 'not available', // deviceMemory in GB, navigator.deviceMemory
|
|
406
|
-
'0bd0': 16, // hardwareConcurrency, navigator.hardwareConcurrency
|
|
407
|
-
'748e': [1920, 1200], // window.screen.width window.screen.height
|
|
408
|
-
'd61f': [1920, 1152], // window.screen.availWidth window.screen.availHeight
|
|
409
|
-
'fc9d': -480, // timezoneOffset, (new Date).getTimezoneOffset()
|
|
410
|
-
'6aa9': 'Asia/Shanghai', //Intl.DateTimeFormat().resolvedOptions().timeZone, // timezone, (new window.Intl.DateTimeFormat).resolvedOptions().timeZone
|
|
411
|
-
'75b8': 1, // sessionStorage, window.sessionStorage, html5 api
|
|
412
|
-
'3b21': 1, // localStorage, window.localStorage, html5 api
|
|
413
|
-
'8a1c': 0, // openDatabase, window.openDatabase, html5 api
|
|
414
|
-
'd52f': 'not available', // cpuClass, navigator.cpuClass
|
|
415
|
-
'adca': BiliApi.BILIBILI_HEADERS['User-Agent'].includes('Windows') ? 'Win32' : 'Linux', // platform, navigator.platform
|
|
416
|
-
'80c9': [
|
|
417
|
-
[
|
|
418
|
-
'PDF Viewer',
|
|
419
|
-
'Portable Document Format',
|
|
420
|
-
[
|
|
421
|
-
['application/pdf', 'pdf'],
|
|
422
|
-
['text/pdf', 'pdf']
|
|
423
|
-
]
|
|
424
|
-
],
|
|
425
|
-
[
|
|
426
|
-
'Chrome PDF Viewer',
|
|
427
|
-
'Portable Document Format',
|
|
428
|
-
[
|
|
429
|
-
['application/pdf', 'pdf'],
|
|
430
|
-
['text/pdf', 'pdf']
|
|
431
|
-
]
|
|
432
|
-
],
|
|
433
|
-
[
|
|
434
|
-
'Chromium PDF Viewer',
|
|
435
|
-
'Portable Document Format',
|
|
436
|
-
[
|
|
437
|
-
['application/pdf', 'pdf'],
|
|
438
|
-
['text/pdf', 'pdf']
|
|
439
|
-
]
|
|
440
|
-
],
|
|
441
|
-
[
|
|
442
|
-
'Microsoft Edge PDF Viewer',
|
|
443
|
-
'Portable Document Format',
|
|
444
|
-
[
|
|
445
|
-
['application/pdf', 'pdf'],
|
|
446
|
-
['text/pdf', 'pdf']
|
|
447
|
-
]
|
|
448
|
-
],
|
|
449
|
-
[
|
|
450
|
-
'WebKit built-in PDF',
|
|
451
|
-
'Portable Document Format',
|
|
452
|
-
[
|
|
453
|
-
['application/pdf', 'pdf'],
|
|
454
|
-
['text/pdf', 'pdf']
|
|
455
|
-
]
|
|
456
|
-
]
|
|
457
|
-
], // plugins
|
|
458
|
-
'13ab': 'f3YAAAAASUVORK5CYII=', // canvas fingerprint
|
|
459
|
-
'bfe9': 'kABYpRAGAVYzWJooB9Bf4P+UortSvxRY0AAAAASUVORK5CYII=', // webgl_str
|
|
460
|
-
'a3c1': [
|
|
461
|
-
'extensions:ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_sRGB;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_provoking_vertex',
|
|
462
|
-
'webgl aliased line width range:[1, 1]',
|
|
463
|
-
'webgl aliased point size range:[1, 1024]',
|
|
464
|
-
'webgl alpha bits:8',
|
|
465
|
-
'webgl antialiasing:yes',
|
|
466
|
-
'webgl blue bits:8',
|
|
467
|
-
'webgl depth bits:24',
|
|
468
|
-
'webgl green bits:8',
|
|
469
|
-
'webgl max anisotropy:16',
|
|
470
|
-
'webgl max combined texture image units:32',
|
|
471
|
-
'webgl max cube map texture size:16384',
|
|
472
|
-
'webgl max fragment uniform vectors:1024',
|
|
473
|
-
'webgl max render buffer size:16384',
|
|
474
|
-
'webgl max texture image units:16',
|
|
475
|
-
'webgl max texture size:16384',
|
|
476
|
-
'webgl max varying vectors:30',
|
|
477
|
-
'webgl max vertex attribs:16',
|
|
478
|
-
'webgl max vertex texture image units:16',
|
|
479
|
-
'webgl max vertex uniform vectors:4096',
|
|
480
|
-
'webgl max viewport dims:[32767, 32767]',
|
|
481
|
-
'webgl red bits:8',
|
|
482
|
-
'webgl renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar',
|
|
483
|
-
'webgl shading language version:WebGL GLSL ES 1.0',
|
|
484
|
-
'webgl stencil bits:0',
|
|
485
|
-
'webgl vendor:Mozilla',
|
|
486
|
-
'webgl version:WebGL 1.0',
|
|
487
|
-
'webgl unmasked vendor:Google Inc. (Intel)',
|
|
488
|
-
'webgl unmasked renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar',
|
|
489
|
-
'webgl vertex shader high float precision:23',
|
|
490
|
-
'webgl vertex shader high float precision rangeMin:127',
|
|
491
|
-
'webgl vertex shader high float precision rangeMax:127',
|
|
492
|
-
'webgl vertex shader medium float precision:23',
|
|
493
|
-
'webgl vertex shader medium float precision rangeMin:127',
|
|
494
|
-
'webgl vertex shader medium float precision rangeMax:127',
|
|
495
|
-
'webgl vertex shader low float precision:23',
|
|
496
|
-
'webgl vertex shader low float precision rangeMin:127',
|
|
497
|
-
'webgl vertex shader low float precision rangeMax:127',
|
|
498
|
-
'webgl fragment shader high float precision:23',
|
|
499
|
-
'webgl fragment shader high float precision rangeMin:127',
|
|
500
|
-
'webgl fragment shader high float precision rangeMax:127',
|
|
501
|
-
'webgl fragment shader medium float precision:23',
|
|
502
|
-
'webgl fragment shader medium float precision rangeMin:127',
|
|
503
|
-
'webgl fragment shader medium float precision rangeMax:127',
|
|
504
|
-
'webgl fragment shader low float precision:23',
|
|
505
|
-
'webgl fragment shader low float precision rangeMin:127',
|
|
506
|
-
'webgl fragment shader low float precision rangeMax:127',
|
|
507
|
-
'webgl vertex shader high int precision:0',
|
|
508
|
-
'webgl vertex shader high int precision rangeMin:31',
|
|
509
|
-
'webgl vertex shader high int precision rangeMax:30',
|
|
510
|
-
'webgl vertex shader medium int precision:0',
|
|
511
|
-
'webgl vertex shader medium int precision rangeMin:31',
|
|
512
|
-
'webgl vertex shader medium int precision rangeMax:30',
|
|
513
|
-
'webgl vertex shader low int precision:0',
|
|
514
|
-
'webgl vertex shader low int precision rangeMin:31',
|
|
515
|
-
'webgl vertex shader low int precision rangeMax:30',
|
|
516
|
-
'webgl fragment shader high int precision:0',
|
|
517
|
-
'webgl fragment shader high int precision rangeMin:31',
|
|
518
|
-
'webgl fragment shader high int precision rangeMax:30',
|
|
519
|
-
'webgl fragment shader medium int precision:0',
|
|
520
|
-
'webgl fragment shader medium int precision rangeMin:31',
|
|
521
|
-
'webgl fragment shader medium int precision rangeMax:30',
|
|
522
|
-
'webgl fragment shader low int precision:0',
|
|
523
|
-
'webgl fragment shader low int precision rangeMin:31',
|
|
524
|
-
'webgl fragment shader low int precision rangeMax:30'
|
|
525
|
-
], // webgl_params, cab be set to [] if webgl is not supported
|
|
526
|
-
'6bc5': 'Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar', // webglVendorAndRenderer
|
|
527
|
-
'ed31': 0,
|
|
528
|
-
'72bd': 0,
|
|
529
|
-
'097b': 0,
|
|
530
|
-
'52cd': [0, 0, 0],
|
|
531
|
-
'a658': [
|
|
532
|
-
'Arial',
|
|
533
|
-
'Arial Black',
|
|
534
|
-
'Calibri',
|
|
535
|
-
'Cambria',
|
|
536
|
-
'Cambria Math',
|
|
537
|
-
'Comic Sans MS',
|
|
538
|
-
'Consolas',
|
|
539
|
-
'Courier',
|
|
540
|
-
'Courier New',
|
|
541
|
-
'Georgia',
|
|
542
|
-
'Helvetica',
|
|
543
|
-
'Impact',
|
|
544
|
-
'Lucida Console',
|
|
545
|
-
'Lucida Sans Unicode',
|
|
546
|
-
'Microsoft Sans Serif',
|
|
547
|
-
'MS Gothic',
|
|
548
|
-
'MS PGothic',
|
|
549
|
-
'MS Sans Serif',
|
|
550
|
-
'MS Serif',
|
|
551
|
-
'Palatino Linotype',
|
|
552
|
-
'Segoe Print',
|
|
553
|
-
'Segoe Script',
|
|
554
|
-
'Segoe UI',
|
|
555
|
-
'Segoe UI Light',
|
|
556
|
-
'Segoe UI Symbol',
|
|
557
|
-
'Tahoma',
|
|
558
|
-
'Times',
|
|
559
|
-
'Times New Roman',
|
|
560
|
-
'Trebuchet MS',
|
|
561
|
-
'Verdana',
|
|
562
|
-
'Wingdings'
|
|
563
|
-
],
|
|
564
|
-
'd02f': '35.749972093850374'
|
|
565
|
-
},
|
|
566
|
-
'54ef': {
|
|
567
|
-
'in_new_ab ': true,
|
|
568
|
-
'ab_version ': {
|
|
569
|
-
'waterfall_article ': 'SHOW '
|
|
570
|
-
},
|
|
571
|
-
'ab_split_num ': {
|
|
572
|
-
'waterfall_article ': 0
|
|
573
|
-
}
|
|
574
|
-
},
|
|
575
|
-
'8b94': '',
|
|
576
|
-
'df35': `${await readSavedCookieItems(cookie, ['_uuid'], false)}`, // _uuid, set from cookie, generated by client side(algorithm remains unknown)
|
|
577
|
-
'07a4': 'zh-CN',
|
|
578
|
-
'5f45': null,
|
|
579
|
-
'db46': 0
|
|
580
|
-
};
|
|
581
|
-
return JSON.stringify(payloadOriginData);
|
|
582
|
-
}
|
|
583
400
|
/**
|
|
584
401
|
* 请求参数POST接口(ExClimbWuzhi)过校验
|
|
585
402
|
* @param cookie 请求所需的cookie
|
|
586
403
|
* @returns 返回POST请求的结果
|
|
587
404
|
*/
|
|
588
405
|
async function postGateway(cookie) {
|
|
589
|
-
const
|
|
406
|
+
const _uuid = await readSavedCookieItems(cookie, ['_uuid'], false);
|
|
407
|
+
const payloadJsonData = await BiliApi.BILIBILI_BROWSER_DATA(_uuid);
|
|
408
|
+
const data = { payload: JSON.stringify(payloadJsonData) };
|
|
590
409
|
const requestUrl = 'https://api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi';
|
|
591
410
|
const config = {
|
|
592
411
|
headers: lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
|
|
@@ -612,8 +431,8 @@ async function postGateway(cookie) {
|
|
|
612
431
|
*/
|
|
613
432
|
async function get_buvid_fp(cookie) {
|
|
614
433
|
const uuid = await readSavedCookieItems(cookie, ['_uuid'], false);
|
|
615
|
-
const
|
|
616
|
-
|
|
434
|
+
const fingerprintData = BiliApi.BILIBILI_FINGERPRINT_DATA(uuid);
|
|
435
|
+
const buvidFp = gen_buvid_fp(fingerprintData);
|
|
617
436
|
return `buvid_fp=${buvidFp};`;
|
|
618
437
|
}
|
|
619
438
|
/**
|
|
@@ -1,77 +1,282 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
static
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Contains code from open-source projects:
|
|
3
|
+
* MurmurHash3 by Karan Lyons (https://github.com/karanlyons/murmurHash3.js)
|
|
4
|
+
*/
|
|
5
|
+
class MurmurHash3 {
|
|
6
|
+
// x64Add 函数:将两个64位整数相加
|
|
7
|
+
//
|
|
8
|
+
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
|
9
|
+
// added together as a 64bit int (as an array of two 32bit ints).
|
|
10
|
+
//
|
|
11
|
+
static x64Add = function (m, n) {
|
|
12
|
+
m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];
|
|
13
|
+
n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];
|
|
14
|
+
var o = [0, 0, 0, 0];
|
|
15
|
+
o[3] += m[3] + n[3];
|
|
16
|
+
o[2] += o[3] >>> 16;
|
|
17
|
+
o[3] &= 0xffff;
|
|
18
|
+
o[2] += m[2] + n[2];
|
|
19
|
+
o[1] += o[2] >>> 16;
|
|
20
|
+
o[2] &= 0xffff;
|
|
21
|
+
o[1] += m[1] + n[1];
|
|
22
|
+
o[0] += o[1] >>> 16;
|
|
23
|
+
o[1] &= 0xffff;
|
|
24
|
+
o[0] += m[0] + n[0];
|
|
25
|
+
o[0] &= 0xffff;
|
|
26
|
+
return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];
|
|
27
|
+
};
|
|
28
|
+
// x64Multiply 函数:将两个64位整数相乘
|
|
29
|
+
//
|
|
30
|
+
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
|
31
|
+
// multiplied together as a 64bit int (as an array of two 32bit ints).
|
|
32
|
+
//
|
|
33
|
+
static x64Multiply = function (m, n) {
|
|
34
|
+
m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];
|
|
35
|
+
n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];
|
|
36
|
+
var o = [0, 0, 0, 0];
|
|
37
|
+
o[3] += m[3] * n[3];
|
|
38
|
+
o[2] += o[3] >>> 16;
|
|
39
|
+
o[3] &= 0xffff;
|
|
40
|
+
o[2] += m[2] * n[3];
|
|
41
|
+
o[1] += o[2] >>> 16;
|
|
42
|
+
o[2] &= 0xffff;
|
|
43
|
+
o[2] += m[3] * n[2];
|
|
44
|
+
o[1] += o[2] >>> 16;
|
|
45
|
+
o[2] &= 0xffff;
|
|
46
|
+
o[1] += m[1] * n[3];
|
|
47
|
+
o[0] += o[1] >>> 16;
|
|
48
|
+
o[1] &= 0xffff;
|
|
49
|
+
o[1] += m[2] * n[2];
|
|
50
|
+
o[0] += o[1] >>> 16;
|
|
51
|
+
o[1] &= 0xffff;
|
|
52
|
+
o[1] += m[3] * n[1];
|
|
53
|
+
o[0] += o[1] >>> 16;
|
|
54
|
+
o[1] &= 0xffff;
|
|
55
|
+
o[0] += m[0] * n[3] + m[1] * n[2] + m[2] * n[1] + m[3] * n[0];
|
|
56
|
+
o[0] &= 0xffff;
|
|
57
|
+
return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];
|
|
58
|
+
};
|
|
59
|
+
// x64Rotl 函数:将给定64位整数左移
|
|
60
|
+
//
|
|
61
|
+
// Given a 64bit int (as an array of two 32bit ints) and an int
|
|
62
|
+
// representing a number of bit positions, returns the 64bit int (as an
|
|
63
|
+
// array of two 32bit ints) rotated left by that number of positions.
|
|
64
|
+
//
|
|
65
|
+
static x64Rotl = function (m, n) {
|
|
66
|
+
n %= 64;
|
|
67
|
+
if (n === 32) {
|
|
68
|
+
return [m[1], m[0]];
|
|
42
69
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
else if (n < 32) {
|
|
71
|
+
return [(m[0] << n) | (m[1] >>> (32 - n)), (m[1] << n) | (m[0] >>> (32 - n))];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
n -= 32;
|
|
75
|
+
return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))];
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
// x64LeftShift 函数:将64位整数左移
|
|
79
|
+
//
|
|
80
|
+
// Given a 64bit int (as an array of two 32bit ints) and an int
|
|
81
|
+
// representing a number of bit positions, returns the 64bit int (as an
|
|
82
|
+
// array of two 32bit ints) shifted left by that number of positions.
|
|
83
|
+
//
|
|
84
|
+
static x64LeftShift = function (m, n) {
|
|
85
|
+
n %= 64;
|
|
86
|
+
if (n === 0) {
|
|
87
|
+
return m;
|
|
88
|
+
}
|
|
89
|
+
else if (n < 32) {
|
|
90
|
+
return [(m[0] << n) | (m[1] >>> (32 - n)), m[1] << n];
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return [m[1] << (n - 32), 0];
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
// x64Xor 函数:返回两个64位整数的异或结果
|
|
97
|
+
//
|
|
98
|
+
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
|
99
|
+
// xored together as a 64bit int (as an array of two 32bit ints).
|
|
100
|
+
//
|
|
101
|
+
static x64Xor = function (m, n) {
|
|
102
|
+
return [m[0] ^ n[0], m[1] ^ n[1]];
|
|
103
|
+
};
|
|
104
|
+
// x64Fmix 函数:MurmurHash3的最终混合步骤
|
|
105
|
+
//
|
|
106
|
+
// Given a block, returns murmurHash3's final x64 mix of that block.
|
|
107
|
+
// (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the
|
|
108
|
+
// only place where we need to right shift 64bit ints.)
|
|
109
|
+
//
|
|
110
|
+
static x64Fmix = function (h) {
|
|
111
|
+
h = MurmurHash3.x64Xor(h, [0, h[0] >>> 1]);
|
|
112
|
+
h = MurmurHash3.x64Multiply(h, [0xff51afd7, 0xed558ccd]);
|
|
113
|
+
h = MurmurHash3.x64Xor(h, [0, h[0] >>> 1]);
|
|
114
|
+
h = MurmurHash3.x64Multiply(h, [0xc4ceb9fe, 0x1a85ec53]);
|
|
115
|
+
h = MurmurHash3.x64Xor(h, [0, h[0] >>> 1]);
|
|
116
|
+
return h;
|
|
117
|
+
};
|
|
118
|
+
// x64hash128 函数:生成128位哈希
|
|
119
|
+
//
|
|
120
|
+
// Given a string and an optional seed as an int, returns a 128 bit
|
|
121
|
+
// hash using the x64 flavor of MurmurHash3, as an unsigned hex.
|
|
122
|
+
//
|
|
123
|
+
static x64hash128 = function (key, seed) {
|
|
124
|
+
key = key || '';
|
|
125
|
+
seed = seed || 0;
|
|
126
|
+
var remainder = key.length % 16;
|
|
127
|
+
var bytes = key.length - remainder;
|
|
128
|
+
var h1 = [0, seed];
|
|
129
|
+
var h2 = [0, seed];
|
|
130
|
+
var k1 = [0, 0];
|
|
131
|
+
var k2 = [0, 0];
|
|
132
|
+
var c1 = [0x87c37b91, 0x114253d5];
|
|
133
|
+
var c2 = [0x4cf5ad43, 0x2745937f];
|
|
134
|
+
for (var i = 0; i < bytes; i += 16) {
|
|
135
|
+
k1 = [
|
|
136
|
+
(key.charCodeAt(i + 4) & 0xff) |
|
|
137
|
+
((key.charCodeAt(i + 5) & 0xff) << 8) |
|
|
138
|
+
((key.charCodeAt(i + 6) & 0xff) << 16) |
|
|
139
|
+
((key.charCodeAt(i + 7) & 0xff) << 24),
|
|
140
|
+
(key.charCodeAt(i) & 0xff) | ((key.charCodeAt(i + 1) & 0xff) << 8) | ((key.charCodeAt(i + 2) & 0xff) << 16) | ((key.charCodeAt(i + 3) & 0xff) << 24)
|
|
141
|
+
];
|
|
142
|
+
k2 = [
|
|
143
|
+
(key.charCodeAt(i + 12) & 0xff) |
|
|
144
|
+
((key.charCodeAt(i + 13) & 0xff) << 8) |
|
|
145
|
+
((key.charCodeAt(i + 14) & 0xff) << 16) |
|
|
146
|
+
((key.charCodeAt(i + 15) & 0xff) << 24),
|
|
147
|
+
(key.charCodeAt(i + 8) & 0xff) |
|
|
148
|
+
((key.charCodeAt(i + 9) & 0xff) << 8) |
|
|
149
|
+
((key.charCodeAt(i + 10) & 0xff) << 16) |
|
|
150
|
+
((key.charCodeAt(i + 11) & 0xff) << 24)
|
|
151
|
+
];
|
|
152
|
+
// 处理 k1 和 k2
|
|
153
|
+
k1 = MurmurHash3.x64Multiply(k1, c1);
|
|
154
|
+
k1 = MurmurHash3.x64Rotl(k1, 31);
|
|
155
|
+
k1 = MurmurHash3.x64Multiply(k1, c2);
|
|
156
|
+
h1 = MurmurHash3.x64Xor(h1, k1);
|
|
157
|
+
h1 = MurmurHash3.x64Rotl(h1, 27);
|
|
158
|
+
h1 = MurmurHash3.x64Add(h1, h2);
|
|
159
|
+
h1 = MurmurHash3.x64Add(MurmurHash3.x64Multiply(h1, [0, 5]), [0, 0x52dce729]);
|
|
160
|
+
k2 = MurmurHash3.x64Multiply(k2, c2);
|
|
161
|
+
k2 = MurmurHash3.x64Rotl(k2, 33);
|
|
162
|
+
k2 = MurmurHash3.x64Multiply(k2, c1);
|
|
163
|
+
h2 = MurmurHash3.x64Xor(h2, k2);
|
|
164
|
+
h2 = MurmurHash3.x64Rotl(h2, 31);
|
|
165
|
+
h2 = MurmurHash3.x64Add(h2, h1);
|
|
166
|
+
h2 = MurmurHash3.x64Add(MurmurHash3.x64Multiply(h2, [0, 5]), [0, 0x38495ab5]);
|
|
167
|
+
}
|
|
168
|
+
k1 = [0, 0];
|
|
169
|
+
k2 = [0, 0];
|
|
170
|
+
switch (remainder) {
|
|
171
|
+
case 15:
|
|
172
|
+
k2 = MurmurHash3.x64Xor(k2, MurmurHash3.x64LeftShift([0, String(key).charCodeAt(i + 14)], 48));
|
|
173
|
+
// fallthrough
|
|
174
|
+
case 14:
|
|
175
|
+
k2 = MurmurHash3.x64Xor(k2, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 13)], 40));
|
|
176
|
+
// fallthrough
|
|
177
|
+
case 13:
|
|
178
|
+
k2 = MurmurHash3.x64Xor(k2, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 12)], 32));
|
|
179
|
+
// fallthrough
|
|
180
|
+
case 12:
|
|
181
|
+
k2 = MurmurHash3.x64Xor(k2, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 11)], 24));
|
|
182
|
+
// fallthrough
|
|
183
|
+
case 11:
|
|
184
|
+
k2 = MurmurHash3.x64Xor(k2, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 10)], 16));
|
|
185
|
+
// fallthrough
|
|
186
|
+
case 10:
|
|
187
|
+
k2 = MurmurHash3.x64Xor(k2, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 9)], 8));
|
|
188
|
+
// fallthrough
|
|
189
|
+
case 9:
|
|
190
|
+
k2 = MurmurHash3.x64Xor(k2, [0, key.charCodeAt(i + 8)]);
|
|
191
|
+
k2 = MurmurHash3.x64Multiply(k2, c2);
|
|
192
|
+
k2 = MurmurHash3.x64Rotl(k2, 33);
|
|
193
|
+
k2 = MurmurHash3.x64Multiply(k2, c1);
|
|
194
|
+
h2 = MurmurHash3.x64Xor(h2, k2);
|
|
195
|
+
// fallthrough
|
|
196
|
+
case 8:
|
|
197
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 7)], 56));
|
|
198
|
+
// fallthrough
|
|
199
|
+
case 7:
|
|
200
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 6)], 48));
|
|
201
|
+
// fallthrough
|
|
202
|
+
case 6:
|
|
203
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 5)], 40));
|
|
204
|
+
// fallthrough
|
|
205
|
+
case 5:
|
|
206
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 4)], 32));
|
|
207
|
+
// fallthrough
|
|
208
|
+
case 4:
|
|
209
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 3)], 24));
|
|
210
|
+
// fallthrough
|
|
211
|
+
case 3:
|
|
212
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 2)], 16));
|
|
213
|
+
// fallthrough
|
|
214
|
+
case 2:
|
|
215
|
+
k1 = MurmurHash3.x64Xor(k1, MurmurHash3.x64LeftShift([0, key.charCodeAt(i + 1)], 8));
|
|
216
|
+
// fallthrough
|
|
217
|
+
case 1:
|
|
218
|
+
k1 = MurmurHash3.x64Xor(k1, [0, key.charCodeAt(i)]);
|
|
219
|
+
k1 = MurmurHash3.x64Multiply(k1, c1);
|
|
220
|
+
k1 = MurmurHash3.x64Rotl(k1, 31);
|
|
221
|
+
k1 = MurmurHash3.x64Multiply(k1, c2);
|
|
222
|
+
h1 = MurmurHash3.x64Xor(h1, k1);
|
|
223
|
+
// fallthrough
|
|
224
|
+
}
|
|
225
|
+
h1 = MurmurHash3.x64Xor(h1, [0, key.length]);
|
|
226
|
+
h2 = MurmurHash3.x64Xor(h2, [0, key.length]);
|
|
227
|
+
h1 = MurmurHash3.x64Add(h1, h2);
|
|
228
|
+
h2 = MurmurHash3.x64Add(h2, h1);
|
|
229
|
+
h1 = MurmurHash3.x64Fmix(h1);
|
|
230
|
+
h2 = MurmurHash3.x64Fmix(h2);
|
|
231
|
+
h1 = MurmurHash3.x64Add(h1, h2);
|
|
232
|
+
h2 = MurmurHash3.x64Add(h2, h1);
|
|
233
|
+
return (('00000000' + (h1[0] >>> 0).toString(16)).slice(-8) +
|
|
234
|
+
('00000000' + (h1[1] >>> 0).toString(16)).slice(-8) +
|
|
235
|
+
('00000000' + (h2[0] >>> 0).toString(16)).slice(-8) +
|
|
236
|
+
('00000000' + (h2[1] >>> 0).toString(16)).slice(-8));
|
|
237
|
+
};
|
|
70
238
|
}
|
|
71
|
-
function gen_buvid_fp(
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
239
|
+
function gen_buvid_fp(browserData) {
|
|
240
|
+
// 将所有自定义数据整合
|
|
241
|
+
const components = [
|
|
242
|
+
{ key: 'userAgent', value: browserData.userAgent },
|
|
243
|
+
{ key: 'webdriver', value: browserData.webdriver }, // WebDriver 信息
|
|
244
|
+
{ key: 'language', value: browserData.language },
|
|
245
|
+
{ key: 'colorDepth', value: browserData.colorDepth },
|
|
246
|
+
{ key: 'deviceMemory', value: browserData.deviceMemory },
|
|
247
|
+
{ key: 'pixelRatio', value: browserData.pixelRatio }, // 设备像素比
|
|
248
|
+
{ key: 'hardwareConcurrency', value: browserData.hardwareConcurrency },
|
|
249
|
+
{ key: 'screenResolution', value: browserData.screenResolution }, // 屏幕分辨率
|
|
250
|
+
{ key: 'availableScreenResolution', value: browserData.availableScreenResolution }, // 可用屏幕分辨率
|
|
251
|
+
{ key: 'timezoneOffset', value: browserData.timezoneOffset }, // 时区偏移
|
|
252
|
+
{ key: 'timezone', value: browserData.timezone },
|
|
253
|
+
{ key: 'sessionStorage', value: browserData.sessionStorage ? 1 : 0 }, // sessionStorage 支持
|
|
254
|
+
{ key: 'localStorage', value: browserData.localStorage ? 1 : 0 }, // localStorage 支持
|
|
255
|
+
{ key: 'indexedDb', value: browserData.indexedDb ? 1 : 0 }, // IndexedDB 支持
|
|
256
|
+
{ key: 'addBehavior', value: browserData.addBehavior ? 1 : 0 }, // addBehavior 支持
|
|
257
|
+
{ key: 'openDatabase', value: browserData.openDatabase ? 1 : 0 }, // openDatabase 支持
|
|
258
|
+
{ key: 'cpuClass', value: browserData.cpuClass },
|
|
259
|
+
{ key: 'platform', value: browserData.platform },
|
|
260
|
+
{ key: 'doNotTrack', value: browserData.doNotTrack },
|
|
261
|
+
{ key: 'plugins', value: browserData.plugins.map(p => p.name).join(',') }, // 插件名称
|
|
262
|
+
{ key: 'canvas', value: browserData.canvas },
|
|
263
|
+
{ key: 'webgl', value: browserData.webgl },
|
|
264
|
+
{ key: 'webglVendorAndRenderer', value: browserData.webglVendorAndRenderer },
|
|
265
|
+
{ key: 'adBlock', value: browserData.adBlock ? 1 : 0 }, // 是否存在广告拦截器
|
|
266
|
+
{ key: 'hasLiedLanguages', value: browserData.hasLiedLanguages ? 1 : 0 },
|
|
267
|
+
{ key: 'hasLiedResolution', value: browserData.hasLiedResolution ? 1 : 0 },
|
|
268
|
+
{ key: 'hasLiedOs', value: browserData.hasLiedOs ? 1 : 0 },
|
|
269
|
+
{ key: 'hasLiedBrowser', value: browserData.hasLiedBrowser ? 1 : 0 },
|
|
270
|
+
{ key: 'touchSupport', value: browserData.touchSupport }, // 支持的触摸点数
|
|
271
|
+
{ key: 'fonts', value: browserData.fonts.map(f => f.replace(/\s+/g, '')).join(',') }, // 字体列表
|
|
272
|
+
{ key: 'fontsFlash', value: browserData.hasLiedOs ? browserData.fonts.map(f => f.replace(/\s+/g, '')).join(',') : 'flash not installed' },
|
|
273
|
+
{ key: 'audio', value: browserData.audio }, // 音频指纹
|
|
274
|
+
{ key: 'enumerateDevices', value: browserData.enumerateDevices.map(f => f.replace(/\s+/g, '')).join(',') }
|
|
275
|
+
];
|
|
276
|
+
const values = components.map(component => component.value).join('~~~');
|
|
277
|
+
// 使用 MurmurHash3 计算指纹
|
|
278
|
+
const fingerprint = MurmurHash3.x64hash128(values, 31); // 调用之前定义的 x64hash128 函数
|
|
279
|
+
return fingerprint;
|
|
75
280
|
}
|
|
76
281
|
|
|
77
282
|
export { gen_buvid_fp };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import md5 from 'md5';
|
|
2
2
|
import fetch from 'node-fetch';
|
|
3
|
+
import { Redis } from 'yunzaijs';
|
|
4
|
+
import BiliApi from './bilibili.main.api.js';
|
|
3
5
|
|
|
4
6
|
const mixinKeyEncTab = [
|
|
5
7
|
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26,
|
|
@@ -33,18 +35,57 @@ function encWbi(params, img_key, sub_key) {
|
|
|
33
35
|
}
|
|
34
36
|
// 获取最新的 img_key 和 sub_key
|
|
35
37
|
async function getWbiKeys(headers, cookie) {
|
|
36
|
-
const
|
|
38
|
+
const IMG_SUB_KEY = 'Yz:yuki:bili:wbi_img_key';
|
|
39
|
+
const wbi_img_data = await Redis.get(IMG_SUB_KEY);
|
|
40
|
+
if (wbi_img_data) {
|
|
41
|
+
const wbi_img_data_json = JSON.parse(wbi_img_data);
|
|
42
|
+
return {
|
|
43
|
+
img_key: wbi_img_data_json.img_key,
|
|
44
|
+
sub_key: wbi_img_data_json.sub_key
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
|
|
49
|
+
headers: {
|
|
50
|
+
// SESSDATA 字段
|
|
51
|
+
'Cookie': cookie,
|
|
52
|
+
'User-Agent': headers['User-Agent'],
|
|
53
|
+
'Referer': 'https://www.bilibili.com/' //对于直接浏览器调用可能不适用
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const { data: { wbi_img: { img_url, sub_url } } } = (await res.json());
|
|
57
|
+
const wbi_img_data = {
|
|
58
|
+
img_key: img_url.slice(img_url.lastIndexOf('/') + 1, img_url.lastIndexOf('.')),
|
|
59
|
+
sub_key: sub_url.slice(sub_url.lastIndexOf('/') + 1, sub_url.lastIndexOf('.'))
|
|
60
|
+
};
|
|
61
|
+
const { microtime } = await getTimeStamp(); // 获取的 microtime 已经是北京时间(毫秒)
|
|
62
|
+
// 创建当前北京时间的 Date 对象
|
|
63
|
+
const current_zh_cn_Time = new Date(microtime);
|
|
64
|
+
// 打印当前北京时间
|
|
65
|
+
console.log(`当前北京时间: ${current_zh_cn_Time}`);
|
|
66
|
+
// 创建明天0点的时间对象
|
|
67
|
+
const tomorrow = new Date(current_zh_cn_Time);
|
|
68
|
+
tomorrow.setHours(0, 0, 0, 0); // 设置明天的0点
|
|
69
|
+
tomorrow.setDate(tomorrow.getDate() + 1); // 日期加1,表示明天
|
|
70
|
+
// 计算剩余秒数
|
|
71
|
+
const secondsUntilTomorrow = Math.floor((tomorrow.getTime() - current_zh_cn_Time.getTime()) / 1000);
|
|
72
|
+
await Redis.set(IMG_SUB_KEY, JSON.stringify(wbi_img_data), { EX: secondsUntilTomorrow - 2 }); // 设置缓存,过期时间为第二天0点前2秒
|
|
73
|
+
return wbi_img_data;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**获取适用于 RTC 的时间戳*/
|
|
77
|
+
async function getTimeStamp() {
|
|
78
|
+
const res = await fetch(BiliApi.BILIBIL_API.biliServerTimeStamp, {
|
|
79
|
+
method: 'GET',
|
|
37
80
|
headers: {
|
|
38
|
-
|
|
39
|
-
'
|
|
40
|
-
'User-Agent': headers['User-Agent'],
|
|
41
|
-
'Referer': 'https://www.bilibili.com/' //对于直接浏览器调用可能不适用
|
|
81
|
+
'Host': 'api.live.bilibili.com',
|
|
82
|
+
'User-Agent': `${BiliApi.USER_AGENT}`
|
|
42
83
|
}
|
|
43
84
|
});
|
|
44
|
-
const { data: {
|
|
85
|
+
const { data: { timestamp, microtime } } = (await res.json());
|
|
45
86
|
return {
|
|
46
|
-
|
|
47
|
-
|
|
87
|
+
timestamp: timestamp,
|
|
88
|
+
microtime: microtime
|
|
48
89
|
};
|
|
49
90
|
}
|
|
50
91
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yz-yuki-plugin",
|
|
3
|
-
"version": "2.0.5-
|
|
3
|
+
"version": "2.0.5-13",
|
|
4
4
|
"description": "优纪插件,yunzaijs 关于 微博推送、B站推送 等功能的拓展插件",
|
|
5
5
|
"author": "snowtafir",
|
|
6
6
|
"type": "module",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"json5": "^2.2.3",
|
|
64
64
|
"jsxp": "^1.0.4",
|
|
65
65
|
"lodash": "^4.17.21",
|
|
66
|
-
"lvyjs": "^0.1.
|
|
66
|
+
"lvyjs": "^0.1.1",
|
|
67
67
|
"md5": "^2.3.0",
|
|
68
68
|
"node-fetch": "^3.3.2",
|
|
69
69
|
"postcss": "^8.4.47",
|