// ==UserScript==
// @name 秒传链接提取
// @namespace https://github.com/vscodev
// @version 0.0.3
// @author vscodev
// @description 大道至简,这是一个全新开发的百度网盘秒传链接提取脚本。
// @license gpl-3.0
// @icon https://vitejs.dev/logo.svg
// @homepageURL https://github.com/vscodev/rapid-upload-userscript
// @match *://pan.baidu.com/disk/main*
// @match *://yun.baidu.com/disk/main*
// @match *://wangpan.baidu.com/disk/main*
// @require https://cdn.jsdelivr.net/npm/sweetalert2@11.7.12/dist/sweetalert2.all.min.js
// @grant GM_xmlhttpRequest
// ==/UserScript==
(t=>{const e=document.createElement("style");e.dataset.source="vite-plugin-monkey",e.textContent=t,document.head.append(e)})(" #rapid-upload-button{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;vertical-align:middle;font:inherit;overflow:visible;text-transform:none;font-family:SFUIText,PingFangSC-Regular,Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-user-select:none;display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;-webkit-appearance:none;text-align:center;box-sizing:border-box;outline:0;margin:0 16px;transition:.1s;color:#fff;background-color:#06a7ff;font-weight:700;padding:8px 24px;height:32px;font-size:14px;border-radius:16px;border:none} ");
(function (Swal) {
'use strict';
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
const HOST = location.host;
const CHECK_LOGIN_URL = `https://${HOST}/api/loginStatus?clienttype=0&app_id=250528&web=1&channel=chunlei`;
const PRE_CREATE_URL = `https://${HOST}/api/precreate?app_id=250528&clienttype=21`;
class ApiError extends Error {
constructor(code, message) {
super(message ?? getErrorMessage(code));
__publicField(this, "code");
this.code = code;
this.name = "ApiError";
}
toString() {
return `${this.message}(错误码:${this.code})`;
}
}
function getErrorMessage(errrno) {
switch (errrno) {
case 0:
return "请求成功";
case 2:
case 31023:
return "参数错误";
case 111:
return "access token 失效";
case -6:
return "身份验证失败";
case 6:
return "不允许接入用户数据";
case 31034:
return "命中接口频控";
case 2131:
return "该分享不存在";
case 10:
return "转存文件已经存在";
case -3:
case -31066:
return "文件不存在";
case 11:
return "自己发送的分享";
case 255:
return "转存数量太多";
case 12:
return "批量转存出错";
case -1:
return "权益已过期";
case -7:
return "文件或目录名错误或无权访问";
case -10:
return "容量不足";
case 404:
return "秒传md5不匹配";
case 406:
return "秒传创建文件失败";
case 407:
return "fileModify接口返回错误,未返回requestid";
default:
return "未知错误";
}
}
function checkLogin() {
return new Promise((resolve, reject) => {
_GM_xmlhttpRequest({
method: "GET",
url: CHECK_LOGIN_URL,
responseType: "json",
onload: (result) => {
const resp = result.response;
if (resp.errno === 0) {
resolve();
} else {
reject(new ApiError(resp.errno, resp.show_msg));
}
},
onerror: (err) => {
reject(err);
}
});
});
}
function doRapidUpload(targetPath, fi) {
return new Promise((resolve, reject) => {
_GM_xmlhttpRequest({
method: "POST",
url: PRE_CREATE_URL,
data: `path=${encodeURIComponent(targetPath + "/" + fi.path)}&size=${fi.size}&isdir=0&block_list=${JSON.stringify(
fi.blockList.map((v) => v.toLowerCase())
)}&autoinit=1&content-md5=${fi.contentMd5}&slice-md5=${fi.sliceMd5.toLowerCase()}&rtype=2`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
responseType: "json",
onload: (result) => {
const resp = result.response;
if (resp.errno === 0) {
if (resp.return_type === 2) {
resolve();
} else {
reject(new ApiError(404, "秒传未生效"));
}
} else {
reject(new ApiError(resp.errno));
}
},
onerror: (err) => {
reject(err);
}
});
});
}
const MAX_ATTEMPTS = 3;
function parseRapidUploadLinks(inputValue) {
return inputValue.split(/\r?\n/g).reduce((filtered, link) => {
const matched = link.trim().match(/^([a-f0-9]{32})#([a-f0-9]{32})#([0-9]{1,20})#(.+)/i);
if (matched) {
filtered.push({
path: matched[4],
size: matched[3],
blockList: [""],
contentMd5: matched[1],
sliceMd5: matched[2]
});
}
return filtered;
}, []);
}
function getCurrentPath() {
const matched = location.href.match(/path=(.+?)(?:&|$)/);
if (matched) {
return decodeURIComponent(matched[1]);
}
return "";
}
function randomizeTextCase(text) {
let ret = "";
for (let i = 0; i < text.length; i++) {
const char = text[i].toLowerCase();
if (Math.random() < 0.5) {
ret += char;
} else {
ret += char.toUpperCase();
}
}
return ret;
}
function sleep(ms = 300) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1) + min);
}
async function tryRapidUpload(targetPath, fi, attempts) {
fi.contentMd5 = attempts === 0 ? fi.contentMd5.toLowerCase() : randomizeTextCase(fi.contentMd5);
try {
await doRapidUpload(targetPath, fi);
} catch (err) {
if (err instanceof ApiError && err.code === 404 && attempts < MAX_ATTEMPTS) {
await sleep(getRandomIntInclusive(300, 1e3));
return tryRapidUpload(targetPath, fi, ++attempts);
}
throw err;
}
}
async function newRapidUploadTask() {
const result = await Swal.fire({
title: "秒传链接提取",
input: "textarea",
inputPlaceholder: "请输入标准格式的秒传提取码,支持批量转存,多个链接以换行符分隔。",
preConfirm: (inputValue) => {
const fileList = parseRapidUploadLinks(inputValue);
if (fileList.length === 0) {
Swal.showValidationMessage(`未检测到有效的的秒传链接`);
}
return fileList;
},
showCancelButton: true,
confirmButtonText: "确定",
cancelButtonText: "取消"
});
if (result.isConfirmed) {
const fileList = result.value ?? [];
if (fileList.length > 0) {
const targetPath = getCurrentPath();
let successCount = 0;
let failureCount = 0;
await Swal.fire({
title: "文件转存中",
html: `正在转存第 <b id="file-num"></b>/<b>${fileList.length}</b> 个文件`,
willOpen: async () => {
var _a;
Swal.showLoading();
const ele = (_a = Swal.getHtmlContainer()) == null ? void 0 : _a.querySelector("#file-num");
for (const [index, fi] of fileList.entries()) {
if (ele) {
ele.textContent = `${index + 1}`;
}
try {
await tryRapidUpload(targetPath, fi, 0);
successCount++;
} catch (err) {
console.error(err);
failureCount++;
}
}
Swal.close();
},
showConfirmButton: false
});
Swal.fire({
title: `转存完毕,成功${successCount}个,失败${failureCount}个`,
confirmButtonText: "确定"
}).then(() => {
location.reload();
});
}
}
}
function injectRapidUploadButton() {
const btn = document.createElement("button");
btn.setAttribute("id", "rapid-upload-button");
btn.innerText = "秒传";
btn.addEventListener("click", newRapidUploadTask);
const toolBar = document.querySelector(".wp-s-agile-tool-bar__header");
toolBar == null ? void 0 : toolBar.appendChild(btn);
}
function main() {
checkLogin().then(() => {
injectRapidUploadButton();
}).catch((err) => {
console.error(err);
});
}
main();
})(Swal);