// ==UserScript==
// @name 剧本杀活动通知生成器
// @namespace https://github.com/heiyexing
// @version 2024-01-30
// @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
// @run-at document-end
// @grant none
// @license MIT
// ==/UserScript==
(function () {
"use strict";
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("已将本周活动信息复制到剪贴板!");
});
})();