-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
466 lines (462 loc) · 13.5 KB
/
index.ts
1
2
3
4
5
6
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
37
38
39
40
41
42
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
import Plugin, { tools, AppClient } from '../../plugin'
class MainSite extends Plugin {
constructor() {
super()
}
public name = '主站功能'
public description = '每天自动做主站功能(观看、分享、投币、漫画(签到,分享))'
public version = '0.0.7'
public author = 'Vector000'
public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set<string> }) {
// 自动签到
defaultOptions.newUserData['main'] = false
defaultOptions.newUserData['mainCoin'] = false
defaultOptions.newUserData['mainCoinGroup'] = []
defaultOptions.info['main'] = {
description: '主站功能',
tip: '每天自动完成主站功能(观看、分享、漫画(签到,分享)、投币[可选])',
type: 'boolean'
}
defaultOptions.info['mainCoin'] = {
description: '主站投币',
tip: '每天自动完成主站投币(不勾选主站功能时此项无效)',
type: 'boolean'
}
defaultOptions.info['mainCoinGroup'] = {
description: '主站up主',
tip: '指定UP主的UID为任务、投币对象,以\",\"间隔;若留空,则任务、投币对象为随机选择该用户的关注up主(不勾选主站投币功能时此项无效)',
type: 'numberArray'
}
whiteList.add('main')
whiteList.add('mainCoin')
whiteList.add('mainCoinGroup')
this.loaded = true
}
public async start({ users }: { users: Map<string, User> }) {
this._bilibili(users)
}
public async loop({ cstMin, cstHour, users }: { cstMin: number, cstHour: number, users: Map<string, User> }) {
if (cstMin === 30 && cstHour % 8 === 4) this._bilibili(users) // 每天04:30, 12:30, 20:30做主站任务
}
/**
* 获取关注列表
*
* @param {User} user
* @returns {number[]}
*/
private async _getAttentionList(user: User) {
let mids: number[] = []
const attentions: XHRoptions = {
url: `https://api.bilibili.com/x/relation/followings?vmid=${user.biliUID}&ps=50&order=desc`,
cookieJar: user.jar,
responseType: 'json',
headers: { "Host": "api.bilibili.com" }
}
const getAttentions = await tools.XHR<attentions>(attentions)
if (getAttentions === undefined) return
if (getAttentions.response.statusCode !== 200) return tools.Log(getAttentions)
if (getAttentions.body.data.list.length > 0) getAttentions.body.data.list.forEach(item => mids.push(item.mid))
if ((<number[]>user.userData.mainCoinGroup).length > 0) mids = <number[]>user.userData.mainCoinGroup
return mids
}
/**
* 获取视频列表
*
* @param {number[]} mids
* @returns {number[]}
*/
private async _getVideoList(mids: number[]) {
let aids: number[] = []
for (let mid of mids) {
const summitVideo: XHRoptions = {
url: `https://api.bilibili.com/x/space/arc/search?mid=${mid}&ps=30&tid=0&pn=1&keyword=&order=pubdate`,
responseType: 'json'
}
const getSummitVideo = await tools.XHR<getSummitVideo>(summitVideo)
if (getSummitVideo === undefined || getSummitVideo.response.statusCode !== 200) continue
else if (getSummitVideo.body.data === undefined || getSummitVideo.body.data === null) continue
else if (getSummitVideo.body.data.list.vlist.length === 0) continue
else getSummitVideo.body.data.list.vlist.forEach(item => { aids.push(item.aid) })
await tools.Sleep(3 * 1000)
}
return aids
}
/**
* 获取cid(视频av号各p对应唯一值)
*
* @param {number} aid
* @returns {number}
*/
private async _getCid(aid: number) {
const cid: XHRoptions = {
url: `https://api.bilibili.com/x/player/pagelist?aid=${aid}`,
responseType: 'json'
}
const getCid = await tools.XHR<any>(cid)
if (getCid === undefined) return
let cids = <getCid>({ data: [] })
cids.data = <cid[]>getCid.body.data
return cids.data[0].cid
}
/**
* 主站功能
*
* @private
* @memberof MainSite
*/
private _bilibili(users: Map<string, User>) {
users.forEach(async (user) => {
if (!user.userData['main']) return
const reward: XHRoptions = {
url: `https://account.bilibili.com/home/reward`,
cookieJar: user.jar,
responseType: 'json',
headers: {
"Referer": `https://account.bilibili.com/account/home`,
"Host": `account.bilibili.com`
}
}
const mainReward = await tools.XHR<mainReward>(reward)
if (await this._getComicInfo(user)) await this._mainComic(user)
if (mainReward === undefined) return
let mids = await this._getAttentionList(user)
let aids: number[] = []
if (mids === undefined || mids.length === 0) {
await (await this._getRankVideo()).forEach(item => aids.push(item.aid))
} else {
aids = await this._getVideoList(mids)
}
if (aids.length === 0) return tools.Log(user.nickname, `视频列表空空的哦,去关注几个up主吧~`)
let aid: number = aids[Math.floor(Math.random() * (aids.length))]
let cid: number = <number>(await this._getCid(aid))
if (cid === undefined) return tools.Log(user.nickname, `获取cid失败`)
if (mainReward.body.data.watch_av) tools.Log(user.nickname, `今天已经看过视频啦~`)
else await this._mainSiteWatch(user, aid, cid)
if (mainReward.body.data.share_av) tools.Log(user.nickname, `今天已经分享过视频啦~`)
else await this._mainSiteShare(user, aid)
if (user.userData['mainCoin']) await this._mainSiteCoin(user, aids, mainReward.body.data.coins_av)
})
}
/**
* 主站观看
*
* @private
* @memberof MainSite
*/
private async _mainSiteWatch(user: User, aid: number, cid: number) {
let ts = Date.now()
const heart: XHRoptions = {
method: 'POST',
url: `https://api.bilibili.com/x/report/web/heartbeat`,
body: `aid=${aid}&cid=${cid}&mid=${user.biliUID}&csrf=${tools.getCookie(user.jar, 'bili_jct')}&played_time=3&realtime=3&start_ts=${ts}&type=3&dt=2&play_type=1`,
cookieJar: user.jar,
responseType: 'json',
headers: {
"Host": "api.bilibili.com",
"Referer": `https://www.bilibili.com/video/av${aid}`
}
}
const avHeart = await tools.XHR<avHeart>(heart)
if (avHeart !== undefined && avHeart.body.code === 0) tools.Log(user.nickname, `已完成主站观看,经验+5`)
else tools.Log(user.nickname, `主站观看失败`)
}
private async _getRankVideo() {
const ranking: XHRoptions = {
method: 'GET',
url: `https://api.bilibili.com/x/web-interface/ranking/v2?rid=0&type=all`,
responseType: 'json',
headers: {
"Host": "api.bilibili.com",
"Referer": `https://www.bilibili.com/`
}
}
const rankList = await tools.XHR<rank>(ranking)
if (rankList !== undefined && rankList.response.statusCode === 200 && rankList.body.code === 0) {
return rankList.body.data.list
} else {
return []
}
}
/**
* 主站分享
*
* @private
* @memberof MainSite
*/
private async _mainSiteShare(user: User, aid: number) {
let ts = Date.now()
const share: XHRoptions = {
method: 'POST',
url: `https://app.bilibili.com/x/v2/view/share/add`,
body: AppClient.signQuery(`access_key=${user.accessToken}&aid=${aid}&appkey=${AppClient.appKey}&build=${AppClient.build}&from=7&mobi_app=android&platform=android&ts=${ts}`),
cookieJar: user.jar,
responseType: 'json',
headers: { "Host": "app.bilibili.com" }
}
const shareAV = await tools.XHR<shareAV>(share, 'Android')
if (shareAV !== undefined && shareAV.body.code === 0) tools.Log(user.nickname, `已完成主站分享,经验+5`)
else tools.Log(user.nickname, `主站分享失败`)
}
/**
* 主站投币
*
* @private
* @memberof MainSite
*/
private async _mainSiteCoin(user: User, aids: number[], coins_av: number) {
if (coins_av === 50) return tools.Log(user.nickname, `已达到投币上限啦~`)
const userInfo: XHRoptions = {
url: `https://account.bilibili.com/site/getCoin`,
cookieJar: user.jar,
responseType: 'json',
headers: {
"Referer": `https://account.bilibili.com/account/home`,
"Host": `account.bilibili.com`
}
}
const mainUserInfo = await tools.XHR<mainUserInfo>(userInfo)
if (mainUserInfo === undefined) return
let coins = mainUserInfo.body.data.money
if (coins === 0) return tools.Log(user.nickname, `已经没有硬币啦~`)
while (coins > 0 && coins_av < 50 && aids.length > 0) {
let i = Math.floor(Math.random() * (aids.length))
let aid = aids[i]
const addCoin: XHRoptions = {
method: 'POST',
url: `https://api.bilibili.com/x/web-interface/coin/add`,
body: `aid=${aid}&multiply=1&select_like=0&cross_domain=true&csrf=${tools.getCookie(user.jar, 'bili_jct')}`,
cookieJar: user.jar,
responseType: 'json',
headers: {
"Referer": `https://www.bilibili.com/av${aid}`,
"Origin": "https://www.bilibili.com",
"Host": `api.bilibili.com`
}
}
const coinAdd = await tools.XHR<coinAdd>(addCoin)
if (coinAdd === undefined || coinAdd.body.code === 34005) continue
if (coinAdd.body.code === 0) {
coins--
coins_av = coins_av + 10
}
aids.splice(i, 1)
await tools.Sleep(3 * 1000)
}
tools.Log(user.nickname, `已完成主站投币,经验+${coins_av}`)
}
/**
* 获取漫画签到信息
*
* @private
* @param user
* @memberof _getComicInfo
*/
private async _getComicInfo(user: User) {
let ts = Date.now()
const sign: XHRoptions = {
method: 'POST',
url: `https://manga.bilibili.com/twirp/activity.v1.Activity/GetClockInInfo`,
body: AppClient.signQuery(`access_key=${user.accessToken}&platform=android&ts=${ts}`),
cookieJar: user.jar,
responseType: 'json'
}
const comicInfo = await tools.XHR<comicUserInfo>(sign, 'Android')
if (comicInfo !== undefined && comicInfo.body.code === 0 && comicInfo.body.data.status === 0) return true
return false
}
/**
* 漫画签到分享
*
* @private
* @param user
* @memberof _mainComic
*/
private async _mainComic(user: User) {
let ts = Date.now()
const sign: XHRoptions = {
method: 'POST',
url: `https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn`,
body: AppClient.signQuery(`access_key=${user.accessToken}&platform=android&ts=${ts}`),
cookieJar: user.jar,
responseType: 'json'
}
const signComic = await tools.XHR<comicSgin>(sign, 'Android')
const share: XHRoptions = {
method: 'POST',
url: `https://manga.bilibili.com/twirp/activity.v1.Activity/ShareComic`,
body: AppClient.signQuery(`access_key=${user.accessToken}&platform=android&ts=${ts}`),
cookieJar: user.jar,
responseType: 'json'
}
const shareComic = await tools.XHR<comicShare>(share, 'Android')
if (signComic !== undefined && signComic.body.code === 0) tools.Log(user.nickname, `已完成漫画签到`)
else tools.Log(user.nickname, `漫画签到失败`)
if (shareComic !== undefined && shareComic.body.code === 0) tools.Log(user.nickname, `已完成漫画签到,经验+${shareComic.body.data.point}`)
else tools.Log(user.nickname, `漫画分享失败`)
}
}
/**
* 主站关注
*
* @interface attentions
*/
interface attentions {
code: number
data: attentionsData
message: string
ttl: number
}
interface attentionsData {
list: attentionsDataList[]
reversion: number
total: number
}
interface attentionsDataList {
mid: number
mtime: number
uname: string
}
/**
* 主站视频
*
* @interface getSummitVideo
*/
interface getSummitVideo {
status: boolean
data: getSummitVideoData
}
interface getSummitVideoData {
page: getgetSummitVideoDataPage
list: getSummitVideoDataList
}
interface getgetSummitVideoDataPage {
count: number
pn: number
ps: number
}
interface getSummitVideoDataList {
vlist: getSummitVideoDataListVlist[]
}
interface getSummitVideoDataListVlist {
aid: number
created: number
mid: number
title: string
}
/**
* 主站cid
*
* @interface getCid
*/
interface getCid {
data: cid[]
}
interface cid {
cid: number
}
/**
* 主站分享返回
*
* @interface shareAV
*/
interface shareAV {
code: number
}
/**
* 主站心跳
*
* @interface avHeart
*/
interface avHeart {
code: number
}
/**
* 主站心跳
*
* @interface avHeart
*/
interface avHeart {
code: number
}
/**
* 主站信息
*
* @interface mainUserInfo
*/
interface mainUserInfo {
code: number
data: mainUserInfoData
}
interface mainUserInfoData {
money: number
}
/**
* 主站任务
*
* @interface mainReward
*/
interface mainReward {
code: number
data: mainRewardData
}
interface mainRewardData {
coins_av: number
login: boolean
share_av: boolean
watch_av: boolean
}
/**
* 投币回调
*
* @interface coinAdd
*/
interface coinAdd {
code: number
}
/**
* 漫画信息
*
* @interface comicUserInfo
*/
interface comicUserInfo {
code: number
data: comicUserInfoData
}
interface comicUserInfoData {
status: number
}
/**
* 漫画签到
*
* @interface
*/
interface comicSgin {
code: number
}
/**
* 漫画分享
*
* @interface comicShare
*/
interface comicShare {
code: number
data: comicShareData
}
interface comicShareData {
point: number
}
interface rank {
code: number
msg: string
data: rankDate
}
interface rankDate {
note: string
list: rankDateList[]
}
interface rankDateList {
aid: number
bvid: string
cid: number
}
export default new MainSite()