CL1024去广告

去广告; 反去广告检测; 顺便移除viidii跳转和生成磁力链接

// ==UserScript==
// @name         CL1024去广告
// @namespace    https://sleazyfork.org/zh-CN/users/193133-pana
// @version      2.6.7
// @description  去广告; 反去广告检测; 顺便移除viidii跳转和生成磁力链接
// @author       pana
// @match        *://*t66y.com/*
// @connect      cdn.jsdelivr.net
// @license      GNU General Public License v3.0 or later
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-end
// ==/UserScript==

(function () {
  const debugStatus = false;
  const updateUrl = 'https://cdn.jsdelivr.net/gh/LightAPIs/adblock_rules@master/cl_rules.json';
  let userBlockRules = {
    version: '',
    reg: {
      img_dynamic: '',
      img_ignore: '',
      img_link: '',
      a_text: '',
      hash: '',
      blank_char: '',
      br: '',
      fid: '',
      viidii_clear: '',
      viidii_replace: '',
    },
    array: {
      block: [],
      br: [],
      jump: [],
      img_src: [],
    },
  };
  const defaultRules = {
    version: '2021.05.06.0',
    reg: {
      img_dynamic: /\.gif$/i,
      img_ignore: /(kanjiantu)\./i,
      img_link: /(playdada|taiwanrugevpn|laifaka|ccy\d+|ft\d+|dj\d+|uu\d+|wyfdc\d+|crv\d+|fr\.usxpic|youhuo\d+|vip\d+|wokkxv)\./i,
      a_text: /點擊這里打開新視窗|外部網站|点击在线播放|賭場|赌场|提款|[博体]彩|葡京|棋牌|彩票|六合彩|[赌賭]博|充值|娱乐[场城]|娛樂城|娱乐平台|贊助|投[注註]|赚钱|玩家|支付宝|裸聊|同城|聊天室|上[门門]|在线约炮|美女主播|美女荷官|美女真人视讯|实时在线|现场表演|性伴侣|真人露脸|免费观看|看片神器|加入会员|加入會員|注册|信誉|免费[送试看]|每日更新|精彩影片|精彩就在|免空精品|直接看片|成人影音|视频站|永久免费|91TV|新片發布|全[球网]|官方合作|永久地址|發佈站|发布站|发布页|导航|打开下载软件|^AV$/i,
      hash: /\?hash=\w{3}([a-z0-9]{40}|[a-z0-9]{32})/i,
      blank_char: /^(?:\s| |-|\|)*$/i,
      br: /(?:(?:\s|&nbsp;|-|\|)*<br>(?:\s|&nbsp;|-|\|)*){2,}/gim,
      fid: /fid=(\d+)/i,
      viidii_clear: /^(?:https?:\/\/)?www\.viidii\.[a-z]+\/\?|^(?:https?:\/\/)?to\.redircdn\.com\/\?|&z$/gi,
      viidii_replace: /_{4,}/g,
    },
    array: {
      block: ['2', '4', '5', '15', '25', '26', '27'],
      br: ['21'],
      jump: ['7', '8', '16', '10', '20', '22'],
      img_src: ['ess-data', 'data-src', 'data-ssa', 'data-ssc', 'data-sss'],
    },
  };
  let updateTime = '';
  const defaultTime = '2000.1.1';
  let consoleStatus = true;
  const varNameArr = [
    'readS',
    'r1eadS',
    'r2eadS',
    'r3eadS',
    'r4eadS',
    'r4eadS',
    'r6eadS',
    'r7eadS',
    'r8eadS',
    'r9eadS',
    'raeadS',
    'r1aeadS',
    'r2aeadS',
    'r3aeadS',
    'r4aeadS',
    'r5aeadS',
    'r6aeadS',
    'r7aeadS',
    'r8aeadS',
    'r9aeadS',
    'spinit',
  ];
  for (const ele of varNameArr) {
    try {
      const _name = `if (typeof ${ele} === "function") { ${ele} = () => { consoleInterface("info", "置换检测函数: %c${ele}", "color: #cccc33;"); }; }`;
      eval(_name);
    } catch (e) {
      console.debug(e);
    }
  }
  const tips = document.getElementsByClassName('tips');
  for (let i = 0; i < tips.length; i++) {
    tips[i].parentNode.removeChild(tips[i]);
  }
  const sptableDoNotRemove = document.getElementsByClassName('sptable_do_not_remove');
  for (let j = 0; j < sptableDoNotRemove.length; j++) {
    sptableDoNotRemove[j].parentNode.removeChild(sptableDoNotRemove[j]);
  }
  GM_addStyle(
    '.tips, .sptable_do_not_remove { display: none !important; } .user_create { color: #FA891B !important; } .cl_user_jump { margin-left: 10px; }'
  );
  class Cl_Image {
    constructor(imgSrc, imgLink) {
      this.imgSrc = imgSrc;
      this.imgLink = imgLink;
    }
  }
  class Img_Ignore extends Cl_Image {
    constructor(ignoreSrc, imgSrc, imgLink) {
      super(imgSrc, imgLink);
      this.matchSrc = ignoreSrc;
    }
  }
  class Img_Dynamic extends Cl_Image {
    constructor(imgSrc, imgLink) {
      super(imgSrc, imgLink);
    }
  }
  class Img_Link extends Cl_Image {
    constructor(matchValue, imgLink, imgSrc) {
      super(imgSrc, imgLink);
      this.matchValue = matchValue;
    }
  }
  class A_Text {
    constructor(matchText, linkText, linkValue) {
      this.matchText = matchText;
      this.linkText = linkText;
      this.linkValue = linkValue;
    }
  }
  class Magnet {
    constructor(hashCode, originalLink) {
      this.magnet = 'magnet:?xt=urn:btih:' + hashCode;
      this.originalLink = originalLink;
    }
    createLinkHtml() {
      return `<br><a class="user_create" target="_self" href="${this.magnet}">${this.magnet}</a>`;
    }
  }
  function blockUserAd() {
    consoleInterface('info', '%cblock rules version:', 'color: orange;', userBlockRules.version);
    if (typeof jQuery == 'function') {
      const fidStr = $('.t3:first a:last').attr('href');
      const fid = userBlockRules.reg.fid.exec(fidStr)[1];
      if (userBlockRules.array.block.includes(fid)) {
        consoleInterface('debug', 'The block rules apply to this page (fid: "%s").', fid);
        removeLinkJump();
        const mainContent = $('.tpc_content:eq(0)');
        const imgIgnoreArr = [];
        const imgDynamicArr = [];
        const imgLinkArr = [];
        mainContent.find('img').each(function (_i, ele) {
          let imgSrc = '';
          for (let item of userBlockRules.array.img_src) {
            if ($(ele).attr(item)) {
              imgSrc = $(ele).attr(item);
              break;
            }
          }
          const dataLink = $(ele).attr('data-link');
          if (userBlockRules.reg.img_ignore.test(imgSrc)) {
            const ignoreSrc = userBlockRules.reg.img_ignore.exec(imgSrc)[0];
            imgIgnoreArr.push(new Img_Ignore(ignoreSrc, imgSrc, dataLink));
          } else if (userBlockRules.reg.img_dynamic.test(imgSrc)) {
            imgDynamicArr.push(new Img_Dynamic(imgSrc, dataLink));
            $(ele).remove();
          } else if (userBlockRules.reg.img_link.test(dataLink)) {
            const matchLink = userBlockRules.reg.img_link.exec(dataLink)[0];
            imgLinkArr.push(new Img_Link(matchLink, dataLink, imgSrc));
            $(ele).remove();
          }
        });
        if (imgIgnoreArr.length > 0) {
          consoleInterface('groupCollapsed', '%c忽略图片(%s).', 'color: #FF9900;', imgIgnoreArr.length);
          consoleInterface('table', imgIgnoreArr);
          consoleInterface('groupEnd');
        }
        if (imgDynamicArr.length > 0) {
          consoleInterface('groupCollapsed', '%c移除动态图广告 (%s).', 'color: #FFFF00;', imgDynamicArr.length);
          consoleInterface('table', imgDynamicArr);
          consoleInterface('groupEnd');
        }
        if (imgLinkArr.length > 0) {
          consoleInterface('groupCollapsed', '%c移除广告链接图片 (%s).', 'color: #999933;', imgLinkArr.length);
          consoleInterface('table', imgLinkArr);
          consoleInterface('groupEnd');
        }
        const aTextArr = [];
        mainContent.find('a').each(function (_i, ele) {
          if (userBlockRules.reg.a_text.test($(ele).text())) {
            const linkText = $(ele).text();
            const matchText = userBlockRules.reg.a_text.exec(linkText)[0];
            aTextArr.push(new A_Text(matchText, linkText, $(ele).attr('href')));
            $(ele).remove();
          }
        });
        if (aTextArr.length > 0) {
          consoleInterface('groupCollapsed', '%c移除广告链接 (%s).', 'color: #CC3333;', aTextArr.length);
          consoleInterface('table', aTextArr);
          consoleInterface('groupEnd');
        }
        removeExtraBlankLinks(mainContent);
        const magnetArr = [];
        mainContent.find('a').each(function (_i, ele) {
          if (userBlockRules.reg.hash.test($(ele).attr('href'))) {
            const originalLink = $(ele).attr('href');
            const hashCode = userBlockRules.reg.hash.exec(originalLink)[1];
            const magnet = new Magnet(hashCode, originalLink);
            $(ele).after(magnet.createLinkHtml());
            magnetArr.push(magnet);
          }
        });
        if (magnetArr.length > 0) {
          consoleInterface('groupCollapsed', '创建磁力链接 (%s).', magnetArr.length);
          consoleInterface('table', magnetArr);
          consoleInterface('groupEnd');
        }
      } else if (userBlockRules.array.br.includes(fid)) {
        consoleInterface('debug', 'Remove extra blank lines on this page (fid: "%s").', fid);
        removeLinkJump();
        removeExtraBlankLinks($('.tpc_content:eq(0)'));
      } else if (userBlockRules.array.jump.includes(fid)) {
        consoleInterface('debug', 'Remove link jump on this page (fid: "%s").', fid);
        removeLinkJump();
      } else {
        consoleInterface('debug', 'The block rules do not apply to this page (fid: "%s").', fid);
      }
    } else {
      consoleInterface('debug', 'The script do not apply to this page.');
      if (/^\/htm_data\/\d{1,2}\/\d{4}\/\d+\.html/i.test(location.pathname)) {
        const userJump = document.createElement('a');
        userJump.className = 'cl_user_jump user_create';
        userJump.textContent = '跳转页面';
        userJump.title = '脚本无法在当前页面下生效,可尝试跳转页面';
        userJump.target = '_self';
        userJump.href = location.pathname.replace(/\/htm_data\/(\d{1,2})\/(\d{4})\/(\d+)\.html/i, '/htm_data/$2/$1/$3.html');
        document.querySelector('.h.guide').appendChild(userJump);
        consoleInterface('info', '%cCreated a jump link.', 'color: purple;');
      }
    }
  }
  function removeLinkJump() {
    $('.tpc_content a').each(function (_i, ele) {
      if ($(ele).attr('href')) {
        $(ele).attr(
          'href',
          $(ele).attr('href').replace(userBlockRules.reg.viidii_clear, '').replace(userBlockRules.reg.viidii_replace, '.')
        );
      }
    });
    $(document).ready(function () {
      $('.tpc_content img').each(function (_i, ele) {
        $(ele).off('click');
        const imgLink = $(ele).attr('data-link');
        if (imgLink) {
          $(ele).click(function () {
            window.open(imgLink);
          });
        }
      });
    });
  }
  function removeExtraBlankLinks(main_content) {
    main_content.find('div, span, b, iframe').each(function (_i, ele) {
      if (userBlockRules.reg.blank_char.test($(ele).text())) {
        $(ele).remove();
      }
    });
    main_content.find('blockquote').each(function (_i, ele) {
      const tempText = $(ele).text();
      if (userBlockRules.reg.blank_char.test(tempText)) {
        if ($(ele).prev().hasClass('quote')) {
          $(ele).prev().remove();
        }
        $(ele).remove();
      }
    });
    main_content.html(main_content.html().replace(userBlockRules.reg.br, '<br>'));
  }
  function convertReg(reg_str) {
    return new RegExp(reg_str.replace(/^\/|\/[a-z]*$/gi, ''), reg_str.replace(/^\/.*\/[^a-z]*/i, ''));
  }
  function getNowDate() {
    const now = new Date();
    return now.getFullYear() + '.' + (now.getMonth() + 1) + '.' + now.getDate();
  }
  function consoleInterface(method, ...theArgs) {
    if (consoleStatus) {
      switch (method) {
        case 'info':
          console.info(...theArgs);
          break;
        case 'debug':
          console.debug(...theArgs);
          break;
        case 'warn':
          console.warn(...theArgs);
          break;
        case 'error':
          console.error(...theArgs);
          break;
        case 'dir':
          console.dir(...theArgs);
          break;
        case 'table':
          console.table(...theArgs);
          break;
        case 'group':
          console.group(...theArgs);
          break;
        case 'groupCollapsed':
          console.groupCollapsed(...theArgs);
          break;
        case 'groupEnd':
          console.groupEnd(...theArgs);
          break;
        default:
          console.log(...theArgs);
      }
    }
  }
  function compare(str1, str2, symbol = '.') {
    const arr1 = str1.split(symbol);
    const arr2 = str2.split(symbol);
    let res = false;
    if (arr1.length === arr2.length) {
      for (let i = arr1.length - 1; i >= 0; i--) {
        if (Number(arr1[i]) > Number(arr2[i])) {
          res = true;
        } else if (Number(arr1[i]) < Number(arr2[i])) {
          res = false;
        }
      }
    }
    return res;
  }
  function assignmentUserBlockRules(readRules) {
    userBlockRules.version = readRules.version;
    for (const rKey in userBlockRules.reg) {
      userBlockRules.reg[rKey] = convertReg(readRules.reg[rKey]);
    }
    for (const aKey in userBlockRules.array) {
      userBlockRules.array[aKey] = readRules.array[aKey];
    }
  }
  function RegisterMenu() {
    try {
      if (consoleStatus) {
        GM_registerMenuCommand('关闭在控制台中打印记录', function () {
          consoleStatus = false;
          GM_setValue('console_status', consoleStatus);
          location.reload();
        });
      } else {
        GM_registerMenuCommand('启用在控制台中打印记录', function () {
          consoleStatus = true;
          GM_setValue('console_status', consoleStatus);
          location.reload();
        });
      }
      GM_registerMenuCommand('更新屏蔽规则', function () {
        const nowDate = getNowDate();
        consoleStatus = true;
        consoleInterface('info', '%cConnect to the network to update the rules.', 'color: #0099CC;');
        const details = {
          method: 'GET',
          url: updateUrl,
          responseType: 'json',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          onload: function (res) {
            let updateStatus = false;
            if (res.status == '200') {
              const readRules = res.response;
              if (compare(readRules.version, userBlockRules.version)) {
                consoleInterface('group', '%cUpdate block rules.', 'color: orange;');
                consoleInterface('table', { old_version: userBlockRules.version, new_version: readRules.version });
                consoleInterface('groupEnd');
                assignmentUserBlockRules(readRules);
                GM_setValue('user_block_rules', readRules);
                updateStatus = true;
              } else {
                consoleInterface('info', '%cNo update required. Network version:', 'color: #0099CC;', readRules.version);
              }
            } else {
              console.warn('The network connection was successful but the response was abnormal. Response status: ', res.status);
            }
            GM_setValue('update_time', nowDate);
            if (updateStatus) {
              consoleInterface('warn', 'Prepare to refresh the page automatically.');
              location.reload();
            }
          },
          onerror: function () {
            console.warn('Update config failed. Please check the network connection.');
            GM_setValue('update_time', nowDate);
          },
        };
        GM_xmlhttpRequest(details);
      });
    } catch (e) {
      console.error('Error registering menu item.');
      console.error(e);
    }
  }
  function updateConfig() {
    const nowDate = getNowDate();
    if (compare(nowDate, updateTime)) {
      consoleInterface('info', '%cConnect to the network to update the rules.', 'color: #0099CC;');
      const details = {
        method: 'GET',
        url: updateUrl,
        responseType: 'json',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        onload: function (res) {
          if (res.status == '200') {
            const readRules = res.response;
            if (compare(readRules.version, userBlockRules.version)) {
              consoleInterface('group', '%cUpdate block rules.', 'color: orange;');
              consoleInterface('table', { old_version: userBlockRules.version, new_version: readRules.version });
              consoleInterface('groupEnd');
              assignmentUserBlockRules(readRules);
              GM_setValue('user_block_rules', readRules);
            } else {
              consoleInterface('info', '%cNo update required. Network version:', 'color: #0099CC;', readRules.version);
            }
          } else {
            console.warn('The network connection was successful but the response was abnormal. Response status: ', res.status);
          }
          GM_setValue('update_time', nowDate);
          blockUserAd();
        },
        onerror: function () {
          console.warn('Update config failed. Please check the network connection.');
          GM_setValue('update_time', nowDate);
          blockUserAd();
        },
      };
      GM_xmlhttpRequest(details);
    } else {
      blockUserAd();
    }
  }
  if (debugStatus) {
    consoleInterface('info', '%cTesting block rules.', 'color: green;');
    userBlockRules = defaultRules;
    updateTime = getNowDate();
    consoleStatus = true;
    updateConfig();
  } else {
    Promise.all([GM_getValue('user_block_rules'), GM_getValue('update_time'), GM_getValue('console_status')])
      .then(function (data) {
        userBlockRules = defaultRules;
        if (data[0] !== undefined) {
          const readRules = data[0];
          if (compare(readRules.version, userBlockRules.version)) {
            assignmentUserBlockRules(readRules);
          }
        }
        if (data[1] !== undefined) {
          updateTime = data[1];
        } else {
          updateTime = defaultTime;
        }
        if (data[2] !== undefined) {
          consoleStatus = data[2];
        } else {
          consoleStatus = true;
        }
        consoleInterface('debug', 'Read the value from the storage.');
        RegisterMenu();
        updateConfig();
      })
      .catch(function (except) {
        console.error('Error reading variable. Please check the value in storage.');
        console.error(except);
        userBlockRules = defaultRules;
        updateTime = defaultTime;
        consoleStatus = true;
        RegisterMenu();
        updateConfig();
      });
  }
})();