星之子 发表于 7 天前

【油猴脚本】GM论坛勋章百宝箱 部分魔改

本帖最后由 星之子 于 2024-11-8 15:12 编辑

前言
本魔改是基于 @咸鱼鱼 开发的 GM论坛勋章百宝箱 这一插件编写的(原帖链接 油叉链接)。

主要改动
1. 在“保存勋章顺序”时指定名称,保存多个不同的方案,以便随时切换配装。
这个功能有点像QQ秀/小花仙保存装扮的感觉,一键切换成另一套衣服。具体使用方法如下:
①保存顺序时可以任意指定名称,以“keyOrder_后缀”的形式储存到 localStorage。
但一些过于刁钻的字符可能导致出错,这里没做测试(偷懒)。


②还原顺序时会弹出窗口。
点击取消无事发生。对于已保存的方案:左键单击即进行排序;右键单击删除方案(会弹出窗口二次确认)。



2. 保存顺序时,在“忽略列表”中的勋章默认排在末尾。

上述列表中,第一行是不可续期的赠礼/咒术,第二行是可续期的。
这个忽略列表可以依据个人喜好自行调整,比如把长得难看、不喜欢的勋章写进去等等。

代码
使用方法:请直接用下方代码,替换原脚本的 795 - 964 行。
// 对照版本:GM论坛勋章百宝箱 2.1.1【数据库更新时间2024.11.04】
// 使用方法:请用本段代码替换原来的 795 - 964 行
// 勋章排序
createLink('按照类型排序', kindOrder);

// 忽略列表设置 将想要直接移动到保存顺序末尾的勋章(通常是赠礼或咒术类)按你想要的顺序排在这里即可
const ignoreList = [
    "遗忘之水", "萨赫的蛋糕", "神秘商店贵宾卡", "雷霆晶球", "吞食魂魄", "闪光糖果盒", "杀意人偶", "太空列车票", "水泡术", "霍格沃茨五日游", "送情书", "千杯不醉", "变骚喷雾", "丢肥皂", "茉香啤酒", "咆哮诅咒", "灵光补脑剂", "祈祷术", "没有梦想的咸鱼",
    "思绪骤聚", "召唤古代战士", "炼金之心", "黑暗交易", "石肤术"];

function kindOrder() {
    // 获取所有匹配的元素
    const elements = document.querySelectorAll('.my_fenlei .myblok');
    const elementsArray = Array.from(elements);

    // 使用 map 函数处理每个元素
    const xunzhangList = elementsArray.map(myBlock => {
      const key = myBlock.getAttribute('key');
      const nameElement = myBlock.querySelector('p b'); // 找到包含名称的 <b> 标签
      const name = nameElement ? nameElement.textContent : '';
      return { : key };
    });

    // 使用 reduce 合并字典
    const mergedDict = xunzhangList.reduce((acc, curr) => {
      return { ...acc, ...curr };
    }, {});

    // 填补未知的勋章
    const mergedDictKey = Object.keys(mergedDict);
    const allCategoriesData = Object.values(categoriesData).flat();
    categoriesData.other = findUniqueValues(mergedDictKey, allCategoriesData);

    function findUniqueValues(a, b) {
      // 将数组 b 转换为一个 Set,以提高查找效率
      const setB = new Set(b);

      // 过滤出在 a 中且不在 b 中的值
      const uniqueValues = a.filter(value => !setB.has(value));

      return uniqueValues;
    }

    const previousInput = localStorage.getItem('sortInput') || orderList.join(' ');

    // 弹出输入框,默认值为之前的内容
    const userInput = prompt("您正在进行按类别排序,是否需要类别顺序?(用空格分隔):", previousInput);

    // 如果用户输入了内容
    if (userInput !== null) {
      // 将输入的内容转换为数组并进行排序
      const sortedArray = userInput.split(' ').map(item => item.trim());

      // 验证用户输入的合理性,如果不全或者输入错误,就给他补全
      // 过滤 userInput,保留在 orderList 中的项
      const filteredInput = sortedArray.filter(item => orderList.includes(item));

      // 找出 orderList 中缺失的元素
      const missingItems = orderList.filter(item => !filteredInput.includes(item));

      // 将 filteredInput 和 missingItems 合并,missingItems 加在最后
      const resultInput = [...filteredInput, ...missingItems];

      // 保存到 localStorage
      localStorage.setItem('sortInput', resultInput.join(' '));

      // 按类别拼接对应的Key
      const order1 = sortedArray.map(e => categoriesData]);
      const order2 = [].concat(...order1);
      const result = order2.map(key => mergedDict).filter(value => value !== undefined);

      postOrder(result);

      // 输出排序后的结果
      alert("排序后的结果:\n" + sortedArray.join(', '));
    }
}

