yz-yuki-plugin 1.0.1-rc.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.
Files changed (124) hide show
  1. package/.puppeteerrc.cjs +4 -0
  2. package/CHANGELOG.md +7 -0
  3. package/LICENSE +21 -0
  4. package/README.md +195 -0
  5. package/defaultConfig/bilibili/config.yaml +41 -0
  6. package/defaultConfig/bilibili/push.yaml +0 -0
  7. package/defaultConfig/help/help.yaml +86 -0
  8. package/defaultConfig/weibo/config.yaml +41 -0
  9. package/defaultConfig/weibo/push.yaml +0 -0
  10. package/lib/apps/bilibili.js +402 -0
  11. package/lib/apps/help.js +37 -0
  12. package/lib/apps/index.js +4 -0
  13. package/lib/apps/version.js +34 -0
  14. package/lib/apps/weibo.js +252 -0
  15. package/lib/components/dynamic/Account.js +26 -0
  16. package/lib/components/dynamic/Content.js +118 -0
  17. package/lib/components/dynamic/Footer.js +36 -0
  18. package/lib/components/dynamic/ForwardContent.js +15 -0
  19. package/lib/components/dynamic/LogoText.js +10 -0
  20. package/lib/components/dynamic/MainPage.js +22 -0
  21. package/lib/components/help/Help.js +33 -0
  22. package/lib/components/index.js +6 -0
  23. package/lib/components/loginQrcode/Page.js +21 -0
  24. package/lib/components/version/Version.js +27 -0
  25. package/lib/index.js +29 -0
  26. package/lib/models/bilibili/bilibili.api.js +49 -0
  27. package/lib/models/bilibili/bilibili.get.web.data.js +80 -0
  28. package/lib/models/bilibili/bilibili.models.js +484 -0
  29. package/lib/models/bilibili/bilibili.query.js +393 -0
  30. package/lib/models/bilibili/bilibili.task.js +256 -0
  31. package/lib/models/bilibili/bilibili.wbi.js +49 -0
  32. package/lib/models/help/help.js +20 -0
  33. package/lib/models/version/version.js +62 -0
  34. package/lib/models/weibo/weibo.api.js +19 -0
  35. package/lib/models/weibo/weibo.get.web.data.js +55 -0
  36. package/lib/models/weibo/weibo.query.js +323 -0
  37. package/lib/models/weibo/weibo.task.js +215 -0
  38. package/lib/types/apps/bilibili.d.ts +6 -0
  39. package/lib/types/apps/help.d.ts +6 -0
  40. package/lib/types/apps/index.d.ts +4 -0
  41. package/lib/types/apps/version.d.ts +6 -0
  42. package/lib/types/apps/weibo.d.ts +6 -0
  43. package/lib/types/components/dynamic/Account.d.ts +13 -0
  44. package/lib/types/components/dynamic/Content.d.ts +12 -0
  45. package/lib/types/components/dynamic/Footer.d.ts +11 -0
  46. package/lib/types/components/dynamic/ForwardContent.d.ts +6 -0
  47. package/lib/types/components/dynamic/LogoText.d.ts +9 -0
  48. package/lib/types/components/dynamic/MainPage.d.ts +34 -0
  49. package/lib/types/components/help/Help.d.ts +12 -0
  50. package/lib/types/components/index.d.ts +5 -0
  51. package/lib/types/components/loginQrcode/Page.d.ts +7 -0
  52. package/lib/types/components/version/Version.d.ts +8 -0
  53. package/lib/types/index.d.ts +5 -0
  54. package/lib/types/models/bilibili/bilibili.api.d.ts +47 -0
  55. package/lib/types/models/bilibili/bilibili.buid.fp.d.ts +2 -0
  56. package/lib/types/models/bilibili/bilibili.get.web.data.d.ts +6 -0
  57. package/lib/types/models/bilibili/bilibili.models.d.ts +20 -0
  58. package/lib/types/models/bilibili/bilibili.query.d.ts +13 -0
  59. package/lib/types/models/bilibili/bilibili.task.d.ts +18 -0
  60. package/lib/types/models/bilibili/bilibili.wbi.d.ts +5 -0
  61. package/lib/types/models/help/help.d.ts +8 -0
  62. package/lib/types/models/version/version.d.ts +7 -0
  63. package/lib/types/models/weibo/weibo.api.d.ts +17 -0
  64. package/lib/types/models/weibo/weibo.get.web.data.d.ts +8 -0
  65. package/lib/types/models/weibo/weibo.query.d.ts +18 -0
  66. package/lib/types/models/weibo/weibo.task.d.ts +17 -0
  67. package/lib/types/utils/config.d.ts +21 -0
  68. package/lib/types/utils/image.d.ts +10 -0
  69. package/lib/types/utils/paths.d.ts +10 -0
  70. package/lib/types/utils/puppeteer.render.d.ts +23 -0
  71. package/lib/utils/config.js +108 -0
  72. package/lib/utils/image.js +26 -0
  73. package/lib/utils/paths.js +18 -0
  74. package/lib/utils/puppeteer.render.js +102 -0
  75. package/package.json +110 -0
  76. package/public/output.css +1 -0
  77. package/resources/css/dynamic/Account.css +68 -0
  78. package/resources/css/dynamic/Content.box.grid.4.css +4 -0
  79. package/resources/css/dynamic/Content.box.grid.9.css +4 -0
  80. package/resources/css/dynamic/Content.css +87 -0
  81. package/resources/css/dynamic/Footer.css +44 -0
  82. package/resources/css/dynamic/ForwardContent.css +11 -0
  83. package/resources/css/dynamic/LogoText.css +15 -0
  84. package/resources/css/dynamic/MainPage.css +93 -0
  85. package/resources/css/help/help.css +182 -0
  86. package/resources/css/loginQrcode/Page.css +55 -0
  87. package/resources/css/version/version.css +116 -0
  88. package/resources/fonts/iconfont.16acc2.ttf +0 -0
  89. package/resources/img/background/Girl.png +0 -0
  90. package/resources/img/icon/dynamic/bili-rich-text-module-goods-taobao.svg +1 -0
  91. package/resources/img/icon/dynamic/bili-rich-text-module-lottery.svg +1 -0
  92. package/resources/img/icon/dynamic/bilibili.svg +6 -0
  93. package/resources/img/icon/dynamic/weibo.svg +43 -0
  94. package/resources/img/icon/puplic/archaic_stone.png +0 -0
  95. package/resources/img/icon/puplic/condessence_crystal.png +0 -0
  96. package/resources/img/icon/puplic/delightful_encounter.png +0 -0
  97. package/resources/img/icon/puplic/diagram.png +0 -0
  98. package/resources/img/icon/puplic/essence_of_pure_sacred_dewdrop.png +0 -0
  99. package/resources/img/icon/puplic/everamber.png +0 -0
  100. package/resources/img/icon/puplic/flower_1.png +0 -0
  101. package/resources/img/icon/puplic/flower_2.png +0 -0
  102. package/resources/img/icon/puplic/kamera.png +0 -0
  103. package/resources/img/icon/puplic/lumidouce_bell.png +0 -0
  104. package/resources/img/icon/puplic/mora.png +0 -0
  105. package/resources/img/icon/puplic/pluie_lotus.png +0 -0
  106. package/resources/img/icon/puplic/restaurant_smoothie.png +0 -0
  107. package/resources/img/icon/puplic/romaritime_flower.png +0 -0
  108. package/resources/img/icon/puplic/shell.png +0 -0
  109. package/resources/img/icon/puplic/spring_of_pure_sacred_dewdrop.png +0 -0
  110. package/resources/img/icon/puplic/surging_sacred_chalice.png +0 -0
  111. package/resources/img/icon/puplic/tourbillon_device.png +0 -0
  112. package/resources/img/icon/puplic/unfading_silky_grace.png +0 -0
  113. package/resources/img/icon/puplic/wisdom.png +0 -0
  114. package/resources/img/icon/puplic/wondrous_lovely_flower.png +0 -0
  115. package/resources/img/icon/puplic//345/262/251/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
  116. package/resources/img/icon/puplic//346/260/264/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
  117. package/resources/img/icon/puplic//350/215/211/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
  118. package/resources/img/icon/puplic//351/222/223/351/261/274.png +0 -0
  119. package/resources/img/icon/puplic//351/233/267/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
  120. package/resources/img/icon/puplic//351/243/216/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
  121. package/resources/img/icon/puplic//351/243/216/350/275/246.png +0 -0
  122. package/resources/img/readme/girl.png +0 -0
  123. package/resources/img/readme/min-Girl.png +0 -0
  124. package/resources/img/readme/mini-help.jpg +0 -0
