KamePT Badge Trial Tool

Try badges before purchase on KamePT

// ==UserScript==
// @name         KamePT Badge Trial Tool
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Try badges before purchase on KamePT
// @author       Your name
// @match        https://kamept.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
  "use strict";

  // 从本地存储加载试用的徽章配置
  const TRIAL_BADGES_KEY = "kame_trial_badges";
  let trialBadges = JSON.parse(localStorage.getItem(TRIAL_BADGES_KEY) || "[]");

  // 创建单个徽章元素
  function createBadgeElement(badgeConfig) {
    const badge = document.createElement("img");
    badge.src = badgeConfig.src;
    badge.title = badgeConfig.title;
    badge.className = "nexus-username-medal preview";
    badge.style.maxHeight = "11px";
    badge.style.maxWidth = "11px";
    badge.style.marginLeft = "2pt";
    return badge;
  }

  // 添加试用按钮到勋章商店页面
  function addTrialButtons() {
    if (!window.location.href.includes("medal.php")) return;

    // 获取表格
    const table = document.querySelector('table[border="1"]');
    if (!table) return;

    // 获取表头行
    const headerRow = table.querySelector("thead tr");
    if (!headerRow) return;

    // 检查是否已经添加了试用列
    if (!headerRow.querySelector(".trial-header")) {
      // 添加"试用"列标题
      const trialHeader = document.createElement("td");
      trialHeader.className = "colhead trial-header";
      trialHeader.textContent = "试用";
      headerRow.appendChild(trialHeader);
    }

    // 为每个勋章行添加试用按钮
    const medalRows = table.querySelectorAll("tbody tr");
    medalRows.forEach((row) => {
      // 检查是否已经添加了试用按钮
      if (row.querySelector(".trial-button")) return;

      const imgElement = row.querySelector("td:first-child img");
      if (!imgElement) return;

      // 检查是否已购买
      const buyButton = row.querySelector(
        'input[type="button"][value="已经购买"]'
      );
      const isAlreadyBought = buyButton !== null;

      const badgeConfig = {
        src: imgElement.src,
        title: row.querySelector("h1")?.textContent || "勋章",
      };

      const trialCell = document.createElement("td");
      const trialButton = document.createElement("input");
      trialButton.type = "button";

      if (isAlreadyBought) {
        trialButton.value = "已拥有";
        trialButton.disabled = true;
        trialButton.style.opacity = "0.5";
      } else {
        trialButton.value = trialBadges.some((b) => b.src === badgeConfig.src)
          ? "取消试用"
          : "试用";
        trialButton.onclick = () => toggleTrialBadge(badgeConfig);
      }

      trialButton.className = "trial-button";
      trialButton.style.cursor = isAlreadyBought ? "not-allowed" : "pointer";
      trialButton.style.padding = "2px 8px";

      trialCell.appendChild(trialButton);
      row.appendChild(trialCell);
    });
  }

  // 切换徽章的试用状态
  function toggleTrialBadge(badgeConfig) {
    const index = trialBadges.findIndex((b) => b.src === badgeConfig.src);
    if (index === -1) {
      trialBadges.push(badgeConfig);
    } else {
      trialBadges.splice(index, 1);
    }

    // 保存到本地存储
    localStorage.setItem(TRIAL_BADGES_KEY, JSON.stringify(trialBadges));

    // 刷新页面以更新显示
    location.reload();
  }

  // 获取当前用户名
  function getCurrentUsername() {
    // 从页面顶部的info tab获取用户名
    const userLink = document.querySelector('#info_block a[class$="_Name"] b');
    return userLink ? userLink.textContent : "";
  }

  // 处理用户详情页面的勋章展示区域
  function processUserDetailsMedals() {
    const medalContainer = document.querySelector(
      'form > div[style*="display: flex"]'
    );
    if (!medalContainer) return;

    // 检查是否为其他用户的页面
    const pageUsername = document.querySelector(
      "h1 > span.nowrap > b"
    )?.textContent;
    const currentUsername = getCurrentUsername();

    if (!pageUsername || !currentUsername || pageUsername !== currentUsername) {
      console.log("当前为其他用户页面,跳过添加试用徽章");
      return;
    }

    // 添加保存按钮禁用逻辑
    const saveButton = document.getElementById("save-user-medal-btn");
    if (saveButton) {
      saveButton.disabled = trialBadges.length > 0;
      saveButton.title = trialBadges.length > 0 ? "试用期间禁止保存设置" : "";
      saveButton.style.opacity = trialBadges.length > 0 ? "0.5" : "1";
      saveButton.style.cursor =
        trialBadges.length > 0 ? "not-allowed" : "pointer";
    }

    // 为每个试用徽章创建展示卡片
    trialBadges.forEach((badgeConfig) => {
      // 检查是否已经存在该徽章
      const existingCard = Array.from(
        medalContainer.querySelectorAll("img.preview")
      ).find((img) => img.src === badgeConfig.src);

      if (!existingCard) {
        // 创建新的勋章卡片容器
        const cardDiv = document.createElement("div");
        cardDiv.style.display = "flex";
        cardDiv.style.flexDirection = "column";
        cardDiv.style.justifyContent = "space-between";
        cardDiv.style.marginRight = "10px";

        // 创建勋章图片容器
        const imgContainer = document.createElement("div");
        const img = document.createElement("img");
        img.src = badgeConfig.src;
        img.title = badgeConfig.title;
        img.className = "preview";
        img.style.maxHeight = "120px";
        img.style.maxWidth = "120px";
        imgContainer.appendChild(img);

        // 创建勋章信息容器
        const infoContainer = document.createElement("div");
        infoContainer.style.display = "flex";
        infoContainer.style.flexDirection = "column";
        infoContainer.style.alignItems = "flex-start";

        const myBadgeBtn = document.querySelector('input[type="button"][value="我的勋章"]');
        if (myBadgeBtn) {
          myBadgeBtn.parentElement.parentElement.remove();
        }

        // 组装卡片
        cardDiv.appendChild(imgContainer);
        // cardDiv.appendChild(infoContainer);

        // 插入到第一个保存按钮前
        const saveButtonDiv = medalContainer.querySelector(
          "div:has(#save-user-medal-btn)"
        );
        if (saveButtonDiv) {
          medalContainer.insertBefore(cardDiv, saveButtonDiv);
        } else {
          medalContainer.appendChild(cardDiv);
        }
      }
    });
  }

  // 添加试用中的徽章到用户名旁
  function addTrialBadges() {
    // 获取当前用户名
    const currentUsername = getCurrentUsername();
    if (!currentUsername) return;

    // 处理用户详情页面的标题
    function processUserDetailsTitle() {
      const titleUsername = document.querySelector("h1 > span.nowrap > b");
      if (titleUsername && titleUsername.textContent === currentUsername) {
        const container = titleUsername.closest(".nowrap");
        if (!container) return;

        // 查找现有徽章
        const existingBadges = Array.from(
          container.querySelectorAll("img.nexus-username-medal-big")
        );
        let lastBadge =
          existingBadges[existingBadges.length - 1] || titleUsername;

        // 添加试用徽章
        trialBadges.forEach((badgeConfig) => {
          const existingTrialBadge = existingBadges.find(
            (img) => img.src === badgeConfig.src
          );

          if (!existingTrialBadge) {
            const newBadge = document.createElement("img");
            newBadge.src = badgeConfig.src;
            newBadge.title = badgeConfig.title;
            newBadge.className = "nexus-username-medal-big preview";
            newBadge.style.maxHeight = "16px";
            newBadge.style.maxWidth = "16px";
            newBadge.style.marginLeft = "4pt";
            lastBadge.parentNode.insertBefore(newBadge, lastBadge.nextSibling);
            lastBadge = newBadge;
          }
        });
      }
    }

    // 处理页面上已有的用户名元素
    function processExistingElements() {
      const currentUsername = getCurrentUsername();
      if (!currentUsername) return;

      const userSpans = document.querySelectorAll('span.nowrap');
      userSpans.forEach(span => {
        const userNameElement = span.querySelector('a[class$="_Name"] b');
        if (userNameElement && userNameElement.textContent === currentUsername) {
          // 查找span后面的所有兄弟节点
          let nextNode = span.nextSibling;
          let foundSpecialPattern = false;

          while (nextNode) {
            if (nextNode.nodeType === Node.TEXT_NODE) {
              if (nextNode.textContent === ')' + '\u00A0\u00A0') {
                // 找到 ")  " 模式
                foundSpecialPattern = true;
                
                // 创建新的文本节点
                const closeBracket = document.createTextNode(')');
                const spaceNode = document.createTextNode('\u00A0\u00A0');
                
                // 替换原节点为 ")"
                nextNode.parentNode.replaceChild(closeBracket, nextNode);
                
                // 添加试用徽章和空格
                let lastInsertedNode = closeBracket;
                trialBadges.forEach(badgeConfig => {
                  const existingBadge = Array.from(span.querySelectorAll('img.nexus-username-medal'))
                    .find(img => img.src === badgeConfig.src);
                  
                  if (!existingBadge) {
                    const newBadge = createBadgeElement(badgeConfig);
                    lastInsertedNode.parentNode.insertBefore(newBadge, lastInsertedNode.nextSibling);
                    lastInsertedNode = newBadge;
                  }
                });
                
                // 在最后一个徽章后添加空格
                lastInsertedNode.parentNode.insertBefore(spaceNode, lastInsertedNode.nextSibling);
                break;
              } else if (nextNode.textContent === ')') {
                // 找到单独的 ")" 节点,继续查找 "  "
                let spaceNode = nextNode.nextSibling;
                while (spaceNode) {
                  if (spaceNode.nodeType === Node.TEXT_NODE && spaceNode.textContent === '\u00A0\u00A0') {
                    foundSpecialPattern = true;
                    // 在 "  " 前添加所有试用徽章
                    trialBadges.forEach(badgeConfig => {
                      const existingBadge = Array.from(span.querySelectorAll('img.nexus-username-medal'))
                        .find(img => img.src === badgeConfig.src);
                      
                      if (!existingBadge) {
                        const newBadge = createBadgeElement(badgeConfig);
                        spaceNode.parentNode.insertBefore(newBadge, spaceNode);
                      }
                    });
                    break;
                  }
                  spaceNode = spaceNode.nextSibling;
                }
                if (foundSpecialPattern) break;
              }
            }
            nextNode = nextNode.nextSibling;
          }

          // 如果没有找到特殊模式,使用原有逻辑
          if (!foundSpecialPattern) {
            const targetNode = Array.from(span.childNodes)
              .find(node => node.nodeType === Node.TEXT_NODE && node.textContent === '\u00A0\u00A0');

            trialBadges.forEach(badgeConfig => {
              const existingBadge = Array.from(span.querySelectorAll('img.nexus-username-medal'))
                .find(img => img.src === badgeConfig.src);
              
              if (!existingBadge) {
                const newBadge = createBadgeElement(badgeConfig);
                if (targetNode) {
                  targetNode.parentNode.insertBefore(newBadge, targetNode);
                } else {
                  span.appendChild(newBadge);
                }
              }
            });
          }
        }
      });
    }

    // 初始处理
    processUserDetailsTitle();
    processExistingElements();

    // 处理用户详情页面的勋章展示区域
    processUserDetailsMedals();

    // 监听动态加载的内容
    const observeTargets = [
      document.getElementById("peerlist"), // 做种用户列表
      document.querySelector(".text"), // 论坛内容区域
    ];

    observeTargets.forEach((target) => {
      if (target) {
        const observer = new MutationObserver((mutations) => {
          mutations.forEach((mutation) => {
            if (mutation.addedNodes.length > 0) {
              processExistingElements();
            }
          });
        });

        observer.observe(target, {
          childList: true,
          subtree: true,
        });
      }
    });
  }

  // 添加清理预览图片的功能
  function fixPreviewCleanup() {
    // 查找预览图片元素
    const previewImg = document.getElementById("nexus-preview");
    if (!previewImg) return;

    // 监听所有徽章的鼠标移出事件
    document.addEventListener(
      "mouseover",
      (e) => {
        if (!e.target.matches("img.nexus-username-medal")) {
          // 如果鼠标不在任何徽章上,隐藏预览
          previewImg.style.display = "none";
        }
      },
      true
    );

    // 监听页面滚动,确保预览不会停留
    window.addEventListener(
      "scroll",
      () => {
        previewImg.style.display = "none";
      },
      { passive: true }
    );

    // 监听鼠标离开页面
    document.addEventListener("mouseout", (e) => {
      if (!e.relatedTarget) {
        previewImg.style.display = "none";
      }
    });
  }

  // 初始化
  function init() {
    addTrialButtons();
    addTrialBadges();
    fixPreviewCleanup();
  }

  // 页面加载完成后运行
  window.addEventListener("load", init);
})();