Sleazy Fork is available in English.

mdf4

Adds a download btn to download all availble Pn whenever possible

  1. // ==UserScript==
  2. // @name mdf4
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3
  5. // @description Adds a download btn to download all availble Pn whenever possible
  6. // @author DA25
  7. // @match *://*/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. function generateLicense(licenseCode) {
  17. if (!!!licenseCode) {
  18. throw new Error("License Code is null");
  19. }
  20. console.log(`Generating LicenseKey using LicenseCode: ${licenseCode}`);
  21. let licCodeWoZerosAndDollar = "";
  22. for (let index = 1; index < licenseCode.length; index++) {
  23. let licenseChar = licenseCode[index];
  24. if (licenseChar === "0") {
  25. licCodeWoZerosAndDollar = licCodeWoZerosAndDollar.concat("1");
  26. } else {
  27. licCodeWoZerosAndDollar = licCodeWoZerosAndDollar.concat(licenseChar);
  28. }
  29. }
  30. let midIndex = Math.floor(licCodeWoZerosAndDollar.length / 2);
  31. let firstHalfLicCode = licCodeWoZerosAndDollar.substring(0, midIndex + 1);
  32. let secondHalfLicCode = licCodeWoZerosAndDollar.substring(midIndex);
  33. let firstHalfLicCodeNum = Number(firstHalfLicCode);
  34. let secondHalfLicCodeNum = Number(secondHalfLicCode);
  35.  
  36. let secMinFirstAbs = Math.abs(secondHalfLicCodeNum - firstHalfLicCodeNum);
  37. let total = secMinFirstAbs * 4;
  38. let totalStr = String(total);
  39. let temp3 = "";
  40. for (let i = 0; i < midIndex + 1; i++) {
  41. for (let j = 1; j <= 4; j++) {
  42. let temp2 = parseInt(licenseCode[i + j]) + parseInt(totalStr[i]);
  43. if (temp2 >= 10) {
  44. temp2 = temp2 - 10
  45. }
  46. temp3 = temp3.concat(String(temp2));
  47. }
  48. }
  49. console.log(`Generated LicenseKey: ${temp3}`);
  50. return temp3;
  51. }
  52.  
  53. function generateLicensedVideoUrl(videoUrl, license) {
  54. if (!!!videoUrl || !!!license) {
  55. throw new Error("VideoUrl or LicenseKey is null");
  56. }
  57. console.log(`Generating LicensedVideoUrl, for VideoUrl: ${videoUrl} using LicenseKey: ${license}`);
  58. const re = /function\/[0-9]+\//g;
  59. if (videoUrl.search(re) === -1) {
  60. console.log("VideoUrl already Licensed", videoUrl);
  61. return videoUrl;
  62. }
  63. let sanitizedVideoUrl = videoUrl.replace(re, "")
  64. let parts = sanitizedVideoUrl.split("/");
  65. let vidCode = parts[5].substring(0, 32);
  66. let licenseResult = license;
  67. let vidCodeCopy = vidCode;
  68. for (let index = vidCode.length - 1; index >= 0; index--) {
  69. let temp = index;
  70. for (let index2 = index; index2 < licenseResult.length; index2++) {
  71. temp = temp + parseInt(licenseResult[index2]);
  72. }
  73. while (temp >= vidCode.length) {
  74. temp = temp - vidCode.length;
  75. }
  76. let temp2 = "";
  77. for (let index3 = 0; index3 < vidCode.length; index3++) {
  78. if (index3 === index) {
  79. temp2 = temp2.concat(vidCode[temp]);
  80. } else if (index3 === temp) {
  81. temp2 = temp2.concat(vidCode[index]);
  82. } else {
  83. temp2 = temp2.concat(vidCode[index3]);
  84. }
  85. }
  86. vidCode = temp2
  87. }
  88. parts[5] = parts[5].replace(vidCodeCopy, vidCode);
  89. let videoUrlOutput = parts.join("/");
  90. console.log("Generated Licensed VideoUrl: ", videoUrlOutput);
  91. return videoUrlOutput;
  92. }
  93.  
  94. function getVideoUrlsKeys(flashvars) {
  95. if (!!!flashvars) {
  96. throw new Error("Flashvars is null");
  97. }
  98. console.log(`Extracting VideoUrlKeys using FlashVars`);
  99. let videoDetectionString = "get_file";
  100. let videoKeys = [];
  101. let flashvarsKeys = Object.entries(flashvars);
  102. for (const [key, value] of flashvarsKeys) {
  103. if (typeof value === "string") {
  104. if (value.includes(videoDetectionString)) {
  105. videoKeys.push(key);
  106. }
  107. }
  108. }
  109. console.log("Extracted VideoUrlKeys:", videoKeys);
  110. return videoKeys;
  111. }
  112.  
  113. function getVideoText(videoKey, flashvars) {
  114. const videoTextPostfixString = "_text";
  115. let videoTextKey = videoKey.concat(videoTextPostfixString);
  116. return flashvars[videoTextKey];
  117. }
  118.  
  119. function getAllLicensedVideos(flashvars) {
  120. if (!!!flashvars) {
  121. throw new Error("Flashvars is null")
  122. }
  123. console.log("Flashvars available. Getting all LicensedVideos");
  124. const licenseCodeKey = "license_code";
  125. let licenseCode = flashvars[licenseCodeKey];
  126. let license = generateLicense(licenseCode);
  127.  
  128. let availableVideoKeys = getVideoUrlsKeys(flashvars);
  129. let allLicensedVideos = []
  130. for (const videoKey of availableVideoKeys) {
  131. let videoUrl = flashvars[videoKey];
  132. let licensedVideoUrl = generateLicensedVideoUrl(videoUrl, license);
  133. let videoText = getVideoText(videoKey, flashvars);
  134. let video = {}
  135. video["url"] = licensedVideoUrl;
  136. video["text"] = videoText;
  137. allLicensedVideos.push(video);
  138. }
  139. console.log("Got all LicensedVideos", allLicensedVideos);
  140. return allLicensedVideos;
  141. }
  142.  
  143. function createdDropdownEle() {
  144. let dropdownWrapper = document.createElement("div");
  145. dropdownWrapper.classList.add("dropdown");
  146.  
  147. let downloadBtn = document.createElement("button");
  148. downloadBtn.classList.add("btn", "btn-dark", "btn-sm", "dropdown-toggle");
  149. downloadBtn.setAttribute("type", "button");
  150. downloadBtn.setAttribute("data-bs-toggle", "dropdown");
  151. downloadBtn.innerText = "DA25-Download";
  152.  
  153. dropdownWrapper.append(downloadBtn);
  154.  
  155. let btnList = document.createElement("ul");
  156. btnList.classList.add("dropdown-menu", "btn-sm");
  157.  
  158. dropdownWrapper.append(btnList);
  159.  
  160. console.log("Dropdown Element created");
  161. return dropdownWrapper;
  162. }
  163.  
  164. function createDownloadEle(url, text) {
  165. let altAnchorEle = document.createElement("a");
  166. altAnchorEle.classList.add("dropdown-item", "btn-sm");
  167. altAnchorEle.setAttribute("href", url);
  168. altAnchorEle.innerText = text;
  169.  
  170. console.log(`Download Element for: ${text} created with url:`, url);
  171. return altAnchorEle;
  172. }
  173.  
  174. function appendDownloadToDropdown(dropdownEle, downloadEle) {
  175. let downloadBtnList = dropdownEle.querySelector("ul.dropdown-menu");
  176. let listItem = document.createElement("li");
  177. listItem.append(downloadEle);
  178. downloadBtnList.append(listItem);
  179. console.log("Download Element appended to Dropdown");
  180. }
  181.  
  182. function attachDropdownToPage(dropdownEle) {
  183. console.log("Attaching Dropdown Element to Page.")
  184. let listEle = document.createElement("li");
  185. listEle.append(dropdownEle);
  186.  
  187. let menuList = document.querySelector(".tabs-menu > ul");
  188.  
  189. if (!!menuList) {
  190. menuList.prepend(listEle);
  191. console.log("Attached Dropdown Element to Video Details Element");
  192. console.log(menuList);
  193. console.log(dropdownEle);
  194. // addBootstrap();
  195. } else {
  196. console.log("Video Details Element is not present.")
  197. document.body.prepend(listEle);
  198. console.log("Attached Dropdown as first Element of Body");
  199. console.log(dropdownEle);
  200. // alert("window.flashvars present but '.tabs-menu > ul' is not");
  201. }
  202. }
  203.  
  204. function addBootstrapToPage() {
  205. let head = document.getElementsByTagName("head")[0];
  206. let bootstrapCssScriptEle = document.createElement("link");
  207. bootstrapCssScriptEle.setAttribute("href", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css");
  208. bootstrapCssScriptEle.setAttribute("rel", "stylesheet");
  209. bootstrapCssScriptEle.setAttribute("integrity", "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC");
  210. bootstrapCssScriptEle.setAttribute("crossorigin", "anonymous");
  211. head.insertAdjacentElement("beforeend", bootstrapCssScriptEle);
  212.  
  213. let body = document.getElementsByTagName("body")[0];
  214. let bootstrapJsScriptEle = document.createElement("script");
  215. bootstrapJsScriptEle.setAttribute("src", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js");
  216. bootstrapJsScriptEle.setAttribute("integrity", "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM");
  217. bootstrapJsScriptEle.setAttribute("crossorigin", "anonymous");
  218. body.insertAdjacentElement("beforeend", bootstrapJsScriptEle);
  219. }
  220.  
  221. function mainFunction() {
  222. console.log("Inside Main Function");
  223. if (window.flashvars) {
  224. console.log("Flashvars are available");
  225. let videos = getAllLicensedVideos(window.flashvars);
  226. let dropdownEle = createdDropdownEle();
  227. for (let video of videos) {
  228. let downloadEle = createDownloadEle(video.url, video.text);
  229. appendDownloadToDropdown(dropdownEle, downloadEle);
  230. }
  231. attachDropdownToPage(dropdownEle);
  232. } else {
  233. console.log("Flashvars are not available");
  234. }
  235. }
  236.  
  237. function docReady(userFunction) {
  238. console.log("Checking if Document is Ready");
  239. // if (document.readyState === "complete" || document.readyState === "interactive") {
  240. // console.log("Document is 'complete' or 'interactive'");
  241. // setTimeout(() => {
  242. // console.log("After timeout of 1 second over. Now running Main Function.")
  243. // userFunction();
  244. // }, 1);
  245. // } else {
  246. // console.log("Document is NOT yet 'complete' or 'interactive'");
  247. // console.log("Adding event listener for 'DOMContentLoaded'")
  248. // document.addEventListener("DOMContentLoaded", () => {
  249. // console.log("'DOMContentLoaded' event caught. Now running Main Function.")
  250. // userFunction()
  251. // });
  252. // }
  253. console.log("Adding event listener for 'DOMContentLoaded'")
  254. document.addEventListener("DOMContentLoaded", () => {
  255. console.log("'DOMContentLoaded' event caught. Now running Main Function.")
  256. userFunction()
  257. });
  258.  
  259. }
  260.  
  261. docReady(mainFunction);
  262.  
  263. })();