脚本// ==UserScript== // @name 123 云盘会员青春版 // @author hmjz100、Qing // @namespace github.com/hmjz100 // @version 1.0.3 // @description 《也许同类型中最好用？》系列 - 显示 123 云盘身份信息为会员，支持超过 1GB 上限下载文件（基于【123云盘下载辅助】修改），支持使用视频倍速、关闭广告、修改头像、修改用户名等功能，自定义程度超高！需要修改头部代码来配置显示内容（非常简单！） // @icon [binary] @license MIT // @match *://*.123pan.com/* // @match *://*.123pan.cn/* // @match *://*.123684.com/* // @match *://*.123865.com/* // @match *://*.123952.com/* // @grant unsafeWindow // @run-at document-start // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js // @downloadURL https://update.greasyfork.org/scripts/513528/123%20%E4%BA%91%E7%9B%98%E4%BC%9A%E5%91%98%E9%9D%92%E6%98%A5%E7%89%88.user.js // @updateURL https://update.greasyfork.org/scripts/513528/123%20%E4%BA%91%E7%9B%98%E4%BC%9A%E5%91%98%E9%9D%92%E6%98%A5%E7%89%88.meta.js // ==/UserScript== (function () { var user = { // 以下设置项中，常规项目（就是以//开头注释的项目）除非特殊说明，否则一般 0 为关闭，1 为开启 vip: 1, // 开启会员修改（总开关） svip: 1, // 显示为超级会员，建议 1 ad: 1, // 关闭广告，建议 1 // 以下是自定义项目（以/*开头注释的项目），修改也非常简单 /* 自定义用户名与头像还有邮箱、手机号、用户 ID，留空则使用已登录账号数据 */ name: "百闻不如一见", photo: "https://cdn.auth0.com/avatars/bw.png", mail: "", // 最好不改，我怕影响支付 phone: "", // 最好不改，我怕影响支付 id: "", // 最好不改，我怕影响支付 /* 成长容量等级，最高可叠加 128 级 */ level: 128, /* 会员过期时间 格式为Unix时间戳，可留空为"" 1638288000 - 2021-11-31 00:00:00 (123上线时) 2147483648 - 2038-01-19 11:14:08 (2038问题时) 253402185600 - 9999-12-31 00:00:00 (终极时) */ endtime: 253402185600, // 以下的常规项目（就是以//开头注释的项目）均为独立功能，不受总开关控制 debug: 0, // 显示本脚本的调试信息到 JavaScript 控制台中，建议 0，另外，1 显示所有，2 仅显示基本，3 仅显示修改其他 Header } var originalOpen = XMLHttpRequest.prototype.open; var originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader; var originalFetch = fetch; unsafeWindow.XMLHttpRequest.prototype.open = function (method, url) { url = new URL(url, location.origin).href; this.url = url if (url.includes('api/user/info')) { // 用户信息 if (user.vip === 1) this.addEventListener('readystatechange', function () { if (this.readyState === 4) { let res, oriRes try { res = JSON.parse(this.responseText), oriRes = JSON.parse(this.responseText) } catch (e) { res = this.response, oriRes = this.response } res.data.Vip = true // VIP res.data.VipLevel = user.svip ? 2 : 1 // SVIP if (user.ad === 1) res.data.IsShowAdvertisement = false // 广告 if (user.endtime) { let time = new Date(user.endtime * 1000) let vipTime = new Date(1727539200 * 1000) let youngTime = new Date(1638288000 * 1000) res.data.VipExpire = time.toLocaleString() // 时间 res.data.UserVipDetailInfos = [{ VipDesc: user.svip === 1 ? "SVIP 会员" : "VIP 会员", TimeDesc: time.toLocaleDateString() + " 到期", IsUse: time >= new Date() }, { VipDesc: '韭菜收割包', TimeDesc: vipTime.toLocaleDateString() + " 生效", IsUse: vipTime <= new Date() }, { VipDesc: '青春创始包', TimeDesc: youngTime.toLocaleDateString() + " 生效", IsUse: youngTime <= new Date() }] } if (user.name) res.data.Nickname = user.name; if (user.photo) res.data.HeadImage = user.photo; if (user.mail) res.data.Mail = user.mail; if (user.phone) res.data.Passport = Number(user.phone); if (user.id) res.data.UID = Number(user.id); if (user.level) res.data.GrowSpaceAddCount = Number(user.level); if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n原始回复:", oriRes, "\n修改回复:", res) Object.defineProperty(this, "responseText", { writable: true, }); Object.defineProperty(this, "response", { writable: true, }); this.response = JSON.stringify(res) this.responseText = JSON.stringify(res) } }) } else if (url.includes('file/download_info')) { // 个人页面的下载 this.addEventListener('readystatechange', async function () { if (this.readyState === 4 && this.status === 200) { let res, oriRes try { res = JSON.parse(this.responseText), oriRes = JSON.parse(this.responseText) } catch (e) { res = this.response, oriRes = this.response } if (res.data && res.data.DownloadUrl) { let originURL = new URL(res.data.DownloadUrl) if (originURL.origin.includes("web-pro")) { // 解密后的直链 let directURL = new URL(decodeURIComponent(atob(originURL.searchParams.get('params'))), originURL.origin) directURL.searchParams.set('auto_redirect', 0) // 修改原始链接 originURL.searchParams.set('params', btoa(directURL.href)) // 最终得出链接 res.data.DownloadUrl = originURL.href if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n原始回复:", oriRes, "\n修改回复:", res) } else { originURL.searchParams.set('auto_redirect', 0) let newURL = new URL('https://web-pro2.123952.com/download-v2/', originURL.origin) newURL.searchParams.set('params', btoa(encodeURI(originURL.href))) newURL.searchParams.set('is_s3', 0); // 一定要解密，最终才能得出链接 res.data.DownloadUrl = decodeURIComponent(newURL.href) if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n原始回复:", oriRes, "\n修改回复:", res) } } Object.defineProperty(this, "responseText", { writable: true, }); Object.defineProperty(this, "response", { writable: true, }); this.response = JSON.stringify(res) this.responseText = JSON.stringify(res) } }); } else if (url.includes('share/download/info')) { // 分享页面的下载 this.addEventListener('readystatechange', async function () { if (this.readyState === 4 && this.status === 200) { let res, oriRes try { res = JSON.parse(this.responseText), oriRes = JSON.parse(this.responseText) } catch (e) { res = this.response, oriRes = this.response } if (res.data && res.data.DownloadURL) { let originURL = new URL(res.data.DownloadURL) if (!originURL.origin.includes("web-pro")) { originURL.searchParams.set('auto_redirect', 0) let newURL = new URL('https://web-pro2.123952.com/download-v2/', originURL.origin) newURL.searchParams.set('params', btoa(encodeURI(originURL.href))) newURL.searchParams.set('is_s3', 0); // 一定要解密，最终才能得出链接 res.data.DownloadURL = decodeURIComponent(newURL.href) if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n原始回复:", oriRes, "\n修改回复:", res) } } Object.defineProperty(this, "responseText", { writable: true, }); Object.defineProperty(this, "response", { writable: true, }); this.response = JSON.stringify(res) this.responseText = JSON.stringify(res) } }); } else if (url.includes('file/batch_download_info')) { // 个人页面的打包下载 this.addEventListener('readystatechange', function () { if (this.readyState === 4 && this.status === 200) { let res, oriRes try { res = JSON.parse(this.responseText), oriRes = JSON.parse(this.responseText) } catch (e) { res = this.response, oriRes = this.response } if (res.data && res.data.DownloadUrl) { let originURL = new URL(res.data.DownloadUrl) if (originURL.origin.includes("web-pro")) { // 解密后的直链 let directURL = new URL(decodeURIComponent(atob(originURL.searchParams.get('params'))), originURL.origin) directURL.searchParams.set('auto_redirect', 0) // 修改原始链接 originURL.searchParams.set('params', btoa(directURL.href)) // 最终得出链接 res.data.DownloadUrl = originURL.href if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n原始回复:", oriRes, "\n修改回复:", res) } else { originURL.searchParams.set('auto_redirect', 0) let newURL = new URL('https://web-pro2.123952.com/download-v2/', originURL.origin) newURL.searchParams.set('params', btoa(encodeURI(originURL.href))) newURL.searchParams.set('is_s3', 0); // 一定要解密，最终才能得出链接 res.data.DownloadUrl = decodeURIComponent(newURL.href) if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n原始回复:", oriRes, "\n修改回复:", res) } } Object.defineProperty(this, "responseText", { writable: true, }); Object.defineProperty(this, "response", { writable: true, }); this.response = JSON.stringify(res) this.responseText = JSON.stringify(res) } }); } else if (url.includes('web_logs') || url.includes('metrics')) { throw new Error('【123 云盘会员青春版】已屏蔽此数据收集器'); } return originalOpen.apply(this, arguments); }; unsafeWindow.fetch = async function (url, options) { if (url.includes('web_logs') || url.includes('metrics')) { throw new Error('【123 云盘会员青春版】已屏蔽此数据收集器'); } return originalFetch(url, options); }; const originalCreateElement = document.createElement; if (user.ad) unsafeWindow.document.createElement = function (tagName) { const element = originalCreateElement.call(this, tagName); if (tagName.toLowerCase() === "div") { const observer = new MutationObserver(mutations => { for (const mutation of mutations) { $(mutation.addedNodes).each(function () { const element = $(this); if (this.tagName === "SPAN" && element.text().includes("点击查看详情")) { const newElement = element.clone(); newElement.text("感谢您使用本脚本，好用的话就点击这儿来给个 Star 吧~"); newElement.off("click").on("click", function () { window.open("https://github.com/hmjz100/123panYouthMember", "_blank"); }); element.replaceWith(newElement); } }); } }); observer.observe(element, { childList: true, subtree: true }); } return element; }; let reddem = unsafeWindow.reddem = () => { const and = { os: "Android", vers: ["6.0", "7.1.2", "8.1.0", "9.0", "10.0"] }; const ios = { os: "iOS", vers: ["12.0", "13.4", "14.0", "15.0"] }; const devs = { "Apple": ios, "Xiaomi": and, "Samsung": and, "Huawei": { ...and, hmos: () => (Math.random() < 0.5 ? "HarmonyOS;" : ""), hmsCore: () => `HMSCore ${Math.floor(Math.random() * 7) + 1}.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 1000)};` }, "Google": and, "Oneplus": and, "Vivo": and, "Oppo": and }; const appXVers = [ "2.1.3", "2.1.4", "2.3.1", "2.3.2", "2.3.4", "2.3.5", "2.3.6", "2.3.7", "2.3.8", "2.3.9", "2.3.12", "2.3.13", "2.3.14", "2.4.0", "2.4.1", "2.4.7"]; const appVers = [ "38", "39", "42", "43", "44", "45", "46", "47", "48", "49", "50", "54", "55", "56", "61", "62", "69"]; const appXVer = appXVers[Math.floor(Math.random() * appXVers.length)]; const appVer = appVers[appXVers.indexOf(appXVer)]; const brands = Object.keys(devs); const brand = brands[Math.floor(Math.random() * brands.length)]; const { os, vers } = devs[brand]; const osVer = vers[Math.floor(Math.random() * vers.length)]; return { ua: `123pan/v${appXVer} (${os}_${osVer};${brand})`, version: Number(appVer), versionX: appXVer, osVersion: osVer, os: os, brand: brand } } // 重写 setRequestHeader 方法 unsafeWindow.XMLHttpRequest.prototype.setRequestHeader = function (header, value) { let url = this.url, resName = header, resValue = value, oriResName = header, oriResValue = value let info = reddem() let headers = { "user-agent": info.ua, "platform": info.os.toLowerCase(), "app-version": info.version, "x-app-version": info.versionX }; if (!!url && url.includes('download')) { // 修改请求头 if (resName.toLowerCase() in headers) { resValue = headers[resName.toLowerCase()]; if (user.debug === 1 || user.debug === 2) console.log("【123 云盘会员青春版】Hook XHR", "\n请求地址:", url, "\n请求头项:", { [oriResName]: oriResValue }, "\n修改头项:", { [resName]: resValue }, "\n随机项目:", info) header = resName; value = resValue; } } return originalSetRequestHeader.apply(this, arguments); }; // hook 解密 base64 的部分 unsafeWindow.atob = function (arguments) { return atob(decodeURIComponent(arguments)) } })();