☄️拷贝漫画增强☄️

拷贝漫画去广告🚫,对日漫版漫画页进行增强:并排布局📖、图片高度自适应↕️、辅助翻页↔️、页码显示⏱、侧边目录栏📑、暗夜模式🌙,请设置即时注入模式以避免页面闪烁⚠️

目前为 2021-09-11 提交的版本。查看 最新版本

// ==UserScript==
// @name         ☄️拷贝漫画增强☄️
// @namespace    http://tampermonkey.net/
// @version      5.6
// @description  拷贝漫画去广告🚫,对日漫版漫画页进行增强:并排布局📖、图片高度自适应↕️、辅助翻页↔️、页码显示⏱、侧边目录栏📑、暗夜模式🌙,请设置即时注入模式以避免页面闪烁⚠️
// @author       Byaidu
// @match        *://*.copymanga.com/*
// @license      GNU General Public License v3.0 or later
// @resource     animate_css https://cdn.jsdelivr.net/npm/[email protected]/animate.min.css
// @resource     element_css https://unpkg.com/[email protected]/lib/theme-chalk/index.css
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/jquery.cookie.js
// @require      https://unpkg.com/[email protected]/lib/index.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/crypto-js.js
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// ==/UserScript==

(function () {
  'use strict';
  //去广告
  GM_addStyle('*[style*="position: relative;"]{display:none !important;}')
  GM_addStyle('.header-jum{display:none !important;}')
  GM_addStyle('.comicContainerAds{display:none !important;}')
  GM_addStyle('.comicDetailAds{display:none !important;}')
  //漫画页检测
  if (location.href.indexOf("chapter") >= 0) {
    //unsafeWindow.eval = () => { }
    //固定header
    GM_addStyle('.header{position:unset !important;}')
    //去除footer
    GM_addStyle('.footer{display:none !important;}')
    //文字居中
    GM_addStyle('body{text-align:center !important;font-size:12px !important;line-height: normal !important;}')
    //图片居中
    GM_addStyle('ul{padding:0px !important;}')
    //body全屏
    GM_addStyle('body{height:unset !important;}')
    //修改滚动条样式
    GM_addStyle('::-webkit-scrollbar {width: 4px;height: 0px;}')
    GM_addStyle('::-webkit-scrollbar-thumb {background-color: rgb(48,48,48);border-radius: 2px;}')
    //修改element-ui样式
    GM_addStyle('.el-menu{border-right:0px !important;}')
    GM_addStyle('.el-drawer__wrapper{width:20%;}')
    GM_addStyle('.el-drawer{background:transparent !important;}')
    GM_addStyle('.el-drawer__body{background:rgba(0,0,0,.8) !important;overflow-y: auto}')
    //去除图片边框
    GM_addStyle('.comicContent{margin-top:20px;user-select: none;}')
    GM_addStyle('.comicContent img{margin-bottom: 50px !important;width:unset !important;}')
    //漫画双页排布
    GM_addStyle('.page_double .comicContent ul{justify-content:center;flex-direction: row-reverse;display: flex;flex-wrap: wrap;}')
    GM_addStyle('.page_double .comicContent img{height:100vh !important;}')
    GM_addStyle('.comicContent-image-list{width:unset !important;}')
    //引入css
    const animate_css = GM_getResourceText("animate_css");
    const element_css = GM_getResourceText("element_css");
    GM_addStyle(animate_css);
    GM_addStyle(element_css);
    GM_addStyle(':root{--animate-duration:500ms;}')
    //添加空页
    GM_addStyle('.page_skip .blank{display:none !important;}')
    //日间模式
    GM_addStyle("body{background:#edecea !important;}")
    //夜间模式
    GM_addStyle("html{background:transparent !important;}")
    GM_addStyle(".dark_mode body{background:#212121 !important;}")
    //读取cookie
    if ($.cookie('dark_mode') === undefined) { $.cookie('dark_mode', true, { expires: 999999, path: '/' }); }
    if ($.cookie('page_skip') === undefined) { $.cookie('page_skip', true, { expires: 999999, path: '/' }); }
    if ($.cookie('page_double') === undefined) { $.cookie('page_double', true, { expires: 999999, path: '/' }); }
    var dark_mode = $.cookie('dark_mode') == 'true';
    var page_skip = $.cookie('page_skip') == 'true';
    var page_double = $.cookie('page_double') == 'true';
    //暗夜模式
    if (dark_mode) {
      $('html').addClass('dark_mode');
    } else {
      $('html').removeClass('dark_mode');
    }
    //插入空页
    if (page_skip) {
      $('html').addClass('page_skip');
    } else {
      $('html').removeClass('page_skip');
    }
    //双页显示
    if (page_double) {
      $('html').addClass('page_double');
    } else {
      $('html').removeClass('page_double');
    }
    $(() => {
      let img_id = 0;
      let id_lock = 0;
      let middle = 0;
      let ch_id = 0;
      (function () {
        var AES_Encrypt = document['querySelector']('.disData')['getAttribute']('contentKey')
          , AES_Key_ = (document['querySelector']('.disUrlPrefix')['getAttribute']('contentKey'),
            document['querySelector']('.disUrlSuffix')['getAttribute']('contentKey'),
            document['querySelector']('.disPass')['getAttribute']('contentKey'))
          , AES_IV_ = AES_Encrypt['substring'](0x0, 0x10)
          , AES_Content_ = AES_Encrypt['substring'](0x10, AES_Encrypt['length'])
          , AES_Key = CryptoJS['enc']['Utf8']['parse'](AES_Key_)
          , AES_IV = CryptoJS['enc']['Utf8']['parse'](AES_IV_)
          , AES_Decrypt_JSON = function (AES_Content) {
            var AES_Content_Hex = CryptoJS['enc']['Hex']['parse'](AES_Content)
              , AES_Content_Base64 = CryptoJS['enc']['Base64']['stringify'](AES_Content_Hex);
            return CryptoJS['AES']['decrypt'](AES_Content_Base64, AES_Key, {
              'iv': AES_IV,
              'mode': CryptoJS['mode']['CBC'],
              'padding': CryptoJS['pad']['Pkcs7']
            })['toString'](CryptoJS['enc']['Utf8'])['toString']()
          }(AES_Content_)
          , AES_Decrypt = JSON['parse'](AES_Decrypt_JSON)
          , content = document['querySelector']('.comicContent-list')
          , idx = 0x0;
        function createContent() {
          var el = document['createElement']('li');
          el['innerHTML'] = '<img src="' + AES_Decrypt[idx]['url'] + '"/>',
            idx++,
            content['append'](el)
        }
        for (var i = 0x0; i < AES_Decrypt['length']; i++) {
          createContent()
        }
      })();
      //计算页数
      window.g_max_pic_count = $('.comicContent ul img').length;
      //添加右下角菜单
      let info = `
        <div id="info" @mouseover="show=1" @mouseleave="show=0">
        <transition name="custom-classes-transition" enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut">
        <template v-if="show"><div id="info_page" class="info_item" @click="switch_page" style="cursor:pointer;">{{message_page}}</div></template></transition>
        <transition name="custom-classes-transition" enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut">
        <template v-if="show"><div id="info_skip" class="info_item" @click="switch_skip" style="cursor:pointer;">{{message_skip}}</div></template></transition>
        <transition name="custom-classes-transition" enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut">
        <template v-if="show"><div id="info_switch" class="info_item" @click="switch_night" style="cursor:pointer;">{{message_switch}}</div></template></transition>
        <transition name="custom-classes-transition" enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut">
        <template v-if="show"><div id="info_full" class="info_item" @click="switch_full" style="cursor:pointer;">{{message_full}}</div></template></transition>
        <template><div id="info_count" class="info_item">{{message_count}}</div></template>
        </div>`;
      let $info = $(info);
      $("body").append($info);
      let info_style = `
        #info {
        bottom: 2%;
        right: 2%;
        padding: 5px 5px;
        background: rgba(48,48,48,.7) !important;
        position: fixed;
        color: rgba(255,255,255,.7);
        border-radius: 3px;
        }
        .info_item{
        padding:5px 0px;
        width:120px;
        }`;
      GM_addStyle(info_style);
      //vue绑定右下角菜单
      var info_app = new Vue({
        el: '#info',
        data: {
          dark: dark_mode,
          page: page_double,
          skip: page_skip,
          show: 0,
          img_id: 0,
          full: 0,
        },
        computed: {
          message_full: function () {
            return this.full ? '↩️退出全屏' : '↕️进入全屏'
          },
          message_switch: function () {
            return this.dark ? '☀️日间模式' : '🌙夜间模式'
          },
          message_page: function () {
            return this.page ? '1️⃣单页排布' : '2️⃣双页排布'
          },
          message_skip: function () {
            return this.skip ? '📑添加空页' : '📄移除空页'
          },
          message_count: function () {
            return (this.skip ? (this.img_id <= 1 ? this.img_id : this.img_id - 1) : this.img_id) + '/' + (g_max_pic_count + 1 - this.skip)
          }
        },
        methods: {
          switch_full: function () {
            this.full = !this.full
            if (this.full) {
              document.documentElement.requestFullscreen()
            } else {
              document.exitFullscreen();
            }
          },
          switch_night: function () {
            this.dark = !this.dark
            $.cookie('dark_mode', this.dark, { expires: 999999, path: '/' });
            if (this.dark) {
              $('html').addClass('dark_mode');
            } else {
              $('html').removeClass('dark_mode');
            }
          },
          switch_skip: function () {
            this.skip = !this.skip
            $.cookie('page_skip', this.skip, { expires: 999999, path: '/' });
            if (this.skip) {
              $("html").addClass('page_skip');
            } else {
              $("html").removeClass('page_skip');
            }
          },
          switch_page: function () {
            this.page = !this.page
            $.cookie('page_double', this.page, { expires: 999999, path: '/' });
            if (this.page) {
              $('html').addClass('page_double');
            } else {
              $('html').removeClass('page_double');
            }
          },
        }
      });
      //添加侧边目录栏
      let sidebar = `
        <div id="sidebar" @mouseleave="drawer=false">
        <div id="toggle" @mouseover="drawer=true" style="top:0px;left:0px;height:100vh;width:20vw;position: fixed;"></div>
        <el-drawer
        title="我是标题"
        :size="size"
        :modal="modal"
        :visible="drawer"
        :with-header="false"
        :direction="direction"
        @open="handleOpen">
        <el-menu background-color="transparent"
        text-color="#fff"
        active-text-color="#ffd04b"
        @select="handleSelect">
        <template v-for="(item, index) in items">
        <el-menu-item v-bind:index="index">{{item.title}}</el-menu-item>
        </template>
        </el-menu>
        </el-drawer>
        </div>`
      let $sidebar = $(sidebar);
      $("body").append($sidebar);
      //vue绑定侧边目录栏
      var sidebar_app = new Vue({
        el: '#sidebar',
        data: {
          drawer: false,
          size: '100%',
          modal: false,
          direction: 'ltr',
          items: [],
        },
        methods: {
          handleSelect(key) {
            location.href = this.items[key].href;
          },
          handleOpen() {
            setTimeout(function () {
              $('.el-drawer__body').animate({ scrollTop: 0 }, 0);
              $('.el-drawer__body').animate({ scrollTop: $('.el-menu>li:nth-child(' + (ch_id - 1) + ')').offset().top - $('.el-drawer__body').offset().top }, 0);
            }, 0)
          },
        }
      });
      (function () {
        var origin = window['location']['origin']
          , pathname = window['location']['pathname']['split']('/')[0x2];
        $.ajax({
          'type': 'GET',
          'timeout': 0x2710,
          'url': origin + '/comicdetail/' + pathname + '/chapters',
          'success': function AES_Recv(AES_Encrypt__) {
            (function (AES_Encrypt_) {
              var AES_Encrypt = AES_Encrypt_
                , AES_Key_ = (document['querySelector']('.disUrlPrefix')['getAttribute']('contentKey'),
                  document['querySelector']('.disUrlSuffix')['getAttribute']('contentKey'),
                  document['querySelector']('.disPass')['getAttribute']('contentKey'))
                , AES_IV_ = AES_Encrypt['substring'](0x0, 0x10)
                , AES_Content_ = AES_Encrypt['substring'](0x10, AES_Encrypt['length'])
                , AES_Key = CryptoJS['enc']['Utf8']['parse'](AES_Key_)
                , AES_IV = CryptoJS['enc']['Utf8']['parse'](AES_IV_)
                , AES_Decrypt_JSON = function (AES_Content) {
                  var AES_Content_Hex = CryptoJS['enc']['Hex']['parse'](AES_Content)
                    , AES_Content_Base64 = CryptoJS['enc']['Base64']['stringify'](AES_Content_Hex);
                  return CryptoJS['AES']['decrypt'](AES_Content_Base64, AES_Key, {
                    'iv': AES_IV,
                    'mode': CryptoJS['mode']['CBC'],
                    'padding': CryptoJS['pad']['Pkcs7']
                  })['toString'](CryptoJS['enc']['Utf8'])['toString']()
                }(AES_Content_)
                , AES_Decrypt = JSON['parse'](AES_Decrypt_JSON)
                , chapters = AES_Decrypt['groups']['default']['chapters'];
              chapters.forEach((i, j) => {
                if (location.href.indexOf(i['id']) >= 0) {
                  ch_id = j;
                  GM_addStyle('.el-menu>li:nth-child(' + (ch_id + 1) + '){background:rgba(255,165,0,.5) !important}')
                }
                sidebar_app.items.push({
                  title: i['name'],
                  href: 'https://copymanga.com/comic/' + pathname + '/chapter/' + i['id']
                })
              })
            })(AES_Encrypt__['results'])
          }
        })
      })();
      //去除憨批类
      $('.comicContent-image-all').removeClass('comicContent-image-all');
      $('.container').removeClass('container');
      $('.comicContent-image-1').removeClass('comicContent-image-1');
      $('.comicContent-image-2').removeClass('comicContent-image-2');
      $('.comicContent-image-3').removeClass('comicContent-image-3');
      $('.comic-size-1').removeClass('comic-size-1');
      $('.comic-size-2').removeClass('comic-size-2');
      $('.comic-size-3').removeClass('comic-size-3');
      $('.comicContent-list').removeClass('comicContent-list');
      //添加空页
      let $blank = $('.comicContent ul li:eq(0)').clone();
      $blank.find('img').addClass('blank');
      $blank.find('img').css('filter', 'brightness(0) invert(1)');
      $('.comicContent ul').prepend($blank);
      //添加图片属性
      let $img = $('.comicContent ul img');
      $.each($img, function (index) {
        //let $src=this.getAttribute('data-src');
        let $src = this.getAttribute('src');
        $src = $src.replace('mirror77', 'mirror');
        $src = $src.replace('mirror277', 'mirror2');
        this.setAttribute('src', $src);
      })
      let $li = $('.comicContent ul li');
      $.each($li, function (index) {
        this.setAttribute('class', 'inner_img');
      })
      //上下方向键滚动页面,左右方向键切换章节
      function scrollUp() {
        if (info_app.img_id == 0) return;
        var id = g_max_pic_count + 1;
        for (var i = 1; i <= Math.min(info_app.img_id, g_max_pic_count); i++) {
          var $img = $(".inner_img:eq(" + (i - 1) + ")");
          if (((id_lock && info_app.img_id >= 1 && info_app.img_id <= g_max_pic_count) ? $(".inner_img:eq(" + (info_app.img_id - 1) + ")").offset().top : pageYOffset) < $img.offset().top + $img.height() + 5) {
            id = i;
            break;
          }
        }
        var $img = $(".inner_img:eq(" + 0 + ")");
        if (((id_lock && info_app.img_id >= 1 && info_app.img_id <= g_max_pic_count) ? $(".inner_img:eq(" + (info_app.img_id - 1) + ")").offset().top : pageYOffset) < $img.offset().top + 5) {
          id = 0;
        }
        var $img = $(".inner_img:eq(" + (g_max_pic_count - 1) + ")");
        id_lock++;
        info_app.img_id = id;
        var $img = $(".inner_img:eq(" + (id - 1) + ")");
        $("html").stop();
        if (id == 0) {
          $("html").animate({ scrollTop: 0 }, 500);
        } else {
          var $img = $(".inner_img:eq(" + (id - 1) + ")");
          $("html").animate({ scrollTop: $img.offset().top }, 500);
        }
        setTimeout(function () { id_lock--; }, 500);
      }
      function scrollDown() {
        if (info_app.img_id == g_max_pic_count + 1) return;
        var id = g_max_pic_count + 1;
        for (var i = Math.max(info_app.img_id, 1); i <= g_max_pic_count; i++) {
          var $img = $(".inner_img:eq(" + (i - 1) + ")");
          if (((id_lock && info_app.img_id >= 1 && info_app.img_id <= g_max_pic_count) ? $(".inner_img:eq(" + (info_app.img_id - 1) + ")").offset().top : pageYOffset) < $img.offset().top - 5) {
            id = i;
            break;
          }
        }
        id_lock++;
        info_app.img_id = id;
        var $img = $(".inner_img:eq(" + (id - 1) + ")");
        $("html").stop();
        if (id == g_max_pic_count + 1) {
          var $img = $(".inner_img:eq(" + (g_max_pic_count - 1) + ")");
          $("html").animate({ scrollTop: $img.offset().top + $img.height() }, 500);
        } else {
          var $img = $(".inner_img:eq(" + (id - 1) + ")");
          $("html").animate({ scrollTop: $img.offset().top }, 500);
        }
        setTimeout(function () { id_lock--; }, 500);
      }
      $(".comicContent").click(function (event) {
        if (event.clientY > $(window).height() / 2) {
          scrollDown();
        } else {
          scrollUp();
        }
      })
      $("body").keydown(function (event) {
        if (event.keyCode == 38) {
          if (info_app.page) scrollUp();
        } else if (event.keyCode == 40) {
          if (info_app.page) scrollDown();
        } else if (event.keyCode == 37) {
          let location_new = $('.footer>div:nth-child(2) a').attr("href");
          if (location_new.indexOf("chapter") >= 0)
            location.href = location_new;
        } else if (event.keyCode == 39) {
          let location_new = $('.footer>div:nth-child(4) a').attr("href");
          if (location_new.indexOf("chapter") >= 0)
            location.href = location_new;
        } else if (event.keyCode == 13) {
          info_app.switch_full();
        }
      })
      //resize事件触发图片和浏览器对齐
      $(window).resize(function () {
        $("html").animate({ scrollTop: $(".inner_img:eq(" + (info_app.img_id) + ")").offset().top }, 0);
      })
      function getID() {
        var id = 0;
        for (var i = 1; i <= window.g_max_pic_count; i++) {
          var $img = $(".inner_img:eq(" + (i - 1) + ")");
          if (pageYOffset > $img.offset().top - 5 && pageYOffset < $img.offset().top + $img.height() - 5) {
            id = i;
            break;
          }
        }
        var $img = $(".inner_img:eq(" + (window.g_max_pic_count - 1) + ")");
        if (pageYOffset > $img.offset().top + $img.height() - 5) {
          id = g_max_pic_count + 1;
        }
        if (id_lock == 0) info_app.img_id = id;
      }
      setInterval(getID, 100);
      window.addEventListener('mousewheel', getID);
    })
  }
})();