// ==UserScript== // @name linodas卡组保存工具 // @namespace http://tampermonkey.net/ // @version 0.3 // @description 提供一个简单的界面来输入卡组ID、卡片名称和数量,并发送保存请求 // @author EviCalf // @match https://www.linodas.com/character/deck // @match https://www.linodas.com/character/deck/id/* // @grant none // ==/UserScript== (function() { 'use strict'; // 添加HTML元素 const customUI = document.createElement('div'); customUI.id = 'custom-ui'; customUI.style.backgroundColor = 'black'; customUI.style.padding = '10px'; customUI.style.border = '1px solid #ccc'; customUI.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)'; customUI.innerHTML = `

linodas卡组保存小工具

卡组列表

`; // 找到 wireframe 和 clearfloat 元素 const decklistFlex = document.querySelector('div.decklist.flex'); if (decklistFlex) { decklistFlex.parentNode.insertBefore(customUI, decklistFlex); } else { console.error('未找到 decklist flex 元素'); document.body.appendChild(customUI); // 如果未找到,则回退到body末尾插入 } function updateDeckList() { const deckListContainer = document.getElementById('deck-list'); deckListContainer.innerHTML = ''; const allDecks = loadAllDecks(); for (const deckName in allDecks) { if (allDecks.hasOwnProperty(deckName)) { const deckItem = document.createElement('div'); deckItem.className = 'deck-item'; deckItem.innerHTML = ` ${deckName} `; deckListContainer.appendChild(deckItem); } } // 添加删除按钮事件监听器 const deleteButtons = document.querySelectorAll('.delete-button'); deleteButtons.forEach(button => { button.addEventListener('click', function() { const deckName = this.getAttribute('data-deck-name'); deleteDeckFromLocalStorage(deckName); }); }); // 添加卡组名称点击事件监听器 const deckNames = document.querySelectorAll('.storage-deck-name'); deckNames.forEach(span => { span.addEventListener('click', function() { const deckName = this.getAttribute('data-deck-name'); const deckData = loadFromLocalStorage(deckName); console.log('Deck Name:', deckName); console.log('Deck Data:', deckData); if (deckData) { document.getElementById('deck-name').value = deckData.name; document.getElementById('card-details').value = deckData.details; } else { console.log('Deck data not found for:', deckName); } }); }); } // 获取所有Cookie function getAllCookies() { return document.cookie; } // 填充当前卡组信息 document.getElementById('fill-button').addEventListener('click', function() { const url = new URL(window.location.href); const pathSegments = url.pathname.split('/'); const deckIdIndex = pathSegments.indexOf('id'); const deckId = deckIdIndex !== -1 && pathSegments.length > deckIdIndex + 1 ? pathSegments[deckIdIndex + 1] : null; if (!deckId) { document.getElementById('response-output').innerHTML = '

请选中卡组名之后再读取!

'; return; } // 找到id为nowdeck的div元素 const nowdeckElement = document.getElementById('nowdeck'); const cardElements = nowdeckElement.querySelectorAll('div.cardlist.flex'); if (!deckId || cardElements.length === 0) { document.getElementById('response-output').innerHTML = '

未找到卡组ID或卡片信息。

'; return; } const cards = []; cardElements.forEach(cardElement => { const cardId = cardElement.id.replace('deck_card', '').replace('_div', ''); const cardNameTag = cardElement.querySelector('a.linodas_card.card.info.format'); const cardCountTag = cardElement.querySelector('span._DECK_CARD_NUM'); if (cardNameTag && cardCountTag) { const cardName = cardNameTag.getAttribute('data-card-id'); const cardCount = cardCountTag.textContent.trim(); cards.push(`card${cardName}=${cardCount}`); } }); document.getElementById('deck-id').value = deckId; document.getElementById('card-details').value = cards.join(', '); document.getElementById('response-output').innerHTML = '

当前卡组信息已填充。

'; }); // 添加提交按钮事件监听器 document.getElementById('submit-button').addEventListener('click', function() { const deckId = document.getElementById('deck-id').value; const deckName = document.getElementById('deck-name').value; const cardDetails = document.getElementById('card-details').value; const responseOutput = document.getElementById('response-output'); if (!deckId || !deckName || !cardDetails) { responseOutput.innerHTML = '

请填写所有字段。

'; return; } // 解析卡片名称和数量 const cardData = cardDetails.split(',').map(item => item.trim().split('=')); const cardParams = cardData.map(([key, value]) => `card[${key}]=${value}`).join('&'); // 构造请求参数 const url = 'https://www.linodas.com/json/deck/action/savedeck'; const headers = { 'accept': 'application/json, text/javascript, */*; q=0.01', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'cookie': getAllCookies(), 'dnt': '1', 'origin': 'https://www.linodas.com', 'priority': 'u=1, i', 'referer': `https://www.linodas.com/character/deck/id/${deckId}`, 'sec-ch-ua': '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0', 'x-requested-with': 'XMLHttpRequest' }; const body = `sel_gearid=${deckId}&${cardParams}`; // 发送请求 fetch(url, { method: 'POST', headers: headers, body: body }) .then(response => response.json()) .then(data => { // 刷新页面 location.reload(); }) .catch(error => { responseOutput.innerHTML = `

