// ==UserScript==
// @name rush4award
// @namespace vurses
// @license Mit
// @match https://www.bilibili.com/blackboard/new-award-exchange.html?task_id=*
// @version 3.5.0
// @author layenh
// @icon https://i0.hdslb.com/bfs/activity-plat/static/b9vgSxGaAg.png
// @homepage https://github.com/vruses/get-bili-redeem
// @supportURL https://github.com/vruses/get-bili-redeem/issues
// @require https://update.gf.qytechs.cn/scripts/535838/1588053/NumberInput.js
// @require https://update.gf.qytechs.cn/scripts/535840/1588055/FloatButton.js
// @run-at document-start
// @grant none
// @description 🔥功能介绍:1、支持B站所有激励计划,是否成功取决于b站接口是否更新,与游戏版本无关;2、根据验证码通过情况自适应请求速度
// ==/UserScript==
// utils.request(p)=>info,inner
const storage = {
set(key, value) {
try {
const data = JSON.stringify(value);
localStorage.setItem(key, data);
} catch (e) {
console.error("Storage Set Error:", e);
}
},
get(key, defaultValue = null) {
try {
const data = localStorage.getItem(key);
return data !== null ? JSON.parse(data) : defaultValue;
} catch (e) {
console.error("Storage Get Error:", e);
return defaultValue;
}
},
};
let ReceiveTime = storage.get("ReceiveTime", 1000);
let SlowerTime = storage.get("SlowerTime", 10000);
const workerJs = function () {
class TimerManager {
constructor() {
this.timers = new Map();
}
set(key, callback, delay) {
this.clean(key);
const id = setTimeout(() => {
callback();
}, delay);
this.timers.set(key, id);
}
clean(key) {
if (this.timers.has(key)) {
clearTimeout(this.timers.get(key));
this.timers.delete(key);
}
}
cleanAll() {
for (let id of this.timers.values()) {
clearTimeout(id);
}
this.timers.clear();
}
has(key) {
return this.timers.has(key);
}
}
const manager = new TimerManager();
// 根据taskName设置定时
self.addEventListener("message", function (e) {
manager.set(
e.data.taskName,
() => self.postMessage(e.data.taskName),
e.data.time
);
});
};
workerJs.toString();
const blob = new Blob([`(${workerJs})()`], { type: "application/javascript" });
const url = URL.createObjectURL(blob);
const worker = new Worker(url);
const originalCall = Function.prototype.call;
Function.prototype.call = function (...args) {
if (this.name === "fb94") {
let temp = this.toString();
temp.indexOf("this.$nextTick(()=>{}),");
temp = temp.replace(
`this.$nextTick(()=>{}),`,
(res) =>
res +
"Object.assign(window,{awardInstance:this}),Object.assign(window,{utils:v}),"
);
// 禁止pub¬ify错误页消息
temp = temp.replace(
`setCommonDialog(t){b.commonErrorDialog=t},`,
`setCommonDialog(t){},`
);
// 防止不再弹出验证码
temp = temp.replace(`e.destroy()`, ``);
temp = eval("(" + temp + ")");
return originalCall.apply(temp, args);
}
return originalCall.apply(this, args);
};
const originalFetch = window.fetch;
window.fetch = function (input, init = {}) {
let url = "";
// 处理 input 可能是字符串或 Request 对象
if (typeof input === "string") {
url = input;
} else if (input instanceof Request) {
url = input.url;
}
if (url.includes("/x/activity_components/mission/receive")) {
return originalFetch
.call(this, input, init)
.then((res) => {
res
.clone()
.json()
.then((res) => {
if (res.code === 202100) {
document.querySelector("a.geetest_close")?.click();
worker.postMessage({ taskName: "receiveTask", time: SlowerTime });
} else {
worker.postMessage({ taskName: "receiveTask", time: ReceiveTime });
}
});
return res;
})
.catch((e) => {
console.log(e);
});
}
return originalFetch.call(this, input, init);
};
window.addEventListener("load", function () {
// 插入到页面的一些信息
const totalStockEl = document.createElement("p");
totalStockEl.className = "extra-info";
totalStockEl.textContent = `总剩余量: ${"未获取"}`;
const cdKeyEl = document.createElement("p");
cdKeyEl.className = "extra-info";
cdKeyEl.textContent = `cdKey: ${"未获取"}`;
const awardPreviewEl = document.createElement("div");
awardPreviewEl.className = "award-preview";
awardPreviewEl.append(cdKeyEl, totalStockEl);
// 文字可选中
document.querySelector(".award-wrap").style.userSelect = "text";
document.querySelector(".award-wrap").append(awardPreviewEl);
if (awardInstance.cdKey) {
return;
}
const loopRequest = function () {
return new Promise((res, rej) => {
setTimeout(res, 1000);
})
.then(() => {
awardInstance.handelReceive();
})
.catch((e) => {
console.log(e);
loopRequest();
});
};
loopRequest();
// 定时获取新的信息
setInterval(() => {
worker.postMessage({ taskName: "getInfoTask", time: 0 });
}, 3000);
console.log(awardInstance);
awardInstance.$watch("pageError", function (newVal, oldVal) {
this.pageError = false;
});
awardInstance.$watch("cdKey", function (newVal, oldVal) {
window.fetch = originalFetch;
worker.terminate();
});
worker.addEventListener("message", function (e) {
console.log("post to window: " + e.data);
if (e.data === "receiveTask") {
awardInstance.handelReceive();
} else if (e.data === "getInfoTask") {
utils.getBounsInfo("6ERA4wloghv5rn00").then((res) => {
totalStockEl.textContent = `总剩余量:${res.stock_info.total_stock}%`;
cdKeyEl.textContent = `cdKey:${awardInstance.cdKey}`;
});
}
});
});
// 在修改间隔后进行存储
// 每次请求发起的间隔
const receiveInput = document.createElement("input-number");
receiveInput.value = ReceiveTime / 1000;
receiveInput._value = receiveInput.value;
Object.defineProperty(receiveInput, "value", {
get() {
return this._value;
},
set(value) {
console.log("receive:" + value);
ReceiveTime = value * 1000;
storage.set("ReceiveTime", value * 1000);
this._value = value;
},
});
// 每次验证使用的时间
const validateInput = document.createElement("input-number");
validateInput.value = SlowerTime / 1000;
validateInput._value = validateInput.value;
Object.defineProperty(validateInput, "value", {
get() {
return this._value;
},
set(value) {
console.log("validate:" + value);
SlowerTime = value * 1000;
storage.set("SlowerTime", value * 1000);
this._value = value;
},
});
// 请求插槽
const intervalFaster = document.createElement("div");
intervalFaster.slot = "interval-faster";
intervalFaster.style.display = "flex";
intervalFaster.style.alignItems = "center";
intervalFaster.innerHTML = `<span style="width: 70px">请求间隔</span>`;
// 验证插槽
const intervalSlower = document.createElement("div");
intervalSlower.slot = "interval-slower";
intervalSlower.style.display = "flex";
intervalSlower.style.alignItems = "center";
intervalSlower.innerHTML = `<span style="width: 70px">验证间隔</span>`;
intervalFaster.append(receiveInput);
intervalSlower.append(validateInput);
const floatButton = document.createElement("float-button");
floatButton.append(intervalFaster, intervalSlower);
document.documentElement.append(floatButton);