} 弹窗关闭后返回空值,可能触发页面刷新
*/
async initDialog() {
let dialog = await Swal.fire({
title: `请阅读完以下全文再继续`,
allowOutsideClick: false,
showCloseButton: true,
showDenyButton: true,
confirmButtonText: '确认',
denyButtonText: '懒得输入...我要直接点亮!',
html: `
你心想道: “没什么可以输入的”
↓
但你不知道的是...
你可以直接按下下方的红色按钮 来跳过这一有趣的流程
或者继续流程,输入某些恶臭的数字 查看彩蛋并点亮
↓
原作者 开发很辛苦,所以请有能力的你请支持下他的公众号
点亮后不仅能精简网盘界面 还能改变众多网盘主题色哦!
`,
...swalDefault
});
if (dialog.isDenied) {
console.log("【LinkSwift】\n正在“注入”点亮按钮设置项目...");
message.warning("正在“注入”设置项目...");
await base.sleep(2500);
base.setValue('setting_init_code', config.base.num);
base.setValue('setting_init_license', config.base.license);
message.success("“注入”成功了!");
await base.sleep(1500);
location.reload();
};
if (dialog.isConfirmed) {
if ($('#init').val() === '114514' || $('#init').val() === '1919810' || $('#init').val() === '1145141919810') {
await Swal.fire({
icon: 'error',
title: '1145141919810',
html: 'homo特有的数字当然不行啦 哼哼哼啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 ',
timer: 4000,
imageUrl: 'https://pic1.zhimg.com/v2-1b97a088e156c015108dec663bba8b04.avis',
allowOutsideClick: false,
timerProgressBar: true,
showConfirmButton: false,
showDenyButton: true,
denyButtonText: '哼哼哼啊啊啊啊啊啊啊啊啊啊',
...swalDefault
});
message.info("成就:你触发了一个homo特有的彩蛋!");
await base.sleep(4000)
Swal.fire({
title: '1145141919810',
text: 'homo特有的数字当然不行啦...吗?',
icon: 'question',
imageUrl: 'https://lh1.hetaousercontent.com/img/7d4c1c0b4adb0e95.jpg',
showConfirmButton: false,
allowOutsideClick: false,
...swalDefault
});
await base.sleep(3000)
base.setValue('setting_init_code', config.base.num);
base.setValue('setting_init_license', config.base.license);
message.success("成就:哼哼哼啊啊啊啊啊啊啊啊地注入成功(喜)");
await base.sleep(1500)
location.reload();
} else {
console.log("【LinkSwift】\n暗号错误")
await this.initDialog();
return;
};
}
},
/**
* 显示主对话框
* @author 油小猴
* @author hmjz100
* @description 使用 SweetAlert2 显示一个自定义样式的对话框,用于展示信息或操作提示。
* @param {string} title - 对话框标题
* @param {string} html - 对话框内容的 HTML 字符串
* @param {string} footer - 对话框底部说明文字
*/
showMainDialog(title, html, footer) {
Swal.fire({
title,
html,
footer: `${footer} `,
customClass,
confirmButtonText: '关闭',
showCloseButton: true,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
willClose: function () {
base._resetAllData();
},
...swalDefault
}).then(function () {
base._resetAllData();
});
},
/**
* 等待指定元素加载完成并执行回调
* @author hmjz100
* @description 监听 DOM 元素是否出现,若未出现则每隔一段时间重试,直到找到为止。
* 支持在 iframe 内部查找元素,适用于异步加载场景。
* @param {string} selectorElem - 要等待的目标元素选择器
* @param {Function} actionFunction - 找到元素后执行的回调函数,接收 jQuery 元素作为参数,返回 true 可以不再继续寻找
* @param {boolean} [bWaitOnce=false] - 是否只执行一次回调,默认为 false,如果不设置为 true 的话需要自行判断是否对元素进行操作
* @param {string} [iframeSelector] - 若目标元素位于 iframe 中,传入 iframe 的选择器
* @param {string} [controlKey] - 控制唯一性的键名,用于避免重复处理
*/
waitForKeyElements(selectorElem, actionFunction, bWaitOnce, iframeSelector, controlKey) {
if (!this.waitForKeyElements.controlObj) {
this.waitForKeyElements.controlObj = {};
}
if (!this.waitForKeyElements.instanceCounter) {
this.waitForKeyElements.instanceCounter = 0;
}
let targetNodes;
if (typeof iframeSelector === "undefined") {
targetNodes = $(selectorElem);
} else {
targetNodes = $(iframeSelector).contents().find(selectorElem);
}
let controlKeyNew = controlKey || `wkfe_${this.waitForKeyElements.instanceCounter++}`;
let btargetsFound = false;
if (targetNodes && targetNodes.length > 0) {
targetNodes.each(function () {
let jThis = $(this);
let alreadyFound = jThis.data(controlKeyNew) || false;
if (!alreadyFound) {
var cancelFound = actionFunction(jThis);
if (cancelFound) {
btargetsFound = true;
} else if (bWaitOnce) {
jThis.data(controlKeyNew, true);
}
}
});
}
let controlObj = this.waitForKeyElements.controlObj;
let timeControl = controlObj[controlKeyNew];
if (btargetsFound && bWaitOnce && timeControl) {
clearInterval(timeControl);
delete controlObj[controlKeyNew];
} else if (!timeControl) {
timeControl = setInterval(() => {
this.waitForKeyElements(selectorElem, actionFunction, bWaitOnce, iframeSelector, controlKeyNew);
}, 1000);
controlObj[controlKeyNew] = timeControl;
}
this.waitForKeyElements.controlObj = controlObj;
},
};
/**
* 百度网盘
* @author 油小猴
* @author hmjz100
*/
let $baidu = {
_getExtra() {
let seKey = decodeURIComponent(base.getCookie('BDCLND'));
return '{' + '"sekey":"' + seKey + '"' + "}";
},
_getSurl() {
let reg = /(?<=s\/|surl=)([a-zA-Z0-9_-]+)/g;
if (reg.test(location.href)) {
return location.href.match(reg)[0];
}
return '';
},
setBDUSS() {
try {
GM_cookie('list', { name: 'BDUSS' }, (cookies, error) => {
if (!error) {
let BDUSS = cookies?.[0]?.value;
if (BDUSS) {
base.setStorage("baiduyunPlugin_BDUSS", { BDUSS });
}
} else {
throw new Error(error)
}
});
} catch (e) {
console.error("【LinkSwift】\nsetBDUSS\n错误信息:", e)
try {
let BDUSS = document.cookie.match(/BDUSS=(.*?)(;|$)/);
if (!!BDUSS || BDUSS === null) throw new Error("document.cookie dosen't had cookie")
base.setStorage("baiduyunPlugin_BDUSS", { BDUSS: BDUSS });
} catch (e) {
console.error("【LinkSwift】\nsetBDUSS\n错误信息:", e)
}
}
},
getBDUSS() {
doc.find('.loading-popup .loading-title').html(`凭证获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取当前账号凭证~
`);
let baiduyunPlugin_BDUSS = base.getStorage('baiduyunPlugin_BDUSS') ? base.getStorage('baiduyunPlugin_BDUSS') : { BDUSS: '' };
return baiduyunPlugin_BDUSS.BDUSS || '';
},
async getToken() {
try {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取授权状态~
`);
// 获取授权状态
let authorize = await base.getFinalUrl(config.$baidu.api.getAccessToken);
// 判断授权情况
if (authorize.includes('authorize')) {
// 没授权,先获取授权的页面
doc.find('.loading-popup .loading-title').html(`授权获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取授权页面~
`);
let html = await base.get(config.$baidu.api.getAccessToken, {}, 'text');
// 提取页面的发送确认授权的参数
let bdstoken = html.match(/name="bdstoken"\s+value="([^"]+)"/)?.[1];
let client_id = html.match(/name="client_id"\s+value="([^"]+)"/)?.[1];
let data = {
grant_permissions_arr: 'netdisk',
bdstoken: bdstoken,
client_id: client_id,
response_type: "token",
display: "page",
grant_permissions: "basic,netdisk"
};
doc.find('.loading-popup .loading-title').html(`授权获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在自动确认授权~
`);
// 发送请求达到自动进行授权
await base.post(config.$baidu.api.getAccessToken, base.stringify(data), {
'Content-Type': 'application/x-www-form-urlencoded',
});
// 再次获取授权状态
let res2 = await base.getFinalUrl(config.$baidu.api.getAccessToken);
let accessToken = res2.match(/access_token=([^&]+)/)?.[1];
if (!!accessToken) {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`授权成功,令牌已缓存~
`);
base.setValue('baidu_access_token', accessToken);
return accessToken;
} else {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`授权失败,等待下一步操作~
`);
return '';
}
} else if (authorize.includes('access_token=')) {
let accessToken = authorize.match(/access_token=([^&]+)/)?.[1];
if (!!accessToken) {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`授权成功,令牌已缓存~
`);
base.setValue('baidu_access_token', accessToken);
return accessToken;
} else {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`授权失败,等待下一步操作~
`);
return '';
}
} else {
return '';
}
} catch (error) {
return '';
}
},
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:百度网盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
doc.on('mouseenter mouseleave click', '.pl-button.g-dropdown-button', function (e) {
if (e.type === 'mouseleave') {
$(e.currentTarget).removeClass('button-open');
} else {
$(e.currentTarget).addClass('button-open');
$(e.currentTarget).find('.pl-dropdown-menu').show();
}
});
doc.on('mouseleave', '.pl-button.g-dropdown-button .pl-dropdown-menu', function (e) {
$(e.currentTarget).hide();
});
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$baidu.getLink();
});
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
selectList = $baidu.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要保存到网盘的文件哦~');
}
message.info('提示: 因网盘限制,请保存到自己网盘后再去下载哦~');
await base.sleep(500);
document.querySelector('.tools-share-save-hb').click();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(o.link[0].dataset.link, { "User-Agent": config.$baidu.api.ua.downloadLink }, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const isIDM = !!idm[index];
if (isIDM) {
// IDM 捕获处理逻辑
o.tip.hide();
o.progress.hide();
o.copy.show();
o.directLink.show();
o.link
.text('链接已被IDM捕获~请查看IDM下载窗口哦!')
.animate({ opacity: '0.5' }, "slow")
.show();
clearInterval(ins[index]);
await base.sleep(2000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
idm[index] = false;
return;
}
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
if (!e.target.dataset.link) {
$(e.target).removeClass('listener-copy-all').addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(
function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000
)
}
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let BDUSS = $baidu.getBDUSS();
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`User-Agent: ${config.$baidu.api.ua.downloadLink}`, `Cookie: BDUSS=${BDUSS}`]);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function (e) {
e.preventDefault();
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
document.documentElement.addEventListener('mouseup', function (e) {
if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) {
e.stopPropagation();
}
}, true);
},
greenerPage() {
page = $baidu.detectPage();
base.waitForKeyElements(".wp-s-header-user__vip-center", function (tag) {
tag.remove();
}, true);
base.waitForKeyElements(".wp-s-header-user__create-team-content", function (tag) {
tag.remove();
}, true);
base.waitForKeyElements(".app-user-vip-center-box.vip-center-type-2", function (tag) {
tag.remove();
}, true);
base.waitForKeyElements(".wp-s-header__vip-btn-tip", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".app-user-vip-center-tip", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements("#web-header-text-s-45", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".wp-s-header__vip-btn", function (tag) {
tag.text("会员中心")
}, true);
base.waitForKeyElements(".KQcHyA", function (tag) {
tag.text("会员中心")
}, true);
base.waitForKeyElements(".gOIbzPb", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".wp-s-header-user__create-team-title", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".web-header-ad-item", function (tag) {
tag.fadeOut();
});
base.waitForKeyElements(".wp-s-header__game-entry", function (tag) {
tag.fadeOut();
}, true)
base.waitForKeyElements(".bd-aside-ad", function (tag) {
tag.fadeOut();
}, true)
base.waitForKeyElements(".btn-img-tips", function (tag) {
tag.fadeOut();
}, true)
base.waitForKeyElements(".nd-operate-guidance", function (tag) {
tag.fadeOut();
}, true)
base.waitForKeyElements(".module-operation-content", function (tag) {
tag.fadeOut();
document.querySelector(".operate-guide-close").click();
document.querySelector(".module-canvas").click();
}, true)
base.waitForKeyElements("[class*='module-'][class*='-box']:not(.module-box), [class*='module-'][class*='-mask']", function (tag) {
tag.fadeOut();
tag.find(".close-mask").click();
}, true)
base.waitForKeyElements(".newIcon", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".u-badge__content.is-dot", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".wp-side-options.g-clearfix", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".wp-s-header-user__drop-channel", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".app-download", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('.g-button[title*="手机"]', function (tag) {
tag.fadeOut();
}, true)
base.waitForKeyElements('.yike-entrance', function (tag) {
tag.remove();
}, true)
base.waitForKeyElements("a.tools__item", function (tag) {
if (tag.attr("linked")) return;
if (tag.attr('href')) {
try {
let url = new URL(tag.closest('a').attr('href'));
url.search = "";
url.hash = url.hash.replace(/\?(.*?)(#|$)/, '$2')
tag.attr('href', url.href)
} catch (e) { }
}
tag.attr("linked", true)
}, true);
base.waitForKeyElements("p.wp-s-aside-nav__main-item-text", function (tag) {
if (tag.attr("linked")) return;
if (tag.closest('a').attr('href')) {
try {
let url = new URL(tag.closest('a').attr('href'));
url.search = "";
url.hash = url.hash.replace(/\?(.*?)(#|$)/, '$2')
tag.closest('a').attr('href', url.href)
} catch (e) { }
}
if (tag.is(":contains('插件'), :contains('相册'), :contains('笔记')") && tag.closest('a').attr('target') !== "_blank") {
tag.closest('a').fadeOut();
} else {
tag.text(tag.text().replace("百度", ""));
}
tag.attr("linked", true)
}, true);
base.waitForKeyElements('dd[node-type="header-link"]', function (tag) {
tag.children().each(function () {
let tag = $(this);
if (!tag.attr("node-type")) return;
let type = tag.attr("node-type");
if (
type !== "disk-home" &&
type !== "mbox-homepage" &&
type !== "find-apps"
) {
tag.fadeOut();
}
});
}, true);
base.waitForKeyElements(".__yunguanjia", function (tag) {
tag.html(``);
}, true)
// 美化分享页面
if (page === 'share') {
base.waitForKeyElements(`iframe[src^="/buy/ad"]`, function (tag) {
tag.fadeOut();
}, true)
base.addStyle(`${mount}-baiduShare`, 'style', `
body, .theme-white.init-new, #layoutApp {
background-color: #DCEFFE !important;
background: #DCEFFE url(https://nd-static.bdstatic.com/m-static/disk-share/widget/pageModule/init-new/image/init-bg_1708266.png) no-repeat center center;
}
#bd-main .bd-left {
background: #ffffffC0;
border-radius: 10px;
}
iframe[src="/buy/ad/home"] {
display: none !important;
}
`, `.${mount}`);
base.waitForKeyElements(`.KPDwCE`, function (tag) {
tag.css('background', 'transparent');
}, true);
base.waitForKeyElements('.share-list .KPDwCE .AuPKyz', function (tag) {
tag.css('background', 'transparent');
}, true);
base.waitForKeyElements(`#layoutMain`, function (tag) {
tag.css({ "border-radius": "24px" });
}, true)
base.waitForKeyElements(".frame-content", function (tag) {
tag.css({ "margin": "auto" });
}, true)
}
},
addButton() {
base.waitForKeyElements(config.$baidu.mount.home, (element) => {
page = $baidu.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(`
`);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.main, (element) => {
page = $baidu.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'main') return;
let $button = $(`
`);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.main, (element) => {
page = $baidu.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'youth') return;
let $button = $(`
`);
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.share, (element) => {
page = $baidu.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
/*let $button = $(`
`);*/
let $button = $(`
下载助手
`)
element.after($button);
})
this.setBDUSS();
},
addInitButton() {
base.waitForKeyElements(config.$baidu.mount.home, (element) => {
page = $baidu.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
let $button = $(``);
$button.click(function () { base.initDialog() });
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.main, (element) => {
page = $baidu.detectPage();
if ($(".pl-button-init").length > 0 || !page || (page !== 'main' && page !== 'youth')) return;
let $button = $(``);
$button.click(function () { base.initDialog() });
element.prepend($button);
})
base.waitForKeyElements(config.$baidu.mount.share, (element) => {
page = $baidu.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(`
点我点亮
`)
$button.click(function () { base.initDialog() });
element.after($button);
})
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
// 获取选择的文件列表
selectList = this.getSelectedList();
let BDUSS = this.getBDUSS(), accessToken = (base.getValue('baidu_access_token') || await $baidu.getToken());
if (!accessToken) {
message.info('提示: 稍后请在新标签页中授权助手哦~');
base.deleteValue('baidu_access_token');
setTimeout(() => {
GM_openInTab(config.$baidu.api.getAccessToken, { active: true, insert: true, setParent: true })
let attempts = 0;
let interval = setInterval(function () {
if (!!base.getValue('baidu_access_token')) {
clearInterval(interval);
accessToken = base.getValue('baidu_access_token')
}
attempts++;
if (attempts > 120) {
clearInterval(interval);
return message.error('提示: 时间太长,我先撤下啦~');
}
}, 1000);
}, 3300);
return;
}
if (!BDUSS) {
let dialog = await Swal.fire({
icon: 'info',
title: `提示`,
html: '你好呀,为了获取百度网盘文件的下载直链 我们需要您安装原作者的辅助扩展 来让 “下载助手” 读取您的网盘账号凭证 获取到的凭证仅用于生成直链,请放心安装ヾ(≧▽≦*)o 不知道如何安装第三方扩展?点此查看详情 如果给浏览器开启了“开发者模式”后频繁提示 “关闭开发者模式”,请使用此补丁 隐藏提示。界面汉化 扩展安装后请刷新本页,以应用最新更改',
showConfirmButton: true,
showDenyButton: true,
showCloseButton: true,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
confirmButtonText: '前往 Chrome(Crx搜搜)',
denyButtonText: '前往 Firefox(Crx搜搜)',
position: 'center',
...swalDefault
});
if (dialog.isConfirmed) {
GM_openInTab('https://www.crxsoso.com/addon/detail/mphijdmblaalbakceeadippfkbgfgaaa', { active: true });
}
if (dialog.isDenied) {
GM_openInTab('https://www.crxsoso.com/firefox/detail/baidunetdiskisasb', { active: true });
}
return;
}
if (page === 'home' || page === 'main') {
if (!selectList.length) {
return message.error('提示: 先勾选要下载的文件哦~');
}
let cnt = 0;
let processed = selectList.filter(f => !f.isdir).length;
async function fetchFiles(dirs) {
let files = [];
for (let dir of dirs) {
doc.find('.loading-popup .loading-title').html(`文件获取中`);
let url = `${config.$baidu.api.getFiles}&dir=${encodeURIComponent(dir.path)}&access_token=${accessToken}`;
let res = await base.get(url, { "User-Agent": config.$baidu.api.ua.downloadLink });
cnt++;
if (res?.list?.length && (res.errno === 0 || res.errmsg === "succ")) {
let subFiles = res.list.filter(f => !f.isdir);
processed += subFiles.length;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} 个文件~
${dir.path}
`);
files = files.concat(subFiles);
if (res.list.some(f => f.isdir)) {
files = files.concat(await fetchFiles(res.list.filter(f => f.isdir)));
}
}
if (cnt >= 50) {
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} 个文件~
休息 3 秒...
`);
await base.sleep(3000);
cnt = 0;
}
}
return files;
}
let files = selectList.filter(f => !f.isdir);
if (selectList.some(f => f.isdir)) {
files = files.concat(await fetchFiles(selectList.filter(f => f.isdir)));
}
if (!files.length) {
return message.error('提示: 文件夹是空的哦~');
}
doc.find('.loading-popup .loading-title').html(`链接获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取文件对应的下载链接~
`);
let fidList = files.map(f => f.fs_id);
let batchSize = 100;
let linkList = [];
for (let i = 0; i < fidList.length; i += batchSize) {
let url = `${config.$baidu.api.getLink}&fsids=${encodeURIComponent(JSON.stringify(fidList.slice(i, i + batchSize)))}&access_token=${accessToken}`;
let res = await base.get(url, { "User-Agent": config.$baidu.api.ua.downloadLink });
if (res?.list?.length && (res.errno === 0 || res.errmsg === "succ")) {
linkList = linkList.concat(res.list);
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${linkList.length} / ${fidList.length} 个链接~
`);
} else {
if (res?.errno) {
if (res.errno === 112) {
return message.error('提示: 页面过期了,刷新重试下吧~ 代码:' + res.errno);
}
if (res.errno === 9019) {
base.deleteValue('baidu_access_token');
return message.error('提示: 访问令牌已过期,刷新网页后再获取一次吧~ 代码:' + res.errno);
}
base.deleteValue('baidu_access_token');
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~ 代码:' + res.errno);
} else {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
}
await base.sleep(1000);
}
if (linkList.length) {
base.showMainDialog(config.base.dom.button[mode].title, this.generateDom(linkList), config.base.dom.button[mode].footer);
} else {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
} else {
return message.error('提示: 页面错误~');
}
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
base.sortByName(list);
list.forEach((v, i) => {
if (v.isdir === 1) return;
let filename = v.server_filename || v.filename;
let size = base.sizeFormat(v.size);
if (!v?.dlink || !v?.dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
let dlink = v.dlink + '&access_token=' + base.getValue('baidu_access_token');
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制链接
`;
}
let BDUSS = this.getBDUSS();
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename, `--header "User-Agent: ${config.$baidu.api.ua.downloadLink}" --header "Cookie: BDUSS=${BDUSS}"`);
if (typeof (alink) === 'object') {
content += `
`;
} else {
alinkAllText += alink + '\r\n';
content += `
`;
}
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename, `-A "${config.$baidu.api.ua.downloadLink}" -b "BDUSS=${BDUSS}"`);
if (typeof (alink) === 'object') {
content += `
`;
} else {
alinkAllText += alink + '\r\n';
content += `
`;
}
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename, `cookie=${encodeURIComponent("BDUSS=" + BDUSS)}&user_agent=${encodeURIComponent(config.$baidu.api.ua.downloadLink)}`);
if (typeof (alink) === 'object') {
alinkAllText += decodeURIComponent(alink.text) + '\r\n';
content += `
`;
} else {
alinkAllText += alink + '\r\n';
content += `
`;
}
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
let List, selectList
try {
List = require("system-core:context/context.js").instanceForSystem.list;
selectList = List.getSelected();
/*if (!selectList.length) {
selectList = List.getCurrentList();
}*/
return selectList;
} catch (e) { }
try {
List = unsafeWindow.document.querySelector('.wp-s-core-pan');
if (List && List.__vue__.selectedList) {
selectList = List.__vue__.selectedList;
return selectList;
}
} catch (e) { }
try {
List = unsafeWindow.document.querySelector('.file-list');
if (List && List.__vue__.allFileList) {
selectList = List.__vue__.allFileList.filter(function (item) { return !!item.selected; });
return selectList;
}
} catch (e) { }
},
getLogid() {
let ut = require("system-core:context/context.js").instanceForSystem.tools.baseService;
return ut.base64Encode(base.getCookie("BAIDUID"));
},
getShareData() {
let res = unsafeWindow.locals.dump();
shareParams.shareType = 'secret';
shareParams.sign = '';
shareParams.timestamp = '';
shareParams.bdstoken = res.bdstoken.value;
shareParams.channel = 'chunlei';
shareParams.clienttype = 0;
shareParams.web = 1;
shareParams.app_id = 250528;
shareParams.encrypt = 0;
shareParams.product = 'share';
shareParams.logid = this.getLogid();
shareParams.shareid = res.shareid.value;
shareParams.uk = res.share_uk.value;
shareParams.shareType === 'secret' && (shareParams.extra = this._getExtra());
shareParams.surl = this._getSurl();
},
detectPage() {
let path = location.pathname;
if (/^\/disk\/home/.test(path)) return 'home';
if (/^\/disk\/main/.test(path)) return 'main';
if (/^\/youth\/pan\/main/.test(path)) return 'youth';
if (/^\/(s|share)\//.test(path)) return 'share';
return '';
},
async initAuthorize() {
base.registerMenuCommand();
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
html: `请稍后`,
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
let url = new URL(location.href);
let auth = new URL(config.$baidu.api.getAccessToken);
const allowedClientIds = [
auth.searchParams.get("client_id"),
'L6g70tBRRIXLsY0Z3HwKqlRE', // pcstest_oauth
'fSds3K4w43rw37tOqlQmTa2kDwaczK4U', // 小度智能词典笔专业版
'TFwtw8uwHxpdkvVqVKdIlx1XqXUnr1zG', // 印象笔记
'9dgBV9yesuBVOXaxls7aVHbLBLqU8yyg', // WPS文档
'l9DdBOG4RYroMscmzK5OChdaGelgd92M', // 小猴云印PC版
'Kyr013gHQBf2immy3fQt1jZ3nZVpiGAm', // 简单打印
'iYCeC9g08h5vuP9UqvPHKKSVrKFXGa1v', // Alist
'IlLqBbU3GjQ0t46TRwFateTprHWl39zF', // 百度手机助手
];
// https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=&scope=basic,netdisk,mobile&display=page&redirect_uri=
if (
/openapi.baidu.com\/oauth\/2.0\/authorize/.test(location.href) &&
url.searchParams.get("response_type").includes("token") &&
url.searchParams.get("scope").includes("netdisk") &&
allowedClientIds.includes(url.searchParams.get("client_id"))
) {
let dialog = await Swal.fire({
icon: 'info',
title: `提示`,
html: '你好呀,为了获取百度网盘文件的下载直链 我们需要您的授权来使 “下载助手” 读取您的网盘文件信息 由于使用了别的应用ID,所以授权的应用名称会有不同 获取到的数据仅用于生成直链,请放心授权ヾ(≧▽≦*)o',
showConfirmButton: true,
showDenyButton: true,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
confirmButtonText: '授权',
denyButtonText: '再想想',
position: 'center'
});
if (dialog.isConfirmed) {
base.waitForKeyElements("button#auth-allow", function (element) {
element[0].click();
}, true)
return;
}
if (dialog.isDenied) {
return await Swal.fire({
icon: 'question',
title: `好吧(* ̄3 ̄)╭`,
html: '那就再想一想 想好了就按下 “授权” 按钮吧~',
timer: 180000,
toast: true,
timerProgressBar: true,
showConfirmButton: false,
showDenyButton: false,
position: 'bottom-end',
})
}
} else if (/openapi.baidu.com\/oauth\/2.0\/login_success/.test(location.href)) {
let int = setInterval(async function () {
if (location.href.includes('access_token') && (location.href.includes('basic+netdisk') || location.href.includes('basic,netdisk'))) {
clearInterval(int)
let token = location.href.match(/access_token=(.*?)&/)[1];
base.setValue('baidu_access_token', token);
let dialog = await Swal.fire({
icon: 'success',
title: `成功啦`,
html: '你已 成功授权/授权过 脚本读取您的网盘文件信息~ 等待 3 秒之后将关闭此页面',
timer: 3000,
timerProgressBar: true,
showConfirmButton: true,
showDenyButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
confirmButtonText: '关闭页面',
position: 'center',
willOpen: function () {
let sec = 3.1;
setInterval(() => {
sec -= 0.1;
document.getElementById("second").innerText = sec.toFixed(1);
}, 100);
setTimeout(() => {
window.close()
}, 3100);
},
});
if (dialog.isConfirmed) {
window.close()
return;
}
} else {
clearInterval(int)
Swal.close()
}
}, 1)
} else {
Swal.close()
}
} else {
Swal.close()
}
},
async initPanLinker() {
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
},
};
/**
* 阿里云盘
* @author 油小猴
* @author hmjz100
*/
let $aliyun = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:阿里云盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
let reactDomGrid = document.querySelector(config.$aliyun.mount.grid);
if (reactDomGrid) {
let dialog = await Swal.fire({
title: '提示',
html: '请先切换到 列表视图 后再获取下载链接哦
',
icon: 'info',
showCloseButton: true,
showDenyButton: true,
confirmButtonText: '切换',
denyButtonText: '不要',
...swalDefault
});
if (dialog.isConfirmed) {
document.querySelector(config.$aliyun.mount.switch).click();
return message.success('提示: 切换为列表视图成功 请再获取一次下载链接吧~');
}
return false;
}
selectList = $aliyun.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要保存到网盘的文件哦~');
}
message.info('提示: 因网盘限制,请保存到自己网盘后再去下载哦~');
await base.sleep(500);
document.querySelector('[class*="btn-save--"]').click();
});
doc.on('click', '.pl-button-mode', async function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
let reactDomGrid = document.querySelector(config.$aliyun.mount.grid);
if (reactDomGrid) {
let dialog = await Swal.fire({
title: '提示',
html: '请先切换到 列表视图 后再获取下载链接哦
',
icon: 'info',
showCloseButton: true,
showDenyButton: true,
confirmButtonText: '切换',
denyButtonText: '不要',
...swalDefault
});
if (dialog.isConfirmed) {
document.querySelector(config.$aliyun.mount.switch).click();
return message.success('提示: 切换为列表视图成功 请再获取一次下载链接吧~');
}
return false;
}
$aliyun.getLink();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, { "Referer": `https://${location.host}/` }, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-copy-filename', async function (e) {
base.setClipboard(e.target.dataset.filename);
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`Referer: https://${location.host}/`]);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-download-all.blob', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
document.documentElement.addEventListener('mouseup', function (e) {
if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) {
e.stopPropagation();
}
}, true);
},
async getFileUrlByOnce(d, f) {
let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
let res = await base.post(config.$aliyun.api.getLink, {
drive_id: d,
file_id: f
}, {
authorization,
"content-type": "application/json;charset=utf-8",
"referer": "https://www.aliyundrive.com/",
"x-canary": "client=windows,app=adrive,version=v6.0.0"
});
if (res.code === 'AccessTokenInvalid') {
return message.error('提示: 访问令牌过期了,请刷新网页后再试');
}
if (res.url) {
return res.url;
}
return '';
},
greenerPage() {
base.waitForKeyElements('[class*="share-list-banner"]', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('[class*="to-app"]', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('[class*="btn-mobile-save"]', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('div[class*="text"]', function (tag) {
if (tag[0].innerHTML.match("SVIP"))
tag.fadeOut();
}, true);
base.waitForKeyElements('[class*="SplashScreenImg--close"]', function (tag) {
tag[0].click();
}, true);
base.waitForKeyElements('[class*="container"]', function (tag) {
tag.find('[class^="icon-close"]').click();
}, true);
base.waitForKeyElements('[class*="popup_main_close"]', function (tag) {
tag[0].click();
}, true);
},
svg: ` `,
addButton() {
base.waitForKeyElements(config.$aliyun.mount.home, (element) => {
page = $aliyun.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(`${$aliyun.svg}下载助手
`);
element.append($button);
})
base.waitForKeyElements(config.$aliyun.mount.share, (element) => {
page = $aliyun.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(`${$aliyun.svg}下载助手
`);
$button.css({ 'margin-right': '10px', "height": "36px", "width": "auto", "padding": "1px 30px" });
element.prepend($button);
})
},
addInitButton() {
let $button = $(`${$aliyun.svg}点我点亮
`);
$button.click(function () { base.initDialog() });
base.waitForKeyElements(config.$aliyun.mount.home, (element) => {
page = $aliyun.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
$button.css({ "width": "auto" });
element.append($button);
})
base.waitForKeyElements(config.$aliyun.mount.share, (element) => {
page = $aliyun.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
$button.css({ 'margin-right': '10px', "height": "36px", "padding": "1px 30px", "width": "auto" });
element.prepend($button);
})
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
if (page === 'home') {
selectList = selectList.filter(item => item.type === 'file')
let batchSize = 15;
let processed = 0;
doc.find('.loading-popup .loading-title').html(`链接获取中`);
for (let i = 0; i < selectList.length; i += batchSize) {
// 当前批次文件
let batch = selectList.slice(i, i + batchSize);
// 过滤掉已有 URL 的文件
let noUrlSelectList = batch.filter(v => !Boolean(v.url));
let hasUrlSelectList = batch.filter(v => Boolean(v.url));
let queue = [];
// 为没有 URL 的文件生成请求队列
noUrlSelectList.forEach((item) => {
queue.push(this.getFileUrlByOnce(item.driveId, item.fileId)
.then(val => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
return val;
}));
});
hasUrlSelectList.forEach((item) => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
});
// 等待本批次的请求结果
const res = await Promise.all(queue);
res.forEach((val, index) => {
noUrlSelectList[index].url = val;
});
// 每次处理完一个批次后,等待 1 秒
await base.sleep(1000);
}
} else {
return message.error('提示: 页面错误~');
}
let html = this.generateDom(selectList);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.type === 'folder') return;
let filename = v.name;
let fid = v.fileId;
let did = v.driveId;
let size = base.sizeFormat(v.size);
let dlink = v.downloadUrl || v.url;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制名称
复制链接
返回
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename, `--header "Referer: https://${location.host}/"`);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename, `&refer=${encodeURIComponent(`https://${location.host}/`)}`);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename, `-e "https://${location.host}/"`);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.querySelector(config.$aliyun.mount.list);
let reactObj = base.findReact(reactDom, 1);
let props = reactObj.pendingProps;
if (props) {
let fileList = props.dataSource || [];
let selectedKeys = props.selectedKeys.split(',');
fileList.forEach(function (val) {
if (selectedKeys.includes(val.fileId)) {
selectedList.push(val);
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(drive)/.test(path)) return 'home';
if (/^\/(s|share)\//.test(path)) return 'share';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (selectList[i].type === 'file') return false;
}
return true;
},
async initPanLinker() {
page = this.detectPage();
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
}
};
/**
* 中国移动云盘 / 和彩云
* @author 油小猴
* @author hmjz100
*/
let $mcloud = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:移动云盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$mcloud.getLink();
});
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
selectList = $mcloud.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要直接下载的文件哦~');
}
if ($mcloud.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
message.info('提示: 因网盘限制,只能够通过页面直接下载哦~');
await base.sleep(500);
document.querySelector('.btn-top.btn-top_dl').click();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
},
greenerPage() {
base.waitForKeyElements(".adv_swiper_menu", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".client-bubble", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".avs-box", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".top-adv-swiper", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".client_download_icon", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".document_top_memberCenter", function (tag) {
$(tag[0]).click(function () {
Swal.fire({
html: ``,
allowOutsideClick: false,
showCloseButton: true,
showConfirmButton: false,
...swalDefault
});
});
}, true);
},
addButton() {
base.waitForKeyElements(config.$mcloud.mount.home, (element) => {
page = $mcloud.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(`下载助手
`);
element.prepend($button);
})
base.waitForKeyElements(config.$mcloud.mount.share, (element) => {
page = $mcloud.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(`下载助手
`);
element.prepend($button);
})
},
addInitButton() {
let $button = $(`点我点亮
`);
$button.click(function () { base.initDialog() });
base.waitForKeyElements(config.$mcloud.mount.home, (element) => {
page = $mcloud.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
$button.addClass('mcloud-button');
element.prepend($button);
})
base.waitForKeyElements(config.$mcloud.mount.share, (element) => {
page = $mcloud.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
$button.addClass('mcloud-share-button').css({ "cursor": "pointer" });
element.prepend($button);
})
},
getRandomString(len) {
len = len || 16;
let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
let maxPos = $chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
},
utob(str) {
const u = String.fromCharCode;
return str.replace(/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g, function (t) {
if (t.length < 2) {
let e = t.charCodeAt(0);
return e < 128 ? t : e < 2048 ? u(192 | e >>> 6) + u(128 | 63 & e) : u(224 | e >>> 12 & 15) + u(128 | e >>> 6 & 63) + u(128 | 63 & e);
}
e = 65536 + 1024 * (t.charCodeAt(0) - 55296) + (t.charCodeAt(1) - 56320);
return u(240 | e >>> 18 & 7) + u(128 | e >>> 12 & 63) + u(128 | e >>> 6 & 63) + u(128 | 63 & e);
});
},
getSign(e, t, a, n) {
let r = "",
i = "";
if (t) {
let s = Object.assign({}, t);
i = JSON.stringify(s),
i = i.replace(/\s*/g, ""),
i = encodeURIComponent(i);
let c = i.split(""),
u = c.sort();
i = u.join("");
}
let A = md5(base.encodeBase(this.utob(i)));
let l = md5(a + ":" + n);
return md5(A + l).toUpperCase();
},
async getFileUrlByOnce(item, index) {
try {
if (item.downloadUrl) return {
index,
downloadUrl: item.downloadUrl
};
if (this.detectPage() === 'home') {
let body = {
fileId: item.contentID
}
let time = new Date(+new Date() + 8 * 3600 * 1000).toJSON().substr(0, 19).replace('T', ' ');
let key = this.getRandomString(16);
let sign = this.getSign(undefined, body, time, key);
let res = await base.post(config.$mcloud.api.getLink, body, {
'Authorization': base.getCookie('authorization'),
'Caller': 'web',
'CMS-DEVICE': 'default',
'Content-Type': "application/json;charset=UTF-8",
'mcloud-channel': '1000101',
'mcloud-client': '10701',
'mcloud-sign': time + "," + key + "," + sign,
'mcloud-version': '7.14.2',
'Origin': 'https://yun.139.com',
'Referer': 'https://yun.139.com/',
'X-DeviceInfo': '||9|7.14.2|chrome|119.0.0.0|||windows 10||zh-CN|||',
'X-Huawei-ChannelSrc': '10000034',
'X-Inner-Ntwk': '2',
'X-M4C-Caller': 'PC',
'X-M4C-Src': '10002',
'X-SvcType': '1',
'X-Yun-Api-Version': 'v1',
'X-Yun-App-Channel': '10000034',
'X-Yun-Channel-Source': '10000034',
'X-Yun-Client-Info': '||9|7.14.2|chrome|119.0.0.0|||windows 10||zh-CN|||||',
'X-Yun-Module-Type': '100',
'X-Yun-Svc-Type': '1'
});
if (res.success) {
return {
index,
downloadUrl: res.data.url
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~'
};
}
}
if (this.detectPage() === 'share') {
let vueDom = document.querySelector(".main_file_list").__vue__;
let res = await base.post(config.$mcloud.api.getShareLink, `linkId=${vueDom.linkID}&contentIds=${item.path}&catalogIds=`, {
'Content-Type': 'application/x-www-form-urlencoded',
});
if (res.code === 0) {
return {
index,
downloadUrl: res.data.redrUrl
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~'
};
}
}
} catch (e) {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~'
};
}
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
if (page === 'home') {
selectList = selectList.filter(item => item.contentID && item.contentName && item.contentSuffix);
let batchSize = 15;
let processed = 0;
doc.find('.loading-popup .loading-title').html(`链接获取中`);
for (let i = 0; i < selectList.length; i += batchSize) {
let batch = selectList.slice(i, i + batchSize);
let queue = [];
batch.forEach((item, localIndex) => {
let globalIndex = i + localIndex;
queue.push(this.getFileUrlByOnce(item, globalIndex)
.then(val => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
return val;
}));
});
let res = await Promise.all(queue);
res.forEach(val => {
selectList[val.index].downloadUrl = val.downloadUrl;
});
await base.sleep(1000);
}
} else {
return message.error('提示: 页面错误~');
}
let html = this.generateDom(selectList);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.dirEtag || v.caName) return;
let filename = v.contentName || v.coName;
let size = base.sizeFormat(v.contentSize || v.coSize);
let dlink = v.downloadUrl;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制链接
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
return document.querySelector(".main_file_list").__vue__.selectList.map(val => val.item);
} catch (e) {
let vueDom = document.querySelector(".home-page").__vue__;
let fileList = vueDom._computedWatchers.fileList.value;
let dirList = vueDom._computedWatchers.dirList.value;
let selectedFileIndex = vueDom.selectedFile;
let selectedDirIndex = vueDom.selectedDir;
let selectFileList = fileList.filter((v, i) => {
return selectedFileIndex.includes(i);
});
let selectDirList = dirList.filter((v, i) => {
return selectedDirIndex.includes(i);
});
return [...selectFileList, ...selectDirList];
}
},
detectPage() {
let path = location.pathname;
if (/^\/w/.test(path)) return 'home';
if (/^\/link|shareweb/.test(path)) return 'share';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (selectList[i].contentID || selectList[i].contentName) return false;
}
return true;
},
async initPanLinker() {
page = this.detectPage();
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
}
};
/**
* 天翼云盘
* @author 油小猴
* @author hmjz100
*/
let $tcloud = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:天翼云盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$tcloud.getLink();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
},
greenerPage() {
base.waitForKeyElements(".advertising-mask", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements("a.client-download.nav-block", function (tag) {
tag.fadeOut();
}, true);
},
addButton() {
let $button = $(``);
$button.find(".pl-dropdown-menu").css({ 'position': 'absolute', 'left': '-1px' })
base.waitForKeyElements(config.$tcloud.mount.home, (element) => {
page = $tcloud.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
$button.find(".pl-dropdown-menu").css({ 'top': '28px' })
element.prepend($button);
})
base.waitForKeyElements(config.$tcloud.mount.share, (element) => {
page = $tcloud.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
$button.css({ 'height': '28px', 'border-radius': '15px' })
$button.find(".pl-dropdown-menu").css({ 'top': '25px' })
element.prepend($button);
})
},
addInitButton() {
let $button = $(`点我点亮
`);
$button.click(function () { base.initDialog() });
base.waitForKeyElements(config.$tcloud.mount.home, (element) => {
page = $tcloud.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
element.prepend($button);
})
base.waitForKeyElements(config.$tcloud.mount.share, (element) => {
page = $tcloud.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
$button.css({ 'height': '28px', 'border-radius': '15px' })
element.prepend($button);
})
},
async getToken() {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取状态~
`);
let res = await base.getFinalUrl(config.$tcloud.api.getAccessToken, {});
let accessToken = res.match(/accessToken=(\w+)/)?.[1];
accessToken && base.setStorage('accessToken', accessToken);
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`获取成功,令牌已缓存~
`);
return accessToken;
},
async getFileUrlByOnce(item, index, token) {
try {
if (item.downloadUrl) return {
index,
downloadUrl: item.downloadUrl
};
let time = Date.now(),
fileId = item.fileId,
o = "AccessToken=" + token + "&Timestamp=" + time + "&fileId=" + fileId,
url = config.$tcloud.api.getLink + '?fileId=' + fileId;
if (item.shareId) {
o = "AccessToken=" + token + "&Timestamp=" + time + "&dt=1&fileId=" + fileId + "&shareId=" + item.shareId;
url += '&dt=1&shareId=' + item.shareId;
}
let sign = md5(o).toString();
let res = await base.get(url, {
"accept": "application/json;charset=UTF-8",
"sign-type": 1,
"accesstoken": token,
"timestamp": time,
"signature": sign
});
if (res.res_code === 0) {
return {
index,
downloadUrl: res.fileDownloadUrl
};
} else if (res.errorCode === 'InvalidSessionKey') {
return {
index,
downloadUrl: '提示: 请先登录网盘~'
};
} else if (res.res_code === 'ShareNotFoundFlatDir') {
return {
index,
downloadUrl: '提示: 请[转存]文件,之后再👉前往[我的网盘]中下载哦~'
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~' + (res.res_code ? res.res_code : "")
};
}
} catch (e) {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~'
};
}
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
selectList = selectList.filter(item => !item.isFolder)
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取状态~
`);
let token = base.getStorage('accessToken') || await this.getToken();
if (!token) {
return message.error('提示: 请先登录网盘~');
}
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`获取缓存成功~
`);
let batchSize = 15;
let processed = 0;
doc.find('.loading-popup .loading-title').html(`链接获取中`);
for (let i = 0; i < selectList.length; i += batchSize) {
let batch = selectList.slice(i, i + batchSize);
let queue = [];
batch.forEach((item, localIndex) => {
let globalIndex = i + localIndex;
queue.push(this.getFileUrlByOnce(item, globalIndex, token)
.then(val => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
return val;
}));
});
let res = await Promise.all(queue);
res.forEach(val => {
selectList[val.index].downloadUrl = val.downloadUrl;
});
await base.sleep(1000);
}
let html = this.generateDom(selectList);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
},
generateDom(list) {
console.log(list)
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.isFolder) return;
let filename = v.fileName;
let size = base.sizeFormat(v.size);
let dlink = v.downloadUrl;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制链接
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
return document.querySelector(".c-file-list").__vue__.selectedList;
} catch (e) {
return [document.querySelector(".info-detail").__vue__.fileDetail];
}
},
detectPage() {
let path = location.pathname;
if (/^\/web\/main/.test(path)) return 'home';
if (/^\/web\/share/.test(path)) return 'share';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (!selectList[i].isFolder) return false;
}
return true;
},
async initPanLinker() {
page = this.detectPage();
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
this.getToken();
}
};
/**
* 迅雷云盘
* @author 油小猴
* @author hmjz100
*/
let $xunlei = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:迅雷云盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$xunlei.getLink();
});
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
selectList = $xunlei.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要保存到网盘的文件哦~');
}
message.info('提示: 因网盘限制,请保存到自己网盘后再去下载哦~');
await base.sleep(500);
document.querySelector('.saveToCloud').click();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-copy-filename', async function (e) {
base.setClipboard(e.target.dataset.filename);
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-bc-btn', async function (e) {
let mirror = base.getMirrorList(e.target.dataset.dlink, config.$xunlei.api.mirror);
base.setClipboard(mirror);
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
},
addButton() {
base.waitForKeyElements(config.$xunlei.mount.home, (element) => {
page = $xunlei.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(`下载助手
`);
element.prepend($button);
})
base.waitForKeyElements(config.$xunlei.mount.share, (element) => {
page = $xunlei.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(`
下载助手
`);
$button.css({ 'margin-right': '10px' });
element.prepend($button);
})
},
addInitButton() {
let $button = $(`点我点亮
`);
$button.click(function () { base.initDialog() });
base.waitForKeyElements(config.$xunlei.mount.home, (element) => {
page = $xunlei.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
element.prepend($button);
})
base.waitForKeyElements(config.$xunlei.mount.share, (element) => {
page = $xunlei.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
$button.css({ 'margin-right': '10px' });
element.prepend($button);
})
},
getToken() {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取状态~
`);
let credentials = {}, captcha = {};
for (let i = 0; i < localStorage.length; i++) {
if (/^credentials_/.test(localStorage.key(i))) {
credentials = base.getStorage(localStorage.key(i));
base.setStorage('');
}
if (/^captcha_[\w]{16}/.test(localStorage.key(i))) {
captcha = base.getStorage(localStorage.key(i));
}
}
let deviceid = /(\w{32})/.exec(base.getStorage('deviceid').split(','))[0];
let token = {
credentials,
captcha,
deviceid
};
return token;
},
async getFileUrlByOnce(item, index, token) {
try {
if (item.downloadUrl) return {
index,
downloadUrl: item.downloadUrl
};
let res = await base.get(config.$xunlei.api.getLink + item.id, {
'Authorization': `${token.credentials.token_type} ${token.credentials.access_token}`,
'content-type': "application/json",
'x-captcha-token': token.captcha.token,
'x-device-id': token.deviceid,
});
if (res.web_content_link) {
return {
index,
downloadUrl: res.web_content_link
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~'
};
}
} catch (e) {
return message.error('提示: 请先登录网盘后再刷新页面呢~');
}
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
if (page === 'home') {
let token = this.getToken();
let batchSize = 15;
let processed = 0;
doc.find('.loading-popup .loading-title').html(`链接获取中`);
for (let i = 0; i < selectList.length; i += batchSize) {
let batch = selectList.slice(i, i + batchSize);
let queue = [];
batch.forEach((item, localIndex) => {
let globalIndex = i + localIndex;
queue.push(this.getFileUrlByOnce(item, globalIndex, token)
.then(val => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
return val;
}));
});
let res = await Promise.all(queue);
res.forEach(val => {
selectList[val.index].downloadUrl = val.downloadUrl;
});
await base.sleep(1000);
}
} else {
return message.error('提示: 页面错误~');
}
let html = this.generateDom(selectList);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.kind === 'drive#folder') return;
let filename = v.name;
let size = base.sizeFormat(+v.size);
let dlink = v.downloadUrl;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
let doms = document.querySelectorAll('.SourceListItem__item--XxpOC');
let selectedList = [];
for (let dom of doms) {
let domVue = dom.__vue__;
if (domVue.selected.includes(domVue.info.id)) {
selectedList.push(domVue.info);
}
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/$/.test(path)) return 'home';
if (/^\/(s|share)\//.test(path)) return 'share';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (selectList[i].kind === 'drive#file') return false;
}
return true;
},
async initPanLinker() {
page = this.detectPage();
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
}
};
/**
* 夸克网盘
* @author 油小猴
* @author hmjz100
*/
let $quark = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:夸克网盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
window.addEventListener('hashchange', async function (e) {
let home = 'https://pan.quark.cn/list#/', all = 'https://pan.quark.cn/list#/list/all';
if (e.oldURL === home && e.newURL === all) return;
await base.sleep(150);
if ($('.quark-button').length > 0) return;
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
});
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$quark.getLink();
});
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
selectList = $quark.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要保存到网盘的文件哦~');
}
message.info('提示: 因网盘限制,请保存到自己网盘后再去下载哦~');
await base.sleep(500);
document.querySelector('.share-path').click();
base.waitForKeyElements(".btn-file.btn-file-primary.confirm-btn", (element) => {
element.one("click", async () => {
await base.sleep(1000);
document.querySelector('.share-save').click();
})
return true;
}, true)
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`Cookie: ${document.cookie}`]);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
},
greenerPage() {
base.waitForKeyElements('[class*="Activity--video-toolbar-activity"]', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('span[class*="SectionHeaderController--icon-download"]', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('div[class*="SectionHeaderController--download-popover"]', function (tag) {
tag.find(".ant-popover-arrow").css({ "left": "75%" });
}, true);
base.waitForKeyElements('div[class*="DetailLayout--client-download"]', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".next-box.share-right-side-content", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('[class*="DetailLayout--container"] .feature-screen', function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements('.ant-modal-content .ant-modal-body .right-wrap', function (tag) {
if (tag.find(".hint").text().includes("客户端")) tag.fadeOut();
}, true);
base.waitForKeyElements(".pc-member-entrance span.button-text", function (tag) {
tag.text("会员中心");
let observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (tag.text() === "会员中心") return
tag.text("会员中心");
});
});
let config = { subtree: true, characterData: true, childList: true };
observer.observe(tag[0], config);
}, true);
base.waitForKeyElements(".pc-member-entrance .tips", function (tag) {
tag.fadeOut();
}, true);
base.waitForKeyElements(".modal .modal-content .halo-animated-background .halo-content .pay-modal .close", function (tag) {
tag[0].click();
}, true);
base.waitForKeyElements(".modal .modal-content .halo-animated-background .halo-content .red-envelope .close", function (tag) {
tag[0].click();
}, true);
},
svg: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+',
addButton() {
base.waitForKeyElements(config.$quark.mount.home, (element) => {
page = $quark.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(``);
$button.css({ "margin-right": "10px", "display": "inline-block" });
element.prepend($button);
})
base.waitForKeyElements(config.$quark.mount.share, (element) => {
page = $quark.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(`下载助手 `);
$button.css({ "height": "36px", "margin-left": "16px", "border-radius": "6px", "display": "inline-block" });
element.append($button);
})
},
addInitButton() {
base.waitForKeyElements(config.$quark.mount.home, (element) => {
page = $quark.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
let $button = $(``);
$button.css({ "margin-right": "10px", "display": "inline-block" });
$button.click(function () { base.initDialog() });
element.prepend($button);
})
base.waitForKeyElements(config.$quark.mount.share, (element) => {
page = $quark.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
let $button = $(`点我点亮 `);
$button.css({ "height": "36px", "margin-left": "16px", "border-radius": "6px", "display": "inline-block" });
$button.click(function () { base.initDialog() });
element.append($button);
})
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
if (page === 'home') {
let data = [];
let batchSize = 15;
let processed = 0;
selectList = selectList.filter(item => item.file === true)
for (let i = 0; i < selectList.length; i += batchSize) {
// 获取当前批次文件
let batch = selectList.slice(i, i + batchSize);
console.log()
let fids = batch.map(item => item.fid);
// 发起请求获取链接
let res = await base.post(config.$quark.api.getLink, { "fids": fids }, { "content-type": "application/json;charset=utf-8", "user-agent": config.$quark.api.ua.downloadLink });
if (res?.code === 31001) {
return message.error('提示: 请先登录网盘~ 代码:' + res.code);
}
if (res?.code !== 0) {
return message.error('提示: 获取链接失败了~ 代码:' + res.code);
}
// 合并响应数据
if (res?.data) {
data.push(...res.data);
}
// 更新处理进度
processed += batch.length;
// 更新UI显示
doc.find('.loading-popup .loading-title').html(`链接获取中`);
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
// 请求间隔节流
await base.sleep(1000);
}
let html = this.generateDom(data);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
} else {
return message.error('提示: 页面错误~');
}
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.file === false) return;
let filename = v.file_name;
let fid = v.fid;
let size = base.sizeFormat(v.size);
let dlink = v.download_url;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制链接
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename, `--header "Cookie: ${document.cookie}"`);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename, `-b "${document.cookie}"`);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename, `cookie=${encodeURIComponent(document.cookie)}`);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.getElementsByClassName('file-list')[0];
let reactObj = base.findReact(reactDom);
let props = reactObj.props;
if (props) {
let fileList = props.list || [];
let selectedKeys = props.selectedRowKeys || [];
fileList.forEach(function (val) {
if (selectedKeys.includes(val.fid)) {
selectedList.push(val);
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(list)/.test(path)) return 'home';
if (/^\/(s|share)\//.test(path)) return 'share';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (selectList[i].file) return false;
}
return true;
},
async initPanLinker() {
page = this.detectPage();
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
}
};
/**
* UC网盘
* @author 油小猴
* @author hmjz100
*/
let $uc = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:UC网盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
window.addEventListener('hashchange', async function (e) {
let home = 'https://drive.uc.cn/list#/', all = 'https://drive.uc.cn/list#/list/all';
if (e.oldURL === home && e.newURL === all) return;
await base.sleep(150);
if ($('.uc-button').length > 0) return;
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
});
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$uc.getLink();
});
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
selectList = $uc.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要保存到网盘的文件哦~');
}
message.info('提示: 因网盘限制,请保存到自己网盘后再去下载哦~');
await base.sleep(500);
document.querySelector('.file-info_r').click();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename, [`Cookie: ${document.cookie}`]);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
},
greenerPage() {
base.waitForKeyElements('[class*="VideoDetail--content-footer"]', function (tag) {
tag.children().each(function () {
const $child = $(this);
if ($child.text().includes('手机客户端')) {
$child.hide();
}
});
}, true);
base.waitForKeyElements('[class*="PCLandingBanner--ad-block"]', function (tag) {
tag.hide();
}, true);
},
svg: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNOSAxMmwyIDIgMi0yeiIvPjxwYXRoIGQ9Ik0xNCA4aDEuNTUzYy44NSAwIDEuMTYuMDkzIDEuNDcuMjY3LjMxMS4xNzQuNTU2LjQzLjcyMi43NTYuMTY2LjMyNi4yNTUuNjUuMjU1IDEuNTR2NC44NzNjMCAuODkyLS4wODkgMS4yMTUtLjI1NSAxLjU0LS4xNjYuMzI3LS40MS41ODMtLjcyMi43NTctLjMxLjE3NC0uNjIuMjY3LTEuNDcuMjY3SDYuNDQ3Yy0uODUgMC0xLjE2LS4wOTMtMS40Ny0uMjY3YTEuNzc4IDEuNzc4IDAgMDEtLjcyMi0uNzU2Yy0uMTY2LS4zMjYtLjI1NS0uNjUtLjI1NS0xLjU0di00Ljg3M2MwLS44OTIuMDg5LTEuMjE1LjI1NS0xLjU0LjE2Ni0uMzI3LjQxLS41ODMuNzIyLS43NTcuMzEtLjE3NC42Mi0uMjY3IDEuNDctLjI2N0gxMSIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTExIDN2MTAiLz48L2c+PC9zdmc+',
addButton() {
base.waitForKeyElements(config.$uc.mount.home, (element) => {
page = $uc.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(``);
$button.css({ "margin-right": "10px", "display": "inline-block" });
element.prepend($button);
})
base.waitForKeyElements(config.$uc.mount.share, (element) => {
page = $uc.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(``);
$button.css({ "margin-left": "10px", "display": "inline-block" });
element.append($button);
})
},
addInitButton() {
let $button = $(``);
$button.click(function () { base.initDialog() });
base.waitForKeyElements(config.$uc.mount.home, (element) => {
page = $uc.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
$button.css({ "margin-right": "10px", "display": "inline-block" });
element.prepend($button);
})
base.waitForKeyElements(config.$uc.mount.share, (element) => {
page = $uc.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
$button.css({ "margin-left": "10px", "display": "inline-block" });
element.append($button);
})
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
if (page === 'home') {
let data = [];
let batchSize = 15;
let processed = 0;
selectList = selectList.filter(item => item.file === true)
for (let i = 0; i < selectList.length; i += batchSize) {
// 获取当前批次文件
let batch = selectList.slice(i, i + batchSize);
console.log()
let fids = batch.map(item => item.fid);
// 发起请求获取链接
let res = await base.post(config.$uc.api.getLink, { "fids": fids }, { "content-type": "application/json;charset=utf-8", "user-agent": config.$quark.api.ua.downloadLink });
if (res?.code === 31001) {
return message.error('提示: 请先登录网盘~ 代码:' + res.code);
}
if (res?.code !== 0) {
return message.error('提示: 获取链接失败了~ 代码:' + res.code);
}
// 合并响应数据
if (res?.data) {
data.push(...res.data);
}
// 更新处理进度
processed += batch.length;
// 更新UI显示
doc.find('.loading-popup .loading-title').html(`链接获取中`);
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
// 请求间隔节流
await base.sleep(1000);
}
let html = this.generateDom(data);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
} else {
return message.error('提示: 页面错误~');
}
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.file === false) return;
let filename = v.file_name;
let fid = v.fid;
let size = base.sizeFormat(v.size);
let dlink = v.download_url;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制链接
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename, `--header "Cookie: ${document.cookie}"`);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename, `-b "${document.cookie}"`);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename, `cookie=${encodeURIComponent(document.cookie)}`);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.getElementsByClassName('file-list')[0];
let reactObj = base.findReact(reactDom);
let props = reactObj.props;
if (props) {
let fileList = props.list || [];
let selectedKeys = props.selectedRowKeys || [];
fileList.forEach(function (val) {
if (selectedKeys.includes(val.fid)) {
selectedList.push(val);
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(list)/.test(path)) return 'home';
if (/^\/(s|share)\//.test(path)) return 'share';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (selectList[i].file) return false;
}
return true;
},
async initPanLinker() {
page = this.detectPage();
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
}
};
/**
* 123云盘
* @author 油小猴
* @author hmjz100
*/
let $123pan = {
addPageListener() {
/*
防止代码因其他原因被执行多次
这段代码出自 Via轻插件,作者谷花泰
*/
const key = encodeURIComponent('LinkSwift:123云盘');
if (window[key]) return;
window[key] = true;
function _factory(e) {
let target = $(e.target);
let item = target.parents('.pl-item');
let link = item.find('.pl-item-link.blob');
let directLink = item.find('.pl-item-link.browser');
let progress = item.find('.pl-item-progress');
let tip = item.find('.pl-item-tip');
let copy = item.find('.pl-item-copy');
let back = item.find('.pl-progress-back');
let stop = item.find('.pl-progress-stop');
return {
item, link, directLink, progress, tip, copy, back, stop, target,
};
}
doc.on('click', '.pl-button-mode', function (e) {
mode = e.target.dataset.mode;
if (!mode) return;
$123pan.getLink();
});
doc.on('click', '.pl-button-save', async function (e) {
e.preventDefault();
selectList = $123pan.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要保存到网盘的文件哦~');
}
message.info('提示: 因网盘限制,请保存到自己网盘后再去下载哦~');
await base.sleep(500);
document.querySelector('.file-info_r').click();
});
doc.on('click', '.listener-link-api.browser', async function (e) {
e.preventDefault();
let dataset = e.currentTarget.dataset;
let href = dataset.link;
$('#downloadIframe').attr('src', href);
});
doc.on('click', '.listener-link-api.blob', async function (e) {
e.preventDefault();
const o = _factory(e);
const $width = o.item.find('.pl-progress-inner');
const $text = o.item.find('.pl-progress-inner-text');
const filename = o.link[0].dataset.filename;
const index = o.link[0].dataset.index;
const size = Number(o.link[0].dataset.size) || 0;
base._resetData(index);
base.get(e.currentTarget.dataset.link, undefined, 'blob', { filename, index });
let startTime = Date.now();
let prevLoaded = 0;
let prevTime = startTime;
ins[index] = setInterval(async function () {
const prog = +progress[index] || 0;
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const loaded = prog * size / 100;
const timeDiff = Math.max(currentTime - prevTime, 1); // 避免除零
const speed = ((loaded - prevLoaded) / (timeDiff / 1000)) || 0;
// 计算剩余时间(保护除零)
const totalProgress = Math.max(prog / 100, 0.01);
const totalElapsedSeconds = elapsedTime / 1000;
const estTotalTime = totalElapsedSeconds / totalProgress;
const remainingTime = estTotalTime - totalElapsedSeconds;
// 更新界面状态
o.link.hide();
o.directLink.hide();
o.tip.hide();
o.stop.show();
o.copy.hide();
o.progress.show();
// 更新进度条
$width.css('width', `${prog}%`);
$text.text(`${prog.toFixed(1)}% | 速度:${base.sizeFormat(speed)} | 剩余:${base.rtimeFormat(remainingTime)}`);
// 更新历史值
prevLoaded = loaded;
prevTime = currentTime;
// 下载完成
if (prog >= 100) {
await base.sleep(1000);
clearInterval(ins[index]);
progress[index] = 0;
o.item.find('.pl-progress-stop').hide();
$text.text('下载完成~ 浏览器下载框应该弹出来了哦~');
o.back.show();
await base.sleep(3000);
o.link.text('增强下载(基于浏览器文件流)').animate({ opacity: '1' }, "slow");
}
}, 500);
});
doc.on('click', '.listener-retry', async function (e) {
let o = _factory(e);
o.tip.hide();
o.link.show();
o.directLink.show();
});
doc.on('click', '.listener-stop', async function (e) {
let o = _factory(e);
let index = o.link[0].dataset.index;
if (request[index]) {
request[index].abort();
clearInterval(ins[index]);
o.item.find('.pl-progress-inner-text').text('正在取消...');
o.item.find('.pl-progress-inner').css('width', 100 + '%');
setTimeout(function () {
o.tip.hide();
o.back.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.progress.hide();
o.stop.hide();
}, 1050)
}
});
doc.on('click', '.listener-back', async function (e) {
let o = _factory(e);
o.progress.hide();
o.tip.hide();
o.link.show();
o.directLink.show();
o.copy.show();
o.stop.hide();
o.back.hide();
});
doc.on('click', '.listener-download-all', function (e) {
$('.pl-item-link.blob').each(function () {
if ($(this).css('display') !== 'none') {
$(this).click();
}
});
$(e.target).text('下载开始,下载进度见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('全部增强下载').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-aria, .listener-copy-all', function (e) {
e.preventDefault();
base.setClipboard(decodeURIComponent(e.target.dataset.link));
$(e.target).text('复制成功').animate({ opacity: '0.5' }, "slow");
setTimeout(function () {
$(e.target).text('重新复制').animate({ opacity: '1' }, "slow");
}, 2000)
});
doc.on('click', '.listener-link-rpc', async function (e) {
let target = $(e.currentTarget);
target.find('.icon-rpc-devices').remove();
target.find('.pl-loading').remove();
target.prepend(base.createLoading());
let res = await base.sendLinkToRPC(e.currentTarget.dataset.link, e.currentTarget.dataset.filename);
if (res === 'success') {
$('.listener-rpc-task').show();
target.removeClass('pl-btn-danger').html('发送成功了!快去看看吧~').animate({ opacity: '0.5' }, "slow");
} else if (res === 'assistant') {
target.addClass('pl-btn-danger').html(`${config.base.assistant.message}👉点击此处安装 👈`);
} else {
target.addClass('pl-btn-danger').text('发送失败,检查一下您的RPC配置信息哦!').animate({ opacity: '0.5' }, "slow");
}
});
doc.on('click', '.listener-send-rpc', function (e) {
$('.listener-link-rpc').click();
$(e.target).text('发送完成,发送结果见上方按钮哦~').animate({ opacity: '0.5' }, "slow");
});
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-rpc-task', function () {
let rpc = JSON.stringify({
domain: base.getValue('setting_rpc_domain'),
port: base.getValue('setting_rpc_port'),
}), url = `${config.base.service.rpc}/?rpc=${base.encodeBase(rpc)}#${base.getValue('setting_rpc_token')}`;
GM_openInTab(url, { active: true });
});
},
greenerPage() {
base.waitForKeyElements(".new-menu-item-image, .special-menu-item-container-migration--label, .sider-member-btn, .video-new-user-tips", (tag) => {
if (tag.is(":hidden")) return;
tag.hide();
}, true)
let allowedTexts = ["其他网盘数据转入", "同步空间", "回收站", "下载客户端"];
base.waitForKeyElements(`.ant-menu.ant-menu-root.ant-menu-inline[role="menu"]`, (tag) => {
tag.find(`[role="menuitem"]`).each(function () {
const menuText = $(this).text().trim();
if (!allowedTexts.includes(menuText) || $(this).is(":hidden")) return;
$(this).hide();
});
}, true)
base.waitForKeyElements(".special-menu-item-container", (tag) => {
tag.find(".special-menu-item-container-migration").each(function () {
const menuText = $(this).text().trim();
if (!allowedTexts.includes(menuText) || $(this).is(":hidden")) return;
$(this).hide();
});
}, true)
base.waitForKeyElements(`.header-btn-list`, (tag) => {
tag.find(`.btn-item`).each(function () {
const menuText = $(this).text().trim();
if (!allowedTexts.includes(menuText) || $(this).is(":hidden")) return;
$(this).hide();
});
}, true)
base.waitForKeyElements(`.rightInfo .register:not(.pl-button, .pl-button-init),
.homeClass > div > .ant-dropdown-trigger:not(.pl-button, .pl-button-init),
.homeClass > div > .sysbut`, function (tag) {
let hasTextNode = false;
tag.contents().each(function () {
if (this.nodeType === 3 && $.trim(this.textContent)) {
hasTextNode = true;
return false; // break the loop
}
});
if (!hasTextNode) return;
tag.css({ "width": "38px" });
tag.contents().each(function () {
if (this.nodeType === 3) {
$(this).remove();
}
});
tag.find('svg').css({ "margin-right": "0" });
});
base.waitForKeyElements('.rightInfo .qrcode_btn', function (tag) {
tag.hide();
}, true);
},
getToken() {
doc.find('.loading-popup .loading-title').html(`令牌获取中`);
doc.find('.loading-popup .swal2-html-container').html(`正在获取令牌~
`);
let token = base.getStorage("authorToken");
return token;
},
async getLink() {
Swal.fire({
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
title: "获取中",
html: `...`,
footer: "如果选的文件较多,请耐心等待获取完成哦!",
customClass: {
popup: 'loading-popup',
header: 'loading-header',
title: 'loading-title',
content: 'loading-content',
input: 'loading-input',
footer: 'loading-footer'
},
willOpen: function () {
Swal.showLoading();
},
...swalDefault
});
selectList = this.getSelectedList();
if (selectList.length === 0) {
return message.error('提示: 请勾选要下载的文件哦~');
}
if (this.isOnlyFolder()) {
return message.error('提示: 请打开文件夹后再勾选文件~');
}
console.log(selectList);
if (page === 'home') {
let token = this.getToken();
let batchSize = 15;
let processed = 0;
selectList = selectList.filter(item => item.Type === 0);
for (let i = 0; i < selectList.length; i += batchSize) {
let batch = selectList.slice(i, i + batchSize);
let queue = [];
doc.find('.loading-popup .loading-title').html(`链接获取中`);
batch.forEach((item, localIndex) => {
let globalIndex = i + localIndex;
queue.push(this.getFileUrlByOnce(item, globalIndex, token)
.then(val => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
return val;
}));
});
let res = await Promise.all(queue);
res.forEach(val => {
selectList[val.index].DownloadUrl = val.downloadUrl;
});
await base.sleep(1000);
}
let html = this.generateDom(selectList);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
} else if (page === 'share') {
let token = this.getToken();
let batchSize = 15;
let processed = 0;
selectList = selectList.filter(item => item.Type === 0);
let pathSplit = location.pathname.split('/').filter(Boolean);
let ShareKey = pathSplit[1];
console.log(selectList)
for (let i = 0; i < selectList.length; i += batchSize) {
let batch = selectList.slice(i, i + batchSize);
let queue = [];
doc.find('.loading-popup .loading-title').html(`链接获取中`);
batch.forEach((item, localIndex) => {
let globalIndex = i + localIndex;
queue.push(this.getFileUrlByOnce(item, globalIndex, token, ShareKey)
.then(val => {
processed++;
doc.find('.loading-popup .swal2-html-container').html(`已获取 ${processed} / ${selectList.length} 个链接~
`);
return val;
}));
});
let res = await Promise.all(queue);
res.forEach(val => {
selectList[val.index].DownloadUrl = val.downloadUrl;
});
await base.sleep(1000);
}
let html = this.generateDom(selectList);
base.showMainDialog(config.base.dom.button[mode].title, html, config.base.dom.button[mode].footer);
} else {
return message.error('提示: 页面错误~');
}
},
async getFileUrlByOnce(item, index, token, ShareKey) {
try {
if (item.DownloadUrl) return {
index,
downloadUrl: item.DownloadUrl
};
let res = null;
if (ShareKey) {
res = await base.post(config.$123pan.api.getShareLink, {
"ShareKey": ShareKey,
"FileID": item.FileId,
"S3keyFlag": item.S3KeyFlag,
"Size": item.Size,
"Etag": item.Etag
}, {
"content-type": "application/json;charset=utf-8",
"authorization": `Bearer ${token}`,
"platform": "ios"
});
} else {
res = await base.post(config.$123pan.api.getLink, {
"driveId": 0,
"etag": item.Etag,
"fileId": item.FileId,
"s3keyFlag": item.S3KeyFlag,
"type": item.Type,
"fileName": item.FileName,
"size": item.Size
}, {
"content-type": "application/json;charset=utf-8",
"authorization": `Bearer ${token}`,
"platform": "ios"
});
}
if (res.data?.DownloadUrl) {
let url = res.data.DownloadUrl;
let surl = new URL(url).searchParams.get("params");
if (surl) url = base.decodeBase(surl);
url = await base.getFinalUrl(url);
return {
index,
downloadUrl: url
};
} else if (res.data?.DownloadURL) {
let url = res.data.DownloadURL;
let surl = new URL(url).searchParams.get("params");
if (surl) url = base.decodeBase(surl);
url = await base.getFinalUrl(url);
return {
index,
downloadUrl: url
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,刷新后再试试吧~'
};
}
} catch (e) {
return message.error('提示: 请先登录网盘后再刷新页面呢~');
}
},
generateDom(list) {
if (!list) {
return message.error('提示: 获取下载链接失败,刷新网页后再试试吧~');
}
let content = '';
let alinkAllText = '';
list.forEach((v, i) => {
if (v.Type !== 0) return;
let filename = v.FileName;
let fileid = v.FileId;
let size = base.sizeFormat(v.Size);
let dlink = v.DownloadUrl || v.DownloadURL;
if (!dlink || !dlink.includes("http")) {
content += `
${filename}
获取下载链接失败,刷新网页后再试试吧~
`;
} else {
if (mode === 'api') {
alinkAllText += dlink + '\r\n';
content += `
${filename}
增强下载(基于浏览器文件流)
直接下载(基于浏览器链接)
复制链接
`;
}
if (mode === 'aria') {
let alink = base.convertLinkToAria(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'rpc') {
content += `
${filename}
将 ${filename} 推送到 RPC 下载器
`;
}
if (mode === 'curl') {
let alink = base.convertLinkToCurl(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
if (mode === 'bc') {
let alink = base.convertLinkToBC(dlink, filename);
alinkAllText += alink + '\r\n';
content += `
`;
}
}
});
content += '
';
if (mode === 'rpc') {
content += ``;
}
return content;
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.getElementsByClassName('ant-table-body')[0];
let reactObj = base.findReact(reactDom);
let props = reactObj.memoizedProps.props;
if (props) {
let fileList = props.data || [];
fileList.forEach(function (val) {
if (val?.checked === true) {
selectedList.push(val);
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
isOnlyFolder() {
for (let i = 0; i < selectList.length; i++) {
if (selectList[i].Type === 0) return false;
}
return true;
},
addButton() {
base.waitForKeyElements(config.$123pan.mount.home, (element) => {
element = element.parent();
page = $123pan.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'home') return;
let $button = $(`
下载助手
`);
$button.css({ "margin-right": "22px", "width": "110px" })
element.prepend($button);
})
base.waitForKeyElements(config.$123pan.mount.share, (element) => {
element = element.parent();
page = $123pan.detectPage();
if ($(".pl-button").length > 0 || !page || page !== 'share') return;
let $button = $(`
下载助手
`);
$button.css({ "width": "100px" })
element.append($button);
})
},
addInitButton() {
base.waitForKeyElements(config.$123pan.mount.home, (element) => {
element = element.parent();
page = $123pan.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'home') return;
let $button = $(`
点我点亮
`);
$button.click(function () { base.initDialog() });
$button.css({ "margin-right": "22px", "width": "110px" })
element.prepend($button);
})
base.waitForKeyElements(config.$123pan.mount.share, (element) => {
element = element.parent();
page = $123pan.detectPage();
if ($(".pl-button-init").length > 0 || !page || page !== 'share') return;
let $button = $(`
点我点亮
`);
$button.click(function () { base.initDialog() });
$button.css({ "width": "100px" })
element.append($button);
})
},
detectPage() {
let path = location.pathname;
if (/^\/$/.test(path)) return 'home';
if (/^\/s\//.test(path)) return 'share';
return '';
},
async initPanLinker() {
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
this.addPageListener();
} else {
this.addInitButton();
}
},
};
// 油小猴
let $youxiaohou = {
async initPanLinker() {
base.createTip();
base.registerMenuCommand();
if (config.base.num === base.getValue('setting_init_code') || config.base.license === base.getValue('setting_init_license')) {
this.addButton();
} else {
this.addInitButton();
}
},
addButton() {
let $button = `
`;
doc.on('click', '.listener-open-setting', function () {
base.showSetting();
});
doc.on('click', '.listener-open-updatelog', function () {
base.showUpdate();
});
doc.on('click', '.listener-open-beautify', function () {
base.showBeautify();
});
doc.on('click', '.listener-open-info', function () {
base.showDebug();
});
document.querySelectorAll(".nav-links").forEach(function (element) {
element.innerHTML += $button
})
},
addInitButton() {
let $button = `
`;
doc.on('click', '.listener-open-init', function () {
base.initDialog();
});
document.querySelectorAll(".nav-links").forEach(function (element) {
element.innerHTML += $button
})
}
}
// 主代码
let main = {
async init() {
base.waitForKeyElements(`html:not(:has(> ${mount})) head`, (element) => {
element.after(`<${mount} class="${mount}" />`)
}, true)
// 先加载默认设置
base.initDefaultConfig();
// 再加载网页样式
base.addPanLinkerStyle();
base.createDownloadIframe();
/**
* 控制台输出
* @author 油小猴
* @author hmjz100
* @description 来自【网盘智能识别助手】,有改动
*/
console.log(`%c %c LinkSwift\n一个基于 JavaScript 的网盘文件下载地址获取工具\n版本:${sversion}\n领域:${(window.self !== window.top ? "[iframe] " : "") + (document.title ? (document.title + " (" + location.origin + location.pathname + ")") : location.href)}`, `background:url(${sicon}) center center no-repeat;background-size:12px;padding:3px`, "");
let storedVersion = base.getValue("setting_init_version");
if (!storedVersion || base.isNewerVersion(sversion, storedVersion)) {
base.waitForKeyElements("body", () => {
base.showUpdate();
base.setValue("setting_init_version", sversion);
return true;
}, true)
}
// 最后判断页面地址并加载对应的initPanLinker
if (/(pan|yun).baidu.com/.test(location.host)) {
$baidu.initPanLinker();
$baidu.greenerPage();
}
if (/openapi.baidu.com\/oauth/.test(location.href)) {
$baidu.initAuthorize()
}
if (/www.(aliyundrive|alipan).com/.test(location.host)) {
$aliyun.initPanLinker();
$aliyun.greenerPage();
}
if (/(yun|caiyun).139.com/.test(location.host)) {
$mcloud.initPanLinker();
$mcloud.greenerPage();
}
if (/cloud.189.cn/.test(location.host)) {
$tcloud.initPanLinker();
$tcloud.greenerPage();
}
if (/pan.xunlei.com/.test(location.host)) {
$xunlei.initPanLinker();
}
if (/pan.quark.cn/.test(location.host)) {
$quark.initPanLinker();
$quark.greenerPage();
}
if (/drive.uc.cn/.test(location.host)) {
$uc.initPanLinker();
$uc.greenerPage();
}
if (/(www|login).(123(pan|684|865|952|912).com|123pan.cn)/.test(location.host)) {
$123pan.initPanLinker();
$123pan.greenerPage();
}
if (/www.youxiaohou.com/.test(location.host)) {
$youxiaohou.initPanLinker();
}
}
};
main.init();
// 这是啥?我不到啊
function idontknow(input) {
let charArray = input.split('');
// Fisher-Yates 洗牌算法
for (let i = charArray.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[charArray[i], charArray[j]] = [charArray[j], charArray[i]];
}
return charArray.join('');
}
})();