Greasy Fork is available in English.

Bilibili Anime HK Macau TW

Fetch bilibili anime for HK Macau TW

  1. // ==UserScript==
  2. // @name Bilibili Anime HK Macau TW
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Fetch bilibili anime for HK Macau TW
  6. // @author You
  7. // @match https://www.bilibili.com/anime/*
  8. // @match https://www.bilibili.com/v/anime/*
  9. // @match https://www.bilibili.com/anime/?hkmotw
  10. // @require https://cdnjs.cloudflare.com/ajax/libs/cash/8.1.0/cash.min.js
  11. // @icon https://www.google.com/s2/favicons?domain=bilibili.com
  12. // @grant none
  13. // @license MIT
  14. // @run-at document-start
  15. // ==/UserScript==
  16. (function $$() {
  17. 'use strict';
  18.  
  19. if (!document || !document.documentElement) window.requestAnimationFrame($$)
  20.  
  21. function addStyle(styleText) {
  22. const styleNode = document.createElement('style');
  23. styleNode.type = 'text/css';
  24. styleNode.textContent = styleText;
  25. document.documentElement.appendChild(styleNode);
  26. return styleNode;
  27. }
  28.  
  29. let fetch = window.fetch;
  30.  
  31. let $ = window.$;
  32. if (!$) return;
  33.  
  34. function last(arr) {
  35. return arr[arr.length - 1]
  36. }
  37.  
  38. /*
  39. function appendNextTo(elm){
  40. if(!elm || !elm.parentNode) return;
  41. elm.parentNode.insertBefore(, elm.nextSibling)
  42. }*/
  43.  
  44. let dk = {}
  45.  
  46. function getTyped(obj, key, type) {
  47.  
  48. if (!obj) return null;
  49. let p = obj;
  50. for (const s of key.split('.')) {
  51. if (!p[s]) return null;
  52. p = p[s];
  53. }
  54. if (type == 'array') return Symbol.iterator in p ? p : null;
  55. return typeof p == type ? p : null;
  56. }
  57.  
  58. function onReady() {
  59.  
  60. setInterval(function() {
  61.  
  62. if (!dk.crumb_item && document.querySelector('#app .bangumi-home-crumb li.crumb-item')) {
  63.  
  64. let lastli = last(document.querySelectorAll('#app .bangumi-home-crumb li.crumb-item'));
  65.  
  66. let menuli = $(lastli).clone().insertAfter(lastli)[0];
  67. dk.crumb_item = menuli;
  68.  
  69. $(menuli.querySelector('a[href]'))
  70. .attr('href', '//www.bilibili.com/anime/?hkmotw')
  71. .text('港澳台');
  72.  
  73.  
  74. }
  75.  
  76. }, 400)
  77.  
  78.  
  79. }
  80.  
  81.  
  82.  
  83. if (document.readyState != 'loading') {
  84. onReady();
  85. } else {
  86. window.addEventListener("DOMContentLoaded", onReady, false);
  87. }
  88.  
  89. async function sleep(ms) {
  90. return new Promise(resolve => setTimeout(resolve, ms));
  91. }
  92.  
  93. let _fTime = -1;
  94.  
  95. let _fetchJson_mutex=Promise.resolve();
  96.  
  97. function fetchJson(url, opts) {
  98.  
  99. return new Promise(resolve=>{
  100.  
  101. if (opts === undefined) {
  102. opts = {
  103. method: 'GET',
  104. //mode: 'no-cors',
  105. cache: 'default',
  106. redirect: "follow",
  107. }
  108. }
  109.  
  110. _fetchJson_mutex=_fetchJson_mutex.then(()=>new Promise(mutex_resolve=>{
  111.  
  112. setTimeout(async function(){
  113.  
  114. let w1 = performance.now();
  115. let res_1 = await fetch(url, opts);
  116. let w2 = performance.now();
  117. _fTime = w2 - w1;
  118. let rObj_1 = null;
  119.  
  120. if (res_1.status >= 200 && res_1.status < 300) {
  121. rObj_1 = await res_1.json();
  122. } else {
  123. throw new Error(res_1.statusText);
  124. }
  125.  
  126. resolve(rObj_1)
  127.  
  128. },7)
  129.  
  130. setTimeout(mutex_resolve,30);
  131.  
  132. }))
  133.  
  134. })
  135.  
  136.  
  137.  
  138. }
  139.  
  140.  
  141. function sPad(x, n, char) {
  142. let m = n - x.length;
  143. if (m > 0) return new Array(m)
  144. .fill(char)
  145. .join('') + x;
  146. return x;
  147. }
  148. let toDate = (dt) => {
  149.  
  150. let yyyy = dt.getFullYear();
  151. let mm = sPad((dt.getMonth() + 1) + '', 2, '0');
  152. let dd = sPad(dt.getDate() + '', 2, '0');
  153.  
  154. return `${yyyy}-${mm}-${dd}`
  155.  
  156. }
  157.  
  158. let to_hhmmss=(date)=>{
  159.  
  160.  
  161. let hh = sPad(date.getHours() + '', 2, '0');
  162. let min = sPad(date.getMinutes() + '', 2, '0');
  163. let ss = sPad(date.getSeconds() + '', 2, '0');
  164.  
  165. return `${hh}:${min}:${ss}`;
  166.  
  167. }
  168.  
  169.  
  170. let nearestDate = (second) => {
  171.  
  172.  
  173. // 2 pm
  174.  
  175. // 2pm 6pm 10pm 2am 6am 10am
  176.  
  177.  
  178. let aDate = new Date(second * 1000);
  179.  
  180. let bDate = new Date(toDate(aDate) + ' 00:00:00');
  181. let cDate = new Date(+bDate + 86400000);
  182. bDate = new Date(+bDate + 50400000);
  183. cDate = new Date(+cDate + 50400000);
  184. let dDate = (aDate - bDate < cDate - aDate) ? bDate : cDate;
  185.  
  186.  
  187. return (+dDate) / 1000;
  188.  
  189. }
  190.  
  191. function sDate(date) {
  192.  
  193. return `${toDate(date)} ${to_hhmmss(date)}`;
  194.  
  195.  
  196.  
  197. }
  198.  
  199. function dDate(date) {
  200.  
  201. return Math.round(+date / 1000);
  202. }
  203.  
  204.  
  205. function deHTML(x) {
  206. deHTML.vDom = deHTML.vDom || $("<vdom></vdom>")[0];
  207. deHTML.vDom.innerHTML = x;
  208.  
  209. return (deHTML.vDom.textContent || '')
  210. .trim();
  211.  
  212.  
  213. }
  214.  
  215. function vdEntry_getTitle(vdEntry, title) {
  216.  
  217. let zTitle = null;
  218. let _region = null;
  219. if (title.length > 0) zTitle = {
  220. aTitle: title.replace(/[\((][僅仅][限限]([\u4E00-\u9FFF]+)[地地][區区][\))]/, (_, a) => {
  221. _region = a;
  222. return '';
  223. })
  224. .trim(),
  225. region: _region
  226. };
  227.  
  228. return zTitle;
  229.  
  230. }
  231.  
  232. function filterDetailedResults(obj) {
  233.  
  234. function isValid(vEntry) {
  235.  
  236.  
  237. let zTitle = vEntry.__ztitle;
  238.  
  239. if (!zTitle) return false;
  240. if (vEntry.season_id > 0) {} else {
  241. return false;
  242. }
  243.  
  244. let ep_id = getTyped(vEntry, 'eps', 'array') ? last(vEntry.eps).id : 0;
  245. if (!ep_id) return false;
  246.  
  247. return true;
  248. }
  249.  
  250.  
  251. let vlist = getTyped(obj, 'data.result', 'array')
  252. if (vlist) {
  253.  
  254.  
  255. for (const vEntry of vlist) {
  256.  
  257. let zTitle = vdEntry_getTitle(vEntry, deHTML(vEntry.title));
  258.  
  259. if (zTitle) {
  260.  
  261. let ep_size_1 = vEntry.ep_size > 0 ? vEntry.ep_size : 0;
  262. let ep_size_2 = getTyped(vEntry, 'eps', 'array') ? vEntry.eps.length : 0;
  263.  
  264. if (ep_size_1 == ep_size_2) zTitle.ep_size = ep_size_1;
  265.  
  266. }
  267.  
  268. vEntry.__ztitle = zTitle;
  269. vEntry.__isValid = isValid(vEntry);
  270.  
  271. }
  272.  
  273. return vlist;
  274.  
  275.  
  276. }
  277.  
  278. return null;
  279.  
  280.  
  281. }
  282.  
  283.  
  284. function cmp(a, b) {
  285. return a > b ? 1 : a < b ? -1 : 0;
  286. }
  287.  
  288. function equals(a, b) {
  289.  
  290. return a && b && typeof a == typeof b && ('length' in a ? a.join('|') == b.join('|') : a == b)
  291. }
  292.  
  293.  
  294. function getExtraction(str) {
  295.  
  296. str = str.trim();
  297. let a1 = /^(今天)(\d+)\:(\d+)(更新)$/.exec(str)
  298. if (a1) {
  299.  
  300. return {
  301. txt: [a1[1], a1[4]],
  302. result: sPad(a1[2] + '', 2, '0') + ':' + a1[3]
  303. };
  304. }
  305.  
  306.  
  307. let a2 = /^(昨天)(\d+)\:(\d+)(更新)$/.exec(str)
  308. if (a2) {
  309.  
  310. return {
  311. txt: [a2[1], a2[4]],
  312. result: sPad(a2[2] + '', 2, '0') + ':' + a2[3]
  313. };
  314. }
  315.  
  316. return null;
  317. }
  318.  
  319. function jLoop(arr, reversed, f) {
  320. if (!reversed) {
  321. for (let vIdx = 0; vIdx <= arr.length - 1; vIdx++) {
  322. f(arr[vIdx])
  323. }
  324. } else {
  325. for (let vIdx = arr.length - 1; vIdx >= 0; vIdx--) {
  326. f(arr[vIdx])
  327.  
  328. }
  329. }
  330. }
  331.  
  332. function generate_xhr_results(resultObject,xhr){
  333.  
  334.  
  335. let szText = JSON.stringify(resultObject);
  336.  
  337. var blob = new Blob(
  338. [szText], // Blob parts.
  339. {
  340. type: "text/plain;charset=utf-8"
  341. }
  342. );
  343.  
  344. let szURL = URL.createObjectURL(blob);
  345.  
  346. console.log(szURL)
  347.  
  348. xhr._open_args[1] = szURL;
  349. xhr.abort();
  350. xhr.open(...xhr._open_args);
  351. xhr.send(...xhr._send_args);
  352.  
  353.  
  354. }
  355.  
  356. async function letsgo(xhr) {
  357.  
  358.  
  359. var original_url = () => `https://bangumi.bilibili.com/api/timeline_v2_global?`;
  360.  
  361.  
  362. var detailed_url = (page) => `https://api.bilibili.com/x/web-interface/search/type?context=&search_type=media_bangumi&page=${page}&order=&keyword=%E5%83%85%E9%99%90%20%E5%9C%B0%E5%8D%80&category_id=&__refresh__=true&_extra=&highlight=1&single_column=0`;
  363.  
  364. var timeorder_url = (page, pagesize) => `https://api.bilibili.com/pgc/season/index/result?season_version=1&spoken_language_type=1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&order=0&st=1&sort=0&page=1&season_type=1&pagesize=${pagesize}&type=1`;
  365.  
  366. let pms0_1 = fetchJson(timeorder_url(1, 240));
  367. let pms0_0 = fetchJson(original_url());
  368.  
  369. let rObj_1 = await pms0_1;
  370. console.log(`fetch-1`, rObj_1)
  371.  
  372. let orderedList_full = getTyped(rObj_1, 'data.list', 'array');
  373.  
  374.  
  375. if (!orderedList_full || orderedList_full.length == 0) {
  376.  
  377. xhr.send(...xhr._send_args);
  378. return;
  379. }
  380.  
  381.  
  382.  
  383. let pm_lastupdate_fix = ()=>new Promise(resolve => {
  384.  
  385. pms0_0.then(rObj_0 => {
  386.  
  387. console.log(`fetch-0`, rObj_0)
  388. let vResults_0 = getTyped(rObj_0, 'result', 'array');
  389.  
  390.  
  391. for (const vEntry of orderedList_full) {
  392.  
  393. let r = vResults_0.filter(ti_entry => ti_entry.season_id == vEntry.season_id)[0];
  394.  
  395. if (r) {
  396.  
  397. vEntry.lastupdate = r.lastupdate;
  398. vEntry.lastupdate_at = r.lastupdate_at;
  399.  
  400. }
  401.  
  402. }
  403.  
  404. console.log('vResults_0', vResults_0)
  405.  
  406.  
  407. }).then(() => {
  408.  
  409. let _temp = null;
  410. let _split = null;
  411. jLoop(orderedList_full, false, vEntry => {
  412.  
  413. if (vEntry.lastupdate > 0) {
  414.  
  415.  
  416. _temp = {
  417. lastupdate: vEntry.lastupdate
  418. };
  419.  
  420. let mmss;
  421. if (mmss = getExtraction(vEntry.order)) {
  422. let split0 = vEntry.lastupdate_at.split(` ${mmss.result}:`)
  423. if (split0.length == 2 && split0[0].length == 10 && split0[1].length == 2) {
  424. _temp.timestr_order = mmss.txt
  425. _temp.lastupdate_at_split = split0;
  426. }
  427. }
  428.  
  429.  
  430.  
  431. } else if (_temp) vEntry.__beforeitem_lastupdate = _temp;
  432.  
  433. })
  434.  
  435. _temp = null;
  436.  
  437. jLoop(orderedList_full, true, vEntry => {
  438.  
  439. if (vEntry.lastupdate > 0) {
  440.  
  441.  
  442. _temp = {
  443. lastupdate: vEntry.lastupdate
  444. };
  445.  
  446. let mmss;
  447. if (mmss = getExtraction(vEntry.order)) {
  448. let split0 = vEntry.lastupdate_at.split(` ${mmss.result}:`)
  449. if (split0.length == 2 && split0[0].length == 10 && split0[1].length == 2) {
  450. _temp.timestr_order = mmss.txt
  451. _temp.lastupdate_at_split = split0;
  452. }
  453. }
  454.  
  455.  
  456.  
  457. } else if (_temp) vEntry.__afteritem_lastupdate = _temp;
  458.  
  459. })
  460.  
  461. console.log('orderedList_full', orderedList_full)
  462.  
  463.  
  464.  
  465. for (const vEntry of orderedList_full) {
  466. //decending order of update time
  467.  
  468.  
  469.  
  470. if (vEntry.lastupdate) continue;
  471.  
  472. let kDate = null;
  473.  
  474. if (vEntry.order) {
  475. let mmss = getExtraction(vEntry.order);
  476. if (vEntry.__beforeitem_lastupdate && vEntry.__afteritem_lastupdate && vEntry.order) {
  477.  
  478. let last_at_equal = equals(vEntry.__beforeitem_lastupdate.lastupdate_at_split, vEntry.__afteritem_lastupdate.lastupdate_at_split);
  479.  
  480.  
  481. if (last_at_equal && equals(vEntry.__beforeitem_lastupdate.timestr_order, vEntry.__afteritem_lastupdate.timestr_order)) {
  482.  
  483. if (mmss) {
  484. kDate = new Date(vEntry.__beforeitem_lastupdate.lastupdate_at_split.join(` ${mmss.result}:`))
  485. }
  486.  
  487. } else if (!last_at_equal && getExtraction(vEntry.order) && equals(getExtraction(vEntry.order)
  488. .txt, vEntry.__beforeitem_lastupdate.timestr_order)) {
  489.  
  490. if (mmss) {
  491. kDate = new Date(vEntry.__beforeitem_lastupdate.lastupdate_at_split.join(` ${mmss.result}:`))
  492. }
  493.  
  494. } else if (!last_at_equal && getExtraction(vEntry.order) && equals(getExtraction(vEntry.order)
  495. .txt, vEntry.__afteritem_lastupdate.timestr_order)) {
  496.  
  497. if (mmss) {
  498. kDate = new Date(vEntry.__afteritem_lastupdate.lastupdate_at_split.join(` ${mmss.result}:`))
  499. }
  500.  
  501. } else if (vEntry.__beforeitem_lastupdate.lastupdate > 0 && vEntry.__afteritem_lastupdate.lastupdate > 0) {
  502. let dtt;
  503. let earliest = vEntry.__afteritem_lastupdate.lastupdate
  504. let latest = vEntry.__beforeitem_lastupdate.lastupdate
  505. if (dtt = vEntry.order.match(/^(\d+)月(\d+)日更新$/)) {
  506.  
  507. let d1 = (+new Date(new Date()
  508. .getFullYear() + `-${sPad(dtt[1],2,'0')}-${dtt[2]}`)) / 1000 + 1;
  509.  
  510. let d2 = d1 + 24 * 60 * 60;
  511. if (d1 > 0 && d2 > 0) {
  512. earliest = earliest > d1 ? earliest : d1;
  513. latest = latest < d2 ? latest : d2;
  514. }
  515. }
  516.  
  517.  
  518. let _dDate = Math.round((earliest + latest) / 2);
  519. kDate = new Date(_dDate * 1000);
  520. if (dDate(kDate) != _dDate) kDate = null;
  521.  
  522.  
  523. }
  524.  
  525.  
  526. } else if ((vEntry.__beforeitem_lastupdate || vEntry.__afteritem_lastupdate) && vEntry.order) {
  527.  
  528. if (vEntry.__beforeitem_lastupdate && getExtraction(vEntry.order) && equals(getExtraction(vEntry.order)
  529. .txt, vEntry.__beforeitem_lastupdate.timestr_order)) {
  530.  
  531. if (mmss) {
  532. kDate = new Date(vEntry.__beforeitem_lastupdate.lastupdate_at_split.join(` ${mmss.result}:`))
  533. }
  534.  
  535. } else if (vEntry.__afteritem_lastupdate && getExtraction(vEntry.order) && equals(getExtraction(vEntry.order)
  536. .txt, vEntry.__afteritem_lastupdate.timestr_order)) {
  537.  
  538. if (mmss) {
  539. kDate = new Date(vEntry.__afteritem_lastupdate.lastupdate_at_split.join(` ${mmss.result}:`))
  540. }
  541.  
  542. }
  543.  
  544.  
  545. }
  546.  
  547. }
  548.  
  549. if (kDate) {
  550.  
  551. vEntry.lastupdate = dDate(kDate)
  552. vEntry.lastupdate_at = sDate(kDate)
  553.  
  554. }
  555.  
  556.  
  557.  
  558.  
  559. }
  560.  
  561.  
  562. console.log('orderedList_full', orderedList_full)
  563.  
  564.  
  565.  
  566.  
  567. }).then(() => {
  568.  
  569.  
  570. resolve();
  571.  
  572.  
  573.  
  574. })
  575.  
  576.  
  577. })
  578.  
  579.  
  580.  
  581.  
  582. let seasons_id_ordered = orderedList_full.map(vEntry => {
  583.  
  584. if (vEntry.season_id > 0) {} else return -1;
  585.  
  586. let zTitle = vdEntry_getTitle(vEntry, vEntry.title);
  587.  
  588. if (zTitle && zTitle.region) return vEntry.season_id;
  589.  
  590. return -1;
  591.  
  592. })
  593.  
  594. let displayedCount = seasons_id_ordered.filter(s => s > 0).length;
  595. if (!displayedCount) {
  596. xhr.send(...xhr._send_args);
  597. return;
  598. }
  599.  
  600.  
  601.  
  602. console.log('orderedList', orderedList_full.filter(vEntry => seasons_id_ordered.includes(vEntry.season_id)))
  603.  
  604. let details_vlist = [];
  605.  
  606. let detailed_page_max = 8;
  607.  
  608.  
  609. let pms_2 = [];
  610.  
  611. let pms_additional = [];
  612. let details_not_found = [];
  613.  
  614. function pm_additionalInfo(vdEntry){
  615.  
  616. return new Promise(resolve=>{
  617.  
  618. (async ()=>{
  619.  
  620.  
  621. let res_pm=fetchJson(`https://api.bilibili.com/x/space/arc/search?mid=11783021&ps=80&tid=13&pn=1&keyword=${encodeURIComponent(vdEntry.__ztitle.aTitle)}&order=pubdate&jsonp=jsonp`)
  622. details_not_found.push(vdEntry)
  623.  
  624. let res= await res_pm;
  625. resolve(res);
  626.  
  627. })();
  628.  
  629.  
  630.  
  631.  
  632.  
  633. })
  634.  
  635. }
  636.  
  637.  
  638.  
  639. function detailP(rObj_2, detailed_page){
  640.  
  641. if(detailed_page == 1 ) {
  642.  
  643. console.log(`fetch-2p${detailed_page}-${_fTime}`, rObj_2)
  644. let page_max = getTyped(rObj_2, 'data.numPages', 'number')
  645. if (page_max > 0 && page_max < detailed_page_max) detailed_page_max = page_max
  646.  
  647. };
  648.  
  649.  
  650. let filtered_results=filterDetailedResults(rObj_2).filter(vEntry => vEntry.__isValid)
  651.  
  652.  
  653. for (const vdEntry of filtered_results) {
  654.  
  655. if ('__idx_ordered' in vdEntry) continue;
  656. vdEntry.__idx_ordered = seasons_id_ordered.indexOf(vdEntry.season_id);
  657. if (vdEntry.__idx_ordered >= 0) continue;
  658.  
  659.  
  660. if (!vdEntry.eps || !vdEntry.eps.length || !vdEntry.__ztitle || !vdEntry.__ztitle.aTitle) continue;
  661. let coverimg = last(vdEntry.eps).cover
  662. if (!coverimg) continue;
  663.  
  664.  
  665. pms_additional.push(pm_additionalInfo(vdEntry));
  666.  
  667.  
  668.  
  669.  
  670.  
  671. }
  672.  
  673.  
  674. details_vlist.push(...filtered_results)
  675. console.log(detailed_page, details_vlist.length , displayedCount)
  676.  
  677. return {original: rObj_2, filtered:filtered_results };
  678. }
  679.  
  680.  
  681.  
  682.  
  683. async function load_detailed_pages(pageFrom, pageTo){
  684. for (let detailed_page = pageFrom; detailed_page <= pageTo ; detailed_page++) {
  685. let pm = fetchJson(detailed_url(detailed_page)).then(res=>detailP(res,detailed_page))
  686. pms_2.push(pm)
  687. }
  688. }
  689.  
  690.  
  691. let dp_pageMax1=Math.ceil(displayedCount / 20)
  692.  
  693. let rObj_2s;
  694. await load_detailed_pages(1, dp_pageMax1)
  695. rObj_2s = await Promise.all(pms_2)
  696. let max_page2 = Math.ceil(pms_2.length / rObj_2s.map(res=>res.filtered.length).reduce((a, b) => a + b, 0) * displayedCount);
  697. let max_page_final = Math.min(max_page2, detailed_page_max)
  698.  
  699. if (rObj_2s.length===dp_pageMax1 && max_page_final>dp_pageMax1){
  700. await load_detailed_pages(dp_pageMax1+1, max_page_final)
  701. rObj_2s = await Promise.all(pms_2)
  702. }
  703.  
  704.  
  705. console.log('obatined details', details_vlist)
  706. console.log('details_not_found', details_not_found)
  707.  
  708.  
  709. await pm_lastupdate_fix();
  710.  
  711.  
  712. console.log('orderedList_full', orderedList_full)
  713.  
  714.  
  715.  
  716. let time_orders = orderedList_full.map((entry, i) => {
  717. return {
  718. season_id: entry.season_id,
  719. order: entry.lastupdate + (i / orderedList_full.length) * 0.45
  720. }
  721. })
  722. .filter(entry => entry.season_id > 0 && entry.order > 0);
  723.  
  724. console.log('time_orders', time_orders)
  725.  
  726. if (details_not_found.length > 0) {
  727.  
  728.  
  729. let rObj_4s = await Promise.all(pms_additional);
  730.  
  731.  
  732. let i = 0;
  733. for (const vdEntry of details_not_found) {
  734.  
  735.  
  736.  
  737. if (!vdEntry || !vdEntry.eps || !vdEntry.eps.length || !vdEntry.__ztitle || !vdEntry.__ztitle.aTitle) continue;
  738. let coverimg = last(vdEntry.eps).cover
  739. if (!coverimg) continue;
  740. let rObj_4 = rObj_4s[i];
  741. i++;
  742.  
  743. let rRes_4 = getTyped(rObj_4, 'data.list.vlist', 'array');
  744.  
  745. let allcovers = vdEntry.eps.map(
  746. s => (s.cover || '').replace(/i\d.hdslb.com/, 'i0.hdslb.com')
  747. ).filter(cover => typeof cover == 'string' && cover.length > 0);
  748.  
  749. let subRes = rRes_4.filter(s => allcovers.includes(s.pic.replace(/i\d.hdslb.com/, 'i0.hdslb.com')));
  750. if (subRes.length == 0) continue;
  751.  
  752.  
  753. if (subRes[0].pic.replace(/i\d.hdslb.com/, 'i0.hdslb.com') == coverimg.replace(/i\d.hdslb.com/, 'i0.hdslb.com')) {} else continue;
  754.  
  755.  
  756.  
  757. console.log('found-2b', vdEntry, subRes[0], subRes)
  758.  
  759. time_orders.push({ season_id: vdEntry.season_id, order: subRes[0].created + 0.5 });
  760.  
  761. }
  762.  
  763.  
  764.  
  765. }
  766.  
  767.  
  768. time_orders = time_orders.sort((a, b) => b.order - a.order);
  769.  
  770. console.log("time_orders", time_orders)
  771. //console.log("time_orders_k", time_orders.filter(s=>s.order-Math.floor(s.order)!=0.5).map(s=> ({season_id:s.season_id, k: to_hhmmss(new Date(Math.floor(s.order)*1000)).substr(3)})).sort((a,b)=>a.k.localeCompare(b.k)))
  772.  
  773. let sortIdx = time_orders.map(s => s.season_id)
  774.  
  775. let tnRes =[];
  776.  
  777. if (details_vlist) {
  778.  
  779. let vDate_fake = new Date;
  780. for (const vEntry of details_vlist) {
  781.  
  782.  
  783.  
  784. let zTitle = vEntry.__ztitle
  785.  
  786. let ep_id = last(vEntry.eps).id;
  787.  
  788. let pic = last(vEntry.eps).cover //:vEntry.cover
  789.  
  790.  
  791. let _sort_order = seasons_id_ordered.indexOf(vEntry.season_id);
  792.  
  793. let _time_order = time_orders.filter(s=>s.season_id == vEntry.season_id)[0];
  794.  
  795.  
  796. let orderedResult = null;
  797. let lastupdate = 0, lastupdate_at ='';
  798.  
  799. if (_sort_order >= 0) {
  800. orderedResult = orderedList_full[_sort_order];
  801.  
  802. if(orderedResult){
  803. lastupdate=orderedResult.lastupdate
  804. lastupdate_at=orderedResult.lastupdate_at
  805. }
  806.  
  807. }
  808.  
  809. if(!lastupdate && _time_order){
  810. lastupdate= Math.floor(_time_order.order)
  811. console.log(vEntry.season_id, lastupdate, sDate(new Date( lastupdate * 1000 )) )
  812.  
  813. lastupdate_at = sDate(new Date( lastupdate * 1000 ))
  814. }
  815.  
  816.  
  817. tnRes.push({
  818. "area": "日本",
  819. "arealimit": 328,
  820. "attention": 0,
  821. "bangumi_id": 0,
  822. "bgmcount": `${zTitle.ep_size||''}`,
  823. "cover": `${pic}`,
  824. "danmaku_count": 0,
  825. "ep_id": ep_id,
  826. "favorites": 0,
  827. "is_finish": (orderedResult ? orderedResult.is_finish : 0),
  828. "lastupdate": (lastupdate ? lastupdate : dDate(vDate_fake)), //1627095601,
  829. "lastupdate_at": (lastupdate_at ? lastupdate_at : sDate(vDate_fake)), //"2021-07-24 11:00:01",
  830. "new": (lastupdate ? lastupdate > Math.round(Date.now() / 1000 - 60 * 60 * 24) : false),
  831. "play_count": 0,
  832. "pub_time": "",
  833. "season_id": vEntry.season_id,
  834. "season_status": 13,
  835. "spid": 0,
  836. "square_cover": `${pic}`,
  837. "title": `${zTitle.aTitle} ${zTitle.region}】`,
  838. "viewRank": 0,
  839. "weekday": -1,
  840. _sort_order:sortIdx.indexOf(vEntry.season_id)
  841. })
  842. }
  843.  
  844. }
  845.  
  846.  
  847.  
  848. console.log('tnRes', [...tnRes])
  849.  
  850. tnRes = tnRes.filter(vEntry => vEntry._sort_order >= 0);
  851. console.log('unsorted', [...tnRes])
  852. tnRes = tnRes.sort((a, b) => cmp(a._sort_order, b._sort_order));
  853.  
  854. console.log('sorted', tnRes)
  855.  
  856.  
  857. xhr._set_anime = true;
  858.  
  859. let resultObject = {
  860. "code": 0,
  861. "message": "success",
  862. "result": tnRes
  863. };
  864.  
  865. generate_xhr_results(resultObject, xhr)
  866.  
  867.  
  868.  
  869. }
  870.  
  871.  
  872. if (location.search == '?hkmotw') {
  873.  
  874. const hKey_fetch = 'mkjmtmvhwtyt'
  875.  
  876. if (!XMLHttpRequest.prototype.open[hKey_fetch]) {
  877.  
  878. XMLHttpRequest.prototype.open = (function(_open) {
  879.  
  880. return function open() {
  881.  
  882. if (arguments[1] === "https://bangumi.bilibili.com/api/timeline_v2_global?") {
  883.  
  884. console.log(204)
  885. this._set_anime = arguments[1];
  886. //Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'responseText').get.call(this))
  887.  
  888. this._open_args = [...arguments];
  889. return _open.apply(this, arguments);
  890. }
  891. //console.log(arguments)
  892. return _open.apply(this, arguments)
  893. }
  894.  
  895. })(XMLHttpRequest.prototype.open)
  896. XMLHttpRequest.prototype.open[hKey_fetch] = true;
  897.  
  898.  
  899. XMLHttpRequest.prototype.send = (function(_send) {
  900.  
  901. return function send() {
  902.  
  903. if (this._set_anime === "https://bangumi.bilibili.com/api/timeline_v2_global?") {
  904.  
  905. console.log(205)
  906. this._send_args = [...arguments];
  907. letsgo(this);
  908. return;
  909. }
  910. return _send.apply(this, arguments)
  911. }
  912.  
  913. })(XMLHttpRequest.prototype.send)
  914. XMLHttpRequest.prototype.send[hKey_fetch] = true;
  915.  
  916. }
  917.  
  918.  
  919.  
  920.  
  921. }
  922.  
  923. addStyle(`
  924. .timeline-box .timeline-item .preview img[src][lazy="loaded"], .timeline-box .timeline-item .preview img[src]:not([lazy]){
  925. background: black;
  926. object-fit: contain;
  927. filter: saturate(1.8) contrast(0.6) brightness(1.2);
  928. }
  929. `)
  930.  
  931.  
  932. // Your code here...
  933. })();