Greasy Fork

Greasy Fork is available in English.

ddrk助手

1.去广告 2.收藏功能 3.历史观看记录 4.自动播放下一集

当前为 2022-05-10 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         ddrk助手
// @namespace    king
// @version      0.4
// @description  1.去广告 2.收藏功能 3.历史观看记录 4.自动播放下一集
// @author       hero-king
// @match        https://ddrk.me/*
// @icon         https://ddrk.me/favicon-32x32.png
// @grant        unsafeWindow
// @grant        GM_listValues
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addValueChangeListener
// @grant        GM_registerMenuCommand
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js
// ==/UserScript==

(function () {
  "use strict";
  const Store = {
    setValue: function (key, value) {
      GM_setValue(key, value);
    },
    getValue: function (key) {
      return GM_getValue(key) || localStorage.getItem(key);
    },
    listValues: function () {
      return GM_listValues();
    },
    getLocalStorageData: function () {
      var len = localStorage.length; // 获取长度
      var arr = new Array(); // 定义数据集
      for (var i = 0; i < len; i++) {
        // 获取key 索引从0开始
        var getKey = localStorage.key(i);
        // 获取key对应的值
        var getVal = localStorage.getItem(getKey);
        // 放进数组
        arr[i] = {
          key: getKey,
          val: getVal,
        };
      }
      return arr;
    },
  };
  const Common = {
    //参数time为休眠时间,单位为毫秒:
    sleep: function (time) {
      return new Promise((resolve) => {
        setTimeout(resolve, time);
      });
    },
  };
  /*去广告*/
  $(".cfa_popup").css({ height: "0px" });
  $("#iaujwnefhw").css({ height: "0", overflow: "hidden" });
  $("#kasjbgih").css({ height: "0", overflow: "hidden" });

  const styleStr = `<style>
    .ddrk-tools__modal {
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      text-align: right;
    }
    .btn_col-default {
      position: absolute;
      top:0;
      font-size:22px;
      color: #2EBF8B;
      padding:6px;
      background-color: rgba(0,0,0,0.4);
      box-shadow: 0px 0px 5px rgba(0,0,0,0.4);
      line-height: 1.2;
      user-select:none;
    }
    .col_list {
      position: fixed;
      top: 35px;
      right: 0;
      width: 0;
      height: auto;
      min-height: 54px;
      box-sizing: border-box;
      background: #000;
      box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.2);
      z-index: 999;
      transition: width .6s;
    }
    .col_list .col_list_arrow{
      position: absolute;
      left: -26px;
      top: 0;
      width: 26px;
      padding: 4px;
      background: #008080;
      color: #000;
      border-top-left-radius: 8px;
      border-bottom-left-radius: 8px;
    }
    .col_list > h6{
      color: #aaa;
      margin: 10px 0 5px 0;
      text-align: center;
      white-space: nowrap;
    }

    .col_list-ul::-webkit-scrollbar {
      width: 5px;
      height: 5px
    }

    .col_list-ul::-webkit-scrollbar-thumb {
      border-radius: 3px;
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      background-color: #999;
    }

    .col_list-ul::-webkit-scrollbar-track {
      background-color: transparent
    }

    .col_list-ul {
      width: 300px;
      height: 300px;
      padding: 5px 0;
      overflow: hidden;
      color: #20B2AA;
    }

    .col_list-ul .col_item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      cursor: pointer;
      margin: 5px 0;
      padding: 0 5px;
      line-height: 25px;
      border: 1px solid transparent;
      border-left: none;
      border-right: none;
    }
    .col_list-ul .col_item .icon_del{
      border-radius: 100%;
      width: 16px;
      height: 16px;
      line-height: 1;
      display: none;
      text-align: center;
      color: #fff;
    }
    <style>`;
  $("head").append(styleStr);

  $(".post-box").on("click", ".btn_col-default", function (e) {
    e.stopPropagation();
  });
  $(".post-box").on("click", ".btn_col-add", function (e) {
    const href = $(this).parent().parent().data("href");
    const name = $(this).parent().parent().find(".post-box-title a").text();
    if (!colList.find((item) => item.href === href)) {
      colList.push({
        name: name.indexOf("(") > -1 ? name.split("(")[0] : name,
        href,
      });
      Store.setValue("ddrk-collection", JSON.stringify(colList));
    }
    reloadCollectHtml(1, $(this));
  });
  $(".post-box").on("click", ".btn_col-remove", function (e) {
    const href = $(this).parent().parent().data("href");
    const index = colList.findIndex((item) => item.href === href);
    if (index !== -1) {
      colList.splice(index, 1);
      Store.setValue("ddrk-collection", JSON.stringify(colList));
    }
    reloadCollectHtml(0, $(this));
  });
  $(".post-box").on("click", ".ddrk-tools__modal", function (e) {
    window.open($(this).parent().data("href"));
    e.stopPropagation();
  });
  $("body").on("click", ".col_list-ul li", function (e) {
    window.open($(this).data("href"));
    e.stopPropagation();
  });
  $("body").on("click", ".col_list-ul li .icon_del", function (e) {
    const href = $(this).parent().data("href");
    const index = colList.findIndex((item) => item.href === href);
    if (index !== -1) {
      colList.splice(index, 1);
      Store.setValue("ddrk-collection", JSON.stringify(colList));
    }
    reloadCollectHtml();
    e.stopPropagation();
  });
  GM_addValueChangeListener(
    "ddrk-collection",
    function (name, oldValue, newValue, remote) {
      reloadColList();
    }
  );
  document.addEventListener("visibilitychange", function () {
    // console.log("-----------", document.visibilityState);
    if (document.visibilityState == "hidden") {
      //切离该页面时执行
      // 标签隐藏时自动暂停播放(待开发)
    } else if (document.visibilityState == "visible") {
      //切换到该页面时执行
      // 刷新历史记录-因为需要和localStorage对比
      reloadHistoryList();
    }
  });

  /**
   * common
   */
  function createHtml(options = {}) {
    const colOuter = $("<div class='col_list'></div>");
    colOuter.css({
      top: options.top,
      "z-index": options["z-index"],
    });
    const title = $(`<h6>${options.title}</h6>`);
    const ul = $("<ul class='col_list-ul'></ul>");
    colOuter.append(title);
    colOuter.append(options.icon);
    colOuter.append(ul);
    $("body").append(colOuter);
    colOuter
      .mouseenter(function () {
        colOuter.css({ width: "300px" });
        ul.css({ overflow: "auto" });
      })
      .mouseleave(function () {
        colOuter.css({ width: "0" });
        ul.css({ overflow: "hidden" });
      });
    return ul;
  }

  /**
   * 蒙层及收藏按钮
   */
  let colList = [];
  const modal = $("<div  class='ddrk-tools__modal'></div>");
  const colButton = $('<span class="btn_col-default btn_col-remove">★</span>');
  $(".post-box").each(function () {
    const tempBtn = colButton.clone(true);
    if (!colList.find((item) => item.href === $(this).data("href"))) {
      tempBtn.addClass("btn_col-add");
      tempBtn.removeClass("btn_col-remove");
      tempBtn.text("☆");
    }
    modal.html(tempBtn);
    $(this).append(modal.clone(true));
  });
  function reloadCollectHtml(tag, tempBtn) {
    if (tempBtn) {
      if (tag === 0) {
        tempBtn.addClass("btn_col-add");
        tempBtn.removeClass("btn_col-remove");
        tempBtn.text("☆");
      } else {
        tempBtn.addClass("btn_col-remove");
        tempBtn.removeClass("btn_col-add");
        tempBtn.text("★");
      }
    } else {
      $(".post-box").each(function () {
        const tempBtn = $(this).find(".btn_col-default");
        if (!colList.find((item) => item.href === $(this).data("href"))) {
          tempBtn.addClass("btn_col-add");
          tempBtn.removeClass("btn_col-remove");
          tempBtn.text("☆");
        } else {
          tempBtn.addClass("btn_col-remove");
          tempBtn.removeClass("btn_col-add");
          tempBtn.text("★");
        }
      });
    }
  }

  /**
   * 收藏列表
   */
  let colUl = null;
  function initCollection() {
    const jsonText = Store.getValue("ddrk-collection");
    if (jsonText) {
      colList = JSON.parse(jsonText);
    }
    const arrowIcon = $(
      '  <svg class="col_list_arrow" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" ><path fill="currentColor" d="M529.408 149.376a29.12 29.12 0 0 1 41.728 0 30.592 30.592 0 0 1 0 42.688L259.264 511.936l311.872 319.936a30.592 30.592 0 0 1-.512 43.264 29.12 29.12 0 0 1-41.216-.512L197.76 534.272a32 32 0 0 1 0-44.672l331.648-340.224zm256 0a29.12 29.12 0 0 1 41.728 0 30.592 30.592 0 0 1 0 42.688L515.264 511.936l311.872 319.936a30.592 30.592 0 0 1-.512 43.264 29.12 29.12 0 0 1-41.216-.512L453.76 534.272a32 32 0 0 1 0-44.672l331.648-340.224z"  ></path></svg>;'
    );
    const colIcon = $(
      '<svg class="col_list_arrow" t="1652086592663" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2982" width="32" height="32"><path d="M856.8 82.8H386.1c-40.4-43.2-135.5-67-188.9-67-94.9 0-175.8 70.5-188.9 164.4-5.6 16-8.3 31.3-8.3 46.7v603.7c0 98.7 80.3 179.2 179.2 179.2h695.7c82 0 148.8-66.7 148.8-148.8V249.8c0-92.2-74.8-167-166.9-167z m0 30.4c60 0 110.5 39.2 128.7 93.2H627.2l-183.5-93.2h413.1z m136.6 747.7c0 65.3-53.1 118.4-118.4 118.4H179.3c-82 0.1-148.9-66.7-148.9-148.8V226.8c0-12.3 2.3-24.7 7-38l0.8-3.2c10.5-79.4 78.7-139.5 159.1-139.5 56.2 0 142.9 26.7 170.1 61.2l4.6 5.8h2.6l242.3 120.3h374.9c0.6 5.3 1.6 10.6 1.6 16.1v611.4z m0 0" fill="#000000" p-id="2983"></path><path d="M201.3 842.6h791v27.8h-791v-27.8z m-92.9 0h30.3v30.3h-30.3v-30.3z m258-260L346.1 693.8c-1.9 10.7 2.3 21.3 11 27.8 8.8 6.5 20.1 7.4 29.8 2.5l98.7-51.6 99.5 53.6c4.3 2.3 8.9 3.4 13.5 3.4 5.7 0 11.5-1.8 16.4-5.3 8.8-6.3 13.3-16.8 11.6-27.6L608.1 586.8l81.8-78c7.8-7.5 10.7-18.6 7.5-29-3.3-10.4-12-17.8-22.7-19.5L564.5 444l-49-101.9c-4.7-9.8-14.4-15.9-25.2-16.1-9.7-0.5-20.7 5.8-25.6 15.5L415.1 441.1l-112 15.1c-10.7 1.5-19.6 8.8-23.1 19.1s-0.8 21.4 6.9 29.1l79.5 78.2z m52.8-111.3c9.2-1.2 17.2-6.9 21.5-15.3l49.2-97.2 47.2 98.3c4.1 8.4 12 14.3 21.2 15.7L666.1 489.6l-78.8 75.2c-6.7 6.4-9.9 15.7-8.4 25l18.5 108.3-97.3-52.3c-4.2-2.3-8.8-3.4-13.4-3.4-4.4 0-8.9 1-13 3.1l-97 49.7 19.6-107.3c1.7-9.2-1.3-18.6-7.9-25.1l-77.3-77 108.1-14.5z m0 0" fill="#000000" p-id="2984"></path></svg>'
    );
    colUl =
      colUl ||
      createHtml({
        top: "35px",
        "z-index": 999,
        title: "收藏夹",
        icon: colIcon,
      });
    reloadColList();
  }
  initCollection();
  function reloadColList() {
    colUl.html("");
    colList.forEach((item, index) => {
      const li = $("<li class='col_item'></li>");
      const span = $(`<span>${index + 1}. ${item.name}</span>`);
      const del = $("<span class='icon_del'>x</span>");
      li.append(span);
      li.append(del);
      li.data("href", item.href);
      li.mouseenter(function () {
        $(this).find(".icon_del").css({ display: "inline-block" });
        $(this).css({
          "box-shadow": "0 0 5px rgba(32,178,170,0.2)",
          "border-color": "rgba(225,255,255,0.4)",
        });
      }).mouseleave(function () {
        $(this).find(".icon_del").css({ display: "none" });
        $(this).css({ "box-shadow": "none", "border-color": "transparent" });
      });
      colUl.append(li);
    });
  }

  /**
   * 历史记录功能
   */
  let historyUl = null;
  function initHistory() {
    const arrowIcon = $(
      '  <svg class="col_list_arrow" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" ><path fill="currentColor" d="M529.408 149.376a29.12 29.12 0 0 1 41.728 0 30.592 30.592 0 0 1 0 42.688L259.264 511.936l311.872 319.936a30.592 30.592 0 0 1-.512 43.264 29.12 29.12 0 0 1-41.216-.512L197.76 534.272a32 32 0 0 1 0-44.672l331.648-340.224zm256 0a29.12 29.12 0 0 1 41.728 0 30.592 30.592 0 0 1 0 42.688L515.264 511.936l311.872 319.936a30.592 30.592 0 0 1-.512 43.264 29.12 29.12 0 0 1-41.216-.512L453.76 534.272a32 32 0 0 1 0-44.672l331.648-340.224z"  ></path></svg>;'
    );
    const hisIcon = $(
      '<svg class="col_list_arrow" t="1652086837248" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4653" width="32" height="32"><path d="M204.8 552.96h204.8a20.48 20.48 0 0 1 0 40.96H204.8a20.48 20.48 0 0 1 0-40.96z" p-id="4654" fill="#000000"></path><path d="M143.36 921.6a40.96 40.96 0 0 1-40.96-40.96V143.36a40.96 40.96 0 0 1 40.96-40.96h614.4a40.96 40.96 0 0 1 40.96 40.96v327.68h40.96V143.36a81.92 81.92 0 0 0-81.92-81.92H143.36a81.92 81.92 0 0 0-81.92 81.92v737.28a81.92 81.92 0 0 0 81.92 81.92h327.68v-40.96z" p-id="4655" fill="#000000"></path><path d="M737.28 512a225.28 225.28 0 1 0 225.28 225.28 225.28 225.28 0 0 0-225.28-225.28z m0 409.6a184.32 184.32 0 1 1 184.32-184.32 184.32 184.32 0 0 1-184.32 184.32z" p-id="4656" fill="#000000"></path><path d="M771.2768 660.6848Q634.88 584.0896 634.88 737.28t136.6016 76.5952q136.192-76.5952-0.2048-153.1904z m-13.5168 122.88Q675.84 829.44 675.84 737.28t81.92-46.08q81.92 46.08 0 92.16zM225.28 307.2h-20.48a20.48 20.48 0 0 0 0 40.96h20.48zM696.32 307.2H266.24v40.96h430.08a20.48 20.48 0 0 0 0-40.96z" p-id="4657" fill="#000000"></path></svg>'
    );
    historyUl =
      historyUl ||
      createHtml({
        top: "85px",
        "z-index": 98,
        title: "观看记录",
        icon: hisIcon,
      });
    reloadHistoryList();
  }
  initHistory();
  // 对比
  function compareLocalData(myList, ddrkList) {
    // 差集
    const minus = ddrkList.filter(
      (ddrkItem) =>
        !myList.some(
          (item) =>
            item.enName === ddrkItem.enName && item.season === ddrkItem.season
        )
    );
    // console.log("-----差集-----", minus);
    const resultList = myList.map((innerItem) => {
      const ddrkItem =
        ddrkList.find(
          (item) =>
            item.enName === innerItem.enName && item.season === innerItem.season
        ) || {};
      return {
        ...innerItem,
        ...ddrkItem,
      };
    });
    return [...minus, ...resultList];
  }
  // 格式化
  function formatLocalData(local) {
    const history = local
      .filter((item) => item.key.indexOf("videojs-resume:") === 0)
      .map((item) => {
        const info = item.key.split("/");
        return {
          ...item,
          url: item.key.split(":")[1],
          enName: info[1],
          season: info.length > 3 && !isNaN(info[2]) ? info[2] : "",
          ep: info.at(-1).replace("?ep=", ""),
        };
      });
    return history;
  }
  // 去重
  function filterLocalData(params) {
    const result = params.reduce((res, cur) => {
      const innerItem = res.find(
        (item) => item.enName === cur.enName && item.season === cur.season
      );
      if (innerItem) {
        if (+cur.ep > +innerItem.ep) {
          res.splice(
            res.findIndex(
              (item) => item.enName === cur.enName && item.season === cur.season
            ),
            1,
            cur
          );
        }
        return res;
      } else {
        return res.concat(cur);
      }
    }, []);
    return result;
  }
  function getDramaName(url) {
    return new Promise((resolve, reject) => {
      // $.get(`https://ddrk.me${url}`, function (result) {
      //   console.log(result);
      //   const name = $(result).find(".post-title").text();
      //   resolve(name);
      // }).error(function (XMLHttpRequest, textStatus, errorThrown) {
      //   console.log(XMLHttpRequest, textStatus, errorThrown);
      // });
      $.ajax({
        url: `https://ddrk.me${url}`,
        type: "get",
        success: function (result) {
          //成功后回调
          const name = $(result).find(".post-title").text();
          resolve(name);
        },
        error: function (e) {
          //失败后回调
          resolve("");
        },
      });
    });
  }
  async function reloadHistoryList() {
    const jsonText = Store.getValue("ddrk-history");
    let jsonList = [];
    if (jsonText) {
      jsonList = JSON.parse(jsonText);
    }

    const localData = Store.getLocalStorageData();
    const his = formatLocalData(localData);
    const filterList = filterLocalData(his);
    let res = compareLocalData(jsonList, filterList);
    // console.log("history-----------------", his);
    for (const item of res) {
      if (!item.name) {
        const name = await getDramaName(item.url);
        item.name = name.indexOf("(") > -1 ? name.split("(")[0] : name;
      }
    }
    // 过滤name不存在的
    res = res.filter((item) => item.name);
    // console.log("result----------------", res);
    Store.setValue("ddrk-history", JSON.stringify(res));
    // ui修改
    historyUl.html("");
    res.forEach((item, index) => {
      const li = $(
        "<li class='col_item' style='word-break: break-all;' ></li>"
      );
      const season = item.season ? `S${item.season}` : "";
      const ep = item.ep ? `E${item.ep}` : "";
      const hour =
        parseInt(item.val / 3600) > 0 ? parseInt(item.val / 3600) : 0;
      const min =
        parseInt((item.val - hour * 3600) / 60) > 0
          ? parseInt((item.val - hour * 3600) / 60)
          : 0;
      const sec = parseInt(item.val - hour * 3600 - min * 60);
      const timeStr = `${hour > 9 ? hour : "0" + hour}:${
        min > 9 ? min : "0" + min
      }:${sec > 9 ? sec : "0" + sec}`;
      const span = $(`<span>${index + 1}. ${item.name} ${season}${ep}</span>`);
      const span2 = $(
        `<span style='font-size: 12px;color: #fff;margin-left: 20px;white-space: nowrap;'>${timeStr}</span>`
      );
      //   const del = $("<span class='icon_del'>x</span>");
      //   li.append(del);
      li.append(span);
      li.append(span2);
      li.data("href", item.url);
      li.mouseenter(function () {
        $(this).css({
          "box-shadow": "0 0 5px rgba(32,178,170,0.2)",
          "border-color": "rgba(225,255,255,0.4)",
        });
        // $(this).find(".icon_del").css({ display: "inline-block" });
      }).mouseleave(function () {
        $(this).css({ "box-shadow": "none", "border-color": "transparent" });
        // $(this).find(".icon_del").css({ display: "none" });
      });
      historyUl.append(li);
    });
  }

  /**
   * 自动跳转并播放下一集
   */
  const autoPlayNext = {
    player: null,
    playerModel: {},
    init() {
      this.initPlayer();
      this.bindEvent();
    },
    initPlayer() {
      this.player = unsafeWindow.videojs.getAllPlayers()[0];
      // 监听
      this.player?.on("ended", async () => {
        // console.log("--------------ended-------------");
        this.getCurrentVideoModel(); // 在下一集之前获取当前video状态
        if (this.playerModel.isInPictureInPicture) {
          //在画中画模式z则退出
          (
            this.player.controlBar.childNameIndex_.pictureInPictureToggle || {}
          ).handleClick();
        }
        this.handleToNext();
        await Common.sleep(200);
        this.initPlayer();
        this.handleToPlay();
        await Common.sleep(1000);
        this.restoreVideoModel();
      });
    },
    bindEvent() {
      // 主动点击下一集
      $(unsafeWindow.document).on(
        "click",
        ".wp-playlist-tracks .wp-playlist-item, icon-angle-right",
        async (e) => {
          await Common.sleep(200);
          this.initPlayer();
        }
      );
    },
    getCurrentVideoModel() {
      // 保存当前video模式
      this.playerModel = {
        isFullscreen: this.player.isFullscreen_, // 全屏
        isInPictureInPicture: this.player.isInPictureInPicture_, // 画中画
        isFullWindow: !!$(".vjs-theater-mode-control-close").length, // 网页全屏:打开时会包含vjs-theater-mode-control-close
      };
    },
    handleToNext() {
      (this.player.controlBar.childNameIndex_.nextButton || {}).handleClick(); // 下一集按钮
    },
    handleToPlay() {
      if (this.player.resumeModal?.opened_) {
        // 已打开恢复弹框则选择 是
        this.player.resumeModal.childNameIndex_.modalButtons.childNameIndex_.resumeButton.el_.click();
      } else {
        this.player.bigPlayButton?.el_.click(); //播放按钮
        window.localStorage.setItem(
          window.location.href.replace("https://ddrk.me", "videojs-resume:"),
          0
        );
      }
    },
    restoreVideoModel() {
      // 恢复上次video模式
      if (this.playerModel.isFullscreen) {
        (
          this.player.controlBar.childNameIndex_.fullscreenToggle || {}
        ).handleClick();
      } else if (this.playerModel.isInPictureInPicture) {
        // (
        //   this.player.controlBar.childNameIndex_.pictureInPictureToggle || {}
        // ).handleClick();
        this.player.controlBar.childNameIndex_.pictureInPictureToggle.el_.click();
      } else if (this.playerModel.isFullWindow) {
        (
          this.player.controlBar.childNameIndex_.theaterModeToggle || {}
        ).handleClick();
      }
    },
  };
  autoPlayNext.init();
})();