请求失败: ${error.message}

`; }); // 保存到LocalStorage saveToLocalStorage(deckName, cardDetails); }); // 保存卡组信息到LocalStorage function saveToLocalStorage(deckName, cardDetails) { const deckData = { name: deckName, details: cardDetails }; console.log('Saving Deck Data:', deckData); // 添加日志 // 保存到 allDecks let allDecks = JSON.parse(localStorage.getItem('allDecks')) || {}; allDecks[deckName] = deckData; localStorage.setItem('allDecks', JSON.stringify(allDecks)); // 保存到 deck_ localStorage.setItem('deck_' + deckName, JSON.stringify(deckData)); updateDeckList(); } // 从LocalStorage加载卡组信息 function loadFromLocalStorage(deckName) { const data = localStorage.getItem('deck_' + deckName); if (data) { const deckData = JSON.parse(data); console.log('Loaded Deck Data:', deckData); // 添加日志 return deckData; } console.log('No data found for deck:', deckName); // 添加日志 return null; } function loadAllDecks() { return JSON.parse(localStorage.getItem('allDecks')) || {}; } function deleteDeckFromLocalStorage(deckName) { let allDecks = JSON.parse(localStorage.getItem('allDecks')) || {}; delete allDecks[deckName]; localStorage.setItem('allDecks', JSON.stringify(allDecks)); updateDeckList(); } // 导出为文件按钮事件监听器 document.getElementById('save-button').addEventListener('click', function() { const allDecks = loadAllDecks(); if (Object.keys(allDecks).length === 0) { document.getElementById('response-output').innerHTML = '

没有卡组数据可以导出。

'; return; } // 将所有卡组数据转换为 JSON 字符串 const jsonData = JSON.stringify(allDecks, null, 2); // 创建 Blob 对象 const blob = new Blob([jsonData], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'all_decks.json'; a.click(); URL.revokeObjectURL(url); document.getElementById('response-output').innerHTML = '

所有卡组数据已导出为文件。

'; }); // 导入文件按钮事件监听器(从本地文件读取并保存到LocalStorage) document.getElementById('import-button').addEventListener('click', function() { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; // 修改为接受.json文件 input.addEventListener('change', function(event) { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { try { const allDecks = JSON.parse(e.target.result); // 清空当前的localStorage localStorage.removeItem('allDecks'); for (const deckName in allDecks) { if (allDecks.hasOwnProperty(deckName)) { localStorage.removeItem('deck_' + deckName); } } // 保存新的卡组信息到localStorage for (const deckName in allDecks) { if (allDecks.hasOwnProperty(deckName)) { saveToLocalStorage(deckName, allDecks[deckName].details); } } document.getElementById('response-output').innerHTML = '

所有卡组数据已成功导入并覆盖当前数据。

'; updateDeckList(); // 更新卡组列表 } catch (error) { document.getElementById('response-output').innerHTML = `

文件解析错误: ${error.message}

`; } }; reader.readAsText(file); } }); input.click(); }); // 本地保存按钮添加事件监听器 document.getElementById('local-save-button').addEventListener('click', function() { const deckName = document.getElementById('deck-name').value; const cardDetails = document.getElementById('card-details').value; if (!deckName || !cardDetails) { document.getElementById('response-output').innerHTML = '

请填写卡组名称和卡片信息。

'; return; } // 调用现有的保存函数 saveToLocalStorage(deckName, cardDetails); document.getElementById('response-output').innerHTML = '

卡片信息已保存到浏览器存储。

'; }); // 初始化时更新卡组列表 updateDeckList(); })();