// 新增按钮保存/还原勋章顺序
createLink('保存勋章顺序', saveKeysOrder);
createLink('还原勋章顺序', showSchemeSelectionModal);

// 保存勋章顺序
function saveKeysOrder() {
    const keys = getKeysFromDivs();
    const filteredKeys = keys.filter(key => !ignoreList.includes(key)); // 过滤掉忽略列表中的勋章
    const schemeName = prompt("请输入保存方案的名称");
    if (schemeName) {
      // 追加忽略列表到最后
      const finalKeysOrder = [...filteredKeys, ...ignoreList];
      saveArrayToLocalStorage(`keyOrder_${schemeName}`, finalKeysOrder);
      //alert('保存成功');
    }
}

// 显示方案选择窗口
function showSchemeSelectionModal() {
    const schemeNames = Object.keys(localStorage).filter(key => key.startsWith('keyOrder_')).map(key => key.replace('keyOrder_', ''));
    const modal = document.createElement('div');
    modal.classList.add('modal-scheme-selection');

    const closeButton = document.createElement('button');
    closeButton.textContent = '取消';
    closeButton.classList.add('close-button');
    closeButton.onclick = () => {
      document.body.removeChild(modal);
    };

    // 先添加“取消”按钮
    modal.appendChild(closeButton);

    schemeNames.forEach(schemeName => {
      const button = document.createElement('button');
      button.textContent = schemeName;
      button.classList.add('scheme-button');

      // 左键单击还原
      button.onclick = () => {
            loadKeysOrder(schemeName);
            document.body.removeChild(modal);
      };

      // 右键单击删除
      button.oncontextmenu = (e) => {
            e.preventDefault(); // 阻止默认右键菜单
            if (confirm(`确定删除方案 "${schemeName}" 吗?`)) {
                removeArrayFromLocalStorage(`keyOrder_${schemeName}`);
                //alert(`方案 "${schemeName}" 已删除`);
                document.body.removeChild(modal); // 关闭窗口以刷新列表
                showSchemeSelectionModal(); // 重新显示更新后的方案列表
            }
      };

      modal.appendChild(button);
    });

    document.body.appendChild(modal);
}

// 增加 CSS 样式
const style = document.createElement('style');
style.textContent = `
    .modal-scheme-selection {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      padding: 24px;
      z-index: 1000;
      border-radius: 10px;
      background-color: #f3f3f3;
    }
    .scheme-button, .close-button {
      background-color: transparent;
      border: 0.125em solid #1A1A1A;
      border-radius: 0.4em;
      color: #3B3B3B;
      font-size: 14px;
      font-weight: 600;
      margin: 0px 0.8em;
      padding: 0.4em 1.2em;
      text-align: center;
      text-decoration: none;
      cursor: pointer;
      transition: all 300ms cubic-bezier(.23, 1, 0.32, 1);
      font-family: Noto Sans SC, Microsoft Yahei, Arial, sans-serif;
    }
    .scheme-button:hover, .close-button:hover {
      color: #fff;
      background-color: #1A1A1A;
      box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
      transform: translateY(-2px);
    }
    .scheme-button:active, .close-button:active {
      box-shadow: none;
      transform: translateY(0);
    }
`;
document.head.appendChild(style);

// 获取所有具有指定类名的div元素
function getKeysFromDivs() {
    const divs = document.querySelectorAll(`div.myblok`);
    const keys = Array.from(divs).map(div => div.querySelector('img').alt);
    return keys;
}

// 从本地存储获取数组
function getArrayFromLocalStorage(key) {
    const storedArray = localStorage.getItem(key);
    return storedArray ? JSON.parse(storedArray) : null;
}

