剧本杀活动通知生成器

用于获取本周剧本杀活动信息并生成 Markdown 代码

目前為 2024-01-29 提交的版本,檢視 最新版本

// ==UserScript==
// @name         剧本杀活动通知生成器
// @namespace    https://github.com/heiyexing
// @version      2024-01-29-2
// @description  用于获取本周剧本杀活动信息并生成 Markdown 代码
// @author       炎熊
// @match        https://yuque.antfin-inc.com/yuhmb7/pksdw8/**
// @match        https://yuque.antfin.com/yuhmb7/pksdw8/**
// @icon         https://www.google.com/s2/favicons?sz=64&domain=antfin-inc.com
// @require      https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.9/dayjs.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.9/locale/zh-cn.min.js
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  "use strict";
console.log("脚本运行成功222")

  function initStyle() {
    const style = document.createElement("style");
    style.innerHTML = `
      .murder-mystery-btn {
          position: fixed;
          bottom: 25px;
          right: 80px;
          width: 40px;
          height: 40px;
          background-color: #fff;
          border-radius: 50%;
          box-shadow: 0 0 10px rgba(0, 0, 0, .2);
          cursor: pointer;
          display: inline-flex;
          justify-content: center;
          align-items: center;
          z-index: 2;
      }
      .murder-mystery-btn img {
          width: 20px;
      }
      `;
    document.head.appendChild(style);
    return style;
  }

  function initBtn() {
    const btn = document.createElement("div");
    btn.className = "murder-mystery-btn";
    const logo = document.createElement("img");
    logo.src =
      "https://mdn.alipayobjects.com/huamei_baaa7a/afts/img/A*f8MvQYdbHPoAAAAAAAAAAAAADqSCAQ/original";
    btn.appendChild(logo);
    document.body.appendChild(btn);
    return btn;
  }

  function getTitleInfo(title) {
    const month = title.match(/\d+(?=\s*月)/)?.[0];
    const date = title.match(/\d+(?=\s*日)/)?.[0];
    const name = title.match(/(?<=《).*?(?=》)/)?.[0];
    if (!month || !date || !name) {
      return null;
    }
    return {
      month: +month,
      date: +date,
      name,
    };
  }

  function getRegExpStr(strList, regexp) {
    for (const str of strList) {
      const result = str.match(regexp);
      if (result) {
        return result[0].trim();
      }
    }
    return "";
  }

  function exeCommandCopyText(text) {
    try {
      const t = document.createElement("textarea");
      t.nodeValue = text;
      t.value = text;
      document.body.appendChild(t);
      t.select();
      document.execCommand("copy");
      document.body.removeChild(t);
      return true;
    } catch (e) {
      console.log(e);
      return false;
    }
  }

  dayjs.locale(dayjs_locale_zh_cn);
  initStyle();
  const btn = initBtn();
  btn.addEventListener("click", async () => {
    if (!window.appData || !Array.isArray(window.appData?.book.toc)) {
      return;
    }
    const tocList = window.appData?.book.toc;
    const pathList = location.pathname.split("/");
    if (pathList.length <= 0) {
      return;
    }
    const docUrl = pathList[pathList.length - 1];
    const currentToc = tocList.find((item) => item.url === docUrl);
    if (!currentToc) {
      return;
    }
    const parentToc = tocList.find(
      (item) => item.uuid === currentToc.parent_uuid
    );
    if (!parentToc) {
      return;
    }
    const targetTocList = tocList.filter(
      (item) => item.parent_uuid === parentToc.uuid
    );

    const targetTimeRangeList = targetTocList
      .map((item) => {
        const titleInfo = getTitleInfo(item.title);
        if (!titleInfo) {
          return item;
        }
        return {
          ...item,
          ...titleInfo,
          dayjs: dayjs()
            .set("month", titleInfo.month - 1)
            .set("date", titleInfo.date),
        };
      })
      .filter((item) => {
        return item.dayjs.isSame(dayjs(), "week");
      })
      .sort((a, b) => a.dayjs - b.dayjs);

    const list = await Promise.all(
      targetTimeRangeList.map((item) => {
        return fetch(
          `${location.origin}/api/docs/${item.url}?book_id=${window.appData?.book.id}&include_contributors=true&include_like=true&include_hits=true&merge_dynamic_data=false`
        )
          .then((res) => res.json())
          .then((res) => {
            const content = res.data.content;
            const div = document.createElement("div");
            div.style = "height: 0px; overflow: hidden;";
            div.innerHTML = content;
            document.body.appendChild(div);
            const rowList = div.innerText.split("\n");

            const tag = getRegExpStr(rowList, /(?<=类型\s*[::]\s*).+/)?.split(/[/||]/).join('/');

            const level = getRegExpStr(
              rowList,
              /(?<=(难度|适合)\s*[::\s*]).+/
            );

            const dm = getRegExpStr(rowList, /(?<=(dm|DM)\s*[::]\s*).+/);

            let place = getRegExpStr(rowList, /(?<=(地点|场地)\s*[::]\s*).+/);

            if (/[Aa]\s?空间/.test(place)) {
              place = "A空间";
            }
            if (/元空间/.test(place)) {
              place = "元空间";
            }

            const persons = getRegExpStr(rowList, /(?<=(人数)\s*[::]\s*).+/)
              .split(/[,,\(\)()「」]/)
              .map((item) => item.replace(/(回复报名|注明男女|及人数)/, ""))
              .filter((item) => item.trim())
              .join("·");

            const week =
              getRegExpStr(rowList, /周[一二三四五六日]/) ||
              `周${
                ["日", "一", "二", "三", "四", "五", "六"][item.dayjs.day()]
              }`;

            const time = getRegExpStr(rowList, /\d{1,2}[::]\d{2}/);

            const [hour = "", minute = ""] = time.split(/[::]/);

            const duration = getRegExpStr(
              rowList,
              /(?<=(预计时.|时长)\s*[::]\s*).+/
            ).replace(/(h|小时)/, "H");

            return {
              ...item,
              tag,
              level,
              dm,
              week,
              hour,
              minute,
              place,
              persons,
              duration,
            };
          });
      })
    );

    const text = `
# 📢 剧本杀活动通知

---
${list
  .map((item) => {
    return `
🎬 《${item.name}》${item.tag}${item.level ? `/${item.level}` : ""}

🕙  ${item.month}.${item.date} ${item.week} ${item.hour}:${item.minute} 📍${
      item.place
    }

💎  DM ${item.dm}【${item.persons}·${
      item.duration
    }】[报名](https://yuque.antfin.com/yuhmb7/pksdw8/${item.url}?singleDoc#)

---
`;
  })
  .join("")}

🙋‍ [玩家报名须知](https://yuque.antfin.com/yuhmb7/pksdw8/igri3gwp127v3v32?singleDoc#),防跳车押金以报名页面为准!

🔜 加入钉群:14575023754,获取更多活动信息!

`;

    exeCommandCopyText(text);
    alert("已将本周活动信息复制到剪贴板!");
  });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址