@@ -0,0 +1,49 @@
1
+ class BiliApi {
2
+ static BILIBIL_API = {
3
+ biliDynamicInfoList: `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space`,
4
+ biliUpFollowFans: `https://api.bilibili.com/x/relation/stat`,
5
+ biliSpaceUserInfo: `https://api.bilibili.com/x/space/acc/info`,
6
+ biliSpaceUserInfoWbi: `https://api.bilibili.com/x/space/wbi/acc/info`,
7
+ biliSearchUp: `https://api.bilibili.com/x/web-interface/search/type`,
8
+ biliLiveStatus: 'https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids',
9
+ biliCard: "https://api.bilibili.com/x/web-interface/card",
10
+ biliStat: "https://api.bilibili.com/x/relation/stat",
11
+ biliLiveUserInfo: "https://api.live.bilibili.com/live_user/v1/Master/info",
12
+ biliOpusDetail: "https://api.bilibili.com/x/polymer/web-dynamic/v1/opus/detail",
13
+ };
14
+ static BILIBILI_HEADERS = {
15
+ 'Accept': '*/*',
16
+ 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
17
+ 'Accept-Encoding': 'gzip, deflate, br',
18
+ 'Content-type': 'application/json;charset=UTF-8',
19
+ Cookie: '',
20
+ 'pragma': "no-cache",
21
+ "Cache-control": "max-age=0",
22
+ 'DNT': '1',
23
+ 'Sec-GPC': '1',
24
+ 'sec-ch-ua-platform': '',
25
+ 'sec-ch-ua-mobile': '?0',
26
+ 'Sec-Fetch-Dest': 'empty',
27
+ 'Sec-Fetch-Mode': 'cors',
28
+ 'Sec-Fetch-Site': 'same-site',
29
+ 'Sec-Fetch-User': '?0',
30
+ 'TE': 'trailers',
31
+ "Upgrade-Insecure-Requests": '1',
32
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
33
+ };
34
+ static BIlIBILI_LOGIN_HEADERS = {
35
+ 'Accept': '*/*',
36
+ 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
37
+ 'Accept-Encoding': 'gzip, deflate, br',
38
+ 'DNT': '1',
39
+ 'Sec-GPC': '1',
40
+ 'Upgrade-Insecure-Requests': '1',
41
+ 'Sec-Fetch-Dest': 'document',
42
+ 'Sec-Fetch-Mode': 'navigate',
43
+ 'Sec-Fetch-Site': 'none',
44
+ 'Sec-Fetch-User': '?1',
45
+ 'TE': 'trailers',
46
+ };
47
+ }
48
+
49
+ export { BiliApi };
@@ -0,0 +1,80 @@
1
+ import axios from 'axios';
2
+ import lodash from 'lodash';
3
+ import { BiliApi } from './bilibili.api.js';
4
+ import { readSyncCookie, readSavedCookieItems, readSavedCookieOtherItems } from './bilibili.models.js';
5
+ import { getWbiSign } from './bilibili.wbi.js';
6
+
7
+ class BiliGetWebData {
8
+ constructor(e) {
9
+ }
10
+ async getBiliDynamicListDataByUid(uid) {
11
+ const url = BiliApi.BILIBIL_API.biliDynamicInfoList;
12
+ let { cookie } = await readSyncCookie();
13
+ const data = {
14
+ offset: '',
15
+ host_mid: uid,
16
+ timezone_offset: -480,
17
+ platform: 'web',
18
+ features: "itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote",
19
+ web_location: "333.999",
20
+ "x-bili-device-req-json": { "platform": "web", "device": "pc" },
21
+ "x-bili-web-req-json": { "spm_id": "333.999" }
22
+ };
23
+ let signCookie = await readSavedCookieItems(cookie, ["SESSDATA"], false) || await readSavedCookieOtherItems(cookie, ["SESSDATA"]);
24
+ const { w_rid, time_stamp } = await getWbiSign(data, BiliApi.BILIBILI_HEADERS, signCookie);
25
+ const params = {
26
+ ...data,
27
+ w_rid: w_rid,
28
+ wts: time_stamp
29
+ };
30
+ const res = await axios.get(url, {
31
+ params,
32
+ timeout: 10000,
33
+ headers: lodash.merge(BiliApi.BILIBILI_HEADERS, { 'Cookie': `${cookie}`, 'Host': `api.bilibili.com`, 'Origin': 'https://www.bilibili.com', 'Referer': `https://www.bilibili.com/`, }),
34
+ });
35
+ return res;
36
+ }
37
+ async getBilibiUserInfoByUid(uid) {
38
+ const url = BiliApi.BILIBIL_API.biliSpaceUserInfoWbi;
39
+ let { cookie } = await readSyncCookie();
40
+ const data = {
41
+ mid: uid,
42
+ jsonp: 'jsonp',
43
+ };
44
+ let signCookie = await readSavedCookieItems(cookie, ["SESSDATA"], false) || await readSavedCookieOtherItems(cookie, ["SESSDATA"]);
45
+ const { w_rid, time_stamp } = await getWbiSign(data, BiliApi.BILIBILI_HEADERS, signCookie);
46
+ const params = {
47
+ ...data,
48
+ w_rid: w_rid,
49
+ wts: time_stamp
50
+ };
51
+ const res = await axios.get(url, {
52
+ params,
53
+ timeout: 5000,
54
+ headers: lodash.merge(BiliApi.BILIBILI_HEADERS, { 'Cookie': `${cookie}`, 'Host': `api.bilibili.com`, 'Origin': 'https://www.bilibili.com', 'Referer': `https://www.bilibili.com/`, }),
55
+ });
56
+ return res;
57
+ }
58
+ async searchBiliUserInfoByKeyword(keyword) {
59
+ const url = BiliApi.BILIBIL_API.biliSearchUp;
60
+ let { cookie } = await readSyncCookie();
61
+ const data = {
62
+ keyword: keyword,
63
+ page: 1,
64
+ search_type: 'bili_user',
65
+ order: 'totalrank',
66
+ pagesize: 5
67
+ };
68
+ const params = {
69
+ ...data
70
+ };
71
+ const res = await axios.get(url, {
72
+ params,
73
+ timeout: 5000,
74
+ headers: lodash.merge(BiliApi.BILIBILI_HEADERS, { 'Cookie': `${cookie}`, 'Host': `api.bilibili.com`, 'Origin': 'https://www.bilibili.com', 'Referer': `https://www.bilibili.com/`, }),
75
+ });
76
+ return res;
77
+ }
78
+ }
79
+
80
+ export { BiliGetWebData };
@@ -0,0 +1,484 @@
1
+ import axios from 'axios';
2
+ import fs__default from 'fs';
3
+ import lodash from 'lodash';
4
+ import fetch from 'node-fetch';
5
+ import { promisify } from 'node:util';
6
+ import path from 'path';
7
+ import QRCode from 'qrcode';
8
+ import YAML from 'yaml';
9
+ import { Segment, Bot, Redis } from 'yunzai';
10
+ import Image from '../../utils/image.js';
11
+ import { _paths } from '../../utils/paths.js';
12
+ import { BiliApi } from './bilibili.api.js';
13
+
14
+ async function applyLoginQRCode(e) {
15
+ const url = 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header';
16
+ const response = await fetch(url, {
17
+ method: "GET",
18
+ headers: lodash.merge(BiliApi.BIlIBILI_LOGIN_HEADERS, { 'user-agent': BiliApi.BILIBILI_HEADERS['User-Agent'] }, { 'Host': 'passport.bilibili.com', }),
19
+ redirect: "follow",
20
+ });
21
+ const res = await response.json();
22
+ if (res?.code === 0) {
23
+ const qrcodeKey = res.data.qrcode_key;
24
+ const qrcodeUrl = res.data.url;
25
+ let loginUrlQrcodeData = await QRCode.toDataURL(`${qrcodeUrl}`);
26
+ const LoginPropsData = {
27
+ data: { url: loginUrlQrcodeData }
28
+ };
29
+ const ScreenshotOptionsData = {
30
+ saveHtmlfile: false,
31
+ };
32
+ const qrCodeImage = await Image.renderPage("bili-login", "LoginQrcodePage", LoginPropsData, ScreenshotOptionsData);
33
+ let qrcodeImg;
34
+ if (qrCodeImage !== false) {
35
+ const { img } = qrCodeImage;
36
+ qrcodeImg = img;
37
+ }
38
+ let msg = [];
39
+ msg.push(Segment.image(qrcodeImg[0]));
40
+ e.reply('请在3分钟内扫码以完成B站登陆绑定');
41
+ e.reply(msg);
42
+ return qrcodeKey;
43
+ }
44
+ else {
45
+ e.reply(`获取B站登录二维码失败: ${res.data.message}`);
46
+ throw new Error(`获取B站登录二维码失败: ${res.data.message}`);
47
+ }
48
+ }
49
+ async function pollLoginQRCode(e, qrcodeKey) {
50
+ const url = `https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=${qrcodeKey}&source=main-fe-header`;
51
+ const response = await fetch(url, {
52
+ method: "GET",
53
+ headers: lodash.merge(BiliApi.BIlIBILI_LOGIN_HEADERS, { 'User-agent': BiliApi.BILIBILI_HEADERS['User-Agent'] }, { 'Host': 'passport.bilibili.com', }),
54
+ redirect: "follow",
55
+ });
56
+ const data = await response.json();
57
+ if (data.code === 0) {
58
+ if (data.data.code === 0) {
59
+ const LoginCookie = response.headers.get('set-cookie');
60
+ e.reply(`~B站登陆成功~`);
61
+ return LoginCookie;
62
+ }
63
+ else if (data.data.code === 86101) {
64
+ await new Promise((resolve) => setTimeout(resolve, 2000));
65
+ (logger ?? Bot.logger)?.mark(`yuki-yuki插件:扫码B站登录:未扫码,轮询中...`);
66
+ return pollLoginQRCode(e, qrcodeKey);
67
+ }
68
+ else if (data.data.code === 86090) {
69
+ await new Promise((resolve) => setTimeout(resolve, 2000));
70
+ return pollLoginQRCode(e, qrcodeKey);
71
+ }
72
+ else if (data.data.code === 86038) {
73
+ e.reply('B站登陆二维码已失效');
74
+ return null;
75
+ }
76
+ else {
77
+ e.reply('处理扫码结果出错');
78
+ throw new Error(`处理扫码结果出错: ${data?.data?.message}`);
79
+ }
80
+ }
81
+ else {
82
+ e.reply('处理扫码结果出错');
83
+ throw new Error(`处理扫码结果出错: ${data?.message}`);
84
+ }
85
+ }
86
+ async function checkBiliLogin(e) {
87
+ const LoginCookie = await readLoginCookie();
88
+ const res = await fetch("https://api.bilibili.com/x/web-interface/nav", {
89
+ method: "GET",
90
+ headers: lodash.merge(BiliApi.BIlIBILI_LOGIN_HEADERS, { 'User-agent': BiliApi.BILIBILI_HEADERS['User-Agent'] }, { "Cookie": `${LoginCookie}`, }),
91
+ redirect: "follow",
92
+ });
93
+ const resData = await res.json();
94
+ Bot.logger?.mark(`B站动态请求code:${JSON.stringify(resData)}`);
95
+ if (resData.code === 0) {
96
+ let uname = resData.data?.uname;
97
+ let mid = resData.data?.mid;
98
+ let money = resData.data?.money;
99
+ let level_info = resData.data?.level_info;
100
+ let current_level = level_info?.current_level;
101
+ let current_exp = level_info?.current_exp;
102
+ let next_exp = level_info?.next_exp;
103
+ e.reply(`~B站账号已登陆~\n昵称:${uname}\nuid:${mid}\n硬币:${money}\n经验等级:${current_level}\n当前经验值exp:${current_exp}\n下一等级所需exp:${next_exp}`);
104
+ }
105
+ else {
106
+ return;
107
+ }
108
+ }
109
+ async function exitBiliLogin(e) {
110
+ const url = 'https://passport.bilibili.com/login/exit/v2';
111
+ const exitCk = await readLoginCookie();
112
+ const [SESSDATA, biliCSRF, DedeUserID] = await Promise.all([
113
+ readSavedCookieItems(exitCk, ['SESSDATA'], false),
114
+ readSavedCookieItems(exitCk, ['bili_jct'], false),
115
+ readSavedCookieItems(exitCk, ['DedeUserID'], false)
116
+ ]);
117
+ if (lodash.trim(SESSDATA).length === 0 || lodash.trim(biliCSRF).length === 0 || lodash.trim(DedeUserID).length === 0) {
118
+ e.reply("当前无可用的B站登录CK可退出登录");
119
+ return;
120
+ }
121
+ const postData = new URLSearchParams({ "biliCSRF": biliCSRF });
122
+ try {
123
+ const resp = await axios.post(url, postData.toString(), {
124
+ headers: {
125
+ "Host": 'passport.bilibili.com',
126
+ "Cookie": `DedeUserID=${DedeUserID}; bili_jct=${biliCSRF}; SESSDATA=${SESSDATA}`,
127
+ "Content-Type": 'application/x-www-form-urlencoded',
128
+ },
129
+ });
130
+ const contentType = resp.headers["Content-Type"];
131
+ if (typeof contentType === 'string' && contentType.includes('text/html')) {
132
+ e.reply("当前缓存的B站登录CK早已失效!");
133
+ return;
134
+ }
135
+ const { code, status, data } = resp.data;
136
+ logger.mark('Response Data:', data);
137
+ if (status) {
138
+ switch (code) {
139
+ case 0:
140
+ e.reply("当前缓存的B站登录CK已在服务器注销~");
141
+ await Redis.set("Yz:yuki:bili:loginCookie", "", { EX: 3600 * 24 * 180 });
142
+ e.reply(`登陆的B站ck并已删除~`);
143
+ break;
144
+ case 2202:
145
+ e.reply("csrf 请求非法,退出登录请求出错");
146
+ break;
147
+ default:
148
+ e.reply("当前缓存的B站登录CK早已失效!");
149
+ }
150
+ }
151
+ else {
152
+ e.reply("服务器响应异常,退出登录请求出错");
153
+ }
154
+ }
155
+ catch (error) {
156
+ console.error('Error during Bili login exit:', error);
157
+ e.reply("退出登录请求出错,请稍后再试");
158
+ }
159
+ }
160
+ async function saveLoginCookie(e, biliLoginCk) {
161
+ if (biliLoginCk && biliLoginCk.length > 0) {
162
+ const LoginCkKey = "Yz:yuki:bili:loginCookie";
163
+ Redis.set(LoginCkKey, biliLoginCk, { EX: 3600 * 24 * 360 });
164
+ }
165
+ else {
166
+ e.reply("扫码超时");
167
+ }
168
+ }
169
+ async function readLoginCookie() {
170
+ const CK_KEY = "Yz:yuki:bili:loginCookie";
171
+ const tempCk = await Redis.get(CK_KEY);
172
+ return tempCk ? tempCk : '';
173
+ }
174
+ async function readLocalBiliCk() {
175
+ const dir = path.join(_paths.root, 'data/yuki-plugin/');
176
+ if (!fs__default.existsSync(dir)) {
177
+ fs__default.mkdirSync(dir, { recursive: true });
178
+ }
179
+ const files = fs__default.readdirSync(dir).filter((file) => file.endsWith('.yaml'));
180
+ const readFile = promisify(fs__default.readFile);
181
+ const promises = files.map((file) => readFile(path.join(dir, file), 'utf8'));
182
+ const contents = await Promise.all(promises);
183
+ const Bck = contents.map((content) => YAML.parse(content));
184
+ return Bck[0];
185
+ }
186
+ async function saveLocalBiliCk(data) {
187
+ const dirPath = path.join(_paths.root, 'data/yuki-plugin/');
188
+ const filePath = path.join(dirPath, 'biliCookie.yaml');
189
+ const cleanedData = String(data).replace(/\s/g, '').trim();
190
+ if (lodash.isEmpty(cleanedData)) {
191
+ fs__default.existsSync(filePath) && fs__default.unlinkSync(filePath);
192
+ }
193
+ else {
194
+ if (!fs__default.existsSync(dirPath)) {
195
+ fs__default.mkdirSync(dirPath, { recursive: true });
196
+ }
197
+ const yamlContent = YAML.stringify(cleanedData);
198
+ fs__default.writeFileSync(filePath, yamlContent, 'utf8');
199
+ }
200
+ }
201
+ async function readTempCk() {
202
+ const CK_KEY = "Yz:yuki:bili:tempCookie";
203
+ const tempCk = await Redis.get(CK_KEY);
204
+ return tempCk ?? '';
205
+ }
206
+ async function saveTempCk(newTempCk) {
207
+ const CK_KEY = "Yz:yuki:bili:tempCookie";
208
+ await Redis.set(CK_KEY, newTempCk, { EX: 3600 * 24 * 180 });
209
+ }
210
+ async function readSyncCookie() {
211
+ const localCk = await readLocalBiliCk();
212
+ const tempCk = await readTempCk();
213
+ const loginCk = await readLoginCookie();
214
+ const validCk = (ck) => ck?.trim().length > 10;
215
+ if (validCk(localCk)) {
216
+ return { cookie: localCk, mark: "localCk" };
217
+ }
218
+ else if (validCk(loginCk)) {
219
+ return { cookie: loginCk + ";", mark: "loginCk" };
220
+ }
221
+ else if (validCk(tempCk)) {
222
+ return { cookie: tempCk, mark: "tempCk" };
223
+ }
224
+ else {
225
+ return { cookie: '', mark: "ckIsEmpty" };
226
+ }
227
+ }
228
+ async function readSavedCookieItems(mark, items, isInverted = false) {
229
+ let ckString;
230
+ switch (mark) {
231
+ case 'localCK':
232
+ ckString = await readLocalBiliCk();
233
+ break;
234
+ case 'tempCK':
235
+ ckString = await readTempCk();
236
+ break;
237
+ case 'loginCK':
238
+ ckString = await readLoginCookie();
239
+ break;
240
+ default:
241
+ ckString = mark;
242
+ }
243
+ const Bck = lodash.trim(ckString);
244
+ if (!Bck) {
245
+ return '';
246
+ }
247
+ if (items[0] === 'all') {
248
+ return Bck;
249
+ }
250
+ const cookiePairs = String(Bck)
251
+ .trim()
252
+ .match(/(\w+)=([^;|,]+)/g)
253
+ ?.map(match => match.split('='))
254
+ .filter(([key, value]) => (isInverted ? !items.includes(key) : items.includes(key)) && value !== '')
255
+ .map(([key, value]) => `${key}=${value}`)
256
+ .join(';') || '';
257
+ return cookiePairs;
258
+ }
259
+ async function readSavedCookieOtherItems(mark, items) {
260
+ return await readSavedCookieItems(mark, items, true);
261
+ }
262
+ async function genUUID() {
263
+ const generatePart = (length) => Array.from({ length }, () => Math.floor(16 * Math.random()))
264
+ .map(num => num.toString(16).toUpperCase())
265
+ .join('');
266
+ const padLeft = (str, length) => str.padStart(length, '0');
267
+ const e = generatePart(8);
268
+ const t = generatePart(4);
269
+ const r = generatePart(4);
270
+ const n = generatePart(4);
271
+ const o = generatePart(12);
272
+ const i = Date.now();
273
+ const uuid = `_uuid=${e}-${t}-${r}-${n}-${o}${padLeft((i % 1e5).toString(), 5)}infoc;`;
274
+ return uuid;
275
+ }
276
+ async function gen_b_lsid() {
277
+ function get_random_str(length) {
278
+ return Array.from({ length }, () => Math.floor(Math.random() * 16).toString(16).toUpperCase()).join('');
279
+ }
280
+ const timestamp = Date.now();
281
+ const randomPart = get_random_str(8);
282
+ const timestampHex = timestamp.toString(16).toUpperCase();
283
+ return `b_lsid=${randomPart}_${timestampHex};`;
284
+ }
285
+ async function getBuvid3_4(uuid) {
286
+ const url = 'https://api.bilibili.com/x/frontend/finger/spi/';
287
+ const headers = lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
288
+ 'Cookie': `_uuid=${uuid}`,
289
+ 'Host': 'api.bilibili.com',
290
+ 'Origin': 'https://www.bilibili.com',
291
+ 'Referer': 'https://www.bilibili.com/',
292
+ });
293
+ const response = await axios.get(url, { headers });
294
+ const { code, data } = response.data;
295
+ if (code === 0) {
296
+ const { b_3: buvid3, b_4: buvid4 } = data;
297
+ return `buvid3=${buvid3};buvid4=${buvid4};`;
298
+ }
299
+ else {
300
+ return '';
301
+ }
302
+ }
303
+ async function getNewTempCk() {
304
+ const uuid = await genUUID();
305
+ const buvid3_buvid4 = await getBuvid3_4(uuid);
306
+ const b_lsid = await gen_b_lsid();
307
+ let newTempCk = `${uuid}${buvid3_buvid4}${b_lsid}`;
308
+ await saveTempCk(newTempCk);
309
+ const result = await postGateway(newTempCk);
310
+ const { code, data } = await result.data;
311
+ if (code !== 0) {
312
+ logger?.mark(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
313
+ }
314
+ else if (code === 0) {
315
+ logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
316
+ }
317
+ }
318
+ async function getPayload(cookie) {
319
+ const payloadOriginData = {
320
+ "3064": 1,
321
+ "5062": `${Date.now()}`,
322
+ "03bf": "https://www.bilibili.com/",
323
+ "39c8": "333.999.fp.risk",
324
+ "34f1": "",
325
+ "d402": "",
326
+ "654a": "",
327
+ "6e7c": "878x1066",
328
+ "3c43": {
329
+ "2673": 0,
330
+ "5766": 24,
331
+ "6527": 0,
332
+ "7003": 1,
333
+ "807e": 1,
334
+ "b8ce": BiliApi.BILIBILI_HEADERS['User-Agent'],
335
+ "641c": 0,
336
+ "07a4": "zh-CN",
337
+ "1c57": "not available",
338
+ "0bd0": 16,
339
+ "748e": [1920, 1200],
340
+ "d61f": [1920, 1152],
341
+ "fc9d": -480,
342
+ "6aa9": "Asia/Shanghai",
343
+ "75b8": 1,
344
+ "3b21": 1,
345
+ "8a1c": 0,
346
+ "d52f": "not available",
347
+ "adca": BiliApi.BILIBILI_HEADERS['User-Agent'].includes('Windows') ? 'Win32' : 'Linux',
348
+ "80c9": [
349
+ ["PDF Viewer", "Portable Document Format", [
350
+ ["application/pdf", "pdf"],
351
+ ["text/pdf", "pdf"]
352
+ ]],
353
+ ["Chrome PDF Viewer", "Portable Document Format", [
354
+ ["application/pdf", "pdf"],
355
+ ["text/pdf", "pdf"]
356
+ ]],
357
+ ["Chromium PDF Viewer", "Portable Document Format", [
358
+ ["application/pdf", "pdf"],
359
+ ["text/pdf", "pdf"]
360
+ ]],
361
+ ["Microsoft Edge PDF Viewer", "Portable Document Format", [
362
+ ["application/pdf", "pdf"],
363
+ ["text/pdf", "pdf"]
364
+ ]],
365
+ ["WebKit built-in PDF", "Portable Document Format", [
366
+ ["application/pdf", "pdf"],
367
+ ["text/pdf", "pdf"]
368
+ ]]
369
+ ],
370
+ "13ab": "f3YAAAAASUVORK5CYII=",
371
+ "bfe9": "kABYpRAGAVYzWJooB9Bf4P+UortSvxRY0AAAAASUVORK5CYII=",
372
+ "a3c1": [
373
+ "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",
374
+ "webgl aliased line width range:[1, 1]",
375
+ "webgl aliased point size range:[1, 1024]",
376
+ "webgl alpha bits:8", "webgl antialiasing:yes",
377
+ "webgl blue bits:8",
378
+ "webgl depth bits:24",
379
+ "webgl green bits:8",
380
+ "webgl max anisotropy:16",
381
+ "webgl max combined texture image units:32",
382
+ "webgl max cube map texture size:16384",
383
+ "webgl max fragment uniform vectors:1024",
384
+ "webgl max render buffer size:16384",
385
+ "webgl max texture image units:16",
386
+ "webgl max texture size:16384",
387
+ "webgl max varying vectors:30",
388
+ "webgl max vertex attribs:16",
389
+ "webgl max vertex texture image units:16",
390
+ "webgl max vertex uniform vectors:4096",
391
+ "webgl max viewport dims:[32767, 32767]",
392
+ "webgl red bits:8",
393
+ "webgl renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar",
394
+ "webgl shading language version:WebGL GLSL ES 1.0",
395
+ "webgl stencil bits:0",
396
+ "webgl vendor:Mozilla",
397
+ "webgl version:WebGL 1.0",
398
+ "webgl unmasked vendor:Google Inc. (Intel)",
399
+ "webgl unmasked renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar",
400
+ "webgl vertex shader high float precision:23",
401
+ "webgl vertex shader high float precision rangeMin:127",
402
+ "webgl vertex shader high float precision rangeMax:127",
403
+ "webgl vertex shader medium float precision:23",
404
+ "webgl vertex shader medium float precision rangeMin:127",
405
+ "webgl vertex shader medium float precision rangeMax:127",
406
+ "webgl vertex shader low float precision:23",
407
+ "webgl vertex shader low float precision rangeMin:127",
408
+ "webgl vertex shader low float precision rangeMax:127",
409
+ "webgl fragment shader high float precision:23",
410
+ "webgl fragment shader high float precision rangeMin:127",
411
+ "webgl fragment shader high float precision rangeMax:127",
412
+ "webgl fragment shader medium float precision:23",
413
+ "webgl fragment shader medium float precision rangeMin:127",
414
+ "webgl fragment shader medium float precision rangeMax:127",
415
+ "webgl fragment shader low float precision:23",
416
+ "webgl fragment shader low float precision rangeMin:127",
417
+ "webgl fragment shader low float precision rangeMax:127",
418
+ "webgl vertex shader high int precision:0",
419
+ "webgl vertex shader high int precision rangeMin:31",
420
+ "webgl vertex shader high int precision rangeMax:30",
421
+ "webgl vertex shader medium int precision:0",
422
+ "webgl vertex shader medium int precision rangeMin:31",
423
+ "webgl vertex shader medium int precision rangeMax:30",
424
+ "webgl vertex shader low int precision:0",
425
+ "webgl vertex shader low int precision rangeMin:31",
426
+ "webgl vertex shader low int precision rangeMax:30",
427
+ "webgl fragment shader high int precision:0",
428
+ "webgl fragment shader high int precision rangeMin:31",
429
+ "webgl fragment shader high int precision rangeMax:30",
430
+ "webgl fragment shader medium int precision:0",
431
+ "webgl fragment shader medium int precision rangeMin:31",
432
+ "webgl fragment shader medium int precision rangeMax:30",
433
+ "webgl fragment shader low int precision:0",
434
+ "webgl fragment shader low int precision rangeMin:31",
435
+ "webgl fragment shader low int precision rangeMax:30"
436
+ ],
437
+ "6bc5": "Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar",
438
+ "ed31": 0,
439
+ "72bd": 0,
440
+ "097b": 0,
441
+ "52cd": [0, 0, 0],
442
+ "a658": ["Arial", "Arial Black", "Calibri", "Cambria", "Cambria Math", "Comic Sans MS", "Consolas", "Courier", "Courier New", "Georgia", "Helvetica", "Impact", "Lucida Console", "Lucida Sans Unicode", "Microsoft Sans Serif", "MS Gothic", "MS PGothic", "MS Sans Serif", "MS Serif", "Palatino Linotype", "Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Light", "Segoe UI Symbol", "Tahoma", "Times", "Times New Roman", "Trebuchet MS", "Verdana", "Wingdings"],
443
+ "d02f": "35.749972093850374"
444
+ },
445
+ "54ef": {
446
+ "in_new_ab ": true,
447
+ "ab_version ": {
448
+ "waterfall_article ": "SHOW "
449
+ },
450
+ "ab_split_num ": {
451
+ "waterfall_article ": 0
452
+ }
453
+ },
454
+ "8b94": "",
455
+ "df35": `${await readSavedCookieItems(cookie, ['_uuid'], false)}`,
456
+ "07a4": "zh-CN",
457
+ "5f45": null,
458
+ "db46": 0
459
+ };
460
+ return JSON.stringify(payloadOriginData);
461
+ }
462
+ async function postGateway(cookie) {
463
+ const payload = getPayload(cookie);
464
+ const requestUrl = 'https://api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi';
465
+ const headers = lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
466
+ 'Cookie': cookie,
467
+ 'Content-type': 'Application/json',
468
+ 'Charset': 'UTF-8',
469
+ }, {
470
+ 'Host': 'api.bilibili.com',
471
+ 'Origin': 'https://www.bilibili.com',
472
+ 'Referer': 'https://www.bilibili.com/',
473
+ });
474
+ try {
475
+ const res = await axios.post(requestUrl, { payload }, { headers });
476
+ return res;
477
+ }
478
+ catch (error) {
479
+ logger.error('Error making POST request:', error);
480
+ throw error;
481
+ }
482
+ }
483
+
484
+ export { applyLoginQRCode, checkBiliLogin, exitBiliLogin, genUUID, gen_b_lsid, getNewTempCk, pollLoginQRCode, postGateway, readSavedCookieItems, readSavedCookieOtherItems, readSyncCookie, readTempCk, saveLocalBiliCk, saveLoginCookie, saveTempCk };