`);
}
const sel = pageNum === 'home' ? panInfo.btn.home : panInfo.btn.main;
const tryInject = () => {
let $toolWrap = $(sel);
if (!$toolWrap.length || $('.pl-button').length) return false;
$toolWrap.prepend($button);
return true;
};
if (!tryInject()) base.listenElement(sel, tryInject);
this.setBDUSS();
this.addPageListener();
},
async getToken() {
const saveToken = (token) => {
if (token) {
base.setValue('baidu_access_token', token);
base.setValue('baidu_access_token_bduss', this.getBDUSS());
this.getCurrentUK().then((uk) => {
if (uk) base.setValue('baidu_access_token_uk', uk);
});
}
return token;
};
const waitForToken = (maxAttempts = 60) => new Promise((resolve) => {
let attempts = 0;
const interval = setInterval(() => {
const token = base.getValue('baidu_access_token');
if (token) {
clearInterval(interval);
resolve(token);
}
attempts++;
if (attempts > maxAttempts) {
clearInterval(interval);
resolve('');
}
}, 1000);
});
try {
if (base.getFinalUrl) {
let res = await base.getFinalUrl(panInfo.pcs[3]);
if (res.includes('authorize')) {
let html = await base.get(panInfo.pcs[3], {}, 'text');
let bdstoken = html.match(/name="bdstoken"\s+value="([^"]+)"/)?.[1];
let client_id = html.match(/name="client_id"\s+value="([^"]+)"/)?.[1];
if (bdstoken && client_id) {
let data = {
grant_permissions_arr: 'netdisk',
bdstoken: bdstoken,
client_id: client_id,
response_type: 'token',
display: 'page',
grant_permissions: 'basic,netdisk'
};
await base.post(panInfo.pcs[3], base.stringify(data), {'Content-Type': 'application/x-www-form-urlencoded'});
let res2 = await base.getFinalUrl(panInfo.pcs[3]);
return saveToken(res2.match(/access_token=([^&]+)/)?.[1]);
}
} else {
return saveToken(res.match(/access_token=([^&]+)/)?.[1]);
}
}
} catch (e) {
}
base.deleteValue('baidu_access_token');
GM_openInTab(panInfo.pcs[3], {active: false, insert: true, setParent: true});
let token = await waitForToken(60);
return saveToken(token);
},
async getCurrentUK() {
try {
let res = await Promise.race([
base.get('https://pan.baidu.com/rest/2.0/xpan/nas?method=uinfo', {"User-Agent": panInfo.ua}),
new Promise((resolve) => setTimeout(() => resolve(null), 3000))
]);
if (res && res.errno === 0 && res.user_info && res.user_info.uk) {
return String(res.user_info.uk);
}
} catch (e) {}
return '';
},
async preflightAccount() {
try {
let accessToken = base.getValue('baidu_access_token');
let storedUK = base.getValue('baidu_access_token_uk');
if (!accessToken || !storedUK) return;
let currentUK = await this.getCurrentUK();
if (!currentUK) return;
if (currentUK !== storedUK) {
base.deleteValue('baidu_access_token');
base.deleteValue('baidu_access_token_bduss');
base.deleteValue('baidu_access_token_uk');
await this.getToken();
}
} catch (e) {
message.error('百度授权失败:' + (e.message || '未知错误'));
}
},
async getPCSLink(maxRequestTime = 1) {
selectedFiles = this.getSelectedList();
let fidArray = this._getFidArray(), res;
if (pageNum === 'home' || pageNum === 'main') {
if (selectedFiles.length === 0) {
Swal.close(); return base.renderDownloadPanel([], this);
}
if (!fidArray.length) {
Swal.close(); return message.error('提示:请打开文件夹后勾选文件!');
}
let currentBDUSS = this.getBDUSS();
let storedBDUSS = base.getValue('baidu_access_token_bduss');
let accessToken = base.getValue('baidu_access_token');
if (accessToken) {
let currentUK = await this.getCurrentUK();
let storedUK = base.getValue('baidu_access_token_uk');
let mismatch = false;
if (currentUK && storedUK && storedUK !== currentUK) mismatch = true;
if (!mismatch && currentBDUSS && storedBDUSS && storedBDUSS !== currentBDUSS) mismatch = true;
if (mismatch) {
base.deleteValue('baidu_access_token');
base.deleteValue('baidu_access_token_bduss');
base.deleteValue('baidu_access_token_uk');
this._linkCache = []; // 账号变了,旧 dlink 绑定的是别人的 uk,全废
accessToken = '';
} else if (currentUK && !storedUK) {
base.setValue('baidu_access_token_uk', currentUK);
} else if (currentBDUSS && !storedBDUSS) {
base.setValue('baidu_access_token_bduss', currentBDUSS);
}
}
if (!accessToken) accessToken = await this.getToken();
const now = Date.now();
const files = selectedFiles.filter(v => +v.isdir !== 1);
const pending = files.filter(it => {
const idx = this._linkCache.findIndex(c => c.id == it.fs_id);
if (idx === -1) return true;
if (this._linkCache[idx].expires > now) {
Object.assign(it, this._linkCache[idx].data);
return false;
}
this._linkCache.splice(idx, 1);
return true;
});
// 百度 fsids 上限 100,取 50 留余量
const BATCH = 50;
let returnedCount = 0, refreshed = false, anyMarked = false;
for (let i = 0; i < pending.length; i += BATCH) {
const batch = pending.slice(i, i + BATCH);
const fsids = encodeURIComponent('[' + batch.map(x => x.fs_id) + ']');
const url = `${panInfo.pcs[0]}&fsids=${fsids}&access_token=${accessToken}`;
try {
res = await base.get(url, {"User-Agent": panInfo.ua});
} catch (e) { res = null; }
if (res && res.errno === 112) {
Swal.close(); return message.error('提示:页面过期,请刷新重试!');
}
if (!res || res.errno !== 0) {
if (!refreshed && maxRequestTime >= 1) {
refreshed = true;
base.deleteValue('baidu_access_token');
base.deleteValue('baidu_access_token_bduss');
base.deleteValue('baidu_access_token_uk');
accessToken = await this.getToken();
i -= BATCH; continue;
}
const reason = res && res.errno
? `获取下载地址失败(错误码 ${res.errno})`
: '请求失败,请重试';
batch.forEach(x => { x.dlink = reason; });
anyMarked = true;
} else if (!Array.isArray(res.list)) {
// 百度会把错误说明塞进 list(如大文件要 SVIP),不重试
const text = typeof res.list === 'string' && res.list ? res.list : '该文件未返回下载链接';
batch.forEach(x => { x.dlink = text; });
anyMarked = true;
} else {
batch.forEach(x => {
const hit = res.list.find(li => li.fs_id == x.fs_id);
if (hit) {
Object.assign(x, hit);
returnedCount++;
this._linkCache.push({ id: x.fs_id, expires: now + 4 * 60 * 60 * 1000, data: hit });
} else if (res.list.length > 0) {
x.dlink = '该文件未返回下载链接(可能已失效或被禁止下载)';
anyMarked = true;
}
});
}
const hc = Swal.getHtmlContainer && Swal.getHtmlContainer();
if (hc) hc.textContent = `已获取 ${Math.min(i + BATCH, pending.length)} / ${pending.length} 个地址`;
if (i + BATCH < pending.length) await base.sleep(1000);
}
if (pending.length > 0 && returnedCount === 0 && !anyMarked) {
if (maxRequestTime >= 1) {
base.deleteValue('baidu_access_token');
base.deleteValue('baidu_access_token_bduss');
base.deleteValue('baidu_access_token_uk');
await this.getToken();
return this.getPCSLink(maxRequestTime - 1);
}
return message.error('提示:获取下载链接失败!请刷新网页后重试!');
}
const normalized = this.normalizeList(files);
base.renderDownloadPanel(normalized, this);
}
},
normalizeList(list) {
return list.map(v => {
let dlink = '';
if (v.dlink) {
dlink = /^https?:\/\//.test(v.dlink)
? v.dlink + '&access_token=' + base.getValue('baidu_access_token')
: v.dlink;
}
return {
filename: v.server_filename || v.filename || '',
sizeStr: base.sizeFormat(v.size),
rawSize: v.size || 0,
dlink: dlink,
ext: base.getExtension(v.server_filename || v.filename),
isFolder: +v.isdir === 1,
raw: v,
};
});
},
async sendLinkToRPC(filename, link) {
let rpc = base._rpcConfig();
if (!rpc) return 'fail';
let BDUSS = this.getBDUSS();
let url = rpc.url;
let rpcData = {
id: new Date().getTime(),
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [`token:${rpc.token}`, [link], {
dir: rpc.dir,
out: base.safeRpcFilename(filename),
header: [`User-Agent: ${panInfo.ua}`, ...(BDUSS ? [`Cookie: BDUSS=${BDUSS}`] : [])],
}]
};
try {
let res = await base.post(url, rpcData, {"User-Agent": panInfo.ua}, '');
if (res.result) return 'success';
base.panelNotice('Aria2 拒绝请求:' + ((res.error && res.error.message) || '未知错误(请检查 RPC 密钥与保存路径)'));
return 'fail';
} catch (e) {
base.panelNotice('无法连接 RPC(' + rpc.domain + ':' + rpc.port + ')' + (e && e.message ? ':' + e.message : '') + ',请确认下载器已启动且 RPC 服务已开启');
return 'fail';
}
},
getSelectedList() {
try {
return require('system-core:context/context.js').instanceForSystem.list.getSelected();
} catch (e) {
let panInfo = document.querySelector('.wp-s-core-pan');
return panInfo && panInfo.__vue__ ? panInfo.__vue__.selectedList : [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/disk\/home/.test(path)) return 'home';
if (/^\/disk\/main/.test(path)) return 'main';
return '';
},
async initPanLinker() {
base.initDefaultConfig();
base.addPanLinkerStyle();
pageNum = this.detectPage();
panInfo = LOCAL_CONFIG.baidu;
Object.freeze && Object.freeze(panInfo);
this.addButton();
base.createTip();
base.registerMenuCommand();
this.preflightAccount();
},
async initAuthorize() {
let authPollTimer = setInterval(() => {
if (/openapi.baidu.com\/oauth\/2.0\/authorize/.test(location.href)) {
let confirmButton =
document.querySelector('#auth-allow') ||
document.querySelector('#accept') ||
document.querySelector('input[type="submit"]') ||
Array.from(document.querySelectorAll('button, a, input[type="button"]')).find(el => {
let t = (el.textContent || el.value || '').trim();
return /^(授权|允许|同意|确认|Allow|Authorize)/i.test(t);
});
if (confirmButton) {
confirmButton.click();
return;
}
}
if (/openapi.baidu.com\/oauth\/2.0\/login_success/.test(location.href)) {
if (location.href.includes('access_token')) {
let token = location.href.match(/access_token=([^]+)/)?.[1];
base.setValue('baidu_access_token', token);
this.getCurrentUK().then((uk) => {
if (uk) base.setValue('baidu_access_token_uk', uk);
});
clearInterval(authPollTimer);
window.close();
}
}
}, 200)
}
};
let ali = {
convertLinkToAria(link, filename, ua) {
filename = base.fixFilename(filename);
// 阿里 CDN 没浏览器 UA 就 403,命令也得带头
return encodeURIComponent(`aria2c "${link}" --out "${filename}" -x 16 -s 16 -k 1M --header "Referer: ${location.origin}/" --header "User-Agent: ${ua || navigator.userAgent}"`);
},
convertLinkToBC(link, filename, ua) {
return base._bc(link, filename, {
'Referer': `${location.origin}/`,
'User-Agent': ua || navigator.userAgent,
});
},
convertLinkToCurl(link, filename, ua) {
let terminal = base.getValue('setting_terminal_type');
filename = base.fixFilename(filename);
// -e 带 Referer:域名会迁移,写死 aliyundrive.com 在 alipan.com 上会 403
return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -e "${location.origin}/" -A "${ua || navigator.userAgent}"`);
},
addPageListener() {
doc.on('click', '.pl-button', async (e) => {
if ($(e.target).closest('.g-button-menu, .menu').length) return;
Swal.showLoading();
try { await this.getPCSLink(); } catch (err) { Swal.close(); base.renderErrorPanel('获取下载链接失败:' + (err && err.message || '未知错误'), this); } finally { if (document.querySelector('.swal2-popup.swal2-loading')) Swal.close(); }
});
},
async getRealLink(d, f) {
try {
let tk = base.getStorage('token');
tk = await base.refreshAliToken(tk);
if (!tk || !tk.access_token) {
Swal.close();
return message.error('提示:Token过期或缺失,请刷新网页后重试!');
}
let authorization = `${tk.token_type} ${tk.access_token}`;
let res = await base.post(panInfo.pcs[1], {
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') {
Swal.close();
return message.error('提示:Token过期,请刷新网页后重试!');
}
if (res.url) {
return res.url;
}
return '';
} catch (e) { return ''; }
},
addButton() {
if (!pageNum) return;
let $toolWrap;
let $button = $(`
`);
if (pageNum === 'home') {
const fallbacks = [
panInfo.btn.home,
'[class*="header--"] [class*="actions--"]',
'[class*="file-list-header"] [class*="action"]',
'header [class*="upload"]',
];
const tryInject = () => {
for (const sel of fallbacks) {
let $el = $(sel);
if ($el.length && $('.pl-button').length === 0) {
$el.append($button);
return true;
}
}
return false;
};
if (!tryInject()) {
fallbacks.forEach(sel => base.listenElement(sel, tryInject));
}
}
this.addPageListener();
},
async getPCSLink() {
selectedFiles = this.getSelectedList();
if (selectedFiles.length === 0) {
Swal.close(); return base.renderDownloadPanel([], this);
}
if (this.isOnlyFolder()) {
Swal.close(); return message.error('提示:请打开文件夹后勾选文件!');
}
let tk = base.getStorage('token');
tk = await base.refreshAliToken(tk);
if (!tk || !tk.access_token) {
Swal.close(); return message.error('提示:请先登录阿里云盘后再下载!');
}
try {
let authorization = `${tk.token_type} ${tk.access_token}`;
const dlQueue = selectedFiles.map(item => base.post(panInfo.pcs[1], {
drive_id: item.driveId,
file_id: item.fileId,
}, {
authorization,
"content-type": "application/json;charset=utf-8",
"referer": "https://www.aliyundrive.com/",
"x-canary": "client=windows,app=adrive,version=v6.0.0"
}));
(await Promise.all(dlQueue)).forEach((res, i) => {
if (res && res.url) selectedFiles[i].downloadUrl = res.url;
});
} catch (e) {
Swal.close();
const m = (e && e.message) || '';
if (/AccessTokenInvalid|token/i.test(m)) {
return message.error('提示:Token已过期,请刷新网页后重试!');
}
return message.error('提示:获取下载链接失败(' + m + '),请刷新重试!');
}
if (selectedFiles.length > 20) {
Swal.close();
return message.error('提示:单次最多可勾选 20 个文件!');
}
let noUrlSelectList = selectedFiles.filter(v => !Boolean(v.downloadUrl))
let queue = [];
noUrlSelectList.forEach((item, index) => {
queue.push(this.getRealLink(item.driveId, item.fileId));
});
const res = await Promise.all(queue);
res.forEach((val, index) => {
if (val && typeof val === 'string' && /^https?:/.test(val)) noUrlSelectList[index].downloadUrl = val;
});
let files = this.normalizeList(selectedFiles);
base.renderDownloadPanel(files, this);
},
normalizeList(list) {
return list.map(v => ({
filename: v.name || '',
sizeStr: base.sizeFormat(v.size),
rawSize: v.size || 0,
dlink: v.downloadUrl || '',
isFolder: v.type === 'folder',
raw: v,
}));
},
async sendLinkToRPC(filename, link) {
let rpc = base._rpcConfig();
if (!rpc) return 'fail';
let url = rpc.url;
const UA = navigator.userAgent;
let rpcData = {
id: new Date().getTime(),
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [`token:${rpc.token}`, [link], {
dir: rpc.dir,
out: base.safeRpcFilename(filename),
header: [`Referer: ${location.origin}/`, `Origin: ${location.origin}`, `User-Agent: ${UA}`]
}]
};
try {
let res = await base.post(url, rpcData, {}, '');
if (res.result) return 'success';
base.panelNotice('Aria2 拒绝请求:' + ((res.error && res.error.message) || '未知错误(请检查 RPC 密钥与保存路径)'));
return 'fail';
} catch (e) {
base.panelNotice('无法连接 RPC(' + rpc.domain + ':' + rpc.port + ')' + (e && e.message ? ':' + e.message : '') + ',请确认下载器已启动且 RPC 服务已开启');
return 'fail';
}
},
getSelectedList() {
try {
let selectedList = [];
let tableDom = document.querySelector(panInfo.dom.list);
if (tableDom) {
let reactObj = base.findReact(tableDom, 1);
if (reactObj) {
let props = reactObj.pendingProps;
if (props) {
let fileList = props.dataSource || [];
let selectedKeys = (props.selectedKeys != null) ? (Array.isArray(props.selectedKeys) ? props.selectedKeys : String(props.selectedKeys).split(',')) : [];
fileList.forEach((val) => {
if (selectedKeys.includes(val.fileId)) {
selectedList.push(Object.assign({}, val));
}
});
}
}
return selectedList;
}
let gridDom = document.querySelector(panInfo.dom.grid);
if (!gridDom) return [];
let gridReact = base.findReact(gridDom, 0);
if (!gridReact) return [];
let dataSource = (gridReact.pendingProps || {}).dataSource || [];
if (!dataSource.length) return [];
document.querySelectorAll('[class*="node-card-container"]').forEach((card) => {
let cb = card.querySelector('input[type=checkbox]');
if (!cb || !cb.checked) return;
let title = card.getAttribute('title') || '';
let hit = dataSource.find((v) => v.name === title);
if (hit) selectedList.push(Object.assign({}, hit));
});
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(drive)/.test(path)) return 'home';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectedFiles.length; i++) {
if (selectedFiles[i].type === 'file') return false;
}
return true;
},
async initPanLinker() {
base.initDefaultConfig();
base.addPanLinkerStyle();
pageNum = this.detectPage();
panInfo = LOCAL_CONFIG.ali;
Object.freeze && Object.freeze(panInfo);
this.addButton();
base.createTip();
base.registerMenuCommand();
}
};
let tianyi = {
convertLinkToAria(link, filename, ua) {
filename = base.fixFilename(filename);
return encodeURIComponent(`aria2c "${link}" --out "${filename}" -x 16 -s 16 -k 1M`);
},
convertLinkToBC(link, filename, ua) {
let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
return encodeURIComponent(`bc://http/${base.e(bc)}`);
},
convertLinkToCurl(link, filename, ua) {
let terminal = base.getValue('setting_terminal_type');
filename = base.fixFilename(filename);
return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
},
addPageListener() {
doc.on('click', '.pl-button', async (e) => {
if ($(e.target).closest('.g-button-menu, .menu').length) return;
Swal.showLoading();
try { await this.getPCSLink(); } catch (err) { Swal.close(); base.renderErrorPanel('获取下载链接失败:' + (err && err.message || '未知错误'), this); } finally { if (document.querySelector('.swal2-popup.swal2-loading')) Swal.close(); }
});
},
_insertBeforeUpload(container, $button) {
if (container.firstChild) {
container.insertBefore($button[0], container.firstChild);
} else {
container.appendChild($button[0]);
}
},
addButton() {
if (!pageNum) return;
let $toolWrap;
let $button = $(`
下载助手
`);
if (pageNum === 'home') {
base.listenElement(panInfo.btn.home, () => {
let container = document.querySelector(panInfo.btn.home);
if (container && $('.pl-button').length === 0) {
this._insertBeforeUpload(container, $button);
}
})
}
this.addPageListener();
},
async getToken() {
let res = await base.getFinalUrl(panInfo.pcs[1], {});
let accessToken = res.match(/accessToken=(\w+)/)?.[1];
accessToken && base.setStorage('accessToken', accessToken);
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 = panInfo.pcs[2] + '?fileId=' + fileId;
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: '提示:请先登录网盘!'
};
return {
index,
downloadUrl: '提示:请先[转存]文件,前往[我的网盘]中下载!'
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,请刷新重试!'
};
}
} catch (e) {
return {
index,
downloadUrl: '获取下载地址失败,请刷新重试!'
};
}
},
async getPCSLink() {
selectedFiles = this.getSelectedList();
if (selectedFiles.length === 0) {
Swal.close(); return base.renderDownloadPanel([], this);
}
if (this.isOnlyFolder()) {
Swal.close(); return message.error('提示:请打开文件夹后勾选文件!');
}
let token = base.getStorage('accessToken') || await this.getToken();
if (!token) {
Swal.close(); return message.error('提示:请先登录网盘!');
}
let queue = [];
selectedFiles.forEach((item, index) => {
queue.push(this.getFileUrlByOnce(item, index, token));
});
const res = await Promise.all(queue);
res.forEach(val => {
selectedFiles[val.index].downloadUrl = val.downloadUrl;
});
let files = this.normalizeList(selectedFiles);
base.renderDownloadPanel(files, this);
},
normalizeList(list) {
return list.map(v => ({
filename: v.fileName || '',
sizeStr: base.sizeFormat(v.size),
rawSize: v.size || 0,
dlink: v.downloadUrl && /^https?:\/\//.test(v.downloadUrl) ? v.downloadUrl : '',
isFolder: !!v.isFolder,
raw: v,
}));
},
async sendLinkToRPC(filename, link) {
let rpc = base._rpcConfig();
if (!rpc) return 'fail';
let url = rpc.url;
let rpcData = {
id: new Date().getTime(),
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [`token:${rpc.token}`, [link], {
dir: rpc.dir,
out: base.safeRpcFilename(filename),
header: []
}]
};
try {
let res = await base.post(url, rpcData, {}, '');
if (res.result) return 'success';
base.panelNotice('Aria2 拒绝请求:' + ((res.error && res.error.message) || '未知错误(请检查 RPC 密钥与保存路径)'));
return 'fail';
} catch (e) {
base.panelNotice('无法连接 RPC(' + rpc.domain + ':' + rpc.port + ')' + (e && e.message ? ':' + e.message : '') + ',请确认下载器已启动且 RPC 服务已开启');
return 'fail';
}
},
getSelectedList() {
try {
return document.querySelector(".c-file-list").__vue__.selectedList;
} catch (e) {
let detail = document.querySelector(".info-detail");
return detail && detail.__vue__ ? [detail.__vue__.fileDetail] : [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/web\/main/.test(path)) return 'home';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectedFiles.length; i++) {
if (!selectedFiles[i].isFolder) return false;
}
return true;
},
async initPanLinker() {
base.initDefaultConfig();
base.addPanLinkerStyle();
pageNum = this.detectPage();
panInfo = LOCAL_CONFIG.tianyi;
Object.freeze && Object.freeze(panInfo);
this.addButton();
this.getToken();
base.createTip();
base.registerMenuCommand();
}
};
let xunlei = {
_homeSelectors: [
'.FileMenu__container--yB0l1',
'.FileMenu__menus--HFKwO',
'.file-menu',
'.source-list-menu',
],
_getAuthCookie() {
let keys = ['userid', 'deviceid', 'XLA_CI', 'xl_fp_rt'];
let parts = [];
for (let k of keys) {
let v = base.getCookie(k);
if (v) parts.push(`${k}=${v}`);
}
return parts.join('; ').replace(/[\\"`$]/g, '');
},
convertLinkToAria(link, filename, ua) {
filename = base.fixFilename(filename);
let cookie = this._getAuthCookie();
let cookieStr = cookie ? ` --header "Cookie: ${cookie}"` : '';
let uaStr = ` --header "User-Agent: ${navigator.userAgent}"`;
// 迅雷多 Range 会断开,aria2 只能单线程
// 迅雷 CDN 认 cookie + UA,缺一个就断连
return encodeURIComponent(`aria2c "${link}" --out "${filename}" -x 1 -s 1${cookieStr}${uaStr}`);
},
convertLinkToBC(link, filename, ua) {
return base._bc(link, filename, {
'Cookie': this._getAuthCookie(),
'User-Agent': ua || navigator.userAgent,
});
},
convertLinkToCurl(link, filename, ua) {
let terminal = base.getValue('setting_terminal_type');
filename = base.fixFilename(filename);
let cookie = this._getAuthCookie();
let cookieStr = cookie ? ` -b "${cookie}"` : '';
return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"${cookieStr} -H "User-Agent: ${navigator.userAgent}"`);
},
addPageListener() {
doc.on('click', '.pl-button', async (e) => {
if ($(e.target).closest('.g-button-menu, .menu').length) return;
Swal.showLoading();
try { await this.getPCSLink(); } catch (err) { Swal.close(); base.renderErrorPanel('获取下载链接失败:' + (err && err.message || '未知错误'), this); } finally { if (document.querySelector('.swal2-popup.swal2-loading')) Swal.close(); }
});
},
_findHomeContainer() {
if (panInfo.btn && panInfo.btn.home) {
let el = document.querySelector(panInfo.btn.home);
if (el) return el;
}
for (let sel of this._homeSelectors) {
let el = document.querySelector(sel);
if (el) return el;
}
return null;
},
addButton() {
if (!pageNum) return;
let $toolWrap;
let $button = $(`
下载助手
`);
if (pageNum === 'home') {
this._smartListen(() => {
let container = this._findHomeContainer();
if (container && $('.pl-button').length === 0) {
$(container).prepend($button);
}
});
}
this.addPageListener();
},
_smartListen(callback) {
const checkInterval = 500;
function check() {
setTimeout(check, checkInterval);
callback();
}
check();
},
getToken() {
let credentials = {}, captcha = {};
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
if (/^credentials_/.test(key)) {
credentials = base.getStorage(key);
}
if (/^captcha_[\w]{16}/.test(key)) {
captcha = base.getStorage(key);
}
}
let deviceid = '';
try {
let lsDevice = base.getStorage('deviceid');
if (lsDevice) {
if (typeof lsDevice === 'string' && lsDevice.includes(',')) {
let match = /(\w{32})/.exec(lsDevice.split(','));
if (match) deviceid = match[1];
} else if (typeof lsDevice === 'string') {
let match = /(\w{32})/.exec(lsDevice);
if (match) deviceid = match[1];
}
}
} catch (e) {}
if (!deviceid) {
let cookieDevice = base.getCookie('peerid') || base.getCookie('deviceid');
if (cookieDevice) {
if (cookieDevice.includes('.') && cookieDevice.length > 32) {
let parts = cookieDevice.split('.');
if (parts[1] && parts[1].length >= 32) {
deviceid = parts[1].substring(0, 32);
}
}
if (!deviceid) {
let match = /([0-9a-f]{32})/i.exec(cookieDevice);
if (match) deviceid = match[1];
}
}
}
if (!deviceid) {
deviceid = Array.from({length: 32}, () =>
Math.floor(Math.random() * 16).toString(16)
).join('');
}
let token = {
credentials,
captcha,
deviceid
};
return token;
},
async getFileUrlByOnce(item, index, token) {
try {
if (item.downloadUrl) return {
index,
downloadUrl: item.downloadUrl
};
let headers = {
'content-type': "application/json",
'x-device-id': token.deviceid,
};
if (token.credentials && token.credentials.access_token) {
let tokenType = token.credentials.token_type || 'Bearer';
headers['Authorization'] = `${tokenType} ${token.credentials.access_token}`;
}
if (token.captcha && token.captcha.token) {
headers['x-captcha-token'] = token.captcha.token;
}
let res = await base.get(panInfo.pcs[0] + item.id, headers);
if (res.web_content_link) {
let mediaLink = '';
if (Array.isArray(res.medias) && res.medias.length > 0) {
let media = res.medias.find(m => m && m.link && m.link.url && m.media_name !== '原始画质') || res.medias[0];
if (media && media.link && media.link.url) {
mediaLink = media.link.url;
}
}
return {
index,
downloadUrl: res.web_content_link,
mediaLink
};
} else if (res.reason) {
return {
index,
downloadUrl: '获取失败:' + (res.reason || res.message || '未知错误')
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,请刷新重试!'
};
}
} catch (e) {
return {
index,
downloadUrl: '获取下载地址失败,请刷新重试!'
};
}
},
async getPCSLink() {
selectedFiles = this.getSelectedList();
if (selectedFiles.length === 0) {
Swal.close(); return base.renderDownloadPanel([], this);
}
if (this.isOnlyFolder()) {
Swal.close(); return message.error('提示:请打开文件夹后勾选文件!');
}
if (pageNum === 'home') {
let queue = [];
let token = this.getToken();
if (!token.credentials || !token.credentials.access_token) {
return message.error('提示:登录凭证获取失败,请先登录网盘后刷新页面!');
}
selectedFiles.forEach((item, index) => {
queue.push(this.getFileUrlByOnce(item, index, token));
});
const res = await Promise.all(queue);
res.forEach(val => {
selectedFiles[val.index].downloadUrl = val.downloadUrl;
if (val.mediaLink) selectedFiles[val.index].mediaLink = val.mediaLink;
});
} else {
let dialog = await Swal.fire({
toast: true,
icon: 'info',
title: `提示:请将文件
[保存到网盘]后前往
[我的网盘]中下载!`,
showConfirmButton: true,
confirmButtonText: '点击保存',
position: 'top',
});
if (dialog.isConfirmed) {
let save = document.querySelector('.saveToCloud');
save && save.click();
return;
}
}
let files = this.normalizeList(selectedFiles);
base.renderDownloadPanel(files, this);
},
normalizeList(list) {
return list.map(v => ({
filename: v.name || '',
sizeStr: base.sizeFormat(+v.size),
rawSize: +v.size || 0,
dlink: v.downloadUrl && /^https?:\/\//.test(v.downloadUrl) ? v.downloadUrl : '',
isFolder: v.kind === 'drive#folder',
raw: v,
}));
},
async sendLinkToRPC(filename, link) {
let rpc = base._rpcConfig();
if (!rpc) return 'fail';
let url = rpc.url;
let authCookie = this._getAuthCookie ? this._getAuthCookie() : '';
let rpcHeader = authCookie
? [`Cookie: ${authCookie}`, `User-Agent: ${navigator.userAgent}`]
: [];
let rpcData = {
id: new Date().getTime(),
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [`token:${rpc.token}`, [link], {
dir: rpc.dir,
out: base.safeRpcFilename(filename),
header: rpcHeader
}]
};
try {
let res = await base.post(url, rpcData, {}, '');
if (res.result) return 'success';
base.panelNotice('Aria2 拒绝请求:' + ((res.error && res.error.message) || '未知错误(请检查 RPC 密钥与保存路径)'));
return 'fail';
} catch (e) {
base.panelNotice('无法连接 RPC(' + rpc.domain + ':' + rpc.port + ')' + (e && e.message ? ':' + e.message : '') + ',请确认下载器已启动且 RPC 服务已开启');
return 'fail';
}
},
getSelectedList() {
try {
let doms = document.querySelectorAll('.SourceListItem__item--XxpOC');
if (doms.length > 0) {
let selectedList = [];
for (let dom of doms) {
let domVue = dom.__vue__;
if (domVue && domVue.info && domVue.selected) {
if (domVue.selected.includes(domVue.info.id)) {
selectedList.push(domVue.info);
}
}
}
if (selectedList.length > 0) return selectedList;
}
let allItems = document.querySelectorAll('[class*="SourceListItem__item"]');
if (allItems.length > 0) {
let selectedList = [];
for (let dom of allItems) {
let domVue = dom.__vue__;
if (domVue) {
let info = domVue.info || domVue.item || (domVue.$props && domVue.$props.info);
let selected = domVue.selected || domVue.fileSelected || (domVue.$props && domVue.$props.selected);
if (info && selected && selected.includes(info.id)) {
selectedList.push(info);
}
}
}
if (selectedList.length > 0) return selectedList;
}
let app = document.querySelector('#__nuxt') || document.querySelector('#app');
if (app && app.__vue__) {
let rootVue = app.__vue__;
let found = this._findSelectedInVueTree(rootVue, 0);
if (found && found.length > 0) return found;
}
return [];
} catch (e) {
return [];
}
},
_findSelectedInVueTree(vm, depth) {
if (depth > 8 || !vm) return null;
try {
if (vm.fileSelected && vm.listInfo && Array.isArray(vm.fileSelected) && vm.fileSelected.length > 0) {
return vm.fileSelected.map(id => vm.listInfo[id]).filter(Boolean);
}
if (vm.$children) {
for (let child of vm.$children) {
let result = this._findSelectedInVueTree(child, depth + 1);
if (result && result.length > 0) return result;
}
}
} catch (e) {}
return null;
},
detectPage() {
let path = location.pathname;
if (/^\/$/.test(path)) return 'home';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectedFiles.length; i++) {
if (selectedFiles[i].kind === 'drive#file') return false;
}
return true;
},
async initPanLinker() {
base.initDefaultConfig();
base.addPanLinkerStyle();
pageNum = this.detectPage();
panInfo = LOCAL_CONFIG.xunlei;
Object.freeze && Object.freeze(panInfo);
this.addButton();
base.createTip();
base.registerMenuCommand();
}
};
let quark = {
convertLinkToAria(link, filename, ua) {
filename = base.fixFilename(filename);
return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "User-Agent: ${panInfo.ua}" --header "Cookie: ${String(document.cookie).replace(/[\\"`$]/g, '')}"`);
},
convertLinkToBC(link, filename, ua) {
// 只带 __pus/__puus 会 412,要给完整 cookie
return base._bc(link, filename, {
'Referer': `${location.origin}/`,
'User-Agent': ua || navigator.userAgent,
'Cookie': String(document.cookie),
});
},
convertLinkToCurl(link, filename, ua) {
let terminal = base.getValue('setting_terminal_type');
filename = base.fixFilename(filename);
return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -A "${panInfo.ua}" -b "${String(document.cookie).replace(/[\\"`$]/g, '')}"`);
},
addPageListener() {
if (this._listenerBound) return;
this._listenerBound = true;
window.addEventListener('hashchange', async (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;
this.addButton();
});
doc.on('click', '.pl-button', async (e) => {
if ($(e.target).closest('.g-button-menu, .menu').length) return;
Swal.showLoading();
try { await this.getPCSLink(); } catch (err) { Swal.close(); base.renderErrorPanel('获取下载链接失败:' + (err && err.message || '未知错误'), this); } finally { if (document.querySelector('.swal2-popup.swal2-loading')) Swal.close(); }
});
},
addButton() {
if (!pageNum) return;
let $toolWrap;
let $button = $(`
`);
if (pageNum === 'home') {
base.listenElement(panInfo.btn.home, () => {
$toolWrap = $(panInfo.btn.home);
$('.pl-button').length === 0 && $toolWrap.prepend($button);
});
}
},
// 夸克不给 token 就派到限速节点,约 30KB/s
async getAccelToken() {
const now = Date.now();
const cached = base.getValue('quark_accel_token');
if (cached && cached.token && cached.expired_timestamp) {
if (cached.expired_timestamp > now + 60000) {
return cached.token;
}
}
const time = Math.floor(now / 1e3);
try {
let res = await base.post(panInfo.pcs[1], {
"conversation_id": "300000" + time,
"conversation_type": 3,
"msg_id": time + "000"
}, {"content-type": "application/json;charset=utf-8", "Cookie": String(document.cookie), "User-Agent": panInfo.ua});
if (res && res.code === 0 && res.data && res.data.token) {
base.setValue('quark_accel_token', res.data);
return res.data.token;
}
} catch (e) {}
return '';
},
async getPCSLink() {
selectedFiles = this.getSelectedList();
if (selectedFiles.length === 0) {
Swal.close(); return base.renderDownloadPanel([], this);
}
if (this.isOnlyFolder()) {
Swal.close(); return message.error('提示:请打开文件夹后勾选文件!');
}
let fids = [];
selectedFiles.forEach(val => {
fids.push(val.fid);
});
if (pageNum === 'home') {
let token = await this.getAccelToken();
let res = await base.post(panInfo.pcs[0], {
"fids": fids,
"speedup_session": "",
"token": token
}, {"content-type": "application/json;charset=utf-8", "Cookie": String(document.cookie), "user-agent": panInfo.ua});
if (res.code === 31001) {
Swal.close(); return message.error('提示:请先登录网盘!');
}
if (res.code !== 0) {
return message.error('提示:获取链接失败!');
}
let files = this.normalizeList(res.data);
base.renderDownloadPanel(files, this);
} else {
let dialog = await Swal.fire({
toast: true,
icon: 'info',
title: `提示:请将文件
[保存到网盘]后前往
[我的网盘]中下载!`,
showConfirmButton: true,
confirmButtonText: '点击保存',
position: 'top',
});
if (dialog.isConfirmed) {
let save = document.querySelector('.file-info_r');
save && save.click();
return;
}
}
},
normalizeList(list) {
return list.map(v => ({
filename: v.file_name || '',
sizeStr: base.sizeFormat(v.size),
rawSize: v.size || 0,
dlink: v.download_url || '',
isFolder: v.file === false,
raw: v,
}));
},
async sendLinkToRPC(filename, link) {
let rpc = base._rpcConfig();
if (!rpc) return 'fail';
let url = rpc.url;
let rpcData = {
id: new Date().getTime(),
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [`token:${rpc.token}`, [link], {
dir: rpc.dir,
out: base.safeRpcFilename(filename),
header: [`User-Agent: ${panInfo.ua}`, `Cookie: ${String(document.cookie)}`],
'user-agent': panInfo.ua,
'referer': `${location.origin}/`
}]
};
try {
let res = await base.post(url, rpcData, {}, '');
if (res.result) return 'success';
base.panelNotice('Aria2 拒绝请求:' + ((res.error && res.error.message) || '未知错误(请检查 RPC 密钥与保存路径)'));
return 'fail';
} catch (e) {
base.panelNotice('无法连接 RPC(' + rpc.domain + ':' + rpc.port + ')' + (e && e.message ? ':' + e.message : '') + ',请确认下载器已启动且 RPC 服务已开启');
return 'fail';
}
},
getSelectedList() {
try {
let selectedList = [];
let reactDom = document.getElementsByClassName('file-list')[0];
let reactObj = base.findReact(reactDom);
if (!reactObj) return [];
let props = reactObj.props;
if (props) {
let fileList = props.list || [];
let selectedKeys = props.selectedRowKeys || [];
fileList.forEach((val) => {
if (selectedKeys.includes(val.fid)) {
selectedList.push(Object.assign({}, val));
}
});
}
return selectedList;
} catch (e) {
return [];
}
},
detectPage() {
let path = location.pathname;
if (/^\/(list)/.test(path)) return 'home';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectedFiles.length; i++) {
if (selectedFiles[i].file) return false;
}
return true;
},
async initPanLinker() {
base.initDefaultConfig();
base.addPanLinkerStyle();
pageNum = this.detectPage();
panInfo = LOCAL_CONFIG.quark;
Object.freeze && Object.freeze(panInfo);
this.addButton();
this.addPageListener();
base.createTip();
base.registerMenuCommand();
}
};
let yidong = {
convertLinkToAria(link, filename, ua) {
filename = base.fixFilename(filename);
return encodeURIComponent(`aria2c "${link}" --out "${filename}" -x 16 -s 16 -k 1M`);
},
convertLinkToBC(link, filename, ua) {
let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
return encodeURIComponent(`bc://http/${base.e(bc)}`);
},
convertLinkToCurl(link, filename, ua) {
let terminal = base.getValue('setting_terminal_type');
filename = base.fixFilename(filename);
return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
},
addPageListener() {
doc.on('click', '.pl-button', async (e) => {
if ($(e.target).closest('.g-button-menu, .menu').length) return;
Swal.showLoading();
try { await this.getPCSLink(); } catch (err) { Swal.close(); base.renderErrorPanel('获取下载链接失败:' + (err && err.message || '未知错误'), this); } finally { if (document.querySelector('.swal2-popup.swal2-loading')) Swal.close(); }
});
},
addButton() {
if (!pageNum) return;
let $toolWrap;
let $button = $(`
下载助手
`);
if (pageNum === 'home') {
base.listenElement(panInfo.btn.home, () => {
$toolWrap = $(panInfo.btn.home);
$('.pl-button').length === 0 && $toolWrap.prepend($button);
})
}
this.addPageListener();
},
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 = base.getRandomString(16);
let sign = base.getSign(undefined, body, time, key);
let res = await base.post(panInfo.pcs[0], body, {
'authorization': base.getCookie('authorization'),
'caller': 'web',
'content-type': "application/json;charset=UTF-8",
'CMS-DEVICE': 'default',
'mcloud-channel': '1000101',
'mcloud-client': '10701',
'mcloud-sign': time + "," + key + "," + sign,
'mcloud-version': '7.14.2',
'x-deviceinfo': '||9|7.17.0|edge||||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.17.0|edge||||windows 10||zh-CN|||||',
'x-yun-module-type': '100',
'x-yun-svc-type': '1',
'x-yun-url-type': '3',
});
if (res.success) {
return {
index,
downloadUrl: res.data.url
};
} else {
return {
index,
downloadUrl: '获取下载地址失败,请刷新重试!'
};
}
}
let res = await base.post(panInfo.pcs[1], `linkId=${vueDom.linkID}&contentIds=${encodeURIComponent(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 getPCSLink() {
selectedFiles = this.getSelectedList();
if (selectedFiles.length === 0) {
Swal.close(); return base.renderDownloadPanel([], this);
}
if (this.isOnlyFolder()) {
return message.error('提示:勾选的全是文件夹,脚本仅支持下载文件,请打开文件夹后勾选文件!');
}
selectedFiles = selectedFiles.filter(v => v && v.contentID);
if (selectedFiles.length === 0) {
return message.error('提示:未获取到文件标识,请刷新页面后重试!');
}
let queue = [];
selectedFiles.forEach((item, index) => {
queue.push(this.getFileUrlByOnce(item, index));
});
const res = await Promise.all(queue);
res.forEach(val => {
selectedFiles[val.index].downloadUrl = val.downloadUrl;
});
let files = this.normalizeList(selectedFiles);
base.renderDownloadPanel(files, this);
},
normalizeList(list) {
return list.map(v => ({
filename: v.contentName || v.coName || '',
sizeStr: base.sizeFormat(v.contentSize || v.coSize),
rawSize: v.contentSize || v.coSize || 0,
dlink: v.downloadUrl && /^https?:\/\//.test(v.downloadUrl) ? v.downloadUrl : '',
isFolder: !!(v.dirEtag || v.caName),
raw: v,
}));
},
async sendLinkToRPC(filename, link) {
let rpc = base._rpcConfig();
if (!rpc) return 'fail';
let url = rpc.url;
let rpcData = {
id: new Date().getTime(),
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [`token:${rpc.token}`, [link], {
dir: rpc.dir,
out: base.safeRpcFilename(filename),
header: []
}]
};
try {
let res = await base.post(url, rpcData, {}, '');
if (res.result) return 'success';
base.panelNotice('Aria2 拒绝请求:' + ((res.error && res.error.message) || '未知错误(请检查 RPC 密钥与保存路径)'));
return 'fail';
} catch (e) {
base.panelNotice('无法连接 RPC(' + rpc.domain + ':' + rpc.port + ')' + (e && e.message ? ':' + e.message : '') + ',请确认下载器已启动且 RPC 服务已开启');
return 'fail';
}
},
getSelectedList() {
let normalize = (item, vue) => {
if (!item || typeof item !== 'object') return null;
if (!item.owner && vue) {
try {
let root = vue.$root || vue;
let s = root && root.$data;
if (s) {
let owner = s.owner || s.account ||
(s.userInfo && (s.userInfo.account || s.userInfo.phone)) ||
(s.globalInfo && (s.globalInfo.account || s.globalInfo.phone)) || '';
if (owner) item.owner = owner;
}
} catch (e) {}
}
return item;
};
let result = [];
try {
let vue = document.querySelector(".main_file_list").__vue__;
let list = vue.selectList;
if (Array.isArray(list) && list.length) {
result = list.map(val => normalize(val.item, vue)).filter(Boolean);
if (result.length) return result;
}
} catch (e) {}
try {
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);
});
let list = [...selectFileList, ...selectDirList];
if (list.length) {
result = list.map(v => normalize(v, vueDom)).filter(Boolean);
if (result.length) return result;
}
} catch (e) {}
try {
let containers = document.querySelectorAll('.main_file_list, [class*="file-list"], [class*="fileList"], .file-box, .home-page');
let markSelectors = ['[class*="selected"]', '[class*="checked"]', 'input[type="checkbox"]:checked'];
containers.forEach(container => {
markSelectors.forEach(sel => {
container.querySelectorAll(sel).forEach(dom => {
let vue = dom.__vue__ || (dom.parentElement && dom.parentElement.__vue__) ||
(dom.closest && dom.closest('[class*="item"]') && dom.closest('[class*="item"]').__vue__);
if (!vue) return;
let item = vue.item || vue.fileData || vue.info ||
(vue.$props && (vue.$props.item || vue.$props.file || vue.$props.data));
if (!item && vue.$data) {
item = vue.$data.item || vue.$data.fileData || vue.$data.info;
}
item = normalize(item, vue);
if (item && !result.includes(item)) result.push(item);
});
});
});
if (result.length) return result;
} catch (e) {}
return [];
},
detectPage() {
let path = location.pathname;
if (/^\/w/.test(path)) return 'home';
return '';
},
isOnlyFolder() {
for (let i = 0; i < selectedFiles.length; i++) {
let v = selectedFiles[i] || {};
if (v.kind === 'folder' || v.folder === true || v.isFolder === true || v.contentType === 'folder' || v.contentType === 'dir') continue;
return false;
}
return true;
},
async initPanLinker() {
base.initDefaultConfig();
base.addPanLinkerStyle();
pageNum = this.detectPage();
panInfo = LOCAL_CONFIG.yidong;
Object.freeze && Object.freeze(panInfo);
this.addButton();
base.createTip();
base.registerMenuCommand();
}
};
let main = {
init() {
base.migrate();
if (/(pan|yun).baidu.com/.test(location.host)) {
baidu.initPanLinker();
}
if (/openapi.baidu.com\/oauth/.test(location.href)) {
baidu.initAuthorize()
}
if (/www.(aliyundrive|alipan).com/.test(location.host)) {
ali.initPanLinker();
}
if (/cloud.189.cn/.test(location.host)) {
tianyi.initPanLinker();
}
if (/pan.xunlei.com/.test(location.host)) {
xunlei.initPanLinker();
}
if (/pan.quark.cn/.test(location.host)) {
quark.initPanLinker();
}
if (/(yun|caiyun).139.com/.test(location.host)) {
yidong.initPanLinker();
}
}
};
// document-start 时 DOM 未就绪,等 DOMContentLoaded 再初始化
const startInit = () => main.init();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startInit, { once: true });
} else {
startInit();
}
})();