您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a download btn to download all availble Pn whenever possible
// ==UserScript== // @name mdf4 // @namespace http://tampermonkey.net/ // @version 0.3 // @description Adds a download btn to download all availble Pn whenever possible // @author DA25 // @match *://*/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; function generateLicense(licenseCode) { if (!!!licenseCode) { throw new Error("License Code is null"); } console.log(`Generating LicenseKey using LicenseCode: ${licenseCode}`); let licCodeWoZerosAndDollar = ""; for (let index = 1; index < licenseCode.length; index++) { let licenseChar = licenseCode[index]; if (licenseChar === "0") { licCodeWoZerosAndDollar = licCodeWoZerosAndDollar.concat("1"); } else { licCodeWoZerosAndDollar = licCodeWoZerosAndDollar.concat(licenseChar); } } let midIndex = Math.floor(licCodeWoZerosAndDollar.length / 2); let firstHalfLicCode = licCodeWoZerosAndDollar.substring(0, midIndex + 1); let secondHalfLicCode = licCodeWoZerosAndDollar.substring(midIndex); let firstHalfLicCodeNum = Number(firstHalfLicCode); let secondHalfLicCodeNum = Number(secondHalfLicCode); let secMinFirstAbs = Math.abs(secondHalfLicCodeNum - firstHalfLicCodeNum); let total = secMinFirstAbs * 4; let totalStr = String(total); let temp3 = ""; for (let i = 0; i < midIndex + 1; i++) { for (let j = 1; j <= 4; j++) { let temp2 = parseInt(licenseCode[i + j]) + parseInt(totalStr[i]); if (temp2 >= 10) { temp2 = temp2 - 10 } temp3 = temp3.concat(String(temp2)); } } console.log(`Generated LicenseKey: ${temp3}`); return temp3; } function generateLicensedVideoUrl(videoUrl, license) { if (!!!videoUrl || !!!license) { throw new Error("VideoUrl or LicenseKey is null"); } console.log(`Generating LicensedVideoUrl, for VideoUrl: ${videoUrl} using LicenseKey: ${license}`); const re = /function\/[0-9]+\//g; if (videoUrl.search(re) === -1) { console.log("VideoUrl already Licensed", videoUrl); return videoUrl; } let sanitizedVideoUrl = videoUrl.replace(re, "") let parts = sanitizedVideoUrl.split("/"); let vidCode = parts[5].substring(0, 32); let licenseResult = license; let vidCodeCopy = vidCode; for (let index = vidCode.length - 1; index >= 0; index--) { let temp = index; for (let index2 = index; index2 < licenseResult.length; index2++) { temp = temp + parseInt(licenseResult[index2]); } while (temp >= vidCode.length) { temp = temp - vidCode.length; } let temp2 = ""; for (let index3 = 0; index3 < vidCode.length; index3++) { if (index3 === index) { temp2 = temp2.concat(vidCode[temp]); } else if (index3 === temp) { temp2 = temp2.concat(vidCode[index]); } else { temp2 = temp2.concat(vidCode[index3]); } } vidCode = temp2 } parts[5] = parts[5].replace(vidCodeCopy, vidCode); let videoUrlOutput = parts.join("/"); console.log("Generated Licensed VideoUrl: ", videoUrlOutput); return videoUrlOutput; } function getVideoUrlsKeys(flashvars) { if (!!!flashvars) { throw new Error("Flashvars is null"); } console.log(`Extracting VideoUrlKeys using FlashVars`); let videoDetectionString = "get_file"; let videoKeys = []; let flashvarsKeys = Object.entries(flashvars); for (const [key, value] of flashvarsKeys) { if (typeof value === "string") { if (value.includes(videoDetectionString)) { videoKeys.push(key); } } } console.log("Extracted VideoUrlKeys:", videoKeys); return videoKeys; } function getVideoText(videoKey, flashvars) { const videoTextPostfixString = "_text"; let videoTextKey = videoKey.concat(videoTextPostfixString); return flashvars[videoTextKey]; } function getAllLicensedVideos(flashvars) { if (!!!flashvars) { throw new Error("Flashvars is null") } console.log("Flashvars available. Getting all LicensedVideos"); const licenseCodeKey = "license_code"; let licenseCode = flashvars[licenseCodeKey]; let license = generateLicense(licenseCode); let availableVideoKeys = getVideoUrlsKeys(flashvars); let allLicensedVideos = [] for (const videoKey of availableVideoKeys) { let videoUrl = flashvars[videoKey]; let licensedVideoUrl = generateLicensedVideoUrl(videoUrl, license); let videoText = getVideoText(videoKey, flashvars); let video = {} video["url"] = licensedVideoUrl; video["text"] = videoText; allLicensedVideos.push(video); } console.log("Got all LicensedVideos", allLicensedVideos); return allLicensedVideos; } function createdDropdownEle() { let dropdownWrapper = document.createElement("div"); dropdownWrapper.classList.add("dropdown"); let downloadBtn = document.createElement("button"); downloadBtn.classList.add("btn", "btn-dark", "btn-sm", "dropdown-toggle"); downloadBtn.setAttribute("type", "button"); downloadBtn.setAttribute("data-bs-toggle", "dropdown"); downloadBtn.innerText = "DA25-Download"; dropdownWrapper.append(downloadBtn); let btnList = document.createElement("ul"); btnList.classList.add("dropdown-menu", "btn-sm"); dropdownWrapper.append(btnList); console.log("Dropdown Element created"); return dropdownWrapper; } function createDownloadEle(url, text) { let altAnchorEle = document.createElement("a"); altAnchorEle.classList.add("dropdown-item", "btn-sm"); altAnchorEle.setAttribute("href", url); altAnchorEle.innerText = text; console.log(`Download Element for: ${text} created with url:`, url); return altAnchorEle; } function appendDownloadToDropdown(dropdownEle, downloadEle) { let downloadBtnList = dropdownEle.querySelector("ul.dropdown-menu"); let listItem = document.createElement("li"); listItem.append(downloadEle); downloadBtnList.append(listItem); console.log("Download Element appended to Dropdown"); } function attachDropdownToPage(dropdownEle) { console.log("Attaching Dropdown Element to Page.") let listEle = document.createElement("li"); listEle.append(dropdownEle); let menuList = document.querySelector(".tabs-menu > ul"); if (!!menuList) { menuList.prepend(listEle); console.log("Attached Dropdown Element to Video Details Element"); console.log(menuList); console.log(dropdownEle); // addBootstrap(); } else { console.log("Video Details Element is not present.") document.body.prepend(listEle); console.log("Attached Dropdown as first Element of Body"); console.log(dropdownEle); // alert("window.flashvars present but '.tabs-menu > ul' is not"); } } function addBootstrapToPage() { let head = document.getElementsByTagName("head")[0]; let bootstrapCssScriptEle = document.createElement("link"); bootstrapCssScriptEle.setAttribute("href", "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"); bootstrapCssScriptEle.setAttribute("rel", "stylesheet"); bootstrapCssScriptEle.setAttribute("integrity", "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"); bootstrapCssScriptEle.setAttribute("crossorigin", "anonymous"); head.insertAdjacentElement("beforeend", bootstrapCssScriptEle); let body = document.getElementsByTagName("body")[0]; let bootstrapJsScriptEle = document.createElement("script"); bootstrapJsScriptEle.setAttribute("src", "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"); bootstrapJsScriptEle.setAttribute("integrity", "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"); bootstrapJsScriptEle.setAttribute("crossorigin", "anonymous"); body.insertAdjacentElement("beforeend", bootstrapJsScriptEle); } function mainFunction() { console.log("Inside Main Function"); if (window.flashvars) { console.log("Flashvars are available"); let videos = getAllLicensedVideos(window.flashvars); let dropdownEle = createdDropdownEle(); for (let video of videos) { let downloadEle = createDownloadEle(video.url, video.text); appendDownloadToDropdown(dropdownEle, downloadEle); } attachDropdownToPage(dropdownEle); } else { console.log("Flashvars are not available"); } } function docReady(userFunction) { console.log("Checking if Document is Ready"); // if (document.readyState === "complete" || document.readyState === "interactive") { // console.log("Document is 'complete' or 'interactive'"); // setTimeout(() => { // console.log("After timeout of 1 second over. Now running Main Function.") // userFunction(); // }, 1); // } else { // console.log("Document is NOT yet 'complete' or 'interactive'"); // console.log("Adding event listener for 'DOMContentLoaded'") // document.addEventListener("DOMContentLoaded", () => { // console.log("'DOMContentLoaded' event caught. Now running Main Function.") // userFunction() // }); // } console.log("Adding event listener for 'DOMContentLoaded'") document.addEventListener("DOMContentLoaded", () => { console.log("'DOMContentLoaded' event caught. Now running Main Function.") userFunction() }); } docReady(mainFunction); })();