[GC] - SDB Contents Collection

2/25/2024, 11:26:31 PM

当前为 2025-04-28 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        [GC] - SDB Contents Collection
// @namespace   https://greasyfork.org/en/users/1225524-kaitlin
// @match       https://www.grundos.cafe/safetydeposit/*
// @grant       GM.setValue
// @grant       GM.getValue
// @grant       GM.addStyle

// @license     MIT
// @version     1.3
// @author      Cupkait
// @icon        https://i.imgur.com/4Hm2e6z.png
// @description 2/25/2024, 11:26:31 PM
// ==/UserScript==


let collect = false;
let active = false;

const sdbStyle = createSdbStyle();
document.head.appendChild(sdbStyle);

const collectContainer = createCollectContainer();
document.querySelector('main .sdb-info').append(collectContainer);

initialize();

async function initialize() {
  collect = await GM.getValue('collect', false);
  active = await GM.getValue('active', false);
  collect ? showNextButtons() : active ? enableNextPageNavigation() : showEnableButton();
}

function createSdbStyle() {
  const style = document.createElement('style');
  style.innerHTML = `
    .collect-sdb {
      text-align: center;
      margin: 10px;
    }
    .collect-sdb a {
      background-color: var(--grid_head);
      border: 1px solid grey;
      padding: 5px 15px;
      margin: 10px;
    }
  `;
  return style;
}

function createCollectContainer() {
  const container = document.createElement('div');
  container.classList.add('collect-sdb');
  return container;
}

function showEnableButton() {
  collectContainer.append(createButton('Begin SDB Data Collection', () => {
    GM.setValue('collect', true).then(showNextButtons);
  }));
}

function showNextButtons() {
  removeAllButtons();
  collectContainer.append(
    createButton('Collect full SDB', () => setActiveAndNavigate('https://www.grundos.cafe/safetydeposit/?view=100')),
    createButton('Collect quest only', () => setActiveAndNavigate('https://www.grundos.cafe/safetydeposit/?page=1&&max_rarity=89&view=100'))
  );
}

function createButton(text, onClick) {
  const button = document.createElement('a');
  button.textContent = text;
  button.addEventListener('click', onClick);
  return button;
}

function removeAllButtons() {
  while (collectContainer.firstChild) collectContainer.firstChild.remove();
}

async function setActiveAndNavigate(url) {
  await Promise.all([GM.setValue('collect', false), GM.setValue('active', true)]);
  window.location.href = url;
}

function enableNextPageNavigation() {
  removeEnableButton();
  collectContainer.append(createButton('Cancel/Restart Collection', cancelCollection));
  initTableProcessing();
}

function removeEnableButton() {
  const enableButton = collectContainer.querySelector('button');
  if (enableButton) enableButton.remove();
}

function appendMessages(messageText) {
  const message = document.createElement('p');
  message.innerHTML = messageText;
  collectContainer.append(message);
}

async function initTableProcessing() {
  await processTableData();
  displayPageInfo();
  setupKeyboardNavigation();
}

async function loadSdbContents() {
  return GM.getValue('sdbContents', []);
}

async function saveSdbContents(contents) {
  await GM.setValue('sdbContents', contents);
}

async function processTableData() {
  const sdbContents = await loadSdbContents();
  const data = document.querySelectorAll('.data');
  const rows = [];

  for (let i = 0; i < data.length; i += 7) {
    const row = createRow(data, i);
    const existingItemIndex = sdbContents.findIndex(item => item.n === row.n);
    if (existingItemIndex > -1) sdbContents[existingItemIndex] = row;
    else sdbContents.push(row);
    rows.push(row);
  }

  await saveSdbContents(sdbContents);
}

function createRow(data, index) {
  return {
    n: data[index + 1].querySelector('strong').textContent,
    r: parseInt(data[index + 1].querySelector('span').textContent.match(/\d+/)[0]),
    p: data[index + 2].querySelector('img').src.split('/').pop(),
    q: parseInt(data[index + 3].textContent),
    t: data[index + 4].querySelector('strong').textContent,
  };
}

function setupKeyboardNavigation() {
  document.addEventListener('keydown', (event) => {
    if (event.key === 'ArrowRight' && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {
      const nextPageLink = [...document.querySelectorAll('.center a')].find(link => link.textContent.trim().startsWith('Next'));
      if (nextPageLink) nextPageLink.click();
    }
  });
}

async function displayPageInfo() {
  const pageCount = document.querySelectorAll('#page option').length;
  const currentPage = parseInt(new URLSearchParams(window.location.search).get('page')) || 1;
  const sdbContents = await loadSdbContents();
  const totalItems = sdbContents.length;
  const endTotal = parseFloat(document.querySelector('main div:nth-child(6)').childNodes[4].textContent.replace(/[^0-9.]/g, '').replace(/,/g, ''));

  console.log(endTotal)

  appendMessages(`Total items collected: <strong>${totalItems.toLocaleString()}</strong>  <br>You are viewing page <strong>${currentPage.toLocaleString()}</strong> / <strong>${pageCount.toLocaleString()}</strong>.`);
  appendMessages(`Click "Next" or press the right arrow key to go to the next page.`);

  if (totalItems === endTotal) appendExportButtons();
}

function appendExportButtons() {
  collectContainer.append(createButton('Export to CSV', exportToCSV), createButton('Copy to Clipboard', copyToClipboard));
  appendMessages(`Export to CSV to make a spreadsheet of the results. Copy to Clipboard to paste into a Virtupets.net Checklist.`)
}

function exportToCSV() {
  loadSdbContents().then(sdbContents => {
    const csvContent = "data:text/csv;charset=utf-8," + sdbContents.map(e => Object.values(e).join(",")).join("\n");
    const link = document.createElement("a");
    link.setAttribute("href", encodeURI(csvContent));
    link.setAttribute("download", "sdbContents.csv");
    document.body.appendChild(link);
    link.click();
    link.remove();
    displayCompletionMessage();
  });
}

async function copyToClipboard() {
  try {
    const sdbContents = await loadSdbContents();
    await navigator.clipboard.writeText(JSON.stringify(sdbContents));
    displayCompletionMessage();
  } catch (err) {
    console.error('Error copying to clipboard:', err);
  }
}


function displayCompletionMessage() {
  const collectContainer = document.querySelector('.collect-sdb'); // or whatever selector you need

  if (!collectContainer) {
    console.error('Collect container not found!');
    return;
  }

  let message = collectContainer.querySelector('.completion-message');

  if (!message) {
    message = document.createElement('p');
    message.classList.add('completion-message');
    collectContainer.append(message);
  }
  message.innerHTML = 'Copy complete! Press "Restart Collection" to return to your usual SDB view.';
}


async function cancelCollection() {
  await Promise.all([GM.setValue('active', false), GM.setValue('sdbContents', [])]);
  window.location.href = 'https://www.grundos.cafe/safetydeposit/?view=100';
}