- // ==UserScript==
- // @name Digit77 Helper
- // @namespace cn.XYZliang.digit77Helper
- // @version 2.4.6
- // @description 自动复制提取码,跳过ouo.io的三秒等待时间!
- // @require https://code.jquery.com/jquery-3.7.1.min.js
- // @license GNU General Public License v3.0
- // @author XYZliang
- // @homepage https://gf.qytechs.cn/zh-CN/scripts/495107-digit77-helper
- // @match *://www.digit77.com/*
- // @match *://ouo.io/*
- // @match *://ouo.press/*
- // @match *://cloaking.link/*
- // @match *://*.sharepoint.com/*
- // @match *://www.aliyundrive.com/*
- // @match *://pan.quark.cn/*
- // @icon https://www.digit77.com/_nuxt/logo-s.BqVYlxIi.png
- // @grant unsafeWindow
- // @grant GM_setClipboard
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_deleteValue
- // @grant GM_listValues
- // @grant GM_xmlhttpRequest
- // @grant GM_notification
- // @grant GM_getClipboard
- // @run-at document-end
- // @connect *
- // ==/UserScript==
- /* globals jQuery, $ */
- 'use strict';
-
- // 用户设置
- let settings = GM_getValue('settings', {
- autofill: true,
- ouo: true,
- cloaking: true,
- quark: true,
- baidu: true,
- onedrive: true,
- aliyun: true,
- error: true,
- });
-
- // Clean up
- cleanupStorage();
-
- let url = location.host;
- // Main logic goes here ---------------------------------------------------------
- if (url.includes('digit77.com')) {
- handleDigit77();
- } else if (url.includes('ouo')) {
- handleOuo();
- } else if (url.includes('cloaking')) {
- handleCloaking();
- } else if (url.includes('pan.quark.cn')) {
- hanndleQuark();
- } else if (url.includes('sharepoint.com')) {
- if (settings.onedrive)
- doFillAction('#txtPassword', '#btnSubmitPassword', 'digit77');
- } else {
- console.log('Unknown url! (' + url + ')');
- return;
- }
-
- // Function definitions ---------------------------------------------------------
- function handleCloakingGo(pw) {
- GM_xmlhttpRequest({
- method: 'POST',
- url: `${location.origin}/links/go`,
- data: $('#go-link').serialize(),
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
- },
- onload: function (response) {
- console.log('Onload response:', response.responseText);
- if (response.status === 200) {
- try {
- var data = JSON.parse(response.responseText);
- if (data.status !== 'error') {
- let realLink = data.url;
- let finalUrlWithPwd = addGetParameter(
- realLink,
- 'Digit77HelperPwd',
- //GM_getValue(pw),
- getPasscode(pw),
- );
- setTimeout(() => {
- window.location.href = finalUrlWithPwd;
- }, 1000);
- } else {
- console.error('Error from server:', data);
- }
- } catch (e) {
- console.error('Failed to parse response:', e);
- }
- } else {
- console.error('Failed to get the real link', response.status);
- }
- },
- onerror: function (response) {
- console.error(
- 'Request failed:',
- response.status,
- response.statusText,
- );
- },
- });
- }
-
- // Function definitions ---------------------------------------------------------
- function handleCloaking() {
- if (!settings.cloaking) return;
- console.group(`[Digital77 Helper] -- ${location.origin}`);
- consoleLog('正在跳过Cloaking');
- // Directly set text using .text() for better consistency and compatibility.
- $('h1').text('Digit77 Helper正在跳过等待!');
- $('#form-continue > button').text('欢迎使用Digit77 Helper');
- let pathSegments = location.pathname.split('/')[1];
-
- if (settings.error) consoleLog('path segments: ' + pathSegments);
- // set cloaking status to 0 for the first time
- GM_setValue('cloaking', 0);
- // if the cloaking status is 0, then set the cloaking status to 1
- if (GM_getValue('cloaking') === 0) {
- GM_setValue('cloaking', 1);
- // click the continue button
- $('#form-continue > button').click();
-
- //request url from cloaking is https://cloaking.link/links/go
- setTimeout(() => {
- handleCloakingGo(pathSegments);
- }, 1000);
- }
- // if find element body > div.container > div > div > div > div:nth-child(5) > a, then extract the link form it
- if (
- $('body > div.container > div > div > div > div:nth-child(5) > a')
- .length > 0
- ) {
- WaitForLink();
- }
- console.groupEnd();
- }
-
- function WaitForLink() {
- // focuse on the link
- $(
- 'body > div.container > div > div > div > section.link-tab-body.mb-5 > div > div > div:nth-child(2) > div > fieldset > div > div.col-md-3.g-link-body > div > div > a',
- ).focus();
- // wait for 5 seconds to get the link
- setTimeout(() => {
- let link = $(
- 'body > div.container > div > div > div > section.link-tab-body.mb-5 > div > div > div:nth-child(2) > div > fieldset > div > div.col-md-3.g-link-body > div > div > a',
- ).attr('href');
- if (link.includes('javascript')) WaitForLink();
- let pw = location.pathname.split('/')[1];
- let passcode = getPasscode(pw)
- if (settings.error)
- consoleLog('Cloaking link: ' + pw + ' pwd: ' + passcode);
- let finalUrl = addGetParameter(
- link,
- 'Digit77HelperPwd',
- //GM_getValue(pw),
- passcode,
- );
- window.location.href = finalUrl;
- }, 2800);
- }
-
- function hanndleQuark() {
- if (!settings.quark) return;
- // get the password from parameter
- const urlObj = new URL(window.location.href);
-
- // if the url contains the parameter Digit77HelperPwd, then fill the password
-
- if (!urlObj.search.includes('Digit77HelperPwd')) {
- return;
- }
-
- const queryParams = new URLSearchParams(urlObj.search);
- const digit77HelperPwd = queryParams.get('Digit77HelperPwd');
- if (settings.error) {
- console.log('Debugging <夸克网盘>: ');
- console.log('href: ', window.location.href);
- console.log('code: ', digit77HelperPwd);
- }
- if (digit77HelperPwd !== undefined) {
- doFillAction(
- '#ice-container > div.ShareReceivePC--wrapcontainer--3OAJUiU.share-container-cls-name-for-get-dom > div.ShareReceivePC--wrapcontent--2fA9pbO > div > div.ShareReceivePC--content--3zjCAuj > div.ShareReceivePC--input-wrap--2FUw27N > input',
- '#ice-container > div.ShareReceivePC--wrapcontainer--3OAJUiU.share-container-cls-name-for-get-dom > div.ShareReceivePC--wrapcontent--2fA9pbO > div > div.ShareReceivePC--content--3zjCAuj > div:nth-child(5) > button',
- digit77HelperPwd,
- );
- } else alert('请手动粘贴提取码:', GM_getClipboard());
- }
-
- function handleOuo() {
- if (!settings.ouo) return;
-
- console.group(`[Digital77 Helper] -- ${location.href}`);
- consoleLog('正在跳过ouo');
-
- // Use .ready() to ensure the DOM is fully loaded before attempting to modify elements.
- $(document).ready(function () {
- // Directly set text using .text() for better consistency and compatibility.
- $('h4').text('Digit77 Helper正在跳过等待!');
- $('.btn-main').text('欢迎使用Digit77 Helper');
-
- let pathSegments = location.pathname.split('/');
- let passcode = getPasscode(pathSegments[2]);
- if (settings.error)
- consoleLog(
- 'path segments: ' +
- pathSegments +
- ' pwd key: ' +
- pathSegments[2] +
- ' pwd: ' +
- //GM_getValue(pathSegments[2]),
- passcode,
- );
- // Check if the path contains 'go' and proceed with the specific logic for those pages.
- if (pathSegments[1] === 'go') {
- let reallyUrlGetter = `${location.origin}/xreallcygo/${pathSegments[2]}`;
- let reallyUrlData = $('#form-go').serialize();
-
- // Use GM_xmlhttpRequest for cross-origin requests.
- GM_xmlhttpRequest({
- method: 'POST',
- url: reallyUrlGetter,
- data: reallyUrlData,
- headers: {
- 'Content-Type':
- 'application/x-www-form-urlencoded;charset=UTF-8',
- },
- onload: function (response) {
- // Construct the final URL with the password parameter if the request was successful.
- let finalUrl = addGetParameter(
- response.finalUrl,
- 'Digit77HelperPwd',
- passcode,
- );
- if (response.status === 200) {
- // Redirect after a slight delay to enhance ad revenue potentially.
- setTimeout(
- () => (window.location.href = finalUrl),
- 1000,
- );
- } else {
- failedToGetJumpAddress(getPasscode(pathSegments[2]));
- }
- },
- onerror: function () {
- failedToGetJumpAddress(getPasscode(pathSegments[2]));
- },
- });
- } else {
- // For non-'go' pages, wait before clicking the main button to pass through ads.
- setTimeout(() => $('.btn-main').click(), 1500);
- }
- });
-
- console.groupEnd();
- }
-
- // Main logic for Digit77 ---------------------------------------------------------
- function handleDigit77() {
- $(document).ready(function () {
- // Create settings form directly
- const settingsFormHtml = `
- <details style="margin-top: 20px;">
- <summary style="background-color: crimson;border-radius: 5px;color:white">Digit77 Helper设置</summary>
- <div class="table-wrapper" style="padding-right: 10px;overflow-x: hidden;">
- <div id="settingsForm" class="settings-form"></div>
- </div>
- </details>`;
-
- console.group(`[Digital77 Helper] -- ${location.href}`);
-
- console.log('Digit77 Helper 加载成功!');
-
- // Options for the observer (which mutations to observe)
- const config = { childList: true, subtree: true };
-
- // Callback function to execute when mutations are observed
- const callback = function (mutationsList, observer) {
- for (let mutation of mutationsList) {
- if (mutation.type === 'childList') {
- let table = document.querySelector('table > tbody');
- if (
- table &&
- table.querySelectorAll('tr > td > div > button')
- .length > 0
- ) {
- observer.disconnect(); // Stop observing
- handleLinks();
-
- // Select description part from the page
- let description = $(
- '#__nuxt > div > section > section > main > div.page_single > div.single_content > div.post_content',
- );
- if (description.length) {
- description.empty();
- description.append(settingsFormHtml);
- populateSettingsForm();
- }
-
- $(
- '#__nuxt > div > section > section > main > div.page_single > div.single_content > div.AdBox > div > div > div.el-table__inner-wrapper > div.el-table__body-wrapper > div > div.el-scrollbar__wrap.el-scrollbar__wrap--hidden-default > div > table > thead > tr > th.el-table_1_column_4.is-center.is-leaf.el-table__cell > div',
- ).text('下载链接 (已成功加载Digit77 Helper)');
-
- break;
- }
- }
- }
- };
-
- // Create an instance of MutationObserver
- const observer = new MutationObserver(callback);
-
- // Select the node that will be observed for mutations
- const targetNode = document.querySelector('#__nuxt');
-
- // Start observing the target node for configured mutations
- observer.observe(targetNode, config);
-
- console.groupEnd();
- });
- }
-
- function handleLinks() {
- const nuxtDataElement = document.querySelector('#__NUXT_DATA__');
-
- // Early exit if no Nuxt data found
- if (!nuxtDataElement) {
- console.error('Failed to get #__NUXT_DATA__');
- return;
- }
-
- try {
- // Parse the JSON data directly from the innerHTML
- const data = JSON.parse(nuxtDataElement.innerHTML);
-
- // Validate parsed data and slice from 21 to 42
- if (!Array.isArray(data)) {
- throw new Error('Parsed data is not an array');
- }
- const relevantData = data.slice(21, 42);
-
- // Process each relevant data element
- relevantData.forEach((item, i) => {
- if (
- typeof item === 'string' &&
- (item.includes('cloaking.link') || item.includes('ouo.io'))
- ) {
- const nextItem = relevantData[i + 1];
- if (
- nextItem &&
- typeof nextItem === 'string' &&
- nextItem.length < 5 &&
- settings.cloaking &&
- !nextItem.includes('盘') &&
- !nextItem.includes('drive')
- ) {
- const key = item.split('/')[3];
- const pwd = nextItem;
- if (settings.error)
- console.log('Key:', key, 'Password:', pwd);
- if (settings.autofill) setPasscode(key, pwd);
- }
- }
- });
- } catch (e) {
- console.error('Failed to parse #__NUXT_DATA__:', e);
- }
-
- if (settings.error) GM_ShowAllValues();
- }
-
- // Helper functions ---------------------------------------------------------
- function failedToGetJumpAddress(pwd) {
- if (!settings.error) {
- return;
- }
- GM_notification(
- '获取ouo跳转链接失败!这导致无法自动填写提取码,请手动粘贴提取码!',
- 'Digit77 helper错误',
- );
- GM_setClipboard(pwd);
- }
-
- function getToday() {
- let date = new Date();
- let day = date.getDate();
- let month = date.getMonth() + 1;
- let year = date.getFullYear();
- let dateKey = `${day}-${month}-${year}`;
- return dateKey;
- }
-
- function setPasscode(key, pwd) {
- // append the password to the list of passcodes in the GM storage
- let passcodes = GM_getValue('passcodes', {});
- // store the passwords by the day-month-year
- let dateKey = getToday();
- if (!passcodes[dateKey]) passcodes[dateKey] = {};
- passcodes[dateKey][key] = pwd;
- GM_setValue('passcodes', passcodes);
- }
-
- function getPasscode(key) {
- let passcodes = GM_getValue('passcodes', {});
- let dateKey = getToday();
- if (passcodes[dateKey] && passcodes[dateKey][key]) {
- return passcodes[dateKey][key];
- }
- return null;
- }
-
- function addGetParameter(url, name, value) {
- url += (url.split('?')[1] ? '&' : '?') + name + '=' + value;
- return url;
- }
-
- // 以下代码修改自 网盘智能识别助手
- let util = {
- parseQuery(name) {
- let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
- let r = location.search.substr(1).match(reg);
- if (r != null) return r[2];
- return null;
- },
-
- sleep(time) {
- return new Promise((resolve) => setTimeout(resolve, time));
- },
-
- addStyle(id, tag, css) {
- tag = tag || 'style';
- let doc = document,
- styleDom = doc.getElementById(id);
- if (styleDom) return;
- let style = doc.createElement(tag);
- style.rel = 'stylesheet';
- style.id = id;
- tag === 'style' ? (style.innerHTML = css) : (style.href = css);
- document.head.appendChild(style);
- },
-
- isHidden(el) {
- try {
- return el.offsetParent === null;
- } catch (e) {
- return false;
- }
- },
-
- query(selector) {
- if (Array.isArray(selector)) {
- let obj = null;
- for (let i = 0; i < selector.length; i++) {
- let o = document.querySelector(selector[i]);
- if (o) {
- obj = o;
- break;
- }
- }
- return obj;
- }
- return document.querySelector(selector);
- },
- };
-
- function doFillAction(inputSelector, buttonSelector, pwd) {
- let maxTime = 10;
- let ins = setInterval(async () => {
- maxTime--;
- let input = util.query(inputSelector);
- let button = util.query(buttonSelector);
- if (input && !util.isHidden(input)) {
- clearInterval(ins);
- let lastValue = input.value;
- input.value = pwd;
- //Vue & React 触发 input 事件
- let event = new Event('input', {
- bubbles: true,
- });
- let tracker = input._valueTracker;
- if (tracker) {
- tracker.setValue(lastValue);
- }
- input.dispatchEvent(event);
- await util.sleep(500); //1秒后点击按钮
- button.click();
- } else {
- maxTime === 0 && clearInterval(ins);
- }
- }, 333);
- }
-
- function populateSettingsForm() {
- const setting_template = [
- {
- id: 'autofill',
- text: '开启自动填写提取码',
- checked: settings.autofill,
- },
- {
- id: 'cloaking',
- text: '跳过cloaking广告页面的等待时间',
- checked: settings.cloaking,
- },
- { id: 'ouo', text: '跳过ouo广告页面的等待时间', checked: settings.ouo },
- { id: 'quark', text: '开启夸克网盘自动提取', checked: settings.quark },
- { id: 'baidu', text: '开启百度网盘自动提取', checked: settings.baidu },
- {
- id: 'onedrive',
- text: '开启OneDrive自动提取',
- checked: settings.onedrive,
- },
- { id: 'error', text: 'Debug 模式', checked: settings.error },
- // Continue with other settings as needed...
- ];
-
- const formContainer = $('#settingsForm');
- formContainer.empty(); // Clear previous contents if any
-
- // Dynamically create and append settings controls
- setting_template.forEach((setting) => {
- const settingControlHtml = `
- <div class="custom-switch custom-control">
- <input class="custom-control-input" type="checkbox" ${
- setting.checked ? 'checked="checked"' : ''
- } id="${setting.id}" name="${setting.id}" />
- <label class="custom-control-label" for="${setting.id}">
- ${setting.text}
- </label>
- </div>`;
- formContainer.append(settingControlHtml);
- });
-
- // Append action buttons
- const actionButtonsHtml = `
- <a class="btn btn-rd btn-block btn-lg btn-coral-pink" id="save">保存设置</a>
- <a class="btn btn-rd btn-block btn-lg btn-coral-pink" id="clean">清除缓存</a>
- <a href="https://github.com/lgcyaxi" target="_blank">关于插件<span class="icon-md fab fa-github linklogo"></span></a>`;
- formContainer.append(actionButtonsHtml);
-
- // Attach event listeners for buttons
- $('#save').on('click', function () {
- let updatedSettings = {};
- $('#settingsForm .custom-control-input').each(function () {
- let settingId = $(this).attr('id');
- let isChecked = $(this).is(':checked');
- updatedSettings[settingId] = isChecked;
- });
-
- // Save the updated settings object directly
- GM_setValue('settings', updatedSettings);
- alert('Settings have been saved successfully.');
- if (settings.error) {
- console.log('Debugging: ', GM_getValue('settings'));
- }
- });
-
- $('#clean').on('click', function () {
- let allValues = GM_listValues();
- allValues.forEach((value) => {
- if (value !== 'settings') GM_deleteValue(value);
- });
- alert('Cache cleared, except for settings.');
- });
- }
-
- function consoleLog(info, ...args) {
- if (typeof info === 'object') {
- let output = '';
- let styles = [];
-
- Object.entries(info).forEach(([key, value]) => {
- output += `%c${key}: %c${value}\n`;
- styles.push('color: #007BFF; font-weight: bold;', 'color: black;');
- });
-
- console.log(output, ...styles, ...args);
- } else {
- console.log(
- `%cDetails:\n%c${info}`,
- 'color: #007BFF; font-weight: bold;',
- 'color: black;',
- ...args,
- );
- }
- }
-
- function GM_ShowAllValues() {
- let output = '';
- let styles = [];
-
- function processValue(value, indent = '') {
- if (typeof value === 'object' && value !== null) {
- Object.entries(value).forEach(([key, val]) => {
- output += `${indent}%c${key}: %c${val}\n`;
- styles.push('color: green;', 'color: black;');
- if (typeof val === 'object' && val !== null) {
- processValue(val, indent + ' ');
- }
- });
- } else {
- output += `${indent}%c${value}: %c${GM_getValue(value)}\n`;
- styles.push('color: green;', 'color: black;');
- }
- }
-
- GM_listValues().forEach((value) => {
- const val = GM_getValue(value);
- processValue({ [value]: val });
- });
-
- consoleLog(output, ...styles);
- }
-
- function cleanupStorage() {
- let values = GM_listValues();
- let todayKey = getToday();
- values.forEach((value) => {
- if (value !== 'passcodes' && value !== 'settings') {
- GM_deleteValue(value);
- } else if (value === 'passcodes') {
- let passcodes = GM_getValue('passcodes', {});
- Object.keys(passcodes).forEach((dateKey) => {
- if (dateKey !== todayKey) {
- delete passcodes[dateKey];
- }
- });
- GM_setValue('passcodes', passcodes);
- }
- });
- consoleLog('已自动清除缓存!');
- }