Sleazy Fork is available in English.

糖心Vlog

🔥不限次看站内所有付费视频,下载视频(日限),复制播放链接,屏蔽广告

  1. // ==UserScript==
  2. // @name 糖心Vlog
  3. // @version 1.0.2
  4. // @description 🔥不限次看站内所有付费视频,下载视频(日限),复制播放链接,屏蔽广告
  5. // @icon https://cdn.luckychajian.com/image/boy.jpeg
  6. // @namespace 糖心Vlog
  7. // @author lucky
  8. // @include */pages/hjsq*
  9. // @include *://tx*.*/*
  10. // @include *://*.tx*.*/*
  11. // @include *://blog.luckly-mjw.cn/*
  12. // @include *://tools.thatwind.com/*
  13. // @include *://tools.bugscaner.com/*
  14. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
  15. // @require https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.8/hls.min.js
  16. // @run-at document-start
  17. // @grant unsafeWindow
  18. // @grant GM_addStyle
  19. // @grant GM_getValue
  20. // @grant GM_setValue
  21. // @grant GM_getResourceText
  22. // @grant GM_xmlhttpRequest
  23. // @charset UTF-8
  24. // @antifeature payment
  25. // @license MIT
  26. // ==/UserScript==
  27.  
  28. function init($){
  29. 'use strict';
  30. if(unsafeWindow.wt_tangxin_script){
  31. return;
  32. }
  33. unsafeWindow.wt_tangxin_script = true;
  34.  
  35. if (location.href.includes('tools.bugscaner.com')) {
  36. util.findTargetElement('.input-group input').then(res => {
  37. const url = location.search.replace('?m3u8=', '').replace(/\s*/g, "")
  38. if (url && url.startsWith('http')) {
  39. $(res).val(url)
  40. }
  41. })
  42. return
  43. }
  44. if (location.href.includes('tools.thatwind.com')) {
  45. GM_addStyle(`.top-ad{display: none !important;}`)
  46. util.findTargetElement('.bx--text-input__field-outer-wrapper input', 10).then(res => {
  47. $(res).val(Date.now())
  48. res.dispatchEvent(new Event("input"))
  49. })
  50. return
  51. }
  52. if (location.href.includes('blog.luckly-mjw.cn')) {
  53. GM_addStyle(`
  54. #m-app a,.m-p-temp-url,.m-p-cross,.m-p-input-container div:nth-of-type(1){display: none !important;}
  55. .m-p-input-container{ display: block;}
  56. .m-p-input-container input{ width: 100%;font-size: 12px;margin-bottom: 5px;}
  57. .m-p-input-container div{ height: 45px;line-height: 45px;font-size: 15px;margin-top: 3px;}
  58. .m-p-stream{line-height: normal;font-size: 12px;}
  59. `)
  60. return
  61. }
  62. const loadScript = function(url) {
  63. const script = document.createElement('script');
  64. script.type = 'text/javascript';
  65. script.src = url;
  66. document.head.appendChild(script);
  67. }
  68. if(typeof Hls === "undefined"){
  69. loadScript('https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.8/hls.min.js')
  70. }
  71.  
  72. const checkLogin = function(){
  73. try{
  74. if (superVip._CONFIG_.user.login_date != new Date().setHours(0, 0, 0,0) || md5x(superVip._CONFIG_.user.ver, 'de').code != md5x(md5x(), 'de').code) {
  75. superVip._CONFIG_.user = ''
  76. GM_setValue('jsxl_user', '')
  77. util.logouted('登录已失效,请重新登录')
  78. $("#wt-my").click()
  79. return false
  80. }
  81. return true
  82. }catch(e){
  83. superVip._CONFIG_.user = ''
  84. GM_setValue('jsxl_user', '')
  85. util.logouted(e.message || '登录已失效,请重新登录')
  86. $("#wt-my").click()
  87. return false
  88. }
  89. }
  90.  
  91. const initPlayerUrl = async function(that, url, params){
  92. if (superVip._CONFIG_.user && superVip._CONFIG_.user.token) {
  93. if(!checkLogin()){
  94. return;
  95. }
  96. if(!params || params.length < 1){
  97. superVip._CONFIG_.videoUrl.requestErrMsg = '参数错误'
  98. util.showTips({ title: '参数错误'})
  99. return
  100. }
  101. try{
  102. let res = await util.asyncHttp(superVip._CONFIG_.apiBaseUrl + '/s' + (Math.floor(Math.random() * 3) + 1) + '00/tangxinSign?code=' + encodeURIComponent(params[0]) + '&version=' + superVip._CONFIG_.version)
  103. if(res.errMsg != 'success' || !res.responseText){
  104. throw new Error('asyncHttp request fail')
  105. }
  106. const result = JSON.parse(res.responseText)
  107. if(result.errCode != 0){
  108. throw new Error(result.errMsg)
  109. }
  110. params[0] = result.data
  111. if(result.newToken){
  112. if(result.newToken) superVip._CONFIG_.user.token = result.newToken;
  113. GM_setValue('jsxl_user', superVip._CONFIG_.user)
  114. }
  115. }catch(e){
  116. superVip._CONFIG_.videoUrl.requestErrMsg = e.message || '请求api失败'
  117. util.showTips({ title: e.message || '请求api失败'})
  118. }
  119. }
  120. }
  121.  
  122. const md5x = function(s, type) {
  123. try {
  124. if (!type) {
  125. const date = new Date().setHours(0, 0, 0, 0) + '';
  126. const day = new Date().getDate();
  127. const code = date.substring(4, 8) * new Date().getDate() + '';
  128. return ec.swaqbt(JSON.stringify({
  129. date: date,
  130. code: code,
  131. day: day
  132. }));
  133. } else {
  134. if(type == 'decode'){
  135. s = ec.cskuecede(s)
  136. }
  137. const token = JSON.parse(ec.sfweccat(s));
  138. if ((new Date(Number(token.date)).getTime() + 86400000) < Date.now()) {
  139. throw Error('md5x expire');
  140. }
  141. if (token.day != new Date(Number(token.date)).getDate()) {
  142. throw Error('md5x err');
  143. }
  144. const code = (new Date(Number(token.date)).setHours(0, 0, 0, 0) + '').substring(4, 8) * token.day;
  145. if (code != token.code) {
  146. throw Error('md5x err2');
  147. }
  148. return token;
  149. }
  150. } catch (e) {
  151. return '';
  152. }
  153. }
  154.  
  155. const ec = {
  156. b64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  157. b64re: /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/,
  158. swaqbt: (string, flag = true) => {
  159. string = String(string);
  160. var bitmap, a, b, c, result = "",
  161. i = 0,
  162. rest = string.length % 3;
  163. for (; i < string.length;) {
  164. if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string
  165. .charCodeAt(i++)) > 255) {
  166. return "Failed to execute swaqbt"
  167. }
  168. bitmap = (a << 16) | (b << 8) | c;
  169. result += ec.b64.charAt(bitmap >> 18 & 63) + ec.b64.charAt(bitmap >> 12 & 63) +
  170. ec.b64.charAt(bitmap >> 6 & 63) + ec.b64.charAt(bitmap & 63);
  171. }
  172. if (flag) return ec.swaqbt(rest ? result.slice(0, rest - 3) + "===".substring(rest) : result,
  173. false)
  174. else return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
  175. },
  176.  
  177. sfweccat: (string, flag = true) => {
  178. string = String(string).replace(/[\t\n\f\r ]+/g, "");
  179. if (!ec.b64re.test(string)) {
  180. return 'Failed to execute sfweccat'
  181. }
  182. string += "==".slice(2 - (string.length & 3));
  183. var bitmap, result = "",
  184. r1, r2, i = 0;
  185. for (; i < string.length;) {
  186. bitmap = ec.b64.indexOf(string.charAt(i++)) << 18 | ec.b64.indexOf(string.charAt(i++)) <<
  187. 12 |
  188. (r1 = ec.b64.indexOf(string.charAt(i++))) << 6 | (r2 = ec.b64.indexOf(string.charAt(
  189. i++)));
  190. result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) :
  191. r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) :
  192. String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
  193. }
  194. if (flag) return ec.sfweccat(result, false)
  195. else return result
  196. },
  197.  
  198. knxkbxen: (s) => {
  199. s = ec.swaqbt(encodeURIComponent(JSON.stringify(s)), false);
  200. const n = Math.round(Math.random() * (s.length > 11 ? 8 : 1) + 1);
  201. const l = s.split('');
  202. const f = l.filter(i => {
  203. i == '=';
  204. })
  205. for (let i = 0; i < l.length; i++) {
  206. if (i == n) l[i] = l[i] + 'JS';
  207. if (l[i] == '=') l[i] = '';
  208. }
  209. return ec.b64[Math.floor(Math.random() * 62)] + (l.join('') + n) + f.length;
  210. },
  211.  
  212. cskuecede: (s) => {
  213. if (s.startsWith('JSXL')) s = s.replace('JSXL', '');
  214. s = s.substring(ec.sfweccat('TVE9PQ=='));
  215. const n = s.substring(s.length - 2, s.length - 1);
  216. const d = s.substring(s.length - 1);
  217. const l = s.substring(0, s.length - 2).split('');
  218. for (let i = 0; i < l.length; i++) {
  219. if (i == (Number(n) + 1)) {
  220. l[i] = '';
  221. l[i + 1] = '';
  222. break;
  223. }
  224. }
  225. for (let i = 0; i < Number(d); i++) {
  226. l.plus('=')
  227. }
  228. return JSON.parse(decodeURIComponent((ec.sfweccat(l.join(''), false))))
  229. }
  230. }
  231.  
  232. const util = {
  233. initAppDate: (haveBox = true)=>{
  234. let roles = '';
  235. if(superVip._CONFIG_.user && superVip._CONFIG_.user.roles){
  236. if(superVip._CONFIG_.user.roles.length > 0 && superVip._CONFIG_.user.roles[0].e){
  237. superVip._CONFIG_.user.roles.sort((a,b) =>{
  238. return a.e < b.e? 1: -1
  239. })
  240. }
  241. superVip._CONFIG_.user.roles.forEach(item => {
  242. if(item.e){
  243. if(item.e > 2047980427789){
  244. item.vip_day = '永久'
  245. }else{
  246. const time = item.e - Date.now()
  247. if(time < 86400000 && time > 0){
  248. if(time > 3600000){
  249. item.vip_day = parseInt(time / 3600000) + '小时'
  250. }else{
  251. item.vip_day = parseInt(time / 60000) + '分钟'
  252. }
  253. }else if(time <= 0){
  254. item.vip_day = '已过期'
  255. item.expire = true
  256. }else{
  257. item.vip_day = parseInt(time / 86400000) + '天'
  258. const d = time % 86400000
  259. if(d > 3600000){
  260. item.vip_day += parseInt(d / 3600000) + '小时'
  261. }
  262. }
  263. }
  264. }
  265. roles += `
  266. <div class="info-box ${item.expire?'expire':''}" data-l="${item.l}">
  267. <div class="avatar-box">
  268. <img class="avatar" src="${superVip._CONFIG_.cdnBaseUrl + '/image/boy.jpeg'}"/>
  269. </div>
  270. <div class="desc">
  271. <div style="font-size: 11px;">${item.n}</div>
  272. </div>
  273. <div class="vip-day">
  274. <div style="font-size: 10px;"></div>
  275. <div style="font-size: 10px;"></div>
  276. </div>
  277. </div>
  278. `;
  279. })
  280. if(haveBox){
  281. $('#wt-set-box .user-box-container .user-box .apps-container').empty()
  282. $('#wt-set-box .user-box-container .user-box .apps-container').append(roles)
  283. }
  284. $('#wt-set-box .user-box-container .user-box .info-box').on('click', function(e) {
  285. const l = e.currentTarget.attributes['data-l']?.value
  286. if(l && l.startsWith('http')){
  287. window.location.href = l
  288. }
  289. })
  290. }
  291. return haveBox? '': roles
  292. },
  293. copyText: (text) => {
  294. if (navigator.clipboard && window.isSecureContext) {
  295. return navigator.clipboard.writeText(text);
  296. } else if (document.execCommand) {
  297. const textArea = document.createElement('textarea');
  298. textArea.style.position = 'fixed';
  299. textArea.style.top = textArea.style.left = '-100vh';
  300. textArea.style.opacity = '0';
  301. textArea.value = text;
  302. document.body.appendChild(textArea);
  303. textArea.focus();
  304. textArea.select();
  305. try {
  306. const success = document.execCommand('copy');
  307. return success ? Promise.resolve() : Promise.reject();
  308. } catch (err) {
  309. return Promise.reject(err);
  310. } finally {
  311. textArea.remove();
  312. }
  313. } else {
  314. return Promise.reject(new Error('Clipboard API not supported and execCommand not available.'));
  315. }
  316. },
  317.  
  318. logined: () => {
  319. $("#wt-my img").addClass('margin-left')
  320. $('#wt-my img').attr('src', superVip._CONFIG_.user.avatar)
  321. $('#wt-set-box .user-box-container .user-info').css('display', 'flex')
  322. $('#wt-set-box .user-box-container .user-info img').attr('src', superVip._CONFIG_.user.avatar)
  323. $('#wt-set-box .user-box-container .user-info .nickname').html(superVip._CONFIG_.user.nickname)
  324. $('#wt-set-box .user-box-container .user-info .username').html(superVip._CONFIG_.user.username)
  325. },
  326.  
  327. logouted: (msg) => {
  328. superVip._CONFIG_.user = '';
  329. $("#wt-my img").removeClass('margin-left')
  330. $('#wt-my img').attr('src',superVip._CONFIG_.cdnBaseUrl + '/image/app.png')
  331. $('#wt-set-box .user-box-container .user-info').css('display', 'none')
  332. GM_setValue('jsxl_user', '')
  333. if(msg){
  334. util.showTips({
  335. title: '请重新登录,errMsg:' + msg
  336. })
  337. }
  338. },
  339.  
  340. showAndHidTips: (name, op = 'set', val = true) => {
  341. let tips = GM_getValue('wt_tips', {})
  342. if (!tips) tips = {}
  343. if (op == 'set') {
  344. tips[name] = val
  345. GM_setValue('wt_tips', tips)
  346. if (val) $('.' + name).addClass('tips-yuan')
  347. else $('.' + name).removeClass('tips-yuan')
  348. return true
  349. } else {
  350. return tips[name] ? true : false
  351. }
  352. },
  353.  
  354. addLogin: () => {
  355. if ($('#wt-login-box').length > 0) {
  356. $("#wt-login-box input").val('');
  357. return;
  358. }
  359. $('body').append(`
  360. <div id="wt-login-mask"></div>
  361. <div id="wt-login-box">
  362. <div class="logo">
  363. <p>@${superVip._CONFIG_.homeUrl}</p>
  364. <p>v ${superVip._CONFIG_.version}</p>
  365. </div>
  366. <div class="close"></div>
  367. <div class="title">账号登录</div>
  368. <div class="input-box">
  369. <input type="text" placeholder="请输入账号" maxLength="15"/>
  370. </div>
  371. <div class="input-box" style="margin-top:10px;">
  372. <input type="text" placeholder="请输入密码" maxLength="15"/>
  373. </div>
  374. <div class="j-login-btn">
  375. <button >登录</button>
  376. </div>
  377. <div class="to-index" style="display: flex;justify-content: space-between;color: #00bcd4; height: 40px;line-height: 40px;font-size: 11px;font-weight: 500;">
  378. <div class="wt-register">注册账号</div>
  379. <div class="wt-index">去发电获取权限?</div>
  380. </div>
  381. </div>
  382. `)
  383. GM_addStyle(`
  384. #wt-login-mask{ display: none;position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 11000;background-color: #0000004d;}
  385. #wt-login-box{position: fixed;margin-top: 3%;top: 50%;left: 50%;transform: translate(-50%,-50%) scale(0);overflow: hidden;background-color: white;padding: 30px;padding-bottom: 0;border-radius: 10px;z-index: 11010;}
  386. #wt-login-box::before{display:none; content:'';position: absolute;width: 250px;height: 250px;border-radius: 200px;background-color: #00bcd4;z-index: -1;opacity: 0.7;bottom: 110px;right: 100px;}
  387. #wt-login-box::after{display:none;content:'';position: absolute;width: 250px;height: 250px;border-radius: 200px;background-color: #2196F3;z-index: -1;opacity: 0.7;top: 115px;right: -112px;}
  388. #wt-login-box .close{position: absolute;right: 0px;top: 0px;width: 40px;height: 40px;}
  389. #wt-login-box .close::before,#wt-login-box .close::after{position: absolute;left: 50%;top: 50%;content: '';width: 16px;height: 2px;border-radius: 1px;background-color: #222;transform: translate(-50%,-50%) rotate(45deg);}
  390. #wt-login-box .close::after,#wt-set-box .close::after{transform: translate(-50%,-50%) rotate(-45deg);}
  391. #wt-login-box .input-box{display: flex;background-color: #f5f5f5;width: 160px;height: 35px;border-radius: 30px;overflow: hidden;font-size: 12px;}
  392. #wt-login-box .input-box input{width: 100%;height: 100%;padding-left: 15px;box-sizing: border-box;outline: none;border: none;background-color: #f5f5f5;font-size: 11px;color: black;letter-spacing: 1px;}
  393. #wt-login-box input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none !important; }
  394. #wt-login-box .title{font-weight: 600;font-size: 16px;color: #3a3a3a;text-align: center;margin-bottom: 20px;}
  395. #wt-login-box .j-login-btn{width: 100px;padding: 2px;height: 40px;font-size: 12px;margin: 15px auto;}
  396. #wt-login-box .j-login-btn button{width: 100%;height: 100%;border-radius: 30px;border: none;color: white;transition: all 0.3s ease;background-color: #00bcd4;}
  397. #wt-login-box .logo{position: absolute;top: 5%;left: 1%; color: #dbdbdb; font-size: 11px;transform: rotate(-15deg);text-align: center;z-index: -10;}
  398. `)
  399. $("#wt-login-mask").on("click", () => {
  400. $('#wt-login-mask').css('display', 'none')
  401. $("#wt-login-box").removeClass('show-set-box')
  402. $("#wt-login-box").addClass('hid-set-box')
  403. })
  404. $("#wt-login-box .close").on("click", () => {
  405. $('#wt-login-mask').css('display', 'none')
  406. $("#wt-login-box").removeClass('show-set-box')
  407. $("#wt-login-box").addClass('hid-set-box')
  408. })
  409. $("#wt-login-box .to-index .wt-register").on("click", () => {
  410. window.open(superVip._CONFIG_.homeUrl + '/#/pages/login/login')
  411. })
  412. $("#wt-login-box .to-index .wt-index").on("click", () => {
  413. window.open(superVip._CONFIG_.homeUrl +'/#/')
  414. })
  415. $("#wt-login-box .j-login-btn button").on("click", async () => {
  416. try{
  417. $('#wt-loading-box').css('display', 'block')
  418. await util.sleep(300);
  419. $("#wt-login-box .j-login-btn button").addClass('btn-anima')
  420. setTimeout(() => {
  421. $("#wt-login-box .j-login-btn button").removeClass('btn-anima')
  422. }, 500)
  423. const username = $("#wt-login-box input")[0].value;
  424. let pwd = $("#wt-login-box input")[1].value;
  425. if(!username || username.length < 5 || username.length > 15 || !/^[A-Za-z0-9]+$/.test(username)){
  426. setTimeout(() => {
  427. $('#wt-loading-box').css('display', 'none')
  428. util.showTips({
  429. title: '账号错误,请使用' + superVip._CONFIG_.homeUrl + '网站注册的账号密码登入插件</br>' + superVip._CONFIG_.guide
  430. })
  431. }, 2000)
  432. return
  433. }
  434. if(!pwd || pwd.length < 5 || pwd.length > 15){
  435. setTimeout(() => {
  436. $('#wt-loading-box').css('display', 'none')
  437. util.showTips({
  438. title: '密码错误,请使用' + superVip._CONFIG_.homeUrl + '网站注册的账号密码登入插件</br>' + superVip._CONFIG_.guide
  439. })
  440. }, 2000)
  441. return
  442. }
  443. $.ajax({
  444. url: superVip._CONFIG_.apiBaseUrl + '/l' + (Math.floor(Math.random() * 2) + 1) + '00/ls',
  445. method: "POST",
  446. timeout: 12000,
  447. data: {
  448. username: username,
  449. password: pwd,
  450. ap: 'HJtFoJUU3JUIzJTk2JUU1JUJGJTgzKYioG',
  451. version: superVip._CONFIG_.version
  452. },
  453. dataType: 'json',
  454. success: function(response) {
  455. if (response.errCode != 0) {
  456. $('#wt-loading-box').css('display', 'none');
  457. util.showTips({
  458. title: response.errMsg + ',' + superVip._CONFIG_.guide
  459. })
  460. } else {
  461. response.data = ec.cskuecede(response.data)
  462. const res = {
  463. avatar: response.data.user.avatar,
  464. username: response.data.user.username,
  465. nickname: response.data.user.nickname,
  466. login_date: new Date().setHours(0,0,0,0),
  467. token: response.data.token,
  468. role: response.data.user.current_role,
  469. roles: response.data.user.roles,
  470. downloadTips: response.data.utilObj.downloadTips
  471. }
  472. superVip._CONFIG_.user = res
  473. superVip._CONFIG_.user.ver = md5x(superVip)
  474. util.logined()
  475. GM_setValue('jsxl_user', res)
  476. GM_setValue('jsxl_login_code', JSON.stringify({u: username, p: pwd}))
  477. if(response.data?.utilObj?.notify){
  478. const historyNotify = GM_getValue('notify')
  479. if (!historyNotify || historyNotify != response.data.utilObj.notify) {
  480. GM_setValue('notifyShow', true);
  481. util.showAndHidTips('wt_my_notify')
  482. GM_setValue('notify', response.data.utilObj.notify)
  483. }
  484. }
  485. $('#wt-loading-box').css('display', 'none')
  486. $('#wt-login-mask').css('display','none')
  487. $("#wt-login-box").removeClass('show-set-box')
  488. $("#wt-login-box").addClass('hid-set-box')
  489. util.showTips({
  490. title: response.errMsg,
  491. success: (e) => {
  492. window.location.reload()
  493. }
  494. })
  495. }
  496. },
  497. error: function(e) {
  498. $('#wt-loading-box').css('display', 'none')
  499. console.log(e)
  500. util.showTips({
  501. title: '网络延迟登录失败,请关掉梯子(vpn)再试或梯子尝试换港台地区节点再试,一般关掉梯子多试几次登录就行,' + superVip._CONFIG_.guide
  502. })
  503. }
  504. });
  505. }catch(e){
  506. $('#wt-loading-box').css('display', 'block')
  507. alert(e)
  508. util.showTips({
  509. title: '网络延迟登录失2,请关掉梯子(vpn)再试或梯子尝试换港台地区节点再试,一般关掉梯子多试几次登录就行,' + superVip._CONFIG_.guide
  510. })
  511. }
  512. })
  513. },
  514.  
  515. asyncHttp: async (url, timeout = 6000, isHeader = true) => {
  516. return new Promise((resolve, reject) => {
  517. var request = new XMLHttpRequest();
  518. request.open('GET', url, true);
  519. if(isHeader){
  520. request.setRequestHeader('luckyToken', superVip._CONFIG_.user.token);
  521. }
  522. request.timeout = timeout;
  523. request.onload = function() {
  524. if (request.readyState == 4) {
  525. if (request.status === 200) {
  526. resolve({
  527. errMsg: 'success',
  528. responseText: request.responseText
  529. });
  530. } else {
  531. resolve({
  532. errMsg: 'err1',
  533. responseText: ''
  534. });
  535. }
  536. }
  537. };
  538. request.onerror = function() {
  539. resolve({
  540. errMsg: 'err2',
  541. responseText: ''
  542. });
  543. };
  544. request.ontimeout = function() {
  545. resolve({
  546. errMsg: 'timeout',
  547. responseText: ''
  548. });
  549. };
  550. request.send();
  551. });
  552. },
  553.  
  554. findTargetElement: (targetContainer, maxTryTime = 30) => {
  555. const body = window.document;
  556. let tabContainer;
  557. let tryTime = 0;
  558. let startTimestamp;
  559. return new Promise((resolve, reject) => {
  560. function tryFindElement(timestamp) {
  561. if (!startTimestamp) {
  562. startTimestamp = timestamp;
  563. }
  564. const elapsedTime = timestamp - startTimestamp;
  565. if (elapsedTime >= 500) {
  566. console.log("find element:" + targetContainer + ",this" + tryTime + "num")
  567. tabContainer = body.querySelector(targetContainer)
  568. if (tabContainer) {
  569. resolve(tabContainer)
  570. } else if (++tryTime === maxTryTime) {
  571. reject()
  572. } else {
  573. startTimestamp = timestamp
  574. }
  575. }
  576. if (!tabContainer && tryTime < maxTryTime) {
  577. requestAnimationFrame(tryFindElement);
  578. }
  579. }
  580. requestAnimationFrame(tryFindElement);
  581. });
  582. },
  583. findTargetElementByVideoSrc: (maxTryTime = 60) => {
  584. const body = window.document;
  585. let videoSrc;
  586. let tryTime = 0;
  587. let startTimestamp;
  588. return new Promise((resolve, reject) => {
  589. function tryFindElement(timestamp) {
  590. if (!startTimestamp) {
  591. startTimestamp = timestamp;
  592. }
  593. const elapsedTime = timestamp - startTimestamp;
  594. if (elapsedTime >= 500) {
  595. const video = document.querySelector('video')
  596. if(video && video.src) videoSrc = video.src
  597. if (videoSrc) {
  598. resolve(videoSrc)
  599. } else if (++tryTime === maxTryTime) {
  600. reject()
  601. } else {
  602. startTimestamp = timestamp
  603. }
  604. }
  605. if (!videoSrc && tryTime < maxTryTime) {
  606. requestAnimationFrame(tryFindElement);
  607. }
  608. }
  609. requestAnimationFrame(tryFindElement);
  610. });
  611. },
  612.  
  613. sleep: (time) => {
  614. return new Promise((res, rej) => {
  615. setTimeout(() => {
  616. res()
  617. }, time)
  618. })
  619. },
  620.  
  621. showTips: (item = {}) => {
  622. $('#wt-maxindex-mask').css('display', 'block');
  623. $("#wt-tips-box").removeClass('hid-set-box');
  624. $("#wt-tips-box").addClass('show-set-box');
  625. $('#wt-tips-box .btn-box').empty()
  626. $('#wt-tips-box .btn-box').append(`
  627. <button class='cancel'>取消</button>
  628. <button class='submit'>确定</button>
  629. `)
  630. if (item.title) $('#wt-tips-box .content').html(item.title);
  631. if (item.doubt) $('#wt-tips-box .btn-box .cancel').css('display', 'block');
  632. if (item.confirm) $('#wt-tips-box .btn-box .submit').html(item.confirm);
  633. if (item.hidConfirm) {
  634. $('#wt-tips-box .submit').css('display', 'none');
  635. } else {
  636. $('#wt-tips-box .submit').css('display', 'block');
  637. }
  638. $('#wt-tips-box .btn-box .submit').on('click', () => {
  639. $('#wt-maxindex-mask').css('display', 'none');
  640. $("#wt-tips-box").removeClass('show-set-box');
  641. $("#wt-tips-box").addClass('hid-set-box');
  642. if (item.success) item.success(true);
  643. })
  644. $('#wt-tips-box .btn-box .cancel').on('click', () => {
  645. $('#wt-maxindex-mask').css('display', 'none');
  646. $("#wt-tips-box").removeClass('show-set-box');
  647. $("#wt-tips-box").addClass('hid-set-box');
  648. if (item.success) item.success(false);
  649. })
  650. },
  651.  
  652. showDownLoadWindow: (show = true, msg) => {
  653. if (!show) {
  654. $('#wt-mask-box').css('display', 'none');
  655. $("#wt-download-box").removeClass('show-set-box');
  656. $("#wt-download-box").addClass('hid-set-box');
  657. return
  658. }
  659. $('#wt-mask-box').css('display', 'block');
  660. const downloadUrl = superVip._CONFIG_.videoUrl.downloadUrlSign;
  661. if (!document.querySelector('#wt-download-box')) {
  662. let items = `<li class="item" data-url="${downloadUrl}" data-type="copy" style="background-color: #00bcd4;color:#e0e0e0;">复制链接</li>`
  663. superVip._CONFIG_.downUtils.forEach((item, index) => {
  664. items += `
  665. <li class="item" data-url="${item.url + (item.isAppend?'':'?m3u8=') + downloadUrl}">${item.title}</li>
  666. `
  667. })
  668. $('body').append(`
  669. <div id="wt-download-box">
  670. <div class="close"></div>
  671. <div class="tips">* ${msg?msg + '(刷新页面或打开其它帖子链接将丢失,链接有效期60分钟)': '视频链接有效期60分钟,请尽快使用。'}</div>
  672. <ul>${items}</ul>
  673. </div>
  674. `)
  675. } else {
  676. $('#wt-download-box').empty()
  677. let items = `<li class="item" data-url="${downloadUrl}" data-type="copy" style="background-color: #00bcd4;color:#e0e0e0;">复制链接</li>`
  678. superVip._CONFIG_.downUtils.forEach((item, index) => {
  679. items += `
  680. <li class="item" data-url="${item.url + (item.isAppend?'':'?m3u8=') + downloadUrl}">${item.title}</li>
  681. `
  682. })
  683. $('#wt-download-box').append(`<view class="close"></view><div class="tips">* ${msg?msg + '(刷新页面或打开其它帖子链接将丢失,链接有效期60分钟)': '刷新页面或打开其它帖子链接将丢失,链接有效期60分钟'}</div><ul>${items}</ul>`)
  684. }
  685. if(superVip._CONFIG_.isMobile && superVip._CONFIG_.isMobile[0] == 'iPhone'){
  686. $('#wt-download-box ul')[0].innerHTML += `<li class="item" data-open="1" data-url="https://apps.apple.com/cn/app/m3u8-mpjex/id6449724938">苹果视频下载软件</li>`
  687. }
  688. if(superVip._CONFIG_.isMobile && superVip._CONFIG_.isMobile[0] == 'Android'){
  689. $('#wt-download-box ul')[0].innerHTML += `<li class="item" data-open="1" data-url="https://wwjf.lanzoul.com/isifQ18id4fa">安卓视频下载软件(密3y3a)</li>`
  690. }
  691.  
  692. $("#wt-download-box").removeClass('hid-set-box');
  693. $("#wt-download-box").addClass('show-set-box');
  694. $("#wt-download-box .item").on('click', function(e) {
  695. const url = e.target.dataset.url
  696. if(e.target.dataset.type == 'copy'){
  697. if(url){
  698. util.copyText(url).then(res => {
  699. util.showTips({
  700. title: '视频地址复制成功,请尽快使用'
  701. })
  702. }).catch(err =>{
  703. util.showTips({
  704. title: '复制失败,请通过下面在线下载再复制输入框内的视频地址'
  705. })
  706. })
  707. }else{
  708. util.showTips({
  709. title: '抱歉,未检测到视频'
  710. })
  711. }
  712. return;
  713. }
  714. if (!url || !url.includes('.m3u8') && e.target.dataset.open != 1) {
  715. util.showTips({
  716. title: '抱歉,未检测到视频,还继续前往吗?',
  717. doubt: true,
  718. success: (res) => {
  719. if (res) {
  720. window.open(url)
  721. }
  722. }
  723. })
  724. } else {
  725. window.open(url);
  726. }
  727. })
  728. $("#wt-download-box .close").on('click', function() {
  729. $("#wt-mask-box").click()
  730. })
  731. },
  732.  
  733. showNotify: (item = {}) => {
  734. $("#wt-notify-box").removeClass('hid-notify-box')
  735. $("#wt-notify-box").addClass('show-notify-box')
  736. let version = superVip._CONFIG_.version
  737. const v = /当前插件版本 (\d\.\d\.\d\.{0,1}\d{0,2})/.exec(item.title)
  738. if (v) item.title = item.title.replace(v[1], version)
  739. if (item.title) $('#wt-notify-box .content').html(item.title + (version ?
  740. '<div style="text-align: right;color: #ccc;font-size: 10px;margin-top: 10px;">v ' +
  741. version + '</div>' : ''))
  742. superVip._CONFIG_.showNotify = true
  743. $('#wt-notify-box a').on('click', (e) => {
  744. e.stopPropagation()
  745. })
  746. $('#wt-notify-box').on('click', () => {
  747. $("#wt-notify-box").removeClass('show-notify-box')
  748. $("#wt-notify-box").addClass('hid-notify-box')
  749. superVip._CONFIG_.showNotify = false
  750. if (item.success) item.success(true)
  751. })
  752. }
  753. }
  754. const superVip = (function() {
  755. const _CONFIG_ = {
  756. homeUrl: 'https://vip.luckychajian.cn',
  757. apiBaseUrl: 'https://api.luckychajian.com',
  758. cdnBaseUrl: 'https://cdn.luckychajian.com',
  759. guide: '如长时间无法登录请前往以下网站查看公告或尝试联系客服</br></br>Lucky公告网址</br></br><a href="http://luckychajian.3vhost.work?pwd=lucky">luckychajian.3vhost.work?pwd=lucky</a>',
  760. isMobile: navigator.userAgent.match(
  761. /(Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini)/i),
  762. vipBoxId: 'wt-vip-jx-box' + Math.ceil(Math.random() * 100000000),
  763. version: '1.0.2',
  764. videoUrl: {},
  765. downUtils: [
  766. {
  767. title: '在线下载1(适合电脑)',
  768. url: 'http://tools.bugscaner.com/m3u8.html',
  769. isAppend: false
  770. },
  771. {
  772. title: '在线下载2(适合电脑)',
  773. url: 'https://tools.thatwind.com/tool/m3u8downloader#m3u8=',
  774. isAppend: true
  775. },
  776. {
  777. title: '在线下载3(适合电脑)',
  778. url: 'https://blog.luckly-mjw.cn/tool-show/m3u8-downloader/index.html?source=',
  779. isAppend: true
  780. }
  781. ]
  782. }
  783. class BaseConsumer {
  784. constructor(body) {
  785. this.parse = () => {
  786. this.interceptHttp()
  787. util.findTargetElement('body').then(container => {
  788. this.generateElement(container).then(
  789. container => this.bindEvent(container))
  790. })
  791. }
  792. }
  793.  
  794. interceptHttp() {
  795. if(location.href.includes('/pages/hjsq')){
  796. const interceptMedia = (element) => {
  797. if(element.src && element.src.match(/\.mp4$/)){
  798. if(!superVip._CONFIG_.videoUrl.playerUrl || superVip._CONFIG_.videoUrl.playerUrl != element.src){
  799. superVip._CONFIG_.videoUrl.downloadUrlSign = element.src
  800. superVip._CONFIG_.videoUrl.playerUrl = element.src
  801. superVip._CONFIG_.videoUrl.type = 0
  802. superVip._CONFIG_.videoUrl.playerType = 'mp4'
  803. util.showAndHidTips('wt_player_haijiao');
  804. }
  805. }
  806. };
  807. setInterval(()=>{
  808. document.querySelectorAll('#myVideo source').forEach(interceptMedia);
  809. },700)
  810. }
  811. const originOpen = XMLHttpRequest.prototype.open;
  812. XMLHttpRequest.prototype.open = function(method, url) {
  813. if(url.endsWith('movie/detail') || url.endsWith('album/search') || url.endsWith('album/photoList') || url.endsWith('post/search')){
  814. this.requestUrl = url
  815. _CONFIG_.videoUrl = {}
  816. util.showAndHidTips('wt_player_haijiao', 'set', false);
  817. if (_CONFIG_.isMobile && _CONFIG_.isMobile[0] == 'iPhone') {
  818. const xhr = this;
  819. const getter = Object.getOwnPropertyDescriptor(
  820. XMLHttpRequest.prototype,
  821. "response"
  822. ).get;
  823. Object.defineProperty(xhr, "responseText", {
  824. get: () => {
  825. let result = getter.call(xhr);
  826. try {
  827. _CONFIG_.videoUrl.aes = result
  828. return result;
  829. } catch (e) {
  830. console.log('发生异常! 解析失败!');;
  831. return result;
  832. }
  833. },
  834. });
  835. util.findTargetElementByVideoSrc().then(res =>{
  836. if(!_CONFIG_.videoUrl.playerUrl || !_CONFIG_.videoUrl.playerUrl.startsWith('http')){
  837. _CONFIG_.videoUrl.playerUrl = res
  838. util.showAndHidTips('wt_player_haijiao');
  839. }
  840. })
  841. }
  842. }
  843. if(url.endsWith('.m3u8')){
  844. if(!superVip._CONFIG_.videoUrl.requestErrMsg){
  845. superVip._CONFIG_.videoUrl = {
  846. playerUrl: url,
  847. downloadUrl: url
  848. }
  849. util.showAndHidTips('wt_player_haijiao');
  850. }
  851. }
  852. if(url.endsWith('movie/block')){
  853. util.findTargetElement('.van-dialog', 20).then(res =>{
  854. if(res.__vue__){
  855. if(res.__vue__.touchMove){
  856. res.__vue__.touchMove = null
  857. }else{
  858. res.__vue__.$parent.touchMove = null
  859. }
  860. }
  861. })
  862. }
  863. return originOpen.call(this, method, url);
  864. }
  865. const oldSend = XMLHttpRequest.prototype.send;
  866. XMLHttpRequest.prototype.send = async function (...args) {
  867. if(this.requestUrl){
  868. await initPlayerUrl(this, this.requestUrl, args)
  869. }
  870. return oldSend.call(this, ...args)
  871. };
  872. }
  873.  
  874. generateElement(container) {
  875. GM_addStyle(`
  876. @font-face {
  877. font-family: 'iconfont'; /* Project id 4784633 */
  878. src: url('//at.alicdn.com/t/c/font_4784633_m832t9irm9f.woff2?t=1734418085047') format('woff2'),
  879. url('//at.alicdn.com/t/c/font_4784633_m832t9irm9f.woff?t=1734418085047') format('woff'),
  880. url('//at.alicdn.com/t/c/font_4784633_m832t9irm9f.ttf?t=1734418085047') format('truetype');
  881. }
  882. .iconfont {
  883. font-family: "iconfont" !important;
  884. font-size: 16px;
  885. font-style: normal;
  886. font-weight: 400 !important;
  887. -webkit-font-smoothing: antialiased;
  888. -moz-osx-font-smoothing: grayscale;
  889. }
  890. @keyframes showSetBox {
  891. 0% {
  892. transform: translate(-50%,-50%) scale(0);
  893. }
  894. 80% {
  895. transform: translate(-50%,-50%) scale(1.1);
  896. }
  897. 100% {
  898. transform: translate(-50%,-50%) scale(1);
  899. }
  900. }
  901. @keyframes hidSetBox {
  902. 0% {
  903. transform: translate(-50%,-50%) scale(1);
  904. }
  905. 80% {
  906. transform: translate(-50%,-50%) scale(1.1);
  907. }
  908. 100% {
  909. transform: translate(-50%,-50%) scale(0);
  910. }
  911. }
  912. @keyframes colorAnima {
  913. 0%{
  914. background-color: #f0f0f0;
  915. color: #5d5d5d;
  916. transform: scale(1);
  917. }
  918. 50%{
  919. transform: scale(1.1);
  920. }
  921. 100%{
  922. background-color: #ff6022;;
  923. color: white;
  924. transform: scale(1);
  925. }
  926. }
  927. @keyframes showNotifyBox {
  928. 0% {
  929. transform: translate(-50%,-100%) scale(0);
  930. }
  931. 80% {
  932. transform: translate(-50%,35px) scale(1.1);
  933. }
  934. 100% {
  935. transform: translate(-50%,35px) scale(1);
  936. }
  937. }
  938. @keyframes hidNotifyBox {
  939. 0% {
  940. transform: translate(-50%,35px) scale(1.1);
  941. }
  942. 80% {
  943. transform: translate(-50%,35px) scale(1);
  944. }
  945. 100% {
  946. transform: translate(-50%,-100%) scale(0);
  947. }
  948. }
  949. @keyframes scale {
  950. 0%{
  951. transform: scale(1);
  952. }
  953. 50%{
  954. transform: scale(1.1);
  955. }
  956. 100%{
  957. transform: scale(1);
  958. }
  959. }
  960. @keyframes circletokLeft {
  961. 0%,100% {
  962. left: 0px;
  963. width: 12px;
  964. height: 12px;
  965. z-index: 0;
  966. }
  967. 25% {
  968. height: 15px;
  969. width: 15px;
  970. z-index: 1;
  971. left: 8px;
  972. transform: scale(1)
  973. }
  974. 50% {
  975. width: 12px;
  976. height: 12px;
  977. left: 22px;
  978. }
  979. 75% {
  980. width: 10px;
  981. height: 10px;
  982. left: 8px;
  983. transform: scale(1)
  984. }
  985. }
  986. @keyframes circletokRight {
  987. 0%,100% {
  988. top: 3px;
  989. left: 22px;
  990. width: 12px;
  991. height: 12px;
  992. z-index: 0
  993. }
  994. 25% {
  995. height: 15px;
  996. width: 15px;
  997. z-index: 1;
  998. left: 24px;
  999. transform: scale(1)
  1000. }
  1001. 50% {
  1002. width: 12px;
  1003. height: 12px;
  1004. left: 0px;
  1005. }
  1006. 75% {
  1007. width: 10px;
  1008. height: 10px;
  1009. left: 24px;
  1010. transform: scale(1)
  1011. }
  1012. }
  1013. .color-anima{
  1014. animation: colorAnima .3s ease 1 forwards;
  1015. }
  1016. .btn-anima{
  1017. animation: scale .3s ease 1 forwards;
  1018. }
  1019.  
  1020. html .van-overflow-hidden, body{ overflow: auto !important;}
  1021. .bg-page .main.blur{ filter: blur(0px) !important;}
  1022. .ad-apps,.new,.van-dialog,.van-overlay,.my-swipe,.drag-area,.control,.android-ad{display:none !important;z-index:-99999 !important;opacity: 0!important;width :0 !important;}
  1023. #wt-resources-box{position: relative; border: 1px dashed #ec8181;background: #fff4f4;}
  1024. .sell-btn{border:none !important;margin-top:20px;}
  1025. .margin-left{ margin-left: 0 !important;}
  1026. .show-set-box{ animation: showSetBox 0.3s ease 1 forwards;}
  1027. .hid-set-box{ animation: hidSetBox 0.3s ease 1 forwards;}
  1028. .show-notify-box{ animation: showNotifyBox 0.3s ease 1 forwards;}
  1029. .hid-notify-box{ animation: hidNotifyBox 0.3s ease 1 forwards;}
  1030. #wt-loading-box{display: none;position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 100000;background-color: #0000004d;}
  1031. #wt-loading-box .loading{position: absolute;width: 35px;height: 17px;top: 50%;left: 50%;transform: translate(-50%,-50%);}
  1032. #wt-loading-box .loading::before,
  1033. #wt-loading-box .loading::after{position: absolute;content: "";top: 3px;background-color: #ffe60f;width: 14px;height: 14px;border-radius: 20px;mix-blend-mode: multiply;animation: circletokLeft 1.2s linear infinite;}
  1034. #wt-loading-box .loading::after{animation: circletokRight 1.2s linear infinite;background-color: #4de8f4;}
  1035. #wt-left-show{ position: fixed;left: 20px;top: 50%;transform: translateY(-50%);z-index: 99999;transition: all 0.3s ease;}
  1036. #wt-left-show i {color: #5f5b5b;font-size: 27px;color: #e91e63;text-shadow: #e91e63 2px 2px 12px;font-size: 25px;margin-left: -1px;}
  1037. #wt-${_CONFIG_.vipBoxId}{
  1038. position: fixed;
  1039. top: 50%;
  1040. transform: translate(0, -50%);
  1041. right: 10px;
  1042. width: 46px;
  1043. border-radius: 30px;
  1044. background: rgb(64 64 64 / 81%);
  1045. box-shadow: 1px 1px 8px 1px rgb(98 99 99 / 34%);
  1046. z-index: 99999;
  1047. transition: all 0.3s ease;
  1048. }
  1049. #wt-${_CONFIG_.vipBoxId} .item{position: relative;height: 60px;}
  1050. .tips-yuan::before{ position: absolute; content: '';top: 12px; right: 6px;width: 8px;height: 8px; border-radius: 10px; background-color: #5ef464;}
  1051. .tips-yuan-err::before{ position: absolute; content: '';top: 12px; right: 6px;width: 8px;height: 8px; border-radius: 10px; background-color: #f83f32;}
  1052. #wt-${_CONFIG_.vipBoxId} .item .iconfont,#wt-${_CONFIG_.vipBoxId} .item img{position: absolute;top:50%;left:50%;transform: translate(-50%,-50%)}
  1053. #wt-login-box .close,#wt-set-box .close,#wt-notify-box .close{position: absolute;right: 0px;top: 0px;width: 40px;height: 40px;z-index: 100;}
  1054. #wt-login-box .close::before,#wt-login-box .close::after,#wt-set-box .close::before,#wt-set-box .close::after,#wt-notify-box .close::before,#wt-notify-box .close::after{position: absolute;left: 50%;top: 50%;content: '';width: 12px;height: 2px;border-radius: 1px;background-color: #6a6a6a;transform: translate(-50%,-50%) rotate(45deg);visibility: visible;}
  1055. #wt-login-box .close::after,#wt-set-box .close::after,#wt-notify-box .close::after{transform: translate(-50%,-50%) rotate(-45deg);}
  1056. #wt-${_CONFIG_.vipBoxId} .absolute-center{ position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}
  1057. #wt-${_CONFIG_.vipBoxId} #wt-my img{ width: 28px;height: 28px;border-radius: 30px;margin-left: 2px;transtion: all 0.3s ease;}
  1058. #wt-${_CONFIG_.vipBoxId} #wt-my-set i {color: white;font-size: 24px;text-shadow: 2px 2px 14px #ffffff;font-family: 'iconfont';}
  1059. #wt-${_CONFIG_.vipBoxId} #wt-my-down i {color: white;font-size: 24px;text-shadow: 2px 2px 15px #ffffff;font-family: 'iconfont';}
  1060. #wt-${_CONFIG_.vipBoxId} #wt-my-notify i {color: white;font-size: 27px;padding: 10px 1px;text-shadow: 2px 2px 12px #ffffff;}
  1061. #wt-${_CONFIG_.vipBoxId} #wt-hid-box i {color: white;font-size: 21px;text-shadow: 2px 2px 12px #ffffff;margin-left: -1px;}
  1062. .wt-player-btn-box .player-btn{ position:absolute;top:42%;left:50%;transform:translate(-50%,-50%);width: 20%}
  1063. .wt-player-btn-box .tips{ position: absolute;bottom: 20px;left:50%;transform: translateX(-50%);color: #FFC107;width: 80%;text-align: center;font-size: 15px;font-weight: 500;}
  1064. #wt-mask-box,#wt-maxindex-mask{display:none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; background-color: #00000057;}
  1065. #wt-maxindex-mask{z-index: 90000;display:none;}
  1066. #wt-set-box{ position:fixed; top:50%;left:50%; transform: translate(-50%,-50%) scale(0);overflow: hidden;background-color: white;box-shadow: 0 15px 30px rgba(0, 0, 0, .15);border-radius: 12px;z-index: 10010;padding: 10px 15px;padding-right: 5px;box-sizing: border-box;width: 300px;}
  1067. #wt-set-box::before{display:none; content:'';position: absolute;width: 150px;height: 150px;border-radius: 100px;background-color: #2196F3;z-index: -1;opacity: 0.7;bottom: 0;transform: translate(-40%,58%);}
  1068. #wt-set-box::after{display:none;content:'';position: absolute;width: 150px;height: 150px;border-radius: 100px;background-color: #FFC107;z-index: -1;opacity: 0.7;top: 0;right: 0;transform: translate(22%,-53%);}
  1069. #wt-set-box .selected-box .selected{ background-color: #ff6022;color: white;}
  1070. #wt-set-box .user-box-container{display: none;letter-spacing: 1px;}
  1071. #wt-set-box .info-box{display:flex;height: 50px;align-items: center;}
  1072. #wt-set-box .expire{ opacity: 0.35;}
  1073. #wt-set-box .info-box .avatar-box{position: relative;height: 36px;width: 36px;background-color: white;border-radius: 7px;box-shadow: rgb(166 166 166 / 20%) 0px 1px 20px 0px;}
  1074. #wt-set-box .user-box .title{text-align: center;font-weight: 600;font-size: 16px;color: #3a3a3a;}
  1075. #wt-set-box .user-box .desc{display: flex;flex-direction: column;height: 36px;justify-content: space-around;flex: 8;font-size: 10px;color: #5d5d5d;margin-left: 10px;}
  1076. #wt-set-box .user-box .vip-day{margin-right: 10px;text-align: center;color: #8a8a8a;font-size: 11px;}
  1077. #wt-set-box .user-box .avatar{position: absolute; width: 36px;height:36px;border-radius: 30px;border-radius: 7px;font-size: 0;}
  1078. #wt-set-box .user-box .user-info{ position: relative; left: -5px; display: flex;align-items: center;margin-bottom: 4px;background-color: #f1f1f1;border-radius: 11px;padding: 7px;}
  1079. #wt-set-box .user-box .user-info .info{margin-left: 10px;width: 180px;}
  1080. #wt-set-box .user-box .user-info .info .nickname{color: #676767;font-size: 12px;letter-spacing: 1px;}
  1081. #wt-set-box .user-box .user-info .info .username{color: #b9b9b9;font-size: 10px;margin-top: 2px;}
  1082. #wt-set-box .user-box .user-info .logout{position: absolute;font-size: 0;right: 12px;}
  1083. #wt-set-box .user-box .user-info .logout button{padding: 0 10px;height: 28px;background-color: #615b5b;border-radius: 30px;color: white;border: none;font-size: 10px;}
  1084. #wt-set-box .user-box .apps-container{ height: 330px; overflow: auto; margin-bottom: 10px;}
  1085. #wt-tips-box,#wt-download-box{ position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) scale(0);overflow: hidden;width: 240px;min-height:130px;background-color: white;border-radius:12px;z-index: 95000;padding:10px 15px;}
  1086. #wt-tips-box,#wt-download-box .tips{ font-size: 10px;margin-top: 30px;color: #00bcd4;letter-spacing: 1px;}
  1087. #wt-tips-box .title{font-size: 16px;text-align: center;font-weight: 600;}
  1088. #wt-tips-box .content{text-align: center;margin: 14px 0;font-size: 12px;color: #2a2a2a;font-weight: 500;word-break: break-word;}
  1089. #wt-tips-box .content p{color: #ff4757;text-align: left;}
  1090. #wt-tips-box a{color: #1E88E5;text-decoration: underline;}
  1091. #wt-tips-box .btn-box{display:flex;justify-content: space-around;}
  1092. #wt-tips-box .btn-box button{min-width: 60px;height: 28px;background-color: #00bcd4;border-radius: 30px;color: white;border: none;font-size: 12px;}
  1093. #wt-tips-box .btn-box .cancel{display: none;background-color: #eee;color:#2a2a2a}
  1094. #wt-tips-box .logo{position: absolute;top: 9%;left: 1%; color: #dbdbdb; font-size: 11px;transform: rotate(-15deg);text-align: center;z-index: -10;}
  1095. #wt-tips-box .version{position: absolute;top: 5%; right: 10%;transform: rotate(-15deg);color: #dbdbdb;}
  1096. #wt-notify-box {position: fixed;top: 2%;left: 50%;transform:translate(-50%,-100%) scale(0);overflow: hidden;width: 80%;min-height: 75px;letter-spacing: 1px;background-color: white;color:#2a2a2a;border-radius: 15px;box-shadow: 0 15px 30px rgba(0, 0, 0, .15);z-index: 95000;}
  1097. #wt-notify-box::after{display:none; content:'';position: absolute;width: 250px;height: 250px;border-radius: 200px;background-color: #03A9F4;z-index: -1;opacity: 0.7;bottom: 0;left: 0;transform: translate(-50%,85%);}
  1098. #wt-notify-box .title{ text-align: center;height: 35px; line-height: 35px;font-size: 15px;font-weight: 600; color: #00bcd4;}
  1099. #wt-notify-box .content{ color: #3a3a3a;padding: 10px 15px;font-size: 12px;}
  1100. #wt-notify-box .content a{color: #1E88E5;text-decoration: underline;}
  1101. #wt-notify-box .content p{margin-bottom: 5px;}
  1102. .wt-player-btn-box{ position:absolute;top:0;left:0;right:0;bottom:0;z-index: 99998;background-color: #0000004d;}
  1103. #wt-video-container{display: none; position:fixed;top: 0;left: 0;right: 0;bottom: 0; z-index: 99998;background-color: black;}
  1104. #wt-video-container .wt-video{ position:absolute;top:50%;width:100%;transform: translateY(-50%);height: 240px; z-index: 99999;}
  1105. #wt-video-container .wt-video video{width:100%;height: 100%;}
  1106. .dplayer-controller{bottom: 30px !important;}
  1107. .main-player{height: 300px;}
  1108. .dplayer.dplayer-hide-controller .dplayer-controller{ opacity: 0 !important;transform: translateY(200%) !important;}
  1109. .wt-close-btn{ font-size: 15px;position: absolute;top: 40px;left: 25px;color: white;}
  1110. #wt-download-box{ z-index: 10010;}
  1111. #wt-download-box .close{position: absolute;right: 0px;top: 0px;width: 40px;height: 40px;}
  1112. #wt-download-box .close::before,#wt-download-box .close::after{position: absolute;left: 50%;top: 50%;content: '';width: 14px;height: 2px;border-radius: 1px;background-color: #adadad;transform: translate(-50%,-50%) rotate(45deg);}
  1113. #wt-download-box .close::after,#wt-download-box .close::after{transform: translate(-50%,-50%) rotate(-45deg);}
  1114. #wt-download-box::before{display:none; content:'';position: absolute;width: 150px;height: 150px;border-radius: 100px;background-color: #00bcd4;z-index: -1;opacity: 0.7;top: 0;left: 0;transform: translate(-38%,-40%);}
  1115. #wt-download-box::after{display:none;content:'';position: absolute;width: 150px;height: 150px;border-radius: 100px;background-color: #FFC107;z-index: -1;opacity: 0.7;bottom: 0;right: 0;transform: translate(62%,30%);}
  1116. #wt-download-box ul li{ height: 38px;line-height: 38px;font-size: 11px;text-align: center;color:#909090;font-weight: 500;background-color: white;box-shadow: rgb(166 166 166 / 20%) 0px 1px 5px 1px;margin: 18px 30px;border-radius: 40px;}
  1117. `)
  1118. if (_CONFIG_.isMobile) {
  1119. GM_addStyle(`
  1120. #wt-set-box {width:80%;}
  1121. `);
  1122. }
  1123. const roles = util.initAppDate(false);
  1124. $(container).append(`
  1125. <div id="wt-${_CONFIG_.vipBoxId}">
  1126. <div id="wt-my" class="item wt_my_haijiao">
  1127. <img src="${_CONFIG_.cdnBaseUrl + '/image/app.png'}"></img>
  1128. </div>
  1129. <div id="wt-my-set" class="item wt_player_haijiao">
  1130. <i class="iconfont">&#xe623;</i>
  1131. </div>
  1132. <div id="wt-my-down" class="item wt_my_down_haijiao">
  1133. <i class="iconfont">&#xe61c;</i>
  1134. </div>
  1135. <div id="wt-my-notify" class="item wt_my_notify" style="padding: 0 11px;">
  1136. <i class="iconfont">&#xe604;</i>
  1137. </div>
  1138. <div id="wt-hid-box" class="item">
  1139. <i class="iconfont">&#xe65f;</i>
  1140. </div>
  1141. </div>
  1142. <div id="wt-left-show" style="transform: translate(-60px,-50%);padding: 10px;">
  1143. <i class="iconfont">&#xe675;</i>
  1144. </div>
  1145. <div id="wt-mask-box"></div>
  1146. <div id="wt-set-box">
  1147. <div class="close"></div>
  1148. <div class="line-box" style="display:none">
  1149. </div>
  1150. <div class="user-box-container">
  1151. <div class="user-box">
  1152. <div class="title" style="margin-bottom: 10px">App</div>
  1153. <div class="user-info">
  1154. <div class="avatar" style="position: relative;">
  1155. <img src="${_CONFIG_.cdnBaseUrl + '/image/app.png'}" style="width: 100%;height: 100%;border-radius: 8px;"></img>
  1156. </div>
  1157. <div class="info">
  1158. <div class="nickname">请登录</div>
  1159. <div class="username">xxxxxxxxxx</div>
  1160. </div>
  1161. <div class="logout">
  1162. <button>退出登录</button>
  1163. </div>
  1164. </div>
  1165. <div class="apps-container"> ${roles}</div>
  1166. </div>
  1167. </div>
  1168. </div>
  1169. <div id="wt-loading-box">
  1170. <div class="loading"></div>
  1171. </div>
  1172. <div id="wt-maxindex-mask"></div>
  1173. <div id="wt-tips-box">
  1174. <div class="title">提示</div>
  1175. <div class="content"></div>
  1176. <div class="btn-box">
  1177. <button class='cancel'>取消</button>
  1178. <button class='submit'>确定</button>
  1179. </div>
  1180. <div class="logo"><p>@${superVip._CONFIG_.homeUrl}</p></div>
  1181. <div class="version"><p>v ${superVip._CONFIG_.version}</p></div>
  1182. </div>
  1183. <div id="wt-notify-box">
  1184. <div class="close"></div>
  1185. <div class="title">通知</div>
  1186. <div class="content"></div>
  1187. </div>
  1188. <div id="wt-video-container">
  1189. <div class="wt-close-btn">
  1190. <i class="van-icon van-icon-close"></i>
  1191. <span style="margin-left: 5px;">退出播放</span>
  1192. </div>
  1193. <div class="wt-video">
  1194. <video id="wt-video" controls></video>
  1195. </div>
  1196. </div>
  1197. `)
  1198. if (_CONFIG_.user && _CONFIG_.user.avatar) {
  1199. util.logined()
  1200. }
  1201. return new Promise((resolve, reject) => resolve(container));
  1202. }
  1203.  
  1204. bindEvent(container) {
  1205. const vipBox = $(`#wt-${_CONFIG_.vipBoxId}`)
  1206. if (GM_getValue('haijiao_hid_controller', null)) {
  1207. vipBox.css("transform", "translate(125%, -50%)")
  1208. $('#wt-left-show').css("transform", "translate(0, -50%)")
  1209. }
  1210.  
  1211. vipBox.find("#wt-my").on("click", () => {
  1212. if (_CONFIG_.user) {
  1213. $('#wt-mask-box').css('display', 'block')
  1214. $("#wt-set-box .user-box-container").css('display', 'block')
  1215. $("#wt-set-box").removeClass('hid-set-box')
  1216. $("#wt-set-box").addClass('show-set-box')
  1217. $('#wt-set-box .user-box-container .nickname').html(_CONFIG_.user.nickname)
  1218. util.initAppDate()
  1219. } else {
  1220. util.addLogin()
  1221. $('#wt-login-mask').css('display','block')
  1222. $("#wt-login-box").removeClass('hid-set-box')
  1223. $("#wt-login-box").addClass('show-set-box')
  1224. const jsxl_login_code = GM_getValue('jsxl_login_code','')
  1225. if(jsxl_login_code){
  1226. try{
  1227. const user = JSON.parse(jsxl_login_code)
  1228. if(user.u && user.u != 'undefined'){
  1229. $("#wt-login-box input")[0].value = user.u;
  1230. }
  1231. if(user.p && user.p != 'undefined'){
  1232. $("#wt-login-box input")[1].value = user.p;
  1233. }
  1234. }catch(e){}
  1235. }
  1236. }
  1237. })
  1238.  
  1239. vipBox.find("#wt-my-set").on("click", async () => {
  1240. try{
  1241. document.querySelector('video').pause()
  1242. }catch(e){}
  1243. if (!_CONFIG_.user) {
  1244. $("#wt-my").click()
  1245. return
  1246. }
  1247. if(_CONFIG_.videoUrl.requestErrMsg){
  1248. util.showTips({ title: _CONFIG_.videoUrl.requestErrMsg})
  1249. return
  1250. }
  1251. if (!_CONFIG_.videoUrl.playerUrl) {
  1252. $('#wt-loading-box').css('display', 'block')
  1253. for (let i = 0; i < 3; i++) {
  1254. await util.sleep(1000)
  1255. if (_CONFIG_.videoUrl.playerUrl) {
  1256. $('#wt-loading-box').css('display', 'none')
  1257. break
  1258. }
  1259. }
  1260. $('#wt-loading-box').css('display', 'none')
  1261. }
  1262. if (_CONFIG_.videoUrl?.playerUrl) {
  1263. $('#wt-video-container').css('display', 'block')
  1264. $("#wt-hid-box").click()
  1265. if(_CONFIG_.videoUrl.playerType == 'mp4'){
  1266. $('.wt-video').empty()
  1267. $('.wt-video').append(`
  1268. <video controls width="100%" height="100%">
  1269. <source src="${_CONFIG_.videoUrl?.playerUrl}">
  1270. </video>
  1271. `)
  1272. return
  1273. }
  1274. if (_CONFIG_.isMobile && _CONFIG_.isMobile[0] == 'iPhone') {
  1275. $('.wt-video').empty()
  1276. $('.wt-video').append(`
  1277. <video controls width="100%" height="100%">
  1278. <source src="${_CONFIG_.videoUrl.playerUrl}" type="application/x-mpegURL">
  1279. </video>
  1280. `)
  1281. } else {
  1282. const video = document.querySelector('.wt-video #wt-video')
  1283. _CONFIG_.hls_dp = new Hls()
  1284. _CONFIG_.hls_dp.loadSource(_CONFIG_.videoUrl.playerUrl)
  1285. _CONFIG_.hls_dp.attachMedia(video)
  1286. _CONFIG_.hls_dp.on(Hls.Events.MANIFEST_PARSED, function() {
  1287. video.play()
  1288. })
  1289. }
  1290. }
  1291. if (!_CONFIG_.videoUrl.playerUrl) {
  1292. util.showTips({
  1293. title: '</br>抱歉未检测到帖子视频,请关掉其它插件再试,或苹果用Focus浏览器,安卓用Via浏览器再试'
  1294. })
  1295. }
  1296. })
  1297.  
  1298. $('#wt-video-container div').on('click', function(e) {
  1299. e.stopPropagation()
  1300. })
  1301.  
  1302. $('.wt-close-btn').on('click', function() {
  1303. $('#wt-video-container').css('display', 'none')
  1304. var videos = document.querySelectorAll('video');
  1305. videos.forEach(function(video) {
  1306. // video.volume = 0.0
  1307. video.pause();
  1308. });
  1309. if (_CONFIG_.hls_dp) _CONFIG_.hls_dp.destroy()
  1310. $("#wt-left-show").click();
  1311. })
  1312.  
  1313. vipBox.find("#wt-my-down").on("click", () => {
  1314. if (!_CONFIG_.user) {
  1315. $("#wt-my").click()
  1316. return
  1317. }
  1318. if(_CONFIG_.isMobile && _CONFIG_.isMobile[0] == 'iPhone' && (!_CONFIG_.videoUrl.aes || !_CONFIG_.videoUrl.playerUrl)){
  1319. util.showTips({ title: '抱歉,未检测到视频'})
  1320. return
  1321. }
  1322. if(_CONFIG_.videoUrl.requestErrMsg){
  1323. util.showTips({ title: _CONFIG_.videoUrl.requestErrMsg})
  1324. return
  1325. }
  1326. if(_CONFIG_.videoUrl.downloadUrlSign){
  1327. util.showDownLoadWindow();
  1328. return;
  1329. }
  1330. if (_CONFIG_.videoUrl.downloadUrl || _CONFIG_.videoUrl.aes) {
  1331. if(_CONFIG_.user && _CONFIG_.user.stopDownload || (_CONFIG_.user.role.use_download_num == _CONFIG_.user.role.max_download_num) ){
  1332. util.showTips({
  1333. title: '抱歉,今日下载次数' + _CONFIG_.user.role.max_download_num + '次已经用完,请明日再下载'
  1334. })
  1335. return;
  1336. }
  1337. util.showTips({
  1338. title: '为了插件的稳定现已日限下载</br>(当前账号日限' + _CONFIG_.user.role.max_download_num +'次,' + superVip._CONFIG_.user.downloadTips +',已使用' + _CONFIG_.user.role.use_download_num +'次,每个插件每日各' + _CONFIG_.user.role.max_download_num +'次),</br>您确定要消耗一次次数来获取视频链接吗(如失败不计数)?',
  1339. doubt: true,
  1340. success: async (confirm) => {
  1341. if (confirm) {
  1342. try {
  1343. $('#wt-loading-box').css('display', 'block')
  1344. await util.sleep(300);
  1345. let obj = ''
  1346. if(_CONFIG_.isMobile && _CONFIG_.isMobile[0] == 'iPhone'){
  1347. obj = {
  1348. code: encodeURIComponent(_CONFIG_.videoUrl.aes),
  1349. isAes: true,
  1350. origin: location.origin
  1351. }
  1352. }else{
  1353. obj = {
  1354. code: ec.knxkbxen(_CONFIG_.videoUrl.downloadUrl.startsWith('http')?_CONFIG_.videoUrl.downloadUrl: location.origin + _CONFIG_.videoUrl.downloadUrl)
  1355. }
  1356. }
  1357. $.ajax({
  1358. url: superVip._CONFIG_.apiBaseUrl + '/d' + (Math.floor(Math.random() * 3) + 1) +'00/downloadTangxin',
  1359. method: 'POST',
  1360. headers: { 'luckyToken': superVip._CONFIG_.user.token},
  1361. contentType: 'application/json',
  1362. data: JSON.stringify(obj),
  1363. dataType: 'json',
  1364. success: function(response) {
  1365. $('#wt-loading-box').css('display', 'none')
  1366. if (response.errCode != 0) {
  1367. throw new Error(response.errMsg)
  1368. }
  1369. if(response.newToken) _CONFIG_.user.token = response.newToken;
  1370. _CONFIG_.user.role.use_download_num = response.useDownloadNum
  1371. _CONFIG_.videoUrl.downloadUrlSign = response.data
  1372. util.showDownLoadWindow(true, response.errMsg);
  1373. GM_setValue('jsxl_user', _CONFIG_.user);
  1374. },
  1375. error: function(error) {
  1376. $('#wt-loading-box').css('display', 'none')
  1377. util.showTips({
  1378. title: '请求jsxl失败'
  1379. })
  1380. }
  1381. })
  1382. } catch (e) {
  1383. console.log(e)
  1384. $('#wt-loading-box').css('display', 'none')
  1385. util.showTips({
  1386. title: e.message +
  1387. '</br>获取下载链接失败,可能此版块视频不支持下载'
  1388. })
  1389. if(e.message.includes('明日再下载')){
  1390. _CONFIG_.user.stopDownload = true
  1391. _CONFIG_.user.role.use_download_num = _CONFIG_.user.role.max_download_num
  1392. GM_setValue('jsxl_user', _CONFIG_.user);
  1393. }
  1394. }
  1395. }
  1396. }
  1397. })
  1398. return;
  1399. }
  1400.  
  1401. util.showTips({
  1402. title: '需要播放按钮有小绿点或暂不支持下载'
  1403. })
  1404. })
  1405.  
  1406. vipBox.find("#wt-hid-box").on("click", () => {
  1407. vipBox.css("transform", "translate(125%, -50%)");
  1408. $('#wt-left-show').css("transform", "translate(0, -50%)")
  1409. GM_setValue('haijiao_hid_controller', 1)
  1410. })
  1411.  
  1412. $('#wt-left-show').on('click', () => {
  1413. $('#wt-left-show').css("transform", "translate(-60px, -50%)");
  1414. vipBox.css("transform", "translate(0, -50%)")
  1415. GM_setValue('haijiao_hid_controller', '')
  1416. })
  1417.  
  1418. $('#wt-mask-box').on('click', () => {
  1419. $('#wt-mask-box').css('display', 'none')
  1420. $("#wt-set-box").removeClass('show-set-box');
  1421. $("#wt-set-box").addClass('hid-set-box')
  1422. $("#wt-download-box").removeClass('show-set-box');
  1423. $("#wt-download-box").addClass('hid-set-box')
  1424. setTimeout(() => {
  1425. $("#wt-set-box .line-box").css('display', 'none');
  1426. $("#wt-set-box .user-box-container").css('display', 'none')
  1427. }, 500)
  1428. })
  1429.  
  1430. $("#wt-set-box .close").on("click", () => {
  1431. $('#wt-mask-box').click()
  1432. })
  1433.  
  1434. vipBox.find("#wt-my-notify").on("click", () => {
  1435. if (_CONFIG_.showNotify) {
  1436. $('#wt-notify-box').click()
  1437. } else {
  1438. const notify = GM_getValue('notify', '');
  1439. if (notify) {
  1440. util.showNotify({
  1441. title: notify
  1442. })
  1443. GM_setValue('notifyShow', false);
  1444. util.showAndHidTips('wt_my_notify', 'set', false)
  1445. } else {
  1446. util.showNotify({
  1447. title: '还没有通知信息'
  1448. })
  1449. };
  1450. }
  1451. })
  1452.  
  1453. $("#wt-set-box .user-box .user-info").on('click', function() {
  1454. util.showTips({
  1455. title: '确定要跳转到插件官网吗?',
  1456. doubt: true,
  1457. success: (res) =>{
  1458. if(res){
  1459. location.href = superVip._CONFIG_.homeUrl
  1460. }
  1461. }
  1462. })
  1463. })
  1464.  
  1465. $('#wt-set-box .logout').on('click', function(e) {
  1466. util.showTips({
  1467. title: '您确定要退出登录吗?',
  1468. doubt: true,
  1469. success: (res) => {
  1470. if (res) {
  1471. util.logouted()
  1472. $('#wt-mask-box').click()
  1473. }
  1474. }
  1475. })
  1476. e.stopPropagation()
  1477. })
  1478.  
  1479. if (!_CONFIG_.user) {
  1480. util.addLogin()
  1481. util.findTargetElement('#wt-my').then(res => {
  1482. setTimeout(() => {
  1483. res.click()
  1484. }, 2500)
  1485. })
  1486. }
  1487. if(GM_getValue('notifyShow')){
  1488. util.showAndHidTips('wt_my_notify')
  1489. }
  1490. }
  1491. }
  1492.  
  1493. return {
  1494. start: () => {
  1495. _CONFIG_.user = GM_getValue('jsxl_user', '')
  1496. if (_CONFIG_.user) {
  1497. if (_CONFIG_.user.login_date && (_CONFIG_.user.login_date != new Date().setHours(0, 0, 0,
  1498. 0))) {
  1499. _CONFIG_.user = ''
  1500. GM_setValue('jsxl_user', '')
  1501. }
  1502. }
  1503. new BaseConsumer().parse()
  1504. },
  1505. _CONFIG_
  1506. }
  1507. })();
  1508. superVip.start();
  1509. }
  1510.  
  1511.  
  1512. if(!window.jQuery){
  1513. const script = document.createElement('script');
  1514. script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js';
  1515. script.onload = function() {
  1516. init(window.jQuery)
  1517. };
  1518. script.onerror = function(e) {
  1519. alert('jquery初始化失败')
  1520. };
  1521. document.head.appendChild(script);
  1522. }else{
  1523. init(window.jQuery)
  1524. }