- // ==UserScript==
- // @name BilibiliExp
- // @namespace BilibiliExp
- // @match *://www.bilibili.com/video/*
- // @version 1.0
- // @author Dreace
- // @license GPL-3.0
- // @description B 站经验助手,自动投币视频、模拟移动端分享、经验获取统计、升级时间估计
- // @grant GM.xmlHttpRequest
- // @grant unsafeWindow
- // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
- // @require https://static.hdslb.com/js/md5.js
- // ==/UserScript==
- // file:///C:/WorkSpace/JavaScript/BilibiliExp/main.js
- (function () {
- 'use strict';
- const coinUrl = "https://api.bilibili.com/x/web-interface/nav?build=0&mobi_app=web"
- const addCoinUrl = "https://api.bilibili.com/x/web-interface/coin/add"
- const shareUrl = "https://app.bilibili.com/x/v2/view/share/complete"
- const shareUrlPre = "https://app.bilibili.com/x/v2/view/share/click"
- const rewardUrl = "https://account.bilibili.com/home/reward"
- let totalCoin = 0
- let expToday = 0
- let aid = ""
- let bili_jct = getCookie("bili_jct")
- try {
- aid = unsafeWindow.vd ? unsafeWindow.vd.aid : unsafeWindow.aid
- } catch (error) {
- console.log("aid 获取失败")
- return
- }
- function addCoin() {
- return biliAjax({
- url: addCoinUrl,
- type: 'POST',
- dataType: 'json',
- data: {
- aid: aid,
- multiply: "1",
- select_like: 0,
- cross_domain: true,
- csrf: bili_jct
- },
- })
- }
- if (aid) {
- gmAjax({
- url: rewardUrl,
- methon: 'GET',
- }).then((res) => {
- if (res.code == 0) {
- expToday = 50 - res.data.coins_av
- } else {
- console.log("等级信息获取失败");
- return
- }
- })
- gmAjax({
- url: rewardUrl,
- methon: 'GET',
- }).then((res) => {
- if (res.code == 0) {
- expToday = 50 - res.data.coins_av
- if (!res.data.share_av) {
- let shareData = {
- access_key: bili_jct,
- actionKey: "appkey",
- aid: aid,
- appkey: "27eb53fc9058f8c3",
- build: "8960",
- device: "phone",
- epid: "",
- from: "711",
- mobi_app: "iphone",
- platform: "ios",
- season_id: "",
- share_channel: "qq",
- share_trace_id: hex_md5(new Date()),
- statistics: "%7B%22appId%22%3A1%2C%22version%22%3A%225.50.1%22%2C%22abtest%22%3A%22890%22%2C%22platform%22%3A1%7D",
- ts: new Date().getTime(),
- }
- let signed = get_sign(shareData, "c2ed53a74eeefe3cf99fbd01d8c9c375")
- GM.xmlHttpRequest({
- method: "POST",
- url: shareUrl,
- data: signed.data + "&sign=" + signed.sign,
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- },
- onload: function (response) {
- let res = JSON.parse(response.responseText)
- if (res.code == 0) {
- GM.xmlHttpRequest({
- method: "POST",
- url: shareUrlPre,
- data: signed.data + "&sign=" + signed.sign,
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- },
- onload: function (response) {
- let res = JSON.parse(response.responseText)
- console.log(res.data.toast)
- }
- });
- }
- }
- });
-
- }
- } else {
- console.log("等级信息获取失败");
- }
- }).then(() => {
- return biliAjax({
- url: coinUrl,
- type: 'GET',
- dataType: 'json',
- })
- }).then((res) => {
- totalCoin = res.data.money
- console.log("当前硬币 " + totalCoin + " 个")
- if (totalCoin < 50) {
- console.log("硬币小于 50,暂不投币")
- } else {
- if (expToday == 0) {
- console.log("今日已获取全部经验")
- }
- return new Promise(function (resolve, reject) {
- setTimeout(() => {
- resolve()
- }, 10000);
- })
- }
- }).then(() => {
- if (totalCoin >= 50 && expToday > 0) {
- console.log("准备投币")
- return addCoin()
- }
- }).then((res) => {
- if (res && res.code == 0) {
- console.log("投了一个币")
- expToday -= 10
- if (expToday > 0) {
- return addCoin()
- }
- }
- }).then((res) => {
- if (res && res.code == 0) {
- console.log("又投了一个币")
- }
- return gmAjax({
- url: rewardUrl,
- methon: 'GET',
- })
- }).then((res) => {
- if (res.code == 0) {
- let rewardInfo = res.data
- let link = document.createElement('link');
- link.rel = 'stylesheet';
- link.href = "//at.alicdn.com/t/font_1537779_4srood2g1uk.css";
- document.body.appendChild(link);
- let style = "color: inherit;display: inline-block;line-height: 1;"
- let spansData = []
- let total = 0
- total += rewardInfo.login ? 5 : 0
- spansData.push({
- ok: rewardInfo.login,
- name: "每日登录",
- text: `${rewardInfo.login ? 5 : 0}/5`,
- className: "icon-login"
- })
- total += rewardInfo.share_av ? 5 : 0
- spansData.push({
- ok: rewardInfo.share_av,
- name: "分享视频",
- text: `${rewardInfo.share_av ? 5 : 0}/5`,
- className: "icon-share"
- })
- total += rewardInfo.watch_av ? 5 : 0
- spansData.push({
- ok: rewardInfo.watch_av,
- name: "观看视频",
- text: `${rewardInfo.watch_av ? 5 : 0}/5`,
- className: "icon-play"
- })
- total += rewardInfo.coins_av
- spansData.push({
- ok: rewardInfo.coins_av == 50,
- name: "视频投币",
- text: `${rewardInfo.coins_av}/50`,
- className: "icon-coin"
- })
- spansData.push({
- ok: total == 65,
- name: "总计",
- text: `${total}/65`,
- className: "icon-total"
- })
- spansData.push({
- ok: false,
- name: `最快到 ${rewardInfo.level_info.current_level + 1} 级剩余天数`,
- text: `${Math.ceil((rewardInfo.level_info.next_exp - rewardInfo.level_info.current_exp) / 65)} 天`,
- className: "icon-day"
- })
- let bar = document.getElementById("arc_toolbar_report")
- bar.style.height = "60px"
- let ops = document.createElement('div')
- ops.className = "ops"
-
- spansData.forEach((item) => {
- let span = document.createElement("span")
- if (item.ok) {
- span.style = "color:rgb(251, 114, 153);"
- } else {
- span.style = "color:rgb(80, 80, 80);"
- }
- span.title = item.name
- span.innerHTML = `<i class="${item.className} iconfont" style="${style}"></i>${item.text}`
- ops.appendChild(span.cloneNode(true))
- })
- ops.style.marginTop = "10px"
- bar.appendChild(ops)
- }
- })
- }
- })();
- function gmAjax(opt) {
- return new Promise((resolve, reject) => {
- GM.xmlHttpRequest({
- method: opt.methon,
- url: opt.url,
- data: opt.data ? opt.data : "",
- headers: opt.headers ? opt.headers : "",
- onload: function (response) {
- let res = JSON.parse(response.responseText)
- resolve(res)
- },
- onError: function (error) {
- reject(error)
- }
- });
- })
- }
- function request(opt) {
- return $.ajax(opt)
- }
- function createPromise() {
- return $.Deferred()
- }
- function biliAjax(opt) {
- let req
- opt.xhrFields = {
- withCredentials: true
- }
- opt.crossDomain = true
- let defer = createPromise()
- req = request(opt)
- req.done(function (d) {
- defer.resolve(d)
- })
- req.fail(d => {
- defer.reject(d)
- })
-
- return defer
- }
- function get_sign(params, key) {
- var s_keys = []
- for (var i in params) {
- s_keys.push(i)
- }
- s_keys.sort()
- var data = ""
- for (var i = 0; i < s_keys.length; i++) {
- data += (data ? "&" : "") + s_keys[i] + "=" + params[s_keys[i]]
- }
- return { sign: hex_md5(data + key), data: data }
- }
- function getCookie(cname) {
- var name = cname + "=";
- var ca = document.cookie.split(';');
- for (var i = 0; i < ca.length; i++) {
- var c = ca[i].trim();
- if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
- }
- return "";
- }