// ==UserScript==
// @name Genshin Impact Map Toggle Chest Pin Style
// @name:en Genshin Impact Map Toggle Chest Pin Style
// @name:zh 原神米游社大地图更换宝箱标点样式
// @name:zh-CN 原神米游社大地图更换宝箱标点样式
// @namespace WEGFan
// @version 1.1.0
// @author WEGFan
// @description Toggle chest pin style between type and obtain way on the fly in the Teyvat Interactive Map
// @description:en Toggle chest pin style between type and obtain way on the fly in the Teyvat Interactive Map
// @description:zh 原神米游社大地图实时切换解谜宝箱的标点样式,可选择显示品质或获取方式
// @description:zh-CN 原神米游社大地图实时切换解谜宝箱的标点样式,可选择显示品质或获取方式
// @license MIT
// @icon https://webstatic.mihoyo.com/ys/app/interactive-map/mapicon.png
// @homepage https://github.com/WEGFan/Genshin-Impact-Map-Toggle-Chest-Pin-Style
// @supportURL https://github.com/WEGFan/Genshin-Impact-Map-Toggle-Chest-Pin-Style/issues
// @match https://webstatic.mihoyo.com/ys/app/interactive-map/*
// @match https://act.hoyolab.com/ys/app/interactive-map/*
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/[email protected]/dist/index.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/i18next.min.js
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(t=>{const e=document.createElement("style");e.dataset.source="vite-plugin-monkey",e.textContent=t,document.head.append(e)})(' .wegfan__chest-marker-style-toggle .chest-marker-style-option{display:flex;justify-content:space-between;align-items:center;margin-top:.04rem;color:#ece6d9bf;font-size:.12rem}.wegfan__chest-marker-style-toggle .button-container{display:flex;gap:.1rem}.wegfan__chest-marker-style-toggle .button-container .button{height:.24rem;width:.57rem;border-radius:.06rem;background-color:#323947;background-position:50%;background-repeat:no-repeat;background-size:100%;overflow:hidden;line-height:.24rem;text-align:center;display:inline-block;white-space:nowrap;text-overflow:ellipsis;cursor:pointer;position:relative}.wegfan__chest-marker-style-toggle .button.selected{color:#d3bc8e}.wegfan__chest-marker-style-toggle .button.selected:after{position:absolute;display:block;content:"";top:0;left:0;width:100%;height:100%;border:.5px solid #d3bc8e;border-radius:.06rem;-webkit-box-sizing:border-box;box-sizing:border-box;z-index:2} ');
(function (i18next, VM) {
'use strict';
function _interopNamespaceDefault(e) {
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
if (e) {
for (const k in e) {
if (k !== 'default') {
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: () => e[k]
});
}
}
}
n.default = e;
return Object.freeze(n);
}
const VM__namespace = /*#__PURE__*/_interopNamespaceDefault(VM);
var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
const languageDetector = {
type: "languageDetector",
async: false,
detect() {
const url = new URL(location.href);
const lang = url.searchParams.get("lang");
if (lang) {
return lang;
}
if (url.host.includes("webstatic.mihoyo.com")) {
return "zh-cn";
}
if (url.host.includes("act.hoyolab.com")) {
return "en-us";
}
return "en-us";
}
};
const translation$1 = {
"解谜宝箱显示样式": '"Puzzle Chest" pin style',
"品质": "Type",
"获取方式": "Obtain way"
};
const enUs = {
translation: translation$1
};
const translation = {
"解谜宝箱显示样式": "解谜宝箱显示样式",
"品质": "品质",
"获取方式": "获取方式"
};
const zhCn = {
translation
};
const i18n = i18next.createInstance({
debug: false,
initImmediate: false,
lowerCaseLng: true,
fallbackLng: "en-us",
resources: {
"en-us": enUs,
"zh-cn": zhCn
}
}).use(languageDetector);
let i18nInited = false;
const init = () => {
var _a, _b;
const map = (_b = (_a = document.querySelector(".mhy-game-gis")) == null ? void 0 : _a.__vue__) == null ? void 0 : _b.map;
const markerLayers = Object.values((map == null ? void 0 : map._layers) ?? {}).filter((layer) => layer._drawMarker);
if (!map || !markerLayers) {
return;
}
if (!i18nInited) {
i18n.init();
i18nInited = true;
}
const insertMarkerStyleTogglePanel = () => {
const className = "wegfan__chest-marker-style-toggle";
if (document.querySelector(`.${className}`)) {
return;
}
const chestFilterPanelContentElement = document.querySelector('[id="13"]>div.filter-panel__labels-content');
if (!chestFilterPanelContentElement) {
return;
}
const panelElement = VM__namespace.m(
/* @__PURE__ */ VM__namespace.h("div", { className: "wegfan__chest-marker-style-toggle" }, /* @__PURE__ */ VM__namespace.h("div", { className: "chest-marker-style-option" }, /* @__PURE__ */ VM__namespace.h("span", null, i18n.t("解谜宝箱显示样式")), /* @__PURE__ */ VM__namespace.h("div", { className: "button-container" }, /* @__PURE__ */ VM__namespace.h("div", { className: "button", "data-chest-marker-style-index": "1", title: i18n.t("品质") }, i18n.t("品质")), /* @__PURE__ */ VM__namespace.h("div", { className: "button", "data-chest-marker-style-index": "2", title: i18n.t("获取方式") }, i18n.t("获取方式")))))
);
chestFilterPanelContentElement.parentElement.insertBefore(panelElement, chestFilterPanelContentElement);
const buttons = panelElement.querySelectorAll(".chest-marker-style-option .button");
const toggleMarkerStyle = (event) => {
event.preventDefault();
buttons.forEach((button) => button.classList.remove("selected"));
event.target.classList.add("selected");
_GM_setValue("markerStyle", event.target.getAttribute("data-chest-marker-style-index"));
markerLayers.forEach((layer) => {
layer._latlngMarkers.dirty = 1;
layer._latlngMarkers.total = 1;
layer.redraw();
});
};
buttons.forEach((button) => {
if (button.getAttribute("data-chest-marker-style-index") === _GM_getValue("markerStyle", "1")) {
button.classList.add("selected");
}
button.addEventListener("click", toggleMarkerStyle);
button.addEventListener("touchend", toggleMarkerStyle);
});
};
const hookMapDrawMarker = (layer) => {
if (layer._wegfan_toggleChestMarkerStyleHooked) {
return;
}
layer._drawMarker = function(t, e) {
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
let n = this;
this._imageLookup || (this._imageLookup = {}), e || (e = n._map.latLngToContainerPoint(t.getLatLng()));
let iconUrl = t.options.icon.options.iconUrl;
const markerStyle = _GM_getValue("markerStyle", "1");
if (markerStyle === "2") {
let extAttrs = (_b2 = (_a2 = t == null ? void 0 : t.attrs) == null ? void 0 : _a2.marker) == null ? void 0 : _b2.ext_attrs;
if (extAttrs) {
let chestSource = (_c = JSON.parse(extAttrs)) == null ? void 0 : _c["3"];
let sourceIconUrl = (_j = (_i = (_h = (_g = (_f = (_e = (_d = t == null ? void 0 : t.attrs) == null ? void 0 : _d.config) == null ? void 0 : _e.group) == null ? void 0 : _f.ext_attr_list) == null ? void 0 : _g[0]) == null ? void 0 : _h.children) == null ? void 0 : _i[chestSource]) == null ? void 0 : _j.icon;
if (sourceIconUrl) {
iconUrl = sourceIconUrl;
}
}
}
if (t.canvas_img && t.previousChestMarkerStyle !== markerStyle) {
t.canvas_img = null;
}
t.previousChestMarkerStyle = markerStyle;
if (t.canvas_img) {
n._drawImage(t, e);
} else if (n._imageLookup[iconUrl]) {
t.canvas_img = n._imageLookup[iconUrl][0], false === n._imageLookup[iconUrl][1] ? n._imageLookup[iconUrl][2].push([
t,
e
]) : n._drawImage(t, e);
} else {
let r = new Image();
r.crossOrigin = "Anonymous", r.src = iconUrl, t.canvas_img = r, n._imageLookup[iconUrl] = [
r,
false,
[
[
t,
e
]
]
], r.onload = function() {
n._imageLookup[iconUrl][1] = true, n._imageLookup[iconUrl][2].forEach(function(t2) {
n._drawImage(t2[0], t2[1]);
});
};
}
};
layer._wegfan_toggleChestMarkerStyleHooked = true;
};
insertMarkerStyleTogglePanel();
markerLayers.forEach((layer) => {
hookMapDrawMarker(layer);
});
};
init();
setInterval(init, 500);
})(i18next, VM);