// ==UserScript==
// @name bilibiliGetExp
// @namespace https://iconquestion.github.io
// @version 1.29
// @description (Original version) Automatically finish DAU task at bilibili to get experience point.
// @author ICONQUESTION
// @match https://t.bilibili.com
// @icon https://bilibili.com/favicon.ico
// @grant none
// @require https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js
// ==/UserScript==
var urlList = {
checkTasks: 'https://api.bilibili.com/x/member/web/exp/reward',
watchVideo: 'https://api.bilibili.com/x/click-interface/web/heartbeat',
shareVideo: 'https://api.biliapi.net/x/share/finish',
dynamic: 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=video&page=1',
videoProperty: 'https://api.bilibili.com/x/player/pagelist',
getAccess_key: 'https://passport.bilibili.com/login/app/third?appkey=1d8b6e7d45233436&api=http://link.acg.tv/forum.php&sign=5f9c0a5c2360c80b858d546a23a4a9dd',
}
//将document.cookie中的'; '替换为'&',从而满足生成URL对象的条件,再利用URL对象的searchParam功能完成cookie检索
var cookies = new URL('http://hello.world/test?' + document.cookie.replaceAll('; ', '&'))
var shareVideoDone = cookies.searchParams.get('shareVideoDone'), watchVideoDone = cookies.searchParams.get('watchVideoDone')
var csrftoken = cookies.searchParams.get('bili_jct')
var mid = cookies.searchParams.get('DedeUserID')
var access_key = cookies.searchParams.get('access_key')
//date用来设置记录性cookies过期时间为第二天0:0:0
var date = new Date()
var currentTime = parseInt((date.getTime()) / 1000);
date.setTime(date.getTime() + 3600 * 24 * 1000)
date.setHours(0, 0, 0, 0)
//调试性开关
/*
var debugMode = {
'true': '无论返回数据显示任务是否完成,都再执行一次',
'false': '根据返回数据情况,有选择地执行'
}
*/
var debugMode = false
/*
var cookieRecordComesFirst={
'true':'以cookies中的任务完成记录为准',
'false':'以fetch请求返回的数据为准'
}
*/
var cookieRecordComesFirst = true
//从这里开始执行
window.onload = function () {
//1.检查登录态
if (!csrftoken || !mid) {
console.log('csrf或mid不存在,请登录。如果您已经登录,请尝试清空cookies后重新登录。')
return;
}
new Promise(function (resolve, reject) {
//2.检查可完成的任务,resolve=成功,reject=出现错误
if (cookieRecordComesFirst) {
console.log('当前模式:cookies记录优先')
var status = { 'share': shareVideoDone, 'watch': watchVideoDone }
console.log(status)
resolve(status)
} else {
console.log('当前模式:fetch请求优先')
checkTasks(resolve, reject)
}
}).then(function (data) {
//在未开启调试模式状态下,如果返回数据表明任务已经全部完成,则程序退出,减少资源占用
if (!debugMode && data.share && data.watch) {
console.log('所有任务已经完成!')
return
}
new Promise(function (resolve, reject) {
//3.从动态列表拉取视频,resolve=成功,reject=无视频或出现错误
grabVideo(resolve, reject)
}).then(function (videoProp) {
//4.1 完成观看视频任务
if (!data.share || debugMode) {
watchVideo(videoProp)
} else {
console.log('观看视频任务已经完成!')
}
//4.2 完成分享视频任务
if (!data.watch || debugMode) {
if (!access_key) {
//4.2.1 获取access_key
new Promise(function (resolve, reject) {
//resolve=用户输入access_key,reject=用户取消操作
getAccessKey(resolve, reject)
}).then(function () {
//4.2.2 分享视频
shareVideo(videoProp)
}, function (msg) {
console.log(msg)
return
})
} else {
//4.2.1 分享视频
shareVideo(videoProp)
}
} else {
console.log('分享视频任务已经完成!')
return
}
}, function (msg) {
console.log(msg)
return
})
}, function (msg) {
console.log(msg)
return
})
}
//检查可获得经验值的任务
function checkTasks(resolve, reject) {
console.log('正在检查任务列表')
fetch(urlList.checkTasks, {
credentials: 'include',
headers: {
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
},
}).then(function (res) {
return res.headers.get('Content-Type').search('application/json') != -1 ? res.json() : undefined
}).then(function (data) {
//console.log(data)
if (!data || !data.data) {
reject('fetch(urlList.checkTasks) 返回数据异常。')
} else {
//传回最内层data(对象)
resolve(data.data)
}
})
}
//抓取视频
function grabVideo(resolve, reject) {
console.log('正在抓取视频')
fetch(urlList.dynamic, {
credentials: 'include',
}).then(function (res) {
return res.headers.get('Content-Type').search('application/json') != -1 ? res.json() : undefined
}).then(function (data) {
//console.log(data)
if (!data || !data.data || !data.data.items) {
reject('fetch(urlList.dynamic) 返回数据类型异常,或返回列表为空。')
return
}
var aid = data.data.items[0].basic.comment_id_str
// console.log(typeof (aid))
var bvid = data.data.items[0].modules.module_dynamic.major.archive.bvid
// console.log(typeof (bvid))
fetch(urlList.videoProperty + '?bvid=' + bvid + '&jsonp=jsonp', {
method: 'GET',
credentials: 'include',
headers: {
'Accept': '*/*',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
},
}).then(function (res) {
return res.headers.get('Content-Type').search('application/json') != -1 ? res.json() : undefined
}).then(function (data) {
//console.log(data)
if (!data || !data.data || !data.data[0].cid) {
reject('fetch(urlList.videoProperty) 返回数据类型异常')
return
}
var cid = data.data[0].cid
//console.log(typeof (cid))
console.log('获取到以下视频数据: aid=' + aid + ', bvid=' + bvid + ', cid=' + cid)
aid && bvid && cid ? resolve([aid, bvid, cid]) : reject('aid/bvid/cid数据异常')
})
})
}
//获取access_key
function getAccessKey(resolve, reject) {
fetch(urlList.getAccess_key, {
credentials: 'include',
}).then(function (res) {
return res.headers.get('Content-Type').search('application/json') != -1 ? res.json() : undefined
}).then(function (data) {
//console.log(data)
if (!data || !data.data || !data.data.confirm_uri) {
reject('fetch(urlList.getAccess_key) 返回数据异常')
return
}
console.log('请右键以下链接,点击"在新标签页中打开",然后复制查询字符串中的access_key字段,粘贴到对话框中')
console.log(data.data.confirm_uri)
if (prompt('请打开浏览器控制台,右键最下方的链接,点击"在新标签页中打开",然后复制查询字符串中的access_key字段,粘贴到这里')) {
document.cookie = 'access_key=' + access_key + '; max-age=15552000; domain=.bilibili.com'
resolve()
} else {
reject('用户已取消操作。')
}
})
}
//这个...不用解释了吧
function shareVideo(videoProp) {
var aid = videoProp[0], bvid = videoProp[1], cid = videoProp[2]
//share_session_id生成方式和作用未知,欢迎补充!
var body = 'access_key=' + access_key + '&appkey=1d8b6e7d45233436&build=6800300&c_locale=zh_CN&channel=bili&disable_rcmd=0&from_spmid=dt.dt.video.0&mobi_app=android&oid=' + aid + '&panel_type=1&platform=android&s_locale=zh_CN&share_channel=biliDynamic&share_id=main.ugc-video-detail.0.0.pv&share_origin=vinfo_share&share_session_id=' + '6609bb15-ac05-4118-8f12-cb' + currentTime + '&sid=' + cid + '&spm_id=main.ugc-video-detail.0.0&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.80.0%22%2C%22abtest%22%3A%22%22%7D&success=true&ts=' + currentTime + '&sign='
body = body + md5(body + '560c52ccd288fed045859ed18bffd973')
console.log('正在分享视频, aid=' + aid)
fetch(urlList.shareVideo, {
method: 'post',
mode: 'cors',
//referrer: "no-referrer",
headers: {
//'Buvid': 'XXAF685A25ED66209F45C4248C26054E197A8',
//'Fp_local': '9ca222f943ae8680669b6cdf2da959e120220715131357006bc66326e8302881',
//'Fp_remote': '9ca222f943ae8680669b6cdf2da959e1202207131056235c836389e254a11b4e',
//'Session_id': '831ec2b1',//暂时不知道如何处理
//'Env': 'prod',
//'App-Key': 'android',
//'User-Agent': 'Mozilla/5.0 BiliDroid/6.80.0 (bbcallen@gmail.com) os/android model/SM-G9730 mobi_app/android build/6800300 channel/bili innerVer/6800300 osVer/7.1.2 network/2',
//'X-Bili-Trace-Id': '390743e355a59747842729ca1962d222:8427c9ca1962d222:0:0',//暂时不知道如何处理
//'X-Bili-Aurora-Eid': 'UlYITlUAD1ID',
//'X-Bili-Mid': mid,
//'X-Bili-Aurora-Zone': '',
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
//'Accept-Encoding': 'gzip',
},
body: body,
}).then(function (res) {
return res.headers.get('Content-Type').search('application/json') != -1 ? res.json() : undefined
}).then(function (data) {
//console.log(data)
if (!data) {
console.log('fetch(urlList.shareVideo) 返回数据异常')
return
}
//每天第一次分享,返回的toast不为空,之后的分享toast为空
console.log(data.data.toast ? data.data.toast : '分享视频任务成功完成')
document.cookie = 'shareVideoDone=true; expires=' + date.toGMTString()
})
}
//观看视频
function watchVideo(videoProp) {
var aid = videoProp[0], bvid = videoProp[1], cid = videoProp[2]
console.log('正在观看视频, aid=' + aid + ', bvid=' + bvid + ', cid=' + cid)
fetch(urlList.watchVideo, {
method: 'post',
credentials: 'include',
headers: {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'aid=' + aid + '&cid=' + cid + '&bvid=' + bvid + '&mid=' + mid + '&csrf=' + csrftoken + '&played_time=11&real_played_time=12&realtime=11&start_ts=' + currentTime + '&type=3&dt=2&play_type=2&from_spmid=444.41.list.card_archive.click&spmid=333.788.0.0&auto_continued_play=0&refer_url=https%3A%2F%2Ft.bilibili.com%2F%3Ftab%3Dvideo&bsource='
}).then(function (res) {
return res.headers.get('Content-Type').search('application/json') != -1 ? res.json() : undefined
}).then(function (data) {
//console.log(data)
if (!data) {
console.log('fetch(urlList.watchVideo) 返回数据异常')
return
}
//正常情况返回string'0',否则返回具体信息
console.log(data.message == '0' ? '观看视频任务成功完成' : data.message)
document.cookie = 'watchVideoDone=true; expires=' + date.toGMTString()
})
}