// 从本地存储删除数组
function removeArrayFromLocalStorage(key) {
    localStorage.removeItem(key);
}

// 保存数组到本地存储
function saveArrayToLocalStorage(key, array) {
    localStorage.setItem(key, JSON.stringify(array));
}

// 还原勋章顺序
function loadKeysOrder(schemeName) {
    const keys = getArrayFromLocalStorage(`keyOrder_${schemeName}`);
    if (!keys) {
      alert(`未找到方案 "${schemeName}"`);
      return;
    }

    const divs = document.querySelectorAll(`div.myblok`);
    const array = Array.from(divs).map(div => {
      return {
            name: div.querySelector('img').alt,
            key: div.getAttribute('key')
      };
    });

    // 创建 name 到 key 的索引映射
    const indexMap = {};
    keys.forEach((value, index) => {
      indexMap = index + 1;
    });

    // 根据映射对 array 排序
    array.sort((a, b) => {
      return (indexMap || Infinity) - (indexMap || Infinity);
    });

    const orderKey = array.map(e => e.key);
    postOrder(orderKey);
}

// 发送排序请求
function postOrder(newOrder) {
    const url = 'https://www.gamemale.com/plugin.php?id=wodexunzhang:showxunzhang';
    const formData = new FormData();
    const data = { newOrder, action: 'newOrder' };

    for (const key in data) {
      if (data.hasOwnProperty(key)) {
            formData.append(key, data);
      }
    }

    fetch(url, {
      method: 'POST',
      body: formData,
    })
      .then(response => {
            location.reload(); // 刷新页面
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
      })
      .then(data => {
            console.log('Success:', data);
      })
      .catch(error => {
            console.error('Error:', error);
      });
}
求赞环节
https://img.gamemale.com/album/202405/31/001344ngqe3xzhqghtgm3f.jpg
星象占卜

凯诺斯 发表于 7 天前

可以保存方案确实不错惹,可以随时进行切换{:6_169:}

大河内太 发表于 7 天前

还以为素才女走..
哦 确实素才女厚{:6_169:}

折棒 发表于 7 天前

萌新有点看不懂惹_(:з)∠)_

紫漾Aro 发表于 7 天前

保存方案可太舒服了,直接美美的一键替换,爽到{:4_86:}

Burry 发表于 7 天前

勋章也能设计方案保存,挺实用脚本。

随心110 发表于 7 天前

好有趣的功能惹~~~这样勋章列表看着就能更美观也跟方便管理惹~~~

亚洛斯 发表于 7 天前

看着很不错的修改的说~多套方案多套切换~

cinder 发表于 7 天前

選項增加了呢,不小心點到回收真的很吐血./w\

娱乐法师火布偶 发表于 7 天前

忽略列表的修改也是很方便了

kimidave 发表于 7 天前

好细心的功能,用心了,可惜我现在勋章很少呢,不过总有一天用得上先码住啦

2297988 发表于 7 天前

看着还是很有用的哇,对强迫症坛友来说很方便了XD

2674820557 发表于 7 天前

感谢分享,但素本可还用不到,呜呜,都没几个勋章

PURO_ 发表于 7 天前

这个脚本适合勋章多的人使用,而且原脚本有过了勋章统计这对俺来说已经够用了{:4_114:}

前方无怪 发表于 7 天前

启动!超级形态!一键变装!这下可以每次不用花大把力气在整理排列美观上了!

不是卖萌的基佬 发表于 7 天前

感觉还不错 等回家试试看这个功能

提尔特 发表于 7 天前

{:6_169:}用过后 勋章变得精美多了

Riverlethe 发表于 7 天前

哈哈哈这标签很调皮啊,回宫那个一看就是灵魂分类的

毛茸茸兽兽 发表于 7 天前

看到有个奇奇怪怪的命名诶(´×ω×`)
挺方便一键切换金币向或血液向之类的排名哇

折木 发表于 7 天前

勋章商场已经被玩出花了(´▽`ʃ♡ƪ)
页: [1] 2 3
查看完整版本: 【油猴脚本】GM论坛勋章百宝箱 部分魔改