- // ==UserScript==
- // @name WoD 物品标记
- // @icon http://info.world-of-dungeons.org/wod/css/WOD.gif
- // @namespace WOD_Tools
- // @description 阿沐的物品标记,被标记的物品很大概率会被处理给钱袋
- // @author Christophero
- // @include http*://*.world-of-dungeons.org/wod/spiel/hero/items.php?*
- // @license MIT License
- // @require https://code.jquery.com/jquery-3.3.1.min.js
- // @require https://cdn.jsdelivr.net/npm/slim-select@2.4.5/dist/slimselect.umd.min.js
- // @resource slimselect_css https://cdn.jsdelivr.net/npm/slim-select@2.4.5/dist/slimselect.min.css
- // @grant GM_addStyle
- // @grant GM_getResourceText
- // @connect www.christophero.xyz
- // @modifier Christophero
- // @version 2023.04.16.2
- // ==/UserScript==
-
- (function () {
- ("use strict");
-
- const MARK_ITEM_OPTION_KEY = "MARK_ITEM_OPTION_KEY";
-
- initComponent();
-
- function saveOption(option) {
- return localStorage.setItem(MARK_ITEM_OPTION_KEY, JSON.stringify(option));
- }
-
- function loadOption() {
- let localMarkItemOption = {};
- const localMarkItemOptionText = localStorage.getItem(MARK_ITEM_OPTION_KEY);
- if (!localMarkItemOptionText) {
- localMarkItemOption = {
- blue: {
- color: "#3498DB",
- label: "蓝色",
- items: [],
- },
- green: {
- color: "#28B463",
- label: "绿色",
- items: [],
- },
- red: {
- color: "#E74C3C",
- label: "红色",
- items: [],
- },
- orange: {
- color: "#D35400",
- label: "橙色",
- items: [],
- },
- };
- } else {
- localMarkItemOption = JSON.parse(localMarkItemOptionText);
- }
- return localMarkItemOption;
- }
-
- /**
- * 导出文件的方法,导出并直接进行下载
- *
- * @param {String} 传入导出文件的数据, 格式为字符串
- * @param {String} 导出文件的文件名称
- */
- const exportFile = (
- text = "",
- filename = "分析内容.txt",
- exportCsv = false
- ) => {
- let blob;
- // 导出数据
- if (exportCsv) {
- blob = new Blob(["\ufeff" + text], {
- type: "text/csv;charset=utf-8;",
- });
- } else {
- blob = new Blob([text]);
- }
- const e = new MouseEvent("click");
- const a = document.createElement("a");
-
- a.download = filename;
- a.href = window.URL.createObjectURL(blob);
- a.dispatchEvent(e);
- };
-
- function exportOption() {
- exportFile(JSON.stringify(loadOption()), "物品标记.json");
- }
-
- const importFileJSON = (ev) => {
- return new Promise((resolve, reject) => {
- const fileDom = ev.target,
- file = fileDom.files[0];
-
- // 格式判断
- if (file.type !== "application/json") {
- reject("仅允许上传json文件");
- }
- // 检验是否支持FileRender
- if (typeof FileReader === "undefined") {
- reject("当前浏览器不支持FileReader");
- }
-
- // 执行后清空input的值,防止下次选择同一个文件不会触发onchange事件
- ev.target.value = "";
-
- // 执行读取json数据操作
- const reader = new FileReader();
- reader.readAsText(file); // 读取的结果还有其他读取方式,我认为text最为方便
-
- reader.onerror = (err) => {
- reject("json文件解析失败", err);
- };
-
- reader.onload = () => {
- const resultData = reader.result;
- if (resultData) {
- try {
- const importData = JSON.parse(resultData);
- resolve(importData);
- } catch (error) {
- reject("读取数据解析失败", error);
- }
- } else {
- reject("读取数据解析失败", error);
- }
- };
- });
- };
-
- function importOption(event) {
- importFileJSON(event)
- .then((option) => {
- console.log("读取到的数据", option);
- saveOption(option);
- alert("导入物品标记数据成功,刷新页面");
- location.reload();
- })
- .catch((err) => {
- console.log(err);
- });
- }
-
- //
- function initComponent() {
- GM_addStyle(GM_getResourceText("slimselect_css"));
- GM_addStyle(
- ".ss-main.mark-select {display: inline-flex !important; width: 120px;}"
- );
-
- const itemSelectMap = {};
- let localMarkItemOption = loadOption();
- let markItemMap = {};
- const markData = [{ html: "<b>无标记</b>", text: "无标记", value: "" }];
- for (let key of Object.keys(localMarkItemOption)) {
- let colorOption = localMarkItemOption[key];
- markData.push({
- html: `<b style="color: ${colorOption.color}">${colorOption.label}</b>`,
- text: colorOption.label,
- value: key,
- });
- colorOption.items.forEach((itemName) => {
- markItemMap[itemName] = key;
- });
- }
- $(".layout_clear .content_table a[href*='item_instance_id']").each(
- function (i, e) {
- const params = $(e).attr("href").split("?")[1];
- const instanceId = new URLSearchParams(params).get("item_instance_id");
- // 道具名称
- const itemName = e.text.replace(/!$/, "");
- const $td = $("<td></td>");
- const $checkbox = $(`<input type="checkbox" class="check-to-mark">`)
- .data("instanceid", instanceId)
- .data("itemname", itemName);
- const $select = $(`<select class="mark-select"></select>`);
-
- $td.append($select, $checkbox);
- $(e).parents("tr:first").append($td);
- const copyMarkData = JSON.parse(JSON.stringify(markData));
- for (let opt of copyMarkData) {
- if (opt.value === markItemMap[itemName]) {
- opt.selected = true;
- }
- }
- const slimSelect = new SlimSelect({
- select: $select[0],
- value: markItemMap[itemName],
- data: copyMarkData,
- settings: {
- showSearch: false,
- },
- events: {
- beforeChange: ([{ value: newVal }], [{ value: oldVal }]) => {
- console.log(oldVal);
- console.log(newVal);
- // 有值切换到无值,则删除存储数据
- if (oldVal) {
- const originColor = markItemMap[itemName];
- const items = localMarkItemOption[originColor].items;
- items.splice(
- items.findIndex((item) => item === itemName),
- 1
- );
- delete markItemMap[itemName];
- saveOption(localMarkItemOption);
- }
- if (newVal) {
- if (!localMarkItemOption[newVal].items.includes(itemName)) {
- localMarkItemOption[newVal].items.push(itemName);
- }
- markItemMap[itemName] = newVal;
- }
- saveOption(localMarkItemOption);
- // return false; // this will stop the change from happening
- },
- },
- });
- itemSelectMap[instanceId] = slimSelect;
- }
- );
-
- // 添加导入导出与标记物品勾选
- const $itemMarkSelect = $('<select class="mark-select"></select>');
- const $exportBtn = $(
- '<input type="button" name="export" value="导出" class="button clickable">'
- ).click(exportOption);
- const $fileBtn = $(
- '<input type="file" id="cleanFile" name="cleanFile" runat="server" style="position:relative; z-index:10; filter:alpha(opacity=0);-moz-opacity:0; opacity:0; width: 65px; left:-65px;">'
- ).change(importOption);
- const $importBtn = $(
- '<input type="button" name="button" value="导入" class="button clickable" style="width:65px;">'
- );
- const $pageRow = $(".layout_clear .content_table .paginator_row.top");
- const $label = $("<span> 物品标记:</span>");
- $pageRow.append($label, $itemMarkSelect, $exportBtn, $importBtn, $fileBtn);
-
- const itemMarkSelect = new SlimSelect({
- select: $itemMarkSelect[0],
- data: markData,
- settings: {
- showSearch: false,
- },
- events: {
- afterChange: ([{ value: newVal }]) => {
- let needCheckedItems = localMarkItemOption[newVal];
- if (!needCheckedItems) return;
- needCheckedItems = needCheckedItems.items;
- $(".layout_clear .content_table a[href*='item_instance_id']").each(
- (i, e) => {
- const itemName = e.text.replace(/!$/, "");
- $(e)
- .parents("tr:first")
- .find('input[name^="doEquipItem["]')
- .prop("checked", needCheckedItems.includes(itemName));
- }
- );
- },
- },
- });
-
- // 添加标记列
- const $markTableHeader = $("<th></th>");
- const $markAllChk = $("<input type='checkbox' class='mark-all'>");
- const $batchSelect = $('<select class="mark-select"></select>');
- $(".layout_clear .content_table thead tr.header").append(
- $markTableHeader.append($batchSelect, $markAllChk)
- );
- $markAllChk.change(function () {
- if ($(this).is(":checked")) {
- $("input.check-to-mark").prop("checked", true);
- } else {
- $("input.check-to-mark").prop("checked", false);
- }
- });
- const batchSelect = new SlimSelect({
- select: $batchSelect[0],
- data: markData,
- settings: {
- showSearch: false,
- },
- events: {
- beforeChange: ([{ value: newVal }], [{ value: oldVal }]) => {
- $("input.check-to-mark:checked").each((i, e) => {
- const instanceId = $(e).data("instanceid");
- const itemName = $(e).data("itemname");
- select = itemSelectMap[instanceId];
- const preVal = select.getSelected()[0];
- select.setSelected(newVal);
- // 有值切换到无值,则删除存储数据
- if (preVal) {
- const originColor = markItemMap[itemName];
- const items = localMarkItemOption[originColor].items;
- items.splice(
- items.findIndex((item) => item === itemName),
- 1
- );
- delete markItemMap[itemName];
- }
- if (newVal) {
- if (!localMarkItemOption[newVal].items.includes(itemName)) {
- localMarkItemOption[newVal].items.push(itemName);
- }
- markItemMap[itemName] = newVal;
- }
- });
- // 有值切换到无值,则删除存储数据
- saveOption(localMarkItemOption);
- // return false; // this will stop the change from happening
- },
- // afterChange: ([{ value: newVal }]) => {
- // $("input.check-to-mark:checked").each((i, e) => {
- // const instanceId = $(e).data("instanceid");
- // select = itemSelectMap[instanceId];
- // select.setSelected(newVal);
- // });
- // },
- },
- });
- }
- })();