- // ==UserScript==
- // @name CN POE Export
- // @namespace https://github.com/cn-poe-community/cn-poe-export-monkey
- // @version 0.0.13
- // @description Export CN POE data.
- // @author me1ting
- // @match https://poe.game.qq.com/my-account
- // @match https://poe.game.qq.com/account/view-profile/*
- // @match https://poe.game.qq.com/forum
- // @icon https://poecdn.game.qq.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU2NvdXRpbmdSZXBvcnQiLCJ3IjoxLCJoIjoxLCJzY2FsZSI6MX1d/584635f3c8/ScoutingReport.png
- // @require https://unpkg.com/cn-poe-translator@0.2.6/dist/translator.global.js
- // @require https://unpkg.com/cn-poe-export-db@0.1.1/dist/db.global.js
- // @require https://unpkg.com/pob-building-creater@0.0.13/dist/creater.global.js
- // @require https://unpkg.com/pako@2.1.0/dist/pako_deflate.min.js
- // @require https://unpkg.com/axios@1.1.2/dist/axios.min.js
- // @require https://unpkg.com/vue@3.3.2/dist/vue.global.prod.js
- // @grant none
- // @license MIT
- // ==/UserScript==
-
- (function(){
- const {computed, ref, reactive, onMounted, openBlock, createElementBlock, Fragment, createElementVNode, withDirectives, vModelText, unref, renderList, toDisplayString, vModelSelect, createCommentVNode, pushScopeId, popScopeId, createBlock, createApp } = Vue;
-
- (function() {
- "use strict";
- try {
- if (typeof document != "undefined") {
- var elementStyle = document.createElement("style");
- elementStyle.appendChild(document.createTextNode("#exportContainer {\n position: fixed;\n bottom: 20px;\n left: 10px;\n z-index: 99999;\n}\n\n.line-container[data-v-69f05dbf] {\n display: flex;\n margin: 3px 0;\n min-height: 25px;\n}\n.line-container select[data-v-69f05dbf] {\n min-height: 25px;\n margin-right: 4px;\n min-width: 100px;\n}\n.line-container input[data-v-69f05dbf] {\n margin-right: 4px;\n}"));
- document.head.appendChild(elementStyle);
- }
- } catch (e) {
- console.error("vite-plugin-css-injected-by-js", e);
- }
- })();
- (function polyfill() {
- const relList = document.createElement("link").relList;
- if (relList && relList.supports && relList.supports("modulepreload")) {
- return;
- }
- for (const link of document.querySelectorAll('link[rel="modulepreload"]')) {
- processPreload(link);
- }
- new MutationObserver((mutations) => {
- for (const mutation of mutations) {
- if (mutation.type !== "childList") {
- continue;
- }
- for (const node of mutation.addedNodes) {
- if (node.tagName === "LINK" && node.rel === "modulepreload")
- processPreload(node);
- }
- }
- }).observe(document, { childList: true, subtree: true });
- function getFetchOpts(link) {
- const fetchOpts = {};
- if (link.integrity)
- fetchOpts.integrity = link.integrity;
- if (link.referrerPolicy)
- fetchOpts.referrerPolicy = link.referrerPolicy;
- if (link.crossOrigin === "use-credentials")
- fetchOpts.credentials = "include";
- else if (link.crossOrigin === "anonymous")
- fetchOpts.credentials = "omit";
- else
- fetchOpts.credentials = "same-origin";
- return fetchOpts;
- }
- function processPreload(link) {
- if (link.ep)
- return;
- link.ep = true;
- const fetchOpts = getFetchOpts(link);
- fetch(link.href, fetchOpts);
- }
- })();
- const main = "";
- const Panel_vue_vue_type_style_index_0_scoped_69f05dbf_lang = "";
- const _export_sfc = (sfc, props) => {
- const target = sfc.__vccOpts || sfc;
- for (const [key, val] of props) {
- target[key] = val;
- }
- return target;
- };
- const _withScopeId = (n) => (pushScopeId("data-v-69f05dbf"), n = n(), popScopeId(), n);
- const _hoisted_1 = { class: "line-container" };
- const _hoisted_2 = ["disabled"];
- const _hoisted_3 = { class: "line-container" };
- const _hoisted_4 = { key: 0 };
- const _hoisted_5 = ["value"];
- const _hoisted_6 = ["value"];
- const _hoisted_7 = ["disabled"];
- const _hoisted_8 = { key: 1 };
- const _hoisted_9 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createElementVNode("select", { disabled: "" }, null, -1));
- const _hoisted_10 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createElementVNode("select", { disabled: "" }, null, -1));
- const _hoisted_11 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createElementVNode("button", { disabled: "" }, "导出", -1));
- const _hoisted_12 = [
- _hoisted_9,
- _hoisted_10,
- _hoisted_11
- ];
- const _hoisted_13 = { class: "line-container" };
- const _hoisted_14 = ["value"];
- const _hoisted_15 = ["disabled"];
- const realm = "pc";
- const _sfc_main$1 = {
- __name: "Panel",
- setup(__props) {
- const accountName = ref("");
- const characters = ref([]);
- const leagues = ref([]);
- const leagueMap = ref(/* @__PURE__ */ new Map());
- const currLeague = ref("");
- const currCharacters = ref([]);
- const currCharacter = ref("");
- const buildingCode = ref("");
- const state = reactive({
- accountName,
- realm,
- characters,
- leagues,
- leagueMap,
- currLeague,
- currCharacters,
- currCharacter,
- buildingCode
- });
- const getCharactersReady = computed(() => {
- return Boolean(state.accountName);
- });
- const selectReady = computed(() => {
- return state.characters.length > 0;
- });
- const exportReady = computed(() => {
- return state.characters.length > 0 && Boolean(state.currCharacter);
- });
- function selectNewLeague() {
- state.currCharacters = state.leagueMap.get(state.currLeague);
- state.currCharacter = state.currCharacters[0].name;
- }
- function getCharacters() {
- const url = "/character-window/get-characters";
- const realm2 = state.realm;
- const accountName2 = state.accountName;
- let form = new URLSearchParams();
- form.append("accountName", accountName2);
- form.append("realm", realm2);
- state.currLeague = "";
- state.currCharacter = "";
- axios.post(url, form).then((res) => {
- const characters2 = res.data;
- state.characters = characters2;
- let leagueMap2 = /* @__PURE__ */ new Map();
- for (const character of characters2) {
- const leagueName = character.league;
- let list = leagueMap2.get(leagueName);
- if (list === void 0) {
- list = [];
- leagueMap2.set(leagueName, list);
- }
- list.push(character);
- }
- state.leagueMap = leagueMap2;
- const leagues2 = Array.from(leagueMap2.keys());
- state.leagues = leagues2;
- if (leagues2.length > 0) {
- state.currLeague = leagues2[0];
- selectNewLeague();
- }
- }).catch((err) => {
- state.leagues = [];
- state.characters = [];
- console.log(err);
- alert(err);
- });
- }
- async function getItems() {
- const url = "/character-window/get-items";
- const realm2 = state.realm;
- const accountName2 = state.accountName;
- const character = state.currCharacter;
- let form = new URLSearchParams();
- form.append("accountName", accountName2);
- form.append("realm", realm2);
- form.append("character", character);
- const res = await axios.post(url, form);
- return res.data;
- }
- async function getPassiveSkills() {
- const url = "/character-window/get-passive-skills";
- const realm2 = state.realm;
- const accountName2 = state.accountName;
- const character = state.currCharacter;
- let params = new URLSearchParams();
- params.append("accountName", accountName2);
- params.append("realm", realm2);
- params.append("character", character);
- const res = await axios.get(url, { params });
- return res.data;
- }
- const factory = CnPoeTranslator.newBasicTranslatorFactory(CnPoeExportDb);
- const jsonTranslator = factory.getJsonTranslator();
- async function exportBuilding() {
- let items;
- let passiveSkills;
- try {
- items = await getItems();
- passiveSkills = await getPassiveSkills();
- } catch (err) {
- alert(`加载角色数据失败: ${err}`);
- }
- jsonTranslator.translateItems(items);
- jsonTranslator.translatePassiveSkills(passiveSkills);
- const building = BuildingCreater.transform(items, passiveSkills);
- const compressed = window.pako.deflate(building.toString());
- const code = btoa(String.fromCharCode.apply(null, compressed)).replaceAll("+", "-").replaceAll("/", "_");
- state.buildingCode = code;
- }
- function copyBuildingCode() {
- navigator.clipboard.writeText(state.buildingCode);
- }
- function getInitialAccountName() {
- let accountName2 = getAccountNameFromProfileLink(window.location.href);
- if (accountName2 !== null) {
- return accountName2;
- }
- const profileLinkNode = document.querySelector("#statusBar .profile-link a");
- if (profileLinkNode !== null) {
- accountName2 = getAccountNameFromProfileLink(profileLinkNode.href);
- if (accountName2 !== null) {
- return accountName2;
- }
- }
- return "";
- }
- const pattern = new RegExp("/account/view-profile/([^/?]+)");
- function getAccountNameFromProfileLink(link) {
- const match = pattern.exec(link);
- if (match) {
- return decodeURI(match[1]);
- }
- return null;
- }
- onMounted(() => {
- state.accountName = getInitialAccountName();
- });
- return (_ctx, _cache) => {
- return openBlock(), createElementBlock(Fragment, null, [
- createElementVNode("span", _hoisted_1, [
- withDirectives(createElementVNode("input", {
- type: "text",
- placeholder: "输入论坛账户名",
- maxlength: "50",
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => state.accountName = $event)
- }, null, 512), [
- [
- vModelText,
- state.accountName,
- void 0,
- { trim: true }
- ]
- ]),
- createElementVNode("button", {
- onClick: getCharacters,
- disabled: !getCharactersReady.value
- }, "开始", 8, _hoisted_2)
- ]),
- createElementVNode("span", _hoisted_3, [
- selectReady.value ? (openBlock(), createElementBlock("div", _hoisted_4, [
- selectReady.value ? withDirectives((openBlock(), createElementBlock("select", {
- key: 0,
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => state.currLeague = $event),
- onChange: selectNewLeague
- }, [
- (openBlock(true), createElementBlock(Fragment, null, renderList(leagues.value, (item) => {
- return openBlock(), createElementBlock("option", {
- key: item,
- value: item
- }, toDisplayString(item), 9, _hoisted_5);
- }), 128))
- ], 544)), [
- [vModelSelect, state.currLeague]
- ]) : createCommentVNode("", true),
- selectReady.value ? withDirectives((openBlock(), createElementBlock("select", {
- key: 1,
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => state.currCharacter = $event)
- }, [
- (openBlock(true), createElementBlock(Fragment, null, renderList(state.currCharacters, (item) => {
- return openBlock(), createElementBlock("option", {
- key: item.name,
- value: item.name
- }, toDisplayString(item.name) + "," + toDisplayString(item.level) + "," + toDisplayString(item.class), 9, _hoisted_6);
- }), 128))
- ], 512)), [
- [vModelSelect, state.currCharacter]
- ]) : createCommentVNode("", true),
- selectReady.value ? (openBlock(), createElementBlock("button", {
- key: 2,
- disabled: !exportReady.value,
- onClick: exportBuilding
- }, "导出", 8, _hoisted_7)) : createCommentVNode("", true)
- ])) : (openBlock(), createElementBlock("div", _hoisted_8, _hoisted_12))
- ]),
- createElementVNode("span", _hoisted_13, [
- createElementVNode("input", {
- disabled: "",
- maxlength: "50",
- value: state.buildingCode
- }, null, 8, _hoisted_14),
- createElementVNode("button", {
- onClick: copyBuildingCode,
- disabled: !state.buildingCode
- }, "复制", 8, _hoisted_15)
- ])
- ], 64);
- };
- }
- };
- const Panel = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-69f05dbf"]]);
- const _sfc_main = {
- __name: "Exporter",
- setup(__props) {
- return (_ctx, _cache) => {
- return openBlock(), createBlock(Panel);
- };
- }
- };
- const container = document.createElement("div");
- container.id = "exportContainer";
- document.body.appendChild(container);
- createApp(_sfc_main).mount("#exportContainer");
-
- })();