Greasy Fork

来自缓存

Greasy Fork is available in English.

Serial Code Tracker

Save and mark serial codes as used when accessed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name           Serial Code Tracker
// @description    Save and mark serial codes as used when accessed.
// @description:ja アクセスされたシリアルコードを保存し、使用済みとしてマークします。
// @author         Ginoa AI
// @namespace      http://greasyfork.icu/ja/users/119008-ginoaai
// @version        1.1
// @match          https://www.hoyolab.com/article/*
// @grant          GM_setValue
// @grant          GM_getValue
// @grant          GM_listValues
// @icon           https://pbs.twimg.com/profile_images/1648150443522940932/4TTHKbGo_400x400.png
// ==/UserScript==

function getSavedCodes() {
  return new Set(GM_listValues());
}

function updateLinkText(node) {
  const savedCodes = getSavedCodes();
  const links = node.querySelectorAll('a');
  links.forEach((link) => {
    if (link.href.includes('code=')) {
      const url = new URL(link.href);
      const code = url.searchParams.get('code');

      if (savedCodes.has(code)) {
        link.textContent = 'アクセス済み';
      }
    }
  });
}

function waitForElement(selector, callback) {
  const element = document.querySelector(selector);
  if (element) {
    callback(element);
  } else {
    const observer = new MutationObserver(() => {
      const element = document.querySelector(selector);
      if (element) {
        observer.disconnect();
        callback(element);
      }
    });
    observer.observe(document.body, { childList: true, subtree: true });
  }
}

document.addEventListener('mousedown', function (event) {
  if (event.button === 0 || event.button === 1) {
    const target = event.target.closest('a');
    if (target && target.href.includes('code=')) {
      const url = new URL(target.href);
      const code = url.searchParams.get('code');
      if (code) {
        GM_setValue(code, true);
        console.log(`Saved code: ${code}`);

        waitForElement('div[class="mhy-article-page__content"]', (ost) => {
          updateLinkText(ost);
        });
      }
    }
  }
});

waitForElement('div[class="mhy-article-page__content"]', (ost) => {
  updateLinkText(ost);
  const observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      for (const addedNode of mutation.addedNodes) {
        if (addedNode.nodeType === Node.ELEMENT_NODE) {
          updateLinkText(addedNode);
        }
      }
    }
  });

  observer.observe(ost, { childList: true, subtree: true });
  console.log('Saved Codes:', getSavedCodes());
});