@ikenxuan/amagi 1.5.5 → 1.5.7
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/business/bilibili/API.d.ts +1 -1
- package/lib/business/bilibili/API.js +2 -2
- package/lib/business/bilibili/getdata.js +3 -25
- package/lib/business/bilibili/getid.js +3 -3
- package/lib/business/bilibili/result.js +1 -1
- package/lib/business/bilibili/sign/wbi.js +5 -5
- package/lib/business/douyin/getdata.js +14 -14
- package/lib/business/douyin/getid.js +3 -3
- package/lib/business/douyin/result.js +1 -1
- package/lib/business/douyin/sign/a_bogus.js +32 -31
- package/lib/index.d.ts +5 -5
- package/lib/index.js +5 -5
- package/lib/model/logger.js +15 -15
- package/lib/model/networks.d.ts +30 -30
- package/lib/model/networks.js +211 -209
- package/lib/server/client.d.ts +6 -6
- package/lib/server/client.js +97 -111
- package/lib/server/listen.js +5 -5
- package/lib/types/BilibiliAPIParams.d.ts +4 -2
- package/lib/types/DouyinAPIParams.d.ts +1 -0
- package/package.json +9 -10
- package/amagi.openapi.json +0 -1
|
@@ -4,7 +4,7 @@ declare class BiLiBiLiAPI {
|
|
|
4
4
|
视频详细信息(data: BilibiliAPIParams['VideoInfoParams']): string;
|
|
5
5
|
视频流信息(data: BilibiliAPIParams['VideoStreamParams']): string;
|
|
6
6
|
/** type参数详见https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/comment/readme.md#评论区类型代码 */
|
|
7
|
-
评论区明细(data
|
|
7
|
+
评论区明细(data?: BilibiliAPIParams['CommentParams']): string;
|
|
8
8
|
表情列表(): string;
|
|
9
9
|
番剧明细(data: BilibiliAPIParams['BangumiInfoParams']): string;
|
|
10
10
|
番剧视频流信息(data: BilibiliAPIParams['BangumiStreamParams']): string;
|
|
@@ -9,8 +9,8 @@ class BiLiBiLiAPI {
|
|
|
9
9
|
return `https://api.bilibili.com/x/player/playurl?avid=${data.avid}&cid=${data.cid}`;
|
|
10
10
|
}
|
|
11
11
|
/** type参数详见https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/comment/readme.md#评论区类型代码 */
|
|
12
|
-
评论区明细(data) {
|
|
13
|
-
return `https://api.bilibili.com/x/v2/reply?sort=1&ps
|
|
12
|
+
评论区明细(data = { number: 20 }) {
|
|
13
|
+
return `https://api.bilibili.com/x/v2/reply?sort=1&ps=${data.number}&type=${data.type}&oid=${data.oid}`;
|
|
14
14
|
}
|
|
15
15
|
表情列表() {
|
|
16
16
|
return 'https://api.bilibili.com/x/emote/user/panel/web?business=reply&web_location=0.0';
|
|
@@ -22,7 +22,7 @@ export default class BilibiliData {
|
|
|
22
22
|
url: BiLiBiLiAPI.视频流信息({ avid: INFODATA.data.aid, cid: INFODATA.data.cid }) + SIGN.QUERY,
|
|
23
23
|
headers: this.headers
|
|
24
24
|
});
|
|
25
|
-
return { INFODATA, DATA
|
|
25
|
+
return { INFODATA, DATA };
|
|
26
26
|
}
|
|
27
27
|
case 'CommentData': {
|
|
28
28
|
const INFODATA = await this.GlobalGetData({ url: BiLiBiLiAPI.视频详细信息({ id_type: 'bvid', id: data.bvid }) });
|
|
@@ -94,6 +94,8 @@ export default class BilibiliData {
|
|
|
94
94
|
});
|
|
95
95
|
return result;
|
|
96
96
|
}
|
|
97
|
+
default:
|
|
98
|
+
return null;
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
async GlobalGetData(options) {
|
|
@@ -108,30 +110,6 @@ export default class BilibiliData {
|
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
|
-
function mapping_table(type) {
|
|
112
|
-
// 使用类型断言来告诉 TypeScript 编译器 Array 对象实际上是一个可以接受字符串索引的对象
|
|
113
|
-
const Array = {
|
|
114
|
-
1: ['DYNAMIC_TYPE_AV', 'DYNAMIC_TYPE_PGC', 'DYNAMIC_TYPE_UGC_SEASON'],
|
|
115
|
-
11: ['DYNAMIC_TYPE_DRAW'],
|
|
116
|
-
12: ['DYNAMIC_TYPE_ARTICLE'],
|
|
117
|
-
17: ['DYNAMIC_TYPE_LIVE_RCMD', 'DYNAMIC_TYPE_FORWARD', 'DYNAMIC_TYPE_WORD', 'DYNAMIC_TYPE_COMMON_SQUARE'],
|
|
118
|
-
19: ['DYNAMIC_TYPE_MEDIALIST']
|
|
119
|
-
};
|
|
120
|
-
for (const key in Array) {
|
|
121
|
-
if (Array[key].includes(type)) {
|
|
122
|
-
return parseInt(key);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return 1;
|
|
126
|
-
}
|
|
127
|
-
function oid(dynamicINFO, dynamicINFO_CARD) {
|
|
128
|
-
if (dynamicINFO.data.item.type == 'DYNAMIC_TYPE_WORD') {
|
|
129
|
-
return dynamicINFO.data.item.id_str;
|
|
130
|
-
}
|
|
131
|
-
else
|
|
132
|
-
return dynamicINFO_CARD.data.card.desc.rid;
|
|
133
|
-
}
|
|
134
|
-
// 同上
|
|
135
113
|
const errorMap = {
|
|
136
114
|
'-1': '应用程序不存在或已被封禁',
|
|
137
115
|
'-2': 'Access Key 错误',
|
|
@@ -12,7 +12,7 @@ export default async function GetBilibiliID(url) {
|
|
|
12
12
|
const bvideoMatch = longLink.match(/video\/([A-Za-z0-9]+)/);
|
|
13
13
|
result = {
|
|
14
14
|
type: "VideoData" /* BilibiliDataType['单个视频作品数据'] */,
|
|
15
|
-
id: bvideoMatch ? bvideoMatch[1] : ''
|
|
15
|
+
id: bvideoMatch ? bvideoMatch[1] : ''
|
|
16
16
|
};
|
|
17
17
|
break;
|
|
18
18
|
}
|
|
@@ -20,7 +20,7 @@ export default async function GetBilibiliID(url) {
|
|
|
20
20
|
const playMatch = longLink.match(/play\/(\w+)/);
|
|
21
21
|
result = {
|
|
22
22
|
type: "BangumiVideoData" /* BilibiliDataType['番剧基本信息数据'] */,
|
|
23
|
-
id: playMatch ? playMatch[1] : ''
|
|
23
|
+
id: playMatch ? playMatch[1] : ''
|
|
24
24
|
};
|
|
25
25
|
break;
|
|
26
26
|
}
|
|
@@ -30,7 +30,7 @@ export default async function GetBilibiliID(url) {
|
|
|
30
30
|
const dynamic_id = tMatch || opusMatch;
|
|
31
31
|
result = {
|
|
32
32
|
type: "DynamicInfoData" /* BilibiliDataType['动态详情数据'] */,
|
|
33
|
-
dynamic_id: dynamic_id ? dynamic_id[1] : ''
|
|
33
|
+
dynamic_id: dynamic_id ? dynamic_id[1] : ''
|
|
34
34
|
};
|
|
35
35
|
break;
|
|
36
36
|
}
|
|
@@ -34,7 +34,7 @@ export default class BilibiliResult {
|
|
|
34
34
|
return {
|
|
35
35
|
code: result !== false && result !== '' ? 200 : 503,
|
|
36
36
|
message: result !== !false && result !== '' ? 'success' : 'error',
|
|
37
|
-
data: result !== !false && result !== '' ? result : null
|
|
37
|
+
data: result !== !false && result !== '' ? result : null
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -2,7 +2,7 @@ import md5 from 'md5';
|
|
|
2
2
|
import fetch from 'node-fetch';
|
|
3
3
|
const mixinKeyEncTab = [
|
|
4
4
|
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,
|
|
5
|
-
17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52
|
|
5
|
+
17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52
|
|
6
6
|
];
|
|
7
7
|
// 对 imgKey 和 subKey 进行字符顺序打乱编码
|
|
8
8
|
const getMixinKey = (orig) => mixinKeyEncTab
|
|
@@ -31,16 +31,16 @@ function encWbi(params, img_key, sub_key) {
|
|
|
31
31
|
async function getWbiKeys(cookie) {
|
|
32
32
|
const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
|
|
33
33
|
headers: {
|
|
34
|
-
Cookie: cookie
|
|
35
|
-
}
|
|
34
|
+
Cookie: cookie
|
|
35
|
+
}
|
|
36
36
|
});
|
|
37
37
|
const responseJson = await res.json();
|
|
38
38
|
const response = responseJson; // 类型断言
|
|
39
39
|
// 确保response是ResponseData类型后再解构
|
|
40
|
-
const { data: { wbi_img: { img_url, sub_url }
|
|
40
|
+
const { data: { wbi_img: { img_url, sub_url } } } = response;
|
|
41
41
|
return {
|
|
42
42
|
img_key: img_url.slice(img_url.lastIndexOf('/') + 1, img_url.lastIndexOf('.')),
|
|
43
|
-
sub_key: sub_url.slice(sub_url.lastIndexOf('/') + 1, sub_url.lastIndexOf('.'))
|
|
43
|
+
sub_key: sub_url.slice(sub_url.lastIndexOf('/') + 1, sub_url.lastIndexOf('.'))
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
export default async function wbi_sign(BASEURL, cookie) {
|
|
@@ -23,21 +23,21 @@ export default class DouyinData {
|
|
|
23
23
|
const VideoData = await this.GlobalGetData({
|
|
24
24
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
25
25
|
method: 'GET',
|
|
26
|
-
headers: this.headers
|
|
26
|
+
headers: this.headers
|
|
27
27
|
});
|
|
28
28
|
return VideoData;
|
|
29
29
|
case 'CommentData':
|
|
30
30
|
this.URL = DouyinAPI.评论({ aweme_id: data.aweme_id });
|
|
31
31
|
const CommentsData = await this.GlobalGetData({
|
|
32
32
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
33
|
-
headers: this.headers
|
|
33
|
+
headers: this.headers
|
|
34
34
|
});
|
|
35
35
|
return CommentsData;
|
|
36
36
|
case 'CommentReplyData':
|
|
37
37
|
this.URL = DouyinAPI.二级评论({ aweme_id: data.aweme_id, comment_id: data.comment_id });
|
|
38
38
|
const CommentReplyData = await this.GlobalGetData({
|
|
39
39
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
40
|
-
headers: this.headers
|
|
40
|
+
headers: this.headers
|
|
41
41
|
});
|
|
42
42
|
return CommentReplyData;
|
|
43
43
|
case 'UserInfoData':
|
|
@@ -46,15 +46,15 @@ export default class DouyinData {
|
|
|
46
46
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
47
47
|
headers: {
|
|
48
48
|
...this.headers,
|
|
49
|
-
Referer: `https://www.douyin.com/user/${data.sec_uid}
|
|
50
|
-
}
|
|
49
|
+
Referer: `https://www.douyin.com/user/${data.sec_uid}`
|
|
50
|
+
}
|
|
51
51
|
});
|
|
52
52
|
return UserInfoData;
|
|
53
53
|
case 'EmojiData':
|
|
54
54
|
this.URL = DouyinAPI.表情();
|
|
55
55
|
const EmojiData = await this.GlobalGetData({
|
|
56
56
|
url: this.URL,
|
|
57
|
-
headers: this.headers
|
|
57
|
+
headers: this.headers
|
|
58
58
|
});
|
|
59
59
|
return EmojiData;
|
|
60
60
|
case 'UserVideosListData':
|
|
@@ -63,8 +63,8 @@ export default class DouyinData {
|
|
|
63
63
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
64
64
|
headers: {
|
|
65
65
|
...this.headers,
|
|
66
|
-
Referer: `https://www.douyin.com/user/${data.sec_uid}
|
|
67
|
-
}
|
|
66
|
+
Referer: `https://www.douyin.com/user/${data.sec_uid}`
|
|
67
|
+
}
|
|
68
68
|
});
|
|
69
69
|
return UserVideoListData;
|
|
70
70
|
case 'SuggestWordsData':
|
|
@@ -73,8 +73,8 @@ export default class DouyinData {
|
|
|
73
73
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
74
74
|
headers: {
|
|
75
75
|
...this.headers,
|
|
76
|
-
Referer: `https://www.douyin.com/search/${encodeURIComponent(String(data.query))}
|
|
77
|
-
}
|
|
76
|
+
Referer: `https://www.douyin.com/search/${encodeURIComponent(String(data.query))}`
|
|
77
|
+
}
|
|
78
78
|
});
|
|
79
79
|
return SuggestWordsData;
|
|
80
80
|
case 'SearchData':
|
|
@@ -83,22 +83,22 @@ export default class DouyinData {
|
|
|
83
83
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
84
84
|
headers: {
|
|
85
85
|
...this.headers,
|
|
86
|
-
Referer: `https://www.douyin.com/https://www.douyin.com/search/${encodeURIComponent(String(data.query))}
|
|
87
|
-
}
|
|
86
|
+
Referer: `https://www.douyin.com/https://www.douyin.com/search/${encodeURIComponent(String(data.query))}`
|
|
87
|
+
}
|
|
88
88
|
});
|
|
89
89
|
return SearchData;
|
|
90
90
|
case 'ExpressionPlusData':
|
|
91
91
|
this.URL = DouyinAPI.互动表情();
|
|
92
92
|
const ExpressionPlusData = await this.GlobalGetData({
|
|
93
93
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
94
|
-
headers: this.headers
|
|
94
|
+
headers: this.headers
|
|
95
95
|
});
|
|
96
96
|
return ExpressionPlusData;
|
|
97
97
|
case 'MusicData':
|
|
98
98
|
this.URL = DouyinAPI.背景音乐({ music_id: data.music_id });
|
|
99
99
|
const MusicData = await this.GlobalGetData({
|
|
100
100
|
url: `${this.URL}&a_bogus=${Sign.AB(this.URL)}`,
|
|
101
|
-
headers: this.headers
|
|
101
|
+
headers: this.headers
|
|
102
102
|
});
|
|
103
103
|
return MusicData;
|
|
104
104
|
default:
|
|
@@ -12,21 +12,21 @@ export default async function GetDouyinID(url) {
|
|
|
12
12
|
const videoMatch = longLink.match(/video\/(\d+)/);
|
|
13
13
|
result = {
|
|
14
14
|
type: "VideoData" /* DouyinDataType['单个视频作品数据'] */,
|
|
15
|
-
aweme_id: videoMatch ? videoMatch[1] : ''
|
|
15
|
+
aweme_id: videoMatch ? videoMatch[1] : ''
|
|
16
16
|
};
|
|
17
17
|
break;
|
|
18
18
|
case /note\/(\d+)/.test(longLink):
|
|
19
19
|
const noteMatch = longLink.match(/note\/(\d+)/);
|
|
20
20
|
result = {
|
|
21
21
|
type: "NoteData" /* DouyinDataType['图集作品数据'] */,
|
|
22
|
-
aweme_id: noteMatch ? noteMatch[1] : ''
|
|
22
|
+
aweme_id: noteMatch ? noteMatch[1] : ''
|
|
23
23
|
};
|
|
24
24
|
break;
|
|
25
25
|
case /user\/(\S+?)\?/.test(longLink):
|
|
26
26
|
const userMatch = longLink.match(/user\/(\S+?)\?/);
|
|
27
27
|
result = {
|
|
28
28
|
type: "UserVideosListData" /* DouyinDataType['用户主页视频列表数据'] */,
|
|
29
|
-
sec_uid: userMatch ? userMatch[1] : ''
|
|
29
|
+
sec_uid: userMatch ? userMatch[1] : ''
|
|
30
30
|
};
|
|
31
31
|
break;
|
|
32
32
|
default:
|
|
@@ -35,7 +35,7 @@ export default class DouyinResult {
|
|
|
35
35
|
return {
|
|
36
36
|
code: result !== false && result !== '' ? 200 : 503,
|
|
37
37
|
message: result !== false && result !== '' ? 'success' : 'error',
|
|
38
|
-
data: result !== false && result !== '' ? result : null
|
|
38
|
+
data: result !== false && result !== '' ? result : null
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -32,7 +32,7 @@ class SM3 {
|
|
|
32
32
|
this.chunk = this.chunk.concat(a.slice(0, f));
|
|
33
33
|
while (this.chunk.length >= 64) {
|
|
34
34
|
this._compress(this.chunk);
|
|
35
|
-
f < a.length ? this.chunk = a.slice(f, Math.min(f + 64, a.length)) : this.chunk = [];
|
|
35
|
+
f < a.length ? (this.chunk = a.slice(f, Math.min(f + 64, a.length))) : (this.chunk = []);
|
|
36
36
|
f += 64;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -71,11 +71,12 @@ class SM3 {
|
|
|
71
71
|
}
|
|
72
72
|
_compress(t) {
|
|
73
73
|
if (t.length < 64) {
|
|
74
|
-
console.error(
|
|
74
|
+
console.error('compress error: not enough data');
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
77
|
for (var f = ((e) => {
|
|
78
78
|
for (var r = new Array(132), t = 0; t < 16; t++) {
|
|
79
|
+
;
|
|
79
80
|
(r[t] = e[4 * t] << 24), (r[t] |= e[4 * t + 1] << 16), (r[t] |= e[4 * t + 2] << 8), (r[t] |= e[4 * t + 3]), (r[t] >>>= 0);
|
|
80
81
|
}
|
|
81
82
|
for (var n = 16; n < 68; n++) {
|
|
@@ -124,16 +125,16 @@ class SM3 {
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
de(e) {
|
|
127
|
-
return 0 <= e && e < 16 ? 2043430169 : 16 <= e && e < 64 ? 2055708042 : (console.error(
|
|
128
|
+
return 0 <= e && e < 16 ? 2043430169 : 16 <= e && e < 64 ? 2055708042 : (console.error('invalid j for constant Tj'), 0);
|
|
128
129
|
}
|
|
129
130
|
pe(e, r, t, n) {
|
|
130
|
-
return 0 <= e && e < 16 ? (r ^ t ^ n) >>> 0 : 16 <= e && e < 64 ? (r & t | r & n | t & n) >>> 0 : (console.error('invalid j for bool function FF'), 0);
|
|
131
|
+
return 0 <= e && e < 16 ? (r ^ t ^ n) >>> 0 : 16 <= e && e < 64 ? ((r & t) | (r & n) | (t & n)) >>> 0 : (console.error('invalid j for bool function FF'), 0);
|
|
131
132
|
}
|
|
132
133
|
he(e, r, t, n) {
|
|
133
|
-
return 0 <= e && e < 16 ? (r ^ t ^ n) >>> 0 : 16 <= e && e < 64 ? (r & t | ~r & n) >>> 0 : (console.error('invalid j for bool function GG'), 0);
|
|
134
|
+
return 0 <= e && e < 16 ? (r ^ t ^ n) >>> 0 : 16 <= e && e < 64 ? ((r & t) | (~r & n)) >>> 0 : (console.error('invalid j for bool function GG'), 0);
|
|
134
135
|
}
|
|
135
136
|
le(e, r) {
|
|
136
|
-
return (e << (r %= 32) | e >>> 32 - r) >>> 0;
|
|
137
|
+
return ((e << (r %= 32)) | (e >>> (32 - r))) >>> 0;
|
|
137
138
|
}
|
|
138
139
|
stringToBytes(str) {
|
|
139
140
|
const n = encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_, r) => String.fromCharCode(parseInt(r, 16)));
|
|
@@ -179,18 +180,18 @@ function result_encrypt(long_str, num) {
|
|
|
179
180
|
s1: 'Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=',
|
|
180
181
|
s2: 'Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=',
|
|
181
182
|
s3: 'ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe',
|
|
182
|
-
s4: 'Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe'
|
|
183
|
+
s4: 'Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe',
|
|
183
184
|
};
|
|
184
185
|
const constant = {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
'0': 16515072,
|
|
187
|
+
'1': 258048,
|
|
188
|
+
'2': 4032,
|
|
189
|
+
str: s_obj[num],
|
|
189
190
|
};
|
|
190
|
-
let result =
|
|
191
|
+
let result = '';
|
|
191
192
|
let lound = 0;
|
|
192
193
|
let long_int = get_long_int(lound, long_str);
|
|
193
|
-
for (let i = 0; i < long_str.length / 3 * 4; i++) {
|
|
194
|
+
for (let i = 0; i < (long_str.length / 3) * 4; i++) {
|
|
194
195
|
if (Math.floor(i / 4) !== lound) {
|
|
195
196
|
lound += 1;
|
|
196
197
|
long_int = get_long_int(lound, long_str);
|
|
@@ -199,20 +200,20 @@ function result_encrypt(long_str, num) {
|
|
|
199
200
|
let temp_int;
|
|
200
201
|
switch (key) {
|
|
201
202
|
case 0:
|
|
202
|
-
temp_int = (long_int & constant[
|
|
203
|
-
result += constant[
|
|
203
|
+
temp_int = (long_int & constant['0']) >> 18;
|
|
204
|
+
result += constant['str'].charAt(temp_int);
|
|
204
205
|
break;
|
|
205
206
|
case 1:
|
|
206
|
-
temp_int = (long_int & constant[
|
|
207
|
-
result += constant[
|
|
207
|
+
temp_int = (long_int & constant['1']) >> 12;
|
|
208
|
+
result += constant['str'].charAt(temp_int);
|
|
208
209
|
break;
|
|
209
210
|
case 2:
|
|
210
|
-
temp_int = (long_int & constant[
|
|
211
|
-
result += constant[
|
|
211
|
+
temp_int = (long_int & constant['2']) >> 6;
|
|
212
|
+
result += constant['str'].charAt(temp_int);
|
|
212
213
|
break;
|
|
213
214
|
case 3:
|
|
214
215
|
temp_int = long_int & 63;
|
|
215
|
-
result += constant[
|
|
216
|
+
result += constant['str'].charAt(temp_int);
|
|
216
217
|
break;
|
|
217
218
|
default:
|
|
218
219
|
break;
|
|
@@ -226,13 +227,13 @@ function get_long_int(round, long_str) {
|
|
|
226
227
|
}
|
|
227
228
|
function gener_random(random, option) {
|
|
228
229
|
return [
|
|
229
|
-
(random & 255 & 170) | option[0] & 85, // 163
|
|
230
|
-
(random & 255 & 85) | option[0] & 170, //87
|
|
231
|
-
(random >> 8 & 255 & 170) | option[1] & 85, //37
|
|
232
|
-
(random >> 8 & 255 & 85) | option[1] & 170, //41
|
|
230
|
+
(random & 255 & 170) | (option[0] & 85), // 163
|
|
231
|
+
(random & 255 & 85) | (option[0] & 170), //87
|
|
232
|
+
((random >> 8) & 255 & 170) | (option[1] & 85), //37
|
|
233
|
+
((random >> 8) & 255 & 85) | (option[1] & 170), //41
|
|
233
234
|
];
|
|
234
235
|
}
|
|
235
|
-
function generate_rc4_bb_str(url_search_params, user_agent, window_env_str, suffix =
|
|
236
|
+
function generate_rc4_bb_str(url_search_params, user_agent, window_env_str, suffix = 'cus', Arguments = [0, 1, 14]) {
|
|
236
237
|
let sm3 = new SM3();
|
|
237
238
|
let start_time = Date.now();
|
|
238
239
|
// url_search_params两次sm3之的结果
|
|
@@ -254,19 +255,19 @@ function generate_rc4_bb_str(url_search_params, user_agent, window_env_str, suff
|
|
|
254
255
|
ddrt: 7,
|
|
255
256
|
paths: {
|
|
256
257
|
include: [{}, {}, {}, {}, {}, {}, {}],
|
|
257
|
-
exclude: []
|
|
258
|
+
exclude: [],
|
|
258
259
|
},
|
|
259
260
|
track: {
|
|
260
261
|
mode: 0,
|
|
261
262
|
delay: 300,
|
|
262
|
-
paths: []
|
|
263
|
+
paths: [],
|
|
263
264
|
},
|
|
264
265
|
dump: true,
|
|
265
|
-
rpU: ''
|
|
266
|
+
rpU: '',
|
|
266
267
|
},
|
|
267
268
|
16: start_time, // 3次加密开始时间
|
|
268
269
|
18: 44, // 固定
|
|
269
|
-
19: [1, 0, 1, 5]
|
|
270
|
+
19: [1, 0, 1, 5],
|
|
270
271
|
};
|
|
271
272
|
// 3次加密开始时间
|
|
272
273
|
b[20] = (b[16] >> 24) & 255;
|
|
@@ -444,7 +445,7 @@ function generate_rc4_bb_str(url_search_params, user_agent, window_env_str, suff
|
|
|
444
445
|
b[65],
|
|
445
446
|
b[66],
|
|
446
447
|
b[70],
|
|
447
|
-
b[71]
|
|
448
|
+
b[71],
|
|
448
449
|
];
|
|
449
450
|
bb = bb.concat(window_env_list).concat(b[72]);
|
|
450
451
|
return rc4_encrypt(String.fromCharCode.apply(null, bb), String.fromCharCode.apply(null, [121]));
|
|
@@ -457,6 +458,6 @@ function generate_random_str() {
|
|
|
457
458
|
return String.fromCharCode.apply(null, random_str_list);
|
|
458
459
|
}
|
|
459
460
|
export default (url, user_agent) => {
|
|
460
|
-
let result_str = generate_random_str() + generate_rc4_bb_str(
|
|
461
|
+
let result_str = generate_random_str() + generate_rc4_bb_str(new URLSearchParams(new URL(url).search).toString(), user_agent, '1536|747|1536|834|0|30|0|0|1536|834|1536|864|1525|747|24|24|Win32');
|
|
461
462
|
return result_encrypt(result_str, 's4') + '=';
|
|
462
463
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
import { client } from
|
|
1
|
+
export * from "./model/index.js";
|
|
2
|
+
export * from "./business/index.js";
|
|
3
|
+
export * from "./types/index.js";
|
|
4
|
+
export * from "./server/index.js";
|
|
5
|
+
import { client } from "./server/index.js";
|
|
6
6
|
declare const amagi: typeof client;
|
|
7
7
|
export { amagi as default };
|
|
8
8
|
export { amagi as Amagi };
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
import { client } from
|
|
1
|
+
export * from "./model/index.js";
|
|
2
|
+
export * from "./business/index.js";
|
|
3
|
+
export * from "./types/index.js";
|
|
4
|
+
export * from "./server/index.js";
|
|
5
|
+
import { client } from "./server/index.js";
|
|
6
6
|
const amagi = client;
|
|
7
7
|
export { amagi as default };
|
|
8
8
|
export { amagi as Amagi };
|
package/lib/model/logger.js
CHANGED
|
@@ -2,27 +2,27 @@ import log from 'loglevel';
|
|
|
2
2
|
import prefix from 'loglevel-plugin-prefix';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
const colors = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
TRACE: chalk.magenta,
|
|
6
|
+
DEBUG: chalk.cyan,
|
|
7
|
+
INFO: chalk.blue,
|
|
8
|
+
WARN: chalk.yellow,
|
|
9
|
+
ERROR: chalk.red
|
|
10
10
|
};
|
|
11
11
|
prefix.reg(log);
|
|
12
12
|
log.enableAll();
|
|
13
13
|
prefix.apply(log, {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
format(level, name, timestamp) {
|
|
15
|
+
const levelKey = level.toUpperCase();
|
|
16
|
+
if (!(levelKey in colors)) {
|
|
17
|
+
throw new Error(`Invalid log level: ${levelKey}`);
|
|
18
|
+
}
|
|
19
|
+
return `${chalk.gray(`[${timestamp}]`)} ${colors[levelKey](level)} ${chalk.green(`${name}:`)}`;
|
|
20
|
+
}
|
|
21
21
|
});
|
|
22
22
|
prefix.apply(log.getLogger('critical'), {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
format(level, name, timestamp) {
|
|
24
|
+
return chalk.red.bold(`[${timestamp}] ${level} ${name}:`);
|
|
25
|
+
}
|
|
26
26
|
});
|
|
27
27
|
const logger = log;
|
|
28
28
|
export default logger;
|
package/lib/model/networks.d.ts
CHANGED
|
@@ -4,35 +4,35 @@ interface HeadersObject {
|
|
|
4
4
|
[key: string]: string;
|
|
5
5
|
}
|
|
6
6
|
export default class Networks {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
7
|
+
url: string | URL;
|
|
8
|
+
method: string;
|
|
9
|
+
Headers: any;
|
|
10
|
+
type: string;
|
|
11
|
+
body?: string;
|
|
12
|
+
fetch: any;
|
|
13
|
+
isGetResult: boolean;
|
|
14
|
+
timeout: number;
|
|
15
|
+
timer: NodeJS.Timeout | undefined;
|
|
16
|
+
data: {};
|
|
17
|
+
redirect: string;
|
|
18
|
+
constructor(data: NetworksConfigType);
|
|
19
|
+
get config(): NetworksConfigType;
|
|
20
|
+
getfetch(): Promise<Response | boolean>;
|
|
21
|
+
returnResult(): Promise<Response>;
|
|
22
|
+
/** 最终地址(跟随重定向) */
|
|
23
|
+
getLongLink(): Promise<string>;
|
|
24
|
+
/** 获取首个302 */
|
|
25
|
+
getLocation(): Promise<string>;
|
|
26
|
+
/** 获取数据并处理数据的格式化,默认json */
|
|
27
|
+
getData(new_fetch?: string): Promise<any | boolean>;
|
|
28
|
+
/** 获取响应头 */
|
|
29
|
+
getHeaders(): Promise<HeadersObject | null>;
|
|
30
|
+
/** 一次性获取响应头和响应体 */
|
|
31
|
+
getHeadersAndData(): Promise<object>;
|
|
32
|
+
Tojson(): Promise<any>;
|
|
33
|
+
ToText(): Promise<void>;
|
|
34
|
+
ToArrayBuffer(): Promise<void>;
|
|
35
|
+
ToBlob(): Promise<void>;
|
|
36
|
+
timeoutPromise(timeout: number): Promise<Response>;
|
|
37
37
|
}
|
|
38
38
|
export {};
|