// ==UserScript==
// @name MC百科 - 便捷工具
// @namespace https://github.com/ifover/UserScript
// @version 0.1
// @author ifover
// @description 在MC百科首页显示收藏列表,方便导航
// @icon https://www.mcmod.cn/images/favicon.ico
// @license MIT
// @match https://*.mcmod.cn/
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @require https://unpkg.com/vue-demi@latest/lib/index.iife.js
// @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
// @require https://unpkg.com/dayjs/dayjs.min.js
// @require https://unpkg.com/dayjs/plugin/customParseFormat.js
// @require https://unpkg.com/dayjs/plugin/weekday.js
// @require https://unpkg.com/dayjs/plugin/localeData.js
// @require https://unpkg.com/dayjs/plugin/weekOfYear.js
// @require https://unpkg.com/dayjs/plugin/weekYear.js
// @require https://unpkg.com/dayjs/plugin/advancedFormat.js
// @require https://unpkg.com/dayjs/plugin/quarterOfYear.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/pinia.iife.prod.js
// @require https://unpkg.com/[email protected]/dist/antd.min.js
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// ==/UserScript==
(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const t=document.createElement("style");t.textContent=e,document.head.append(t)})(" #app{background-color:#e9e9e9;font-size:12px;position:fixed;left:10px;top:286px;border-radius:4px;z-index:10}.ant-tree{background-color:transparent}.ant-tree-title a{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:230px}.ant-tree-treenode.ant-tree-treenode-switcher-close,.ant-tree-treenode.ant-tree-treenode-switcher-open,.ant-tree-treenode.ant-tree-treenode-disabled{position:sticky;top:0;z-index:10;background-color:#e9e9e9}.ant-tree-treenode.ant-tree-treenode-disabled{top:28px}#app[data-v-8268fb43]{background-color:#e9e9e9;font-size:12px;position:fixed;left:10px;top:286px;border-radius:4px;z-index:10}.ant-tree[data-v-8268fb43]{background-color:transparent}.ant-tree-title a[data-v-8268fb43]{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:230px}.ant-tree-treenode.ant-tree-treenode-switcher-close[data-v-8268fb43],.ant-tree-treenode.ant-tree-treenode-switcher-open[data-v-8268fb43],.ant-tree-treenode.ant-tree-treenode-disabled[data-v-8268fb43]{position:sticky;top:0;z-index:10;background-color:#e9e9e9}.ant-tree-treenode.ant-tree-treenode-disabled[data-v-8268fb43]{top:28px}.mm_tools[data-v-8268fb43]{width:362px;padding:6px 8px;max-height:520px;overflow-y:scroll}.mm_tools .mm_mask[data-v-8268fb43]{width:calc(100% - 8px);height:6px;position:absolute;left:0;right:0;top:0;z-index:11;border-radius:4px 4px 0 0;background-color:#e9e9e9}.mm_tools[data-v-8268fb43]::-webkit-scrollbar{width:8px}.mm_tools[data-v-8268fb43]::-webkit-scrollbar-thumb{border-radius:8px;background-color:#c1c1c1}.mm_tools[data-v-8268fb43]::-webkit-scrollbar-track{background-color:#f1f1f1;border-radius:0 8px 8px 0}.cover[data-v-8268fb43]{width:60px;opacity:.77;margin-right:6px}.mm_fav_li[data-v-8268fb43]{display:flex;align-items:center;padding:2px 0}.mm_fav_title[data-v-8268fb43]{width:230px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis} ");
(function (vue, pinia$1, antDesignVue) {
'use strict';
var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
const useUserStore = pinia$1.defineStore("user", {
state: () => ({
userID: "0000"
}),
actions: {
actionUserID(id) {
this.userID = id;
}
}
});
const json2FormData = (json) => {
return Object.keys(json).map((key) => {
return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
}).join("&");
};
const request = (url, data) => {
const userStore = useUserStore();
return new Promise((resolve, reject) => {
_GM_xmlhttpRequest({
method: "POST",
url,
data: json2FormData(data),
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": `https://center.mcmod.cn/${userStore.userID}/`
},
responseType: "json",
onload: (response) => {
if (response.responseText) {
resolve(response.response);
} else {
reject(response);
}
}
});
});
};
const _hoisted_1 = { class: "mm_tools" };
const _hoisted_2 = { class: "mm_fav_list" };
const _hoisted_3 = ["href", "title"];
const _hoisted_4 = { class: "mm_fav_li" };
const _hoisted_5 = ["src", "alt"];
const _hoisted_6 = { class: "mm_fav_title" };
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
__name: "App",
setup(__props) {
const userStore = useUserStore();
vue.reactive([]);
const expandedKeys = vue.ref([]);
const selectedKeys = vue.ref([]);
let treeFavData = vue.ref([]);
const getUserID = () => {
let userUrlNode = document.querySelector(".top-username a");
if (!userUrlNode) return null;
let url = userUrlNode.getAttribute("href");
let arr = url == null ? void 0 : url.match(/\d+/);
if (arr == null ? void 0 : arr.length) {
userStore.actionUserID(arr[0]);
}
};
const getFavoriteFold = async () => {
let u = "https://center.mcmod.cn/frame/CenterFavoriteFold/";
let d = {
uid: userStore.userID,
data: JSON.stringify({})
};
let res = {};
res = await request(u, d);
let { state, html } = res;
if (state !== 0) return;
let node = new DOMParser().parseFromString(html, "text/html");
let nodeList = node.querySelectorAll(".favorite-fold-list ul > a");
let _favList = [];
nodeList.forEach((n) => {
var _a, _b;
let favID = n.getAttribute("data-id");
let favName = (_a = n.querySelector('li span[class="title"]')) == null ? void 0 : _a.getAttribute("title");
let c = (_b = n.querySelector('li span[class="count"]')) == null ? void 0 : _b.getAttribute("title");
let modCount = 0, modPackCount = 0;
if (c) {
c.split(",").forEach((o) => {
let modMatch = o.match(/(\d+).个模组/);
if (modMatch && modMatch.length) modCount = parseInt(modMatch[1]);
let modPackMatch = o.match(/(\d+).个整合包/);
if (modPackMatch && modPackMatch.length) modPackCount = parseInt(modPackMatch[1]);
});
}
_favList.push({
key: favID,
favID,
favName,
title: favName,
// title: `${favName} 模组x${modCount} 整合包x${modPackCount}`,
modCount,
modPackCount,
isLeaf: modCount === 0 && modPackCount === 0
});
});
treeFavData.value = _favList;
};
const onLoadData = (treeNode) => {
return new Promise(async (resolve) => {
let { favID, favName, modCount, modPackCount, key, title, children, isLeaf } = treeNode.dataRef;
if (children) {
resolve();
return;
}
let modArr = [];
const getFavList = async (category) => {
let u = "https://center.mcmod.cn/frame/CenterFavoriteSoltPage/";
let d = {
uid: userStore.userID,
data: JSON.stringify({
fold: key,
category
})
};
let res = {};
res = await request(u, d);
let { state, html } = res;
if (state !== 0) return;
let node = new DOMParser().parseFromString(html, "text/html");
let nodeList = node.querySelectorAll(".favorite-slot-ul li");
nodeList.forEach((n) => {
var _a;
let modID = n.getAttribute("data-id");
let modURL = (_a = n.querySelector('span[class="cover"] a')) == null ? void 0 : _a.getAttribute("href");
let _modInfoNode = n.querySelector('span[class="cover"] img');
let modPic = _modInfoNode == null ? void 0 : _modInfoNode.getAttribute("src");
let modName = _modInfoNode == null ? void 0 : _modInfoNode.getAttribute("alt");
modArr.push({
title: modName,
key: modID,
modPic,
modURL,
isLeaf: true
});
});
};
if (modCount) {
modArr.push({
title: `模组 (${modCount})`,
disabled: true,
isLeaf: true
});
await getFavList("class");
}
if (modPackCount) {
modArr.push({
title: `整合包 (${modPackCount})`,
disabled: true,
isLeaf: true
});
await getFavList("modpack");
}
if (treeNode.dataRef) treeNode.dataRef.children = modArr;
resolve();
});
};
vue.onMounted(() => {
getUserID();
if (!userStore.userID) return;
getFavoriteFold();
});
const handleTreeSelect = (sKeys, info) => {
console.log(sKeys);
expandedKeys.value = sKeys;
};
return (_ctx, _cache) => {
const _component_a_tree = vue.resolveComponent("a-tree");
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
_cache[2] || (_cache[2] = vue.createElementVNode("div", { class: "mm_mask" }, null, -1)),
vue.createElementVNode("div", _hoisted_2, [
vue.createVNode(_component_a_tree, {
expandedKeys: expandedKeys.value,
"onUpdate:expandedKeys": _cache[0] || (_cache[0] = ($event) => expandedKeys.value = $event),
selectedKeys: selectedKeys.value,
"onUpdate:selectedKeys": _cache[1] || (_cache[1] = ($event) => selectedKeys.value = $event),
blockNode: true,
"show-line": false,
"show-icon": false,
selectable: false,
"tree-data": vue.unref(treeFavData),
"load-data": onLoadData,
onSelect: handleTreeSelect
}, {
title: vue.withCtx(({ title, key, modPic, modURL }) => [
modURL ? (vue.openBlock(), vue.createElementBlock("a", {
key: 0,
target: "_blank",
href: modURL,
title
}, [
vue.createElementVNode("div", _hoisted_4, [
modPic ? (vue.openBlock(), vue.createElementBlock("img", {
key: 0,
class: "cover",
src: modPic,
alt: title
}, null, 8, _hoisted_5)) : vue.createCommentVNode("", true),
vue.createElementVNode("span", _hoisted_6, vue.toDisplayString(title), 1)
])
], 8, _hoisted_3)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
vue.createTextVNode(vue.toDisplayString(title), 1)
], 64))
]),
_: 1
}, 8, ["expandedKeys", "selectedKeys", "tree-data"])
])
]);
};
}
});
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8268fb43"]]);
const app = vue.createApp(App);
const pinia = pinia$1.createPinia();
app.use(pinia);
app.use(antDesignVue.Tree);
app.mount(
(() => {
const nodeDiv = document.createElement("div");
nodeDiv.id = "app";
document.body.append(nodeDiv);
return nodeDiv;
})()
);
})(Vue, Pinia, antd);