- // ==UserScript==
- // @name Easy Offline pikpak addon
- // @namespace hoothin
- // @version 2024-08-16
- // @description Add pikpak support for Easy Offline
- // @author hoothin
- // @match *://*/*
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_xmlhttpRequest
- // @grant GM_notification
- // @grant unsafeWindow
- // @run-at document-start
- // @require https://unpkg.com/crypto-js@4.2.0/crypto-js.js
- // @connect user.mypikpak.com
- // @connect api-drive.mypikpak.com
- // ==/UserScript==
-
- (function() {
- 'use strict';
- let info = GM_getValue("pikpakUserInfo"), device_id, user_id;
- const CLIENT_ID = "YNxT9w7GMdWvEOKa";
- const CLIENT_SECRET = "dbw2OtmVEeuUvIptb1Coyg";
- const CLIENT_VERSION = "1.47.1";
- const PACKAG_ENAME = "com.pikcloud.pikpak";
- const SDK_VERSION = "2.0.4.204000";
- const APP_NAME = "com.pikcloud.pikpak";
- function captchaInit() {
- return new Promise(resolve => {
- let meta = {};
- if (/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(info.userName)) {
- meta.email = info.userName;
- } else if (/\d{11,18}/.test(info.userName)) {
- meta.phone_number = info.userName;
- } else {
- meta.username = info.userName;
- }
- let params = {
- "client_id": CLIENT_ID,
- "action": "POST:https://user.mypikpak.com/v1/auth/signin",
- "device_id": device_id,
- "meta": meta
- }
- GM_xmlhttpRequest({
- method: 'POST',
- url: 'https://user.mypikpak.com/v1/shield/captcha/init',
- data: JSON.stringify(params),
- onload: (res) => {
- if(res.status === 200) {
- let data = JSON.parse(res.responseText);
- resolve(data);
- } else {
- info.loginInfo = null;
- GM_setValue("pikpakUserInfo", info);
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- }
- },
- onerror: (e) => {
- GM_notification("Error: " + (e.statusText || e.error));
- },
- ontimeout: (e) => {
- GM_notification("Error: " + (e.statusText || e.error));
- }
- });
- });
- }
- function buildCustomUserAgent() {
- let signature_base = `${device_id}${PACKAG_ENAME}1appkey`;
- let sha1_result = CryptoJS.SHA1(signature_base).toString(CryptoJS.enc.Hex);
- let md5_result = CryptoJS.MD5(sha1_result).toString(CryptoJS.enc.Hex);
-
- let device_sign = `div101.${device_id}${md5_result}`;
-
- let user_agent_parts = [
- `ANDROID-${APP_NAME}/${CLIENT_VERSION}`,
- "protocolVersion/200",
- "accesstype/",
- `clientid/${CLIENT_ID}`,
- `clientversion/${CLIENT_VERSION}`,
- "action_type/",
- "networktype/WIFI",
- "sessionid/",
- `deviceid/${device_id}`,
- "providername/NONE",
- `devicesign/${device_sign}`,
- "refresh_token/",
- `sdkversion/${SDK_VERSION}`,
- `datetime/${Date.now()}`,
- `usrno/${user_id}`,
- `appname/${APP_NAME}`,
- "session_origin/",
- "grant_type/",
- "appid/",
- "clientip/",
- "devicename/Xiaomi_M2004j7ac",
- "osversion/13",
- "platformversion/10",
- "accessmode/",
- "devicemodel/M2004J7AC",
- ]
-
- return user_agent_parts.join(" ");
- }
- document.addEventListener("click", function(e) {
- if (e.target && e.target.getAttribute && e.target.getAttribute("name") === "pikpak" && e.target.parentNode.id === "icons") {
- GM_setValue("pikpakUserInfo", "");
- alert("PikPak account has been cleared");
- }
- });
- var _unsafeWindow = (typeof unsafeWindow === 'undefined') ? window : unsafeWindow;
- if (!_unsafeWindow.eoAddons) _unsafeWindow.eoAddons = {};
- _unsafeWindow.eoAddons.pikpak = {
- regex: /mypikpak\.com/,
- url: "http://user.mypikpak.com/",
- bgColor: "2265ff",
- noTxt: true,
- linkRegExp: /^magnet:\?xt|^PikPak:\/\/|\.(torrent|mp4|mp3|rar|7z|zip|rmvb|mkv|avi|iso)$/i,
- directUrl: function(offUrl) {
- if (!info) {
- let userName = prompt("userName");
- if (!userName) return;
- let userPass = prompt("userPass");
- if (!userPass) return;
- info = {userName: userName, userPass: userPass};
- GM_setValue("pikpakUserInfo", info);
- }
- var postUrl = async () => {
- let postData;
- if (offUrl.indexOf('PikPak://') === 0) {
- const urlData = offUrl.substring(9).split('|')
- postData = {
- kind: "drive#file",
- name: urlData[0],
- size: urlData[1],
- hash: urlData[2],
- upload_type: "UPLOAD_TYPE_RESUMABLE",
- objProvider: {
- provider: "UPLOAD_TYPE_UNKNOWN"
- }
- }
- } else {
- postData = {
- kind: "drive#file",
- name: "",
- upload_type: "UPLOAD_TYPE_URL",
- url: {
- url: offUrl
- },
- params: {"from":"file"},
- folder_type: "DOWNLOAD"
- }
- }
- GM_xmlhttpRequest({
- method: 'POST',
- url: 'https://api-drive.mypikpak.com/drive/v1/files',
- data: JSON.stringify(postData),
- headers: {
- "Content-Type": "application/json; charset=utf-8",
- authorization: info.loginInfo.token_type + ' ' + info.loginInfo.access_token,
- "X-Captcha-Token": info.captchaData.captcha_token
- },
- onload: (res) => {
- if(res.status === 200) {
- GM_notification("Task OK");
- } else if(res.status === 401) {
- info.loginInfo=null;
- GM_setValue("pikpakUserInfo", info);
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- } else if(res.status === 400) {
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- } else if(res.status === 403) {
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- }
- },
- onerror: (e) => {
- GM_notification("Error: " + (e.statusText || e.error));
- },
- ontimeout: (e) => {
- GM_notification("Error: " + (e.statusText || e.error));
- }
- })
- };
- device_id = CryptoJS.MD5(`${info.userName}${info.userPass}`).toString(CryptoJS.enc.Hex);
- (async () => {
- if (!info.captchaData || info.captchaData.expires < new Date().getTime()) {
- let captchaData = await captchaInit();
- info.captchaData = captchaData;
- if (!info.captchaData.expires && info.captchaData.expires_in) {
- info.captchaData.expires = new Date().getTime() + 1000 * info.captchaData.expires_in;
- }
- GM_setValue("pikpakUserInfo", info);
- }
- if (!info.loginInfo || info.loginInfo.expires < new Date().getTime()) {
- let data = {
- "client_id": CLIENT_ID,
- "client_secret": CLIENT_SECRET,
- "password": info.userPass,
- "username": info.userName,
- "captcha_token": info.captchaData.captcha_token,
- }
- GM_xmlhttpRequest({
- method: 'POST',
- url: 'https://user.mypikpak.com/v1/auth/signin',
- data: JSON.stringify(data),
- headers: {
- 'user-agent': 'accessmode/ devicename/Netease_Mumu appname/android-com.pikcloud.pikpak cmd/login appid/ action_type/ clientid/YNxT9w7GMdWvEOKa deviceid/56e000d71f4660700ca974f2305171c5 refresh_token/ grant_type/ networktype/WIFI devicemodel/MuMu accesstype/ sessionid/ osversion/6.0.1 datetime/1636364470779 sdkversion/1.0.1.101600 protocolversion/200 clientversion/ providername/NONE clientip/ session_origin/ devicesign/div101.56e000d71f4660700ca974f2305171c5b94c3d4196a9dd74e49d7710a7af873d platformversion/10 usrno/null'
- },
- onload: (res) => {
- if (res.status === 200) {
- info.loginInfo = JSON.parse(res.responseText);
- if (!info.loginInfo.expires && info.loginInfo.expires_in) {
- info.loginInfo.expires = new Date().getTime() + 1000 * info.loginInfo.expires_in;
- }
- GM_setValue("pikpakUserInfo", info);
- postUrl();
- } else if (res.status === 401) {
- GM_setValue("pikpakUserInfo","");
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- } else if (res.status === 400) {
- GM_setValue("pikpakUserInfo","");
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- } else if (res.status === 403) {
- GM_setValue("pikpakUserInfo","");
- const msg = JSON.parse(res.responseText).error_description;
- alert(msg);
- }
- },
- onerror: (e) => {
- GM_notification("Error: " + (e.statusText || e.error));
- },
- ontimeout: (e) => {
- GM_notification("Error: " + (e.statusText || e.error));
- }
- })
- } else {
- postUrl();
- }
- })();
- return false;
- },
- bgImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAArbP5MdNFMdNIrbP4sbP1QdctQdcwvbv////8dYf8sbP9smP/09/8qaf/V4f8iZf/u8/+lwP+duv+UtP+PsP9hkP92n/9nlP/K2v/F1v+7z/+Ytv9Wif9Aef91nv9e7pgKAAAACHRSTlMA+puT/PWHhQBB7XEAAACQSURBVBjTTY8JCsQwCEWdrjFm37p37n/LMdAJfSTgf4IoAPQf8fDpgek4N9NxnwQZJx0/w+UMNd/XV6nluqsBQbRp79Xqvd7ICBCuaHuElMJhdXEspMKGko/YA2LYXyKuiGt8Ca3rfwm052nbjILV1IyFBZFZck4xppwXQ8Srk2wQzXzcIBpDB8w0/vM4AfwACl4LKjajMX0AAAAASUVORK5CYII="
- };
- })();