GameMale
登陆 / 注册 搜索

USERCENTER

SEARCHSITE

搜索

查看: 1654|回复: 48
收起左侧

[功能优化] 【油猴脚本】GM论坛勋章百宝箱 部分魔改

    [复制链接] |关注本帖

SCP-s-1889-第二页『随时随地开启!』无尽的怀表『随时随地开启!』被释放的灵魂我已倾听,我已感受,我已思考十字叶章Futūrum(未来)可怖的眼球男巫之歌

     楼主| 星之子 发表于 2024-11-8 14:31:21 | 显示全部楼层 |阅读模式 |取消关注该作者的回复
    本帖最后由 星之子 于 2024-11-8 15:12 编辑
    前言
    本魔改是基于 @咸鱼鱼 开发的 GM 这一插件编写的(原帖链接 油叉链接)。

    主要改动

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


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



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

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

    代码

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

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

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

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

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

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

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

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

    33.         return uniqueValues;
    34.     }

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

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

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

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

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

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

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

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

    55.         postOrder(result);

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

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

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

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

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

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

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

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

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

    107.         modal.appendChild(button);
    108.     });

    109.     document.body.appendChild(modal);
    110. }

    111. // 增加 CSS 样式
    112. const style = document.createElement('style');
    113. style.textContent = `
    114.     .modal-scheme-selection {
    115.         position: fixed;
    116.         top: 50%;
    117.         left: 50%;
    118.         transform: translate(-50%, -50%);
    119.         padding: 24px;
    120.         z-index: 1000;
    121.         border-radius: 10px;
    122.         background-color: #f3f3f3;
    123.     }
    124.     .scheme-button, .close-button {
    125.         background-color: transparent;
    126.         border: 0.125em solid #1A1A1A;
    127.         border-radius: 0.4em;
    128.         color: #3B3B3B;
    129.         font-size: 14px;
    130.         font-weight: 600;
    131.         margin: 0px 0.8em;
    132.         padding: 0.4em 1.2em;
    133.         text-align: center;
    134.         text-decoration: none;
    135.         cursor: pointer;
    136.         transition: all 300ms cubic-bezier(.23, 1, 0.32, 1);
    137.         font-family: Noto Sans SC, Microsoft Yahei, Arial, sans-serif;
    138.     }
    139.     .scheme-button:hover, .close-button:hover {
    140.         color: #fff;
    141.         background-color: #1A1A1A;
    142.         box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
    143.         transform: translateY(-2px);
    144.     }
    145.     .scheme-button:active, .close-button:active {
    146.         box-shadow: none;
    147.         transform: translateY(0);
    148.     }
    149. `;
    150. document.head.appendChild(style);

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

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

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

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

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

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

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

    189.     // 根据映射对 array 排序
    190.     array.sort((a, b) => {
    191.         return (indexMap[a.name] || Infinity) - (indexMap[b.name] || Infinity);
    192.     });

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

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

    201.     for (const key in data) {
    202.         if (data.hasOwnProperty(key)) {
    203.             formData.append(key, data[key]);
    204.         }
    205.     }

    206.     fetch(url, {
    207.         method: 'POST',
    208.         body: formData,
    209.     })
    210.         .then(response => {
    211.             location.reload(); // 刷新页面
    212.             if (!response.ok) {
    213.                 throw new Error('Network response was not ok');
    214.             }
    215.         })
    216.         .then(data => {
    217.             console.log('Success:', data);
    218.         })
    219.         .catch(error => {
    220.             console.error('Error:', error);
    221.         });
    222. }
    复制代码

    求赞环节


    来自群组: 星象占卜

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    评分

    参与人数 12血液 +40 追随 +12 堕落 +7 收起 理由
    singto + 1 + 1
    Pshall4Cle + 1 + 1
    仿生人2778号 + 1 + 1
    Okabe + 2 + 1 很给力!
    折木 + 5 + 1 + 1 很给力!
    大零食主义 + 1 + 1 + 1 赞一个
    PURO_ + 1 + 1 不错!
    黑炭先森 + 1
    亚洛斯 + 8 + 1 + 1 赞一个!
    紫漾Aro + 1 很给力!

    查看全部评分

    本帖被以下淘专辑推荐:

    回复

    使用道具 举报

    金猪猪储蓄罐㊖『随时随地开启!』漂洋小船『随时随地开启!』冒险用指南针破损的旧书丛林的鸟飞走了雪王的心脏人鱼之泪幽灵竹筒

      回复

      使用道具 举报

      『圣洁化身』虚空之海的鲸泰比里厄斯岛田源氏超人.杰森‧斯坦森.月光骑士月光骑士安杜因·乌瑞恩丹妮莉丝·坦格利安

        回复

        使用道具 举报

        枕套幽灵GHOST神奇四叶草

          回复

          使用道具 举报

          乘风破浪的武士刀『召唤好运的角笛』男巫之歌

            回复

            使用道具 举报

            石肤术金猪猪储蓄罐㊖实现梦想業火死鬥魔法不朽·传奇不熄卡洛斯·奥利维拉白野威十年一梦官复原职男巫之歌

              回复

              使用道具 举报

              森林鹿金牌矿工熔岩鹰不曾寄出的信件格拉迪欧拉斯小丑与格雷与星光璀璨御医神兔月光骑士最终幻想XVI

                回复

                使用道具 举报

                猩红魔鹫裸体克里斯永远的克叔不朽之恋

                  回复

                  使用道具 举报

                  BIG BOSS虚空之海的鲸雄躯的昇格爬行植物Ⓛ粉猪猪储蓄罐㊖爬行植物Ⓡ

                    回复

                    使用道具 举报

                    百相千面-晦永远的克叔業火死鬥实现梦想官复原职虚空之海的鲸Zootopia幸运女神的微笑『逆境中的幸运女神』御医神兔

                      回复

                      使用道具 举报

                      牧羊人猎鹰图腾眼镜蛇图腾寻觅库伦 (审判)山猫图腾【新手友好】昆進

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

                        使用道具 举报

                        炽天使之拥GHOST幸运女神的微笑官复原职丹妮莉丝·坦格利安普隆普特·阿金塔姆克莱夫・罗兹菲尔德骑兽之子不朽之恋赛博朋克2077

                          回复

                          使用道具 举报

                          枕套幽灵『樱花树灵』

                            回复

                            使用道具 举报

                            Drover.冒险专用绳索格拉迪欧拉斯金牌矿工索尔·奥丁森.『逆境中的幸运女神』骑兽之子岛田源氏杰西·麦克雷

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

                              使用道具 举报

                              阿怪GHOST吃饱金币的Doge秘密空瓶裸体克里斯【圣诞限定】心心念念小雪人【夏日限定】夏日的泰凯斯史莱姆牧场虚空之海的鲸不朽之恋

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

                                使用道具 举报

                                20x43 隐形➀吃饱金币的Doge冒险用指南针金牌矿工小小安全帽小小舞台阿拉喵?神灯金猪猪储蓄罐㊖『梦旅存根』

                                  回复

                                  使用道具 举报

                                  BIG BOSS肥皂铁牛泰比里厄斯吃饱金币的Doge亚瑟‧摩根自由克里斯·埃文斯艾吉奥杰森‧斯坦森.

                                    回复

                                    使用道具 举报

                                    希尔瓦娜斯·风行者麦迪文(Medivh).阿尔萨斯‧米奈希尔枯荣明灭卡德加(Khadgar).安杜因·乌瑞恩我的天使夏日柯基幸福的小阿尔吃饱金币的Doge

                                      回复

                                      使用道具 举报

                                      真理世界灵光补脑剂我的天使GM吸血伯爵吃饱金币的Doge阿拉喵?神灯和你一起飞行的皮卡丘小小舞台永浴爱河

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

                                        使用道具 举报

                                        火柴 - Gamemale萨菲罗斯炽天使之拥亚索诺克提斯·路西斯·伽拉姆官复原职業火死鬥璀璨之焰虚空之海的鲸

                                          回复

                                          使用道具 举报

                                          您需要登录后才可以回帖 登录 | 立即注册

                                          本版积分规则

                                          文字版|手机版|小黑屋|GameMale

                                          GMT+8, 2024-11-21 18:51 , Processed in 0.143628 second(s), 146 queries , Redis On.

                                          Copyright © 2013-2024 GameMale

                                          All Rights Reserved.

                                          快速回复 返回列表