LinuxDo@真假始皇

看着坛子里的始皇头像无处不在,还有始皇两个字的名字左一个、右一个的出现,让你有点分不清楚谁是真正的始皇了么?那么就用上这个脚本吧。

目前为 2024-04-19 提交的版本。查看 最新版本

// ==UserScript==
// @name       LinuxDo@真假始皇
// @namespace  bmqy.net
// @version    1.0.0
// @author     bmqy
// @icon       https://cdn.linux.do/uploads/default/original/1X/3a18b4b0da3e8cf96f7eea15241c3d251f28a39b.png
// @match      https://linux.do/*
// @connect    cfw.887776.xyz
// @grant      GM_getValue
// @grant      GM_setValue
// @grant      GM_xmlhttpRequest
// @description 看着坛子里的始皇头像无处不在,还有始皇两个字的名字左一个、右一个的出现,让你有点分不清楚谁是真正的始皇了么?那么就用上这个脚本吧。
// ==/UserScript==

(function () {
  'use strict';

  const api = "https://cfw.887776.xyz/linuxdo-tf-shihuang";
  let blacklist = [];
  let update = 0;
  let storeKey = "TFShiHuangBlacklist";
  function init() {
    getBlacklist();
    onMutationObserver();
  }
  function getBlacklist() {
    let storeVal = GM_getValue(storeKey) || {
      blacklist: [],
      update: 0
    };
    blacklist = storeVal.blacklist;
    update = storeVal.update;
    update = parseInt(update);
  }
  function syncBlacklist() {
    let $syncBtn = document.querySelector(".sync-blacklist-btn");
    $syncBtn.innerText = "上次同步:同步中...";
    GM_xmlhttpRequest({
      method: "get",
      url: api,
      headers: {
        "Content-Type": "application/json; charset=utf-8"
      },
      responseType: "json",
      onload: function(xhr) {
        if (xhr.status == 200) {
          blacklist = xhr.response.blacklist;
          update = xhr.response.update;
          update = parseInt(update);
        } else {
          blacklist = [];
        }
        GM_setValue(storeKey, {
          blacklist,
          update
        });
        $syncBtn.innerText = "上次同步:" + new Date(update).toLocaleString();
      },
      onerror: function(xhr) {
        console.log("获取黑名单错误:" + xhr.responseText);
      }
    });
  }
  function getRandomString() {
    const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    let random = "";
    for (var i = 0; i < 18; i++) {
      random += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return random;
  }
  function insertAddBlacklistBtn(element, cardName) {
    let $addBtn = document.createElement("button");
    $addBtn.type = "button";
    $addBtn.title = "LinuxDo@真假始皇 - 标记按钮,如无效,请刷新页面";
    $addBtn.setAttribute("class", "add-blacklist-btn widget-button btn-flat post-action-menu__copy-link no-text btn-icon");
    $addBtn.setAttribute("cardName", cardName);
    if (!blacklist.includes(cardName)) {
      $addBtn.innerText = "+ 标记他 +";
      $addBtn.addEventListener("click", function() {
        updateBlacklist(element, cardName, "add");
      });
    } else {
      $addBtn.innerText = "- 标错了 -";
      $addBtn.addEventListener("click", function() {
        updateBlacklist(element, cardName, "remove");
      });
    }
    let parent = element.querySelector(".actions");
    parent.insertBefore($addBtn, parent.firstChild);
  }
  function insertSyncBlacklistBtn() {
    let $syncBtnBox = document.createElement("div");
    $syncBtnBox.setAttribute("style", "position:relative;top: 80px;margin-top: 1em;display: flex;gap: .5em;flex-wrap:wrap;transition: opacity .2s ease-in;");
    let $syncBtn = document.createElement("button");
    $syncBtn.type = "button";
    $syncBtn.title = "LinuxDo@真假始皇 - 同步按钮,如无效,请刷新页面";
    $syncBtn.setAttribute("class", "sync-blacklist-btn show-summary btn btn-small");
    $syncBtn.setAttribute("style", "white-space: nowrap;");
    $syncBtn.innerText = "上次同步:" + (!update ? "从未" : new Date(update).toLocaleString());
    $syncBtn.addEventListener("click", function() {
      syncBlacklist();
    });
    $syncBtnBox.appendChild($syncBtn);
    let parent = document.querySelector(".topic-timeline");
    if (parent && !parent.querySelector(".sync-blacklist-btn")) {
      parent.appendChild($syncBtnBox);
    }
  }
  function updateBlacklist(element, cardName, action) {
    if (cardName === "neo" || !cardName) {
      return false;
    }
    let $addBtn = element.querySelector(".add-blacklist-btn");
    $addBtn.innerText = action === "add" ? "· 标记中... ·" : "· 移除中... ·";
    GM_xmlhttpRequest({
      method: "post",
      url: api,
      headers: {
        "Content-Type": "application/json; charset=utf-8"
      },
      data: JSON.stringify({ cardName, action }),
      responseType: "json",
      onload: function(xhr) {
        if (xhr.status == 200) {
          blacklist.push(cardName);
          changeFakeAvatar(element, action);
          $addBtn.innerText = action === "add" ? "- 标错了 -" : "+ 标记他 +";
          $addBtn.removeEventListener("click", updateBlacklist);
          $addBtn.addEventListener("click", function() {
            updateBlacklist(element, cardName, action);
          });
          syncBlacklist();
        } else {
          console.log("标记失败:" + xhr.responseText);
        }
      },
      onerror: function(xhr) {
        console.log("标记失败:" + xhr.responseText);
      }
    });
  }
  function changeFakeAvatar(element, action) {
    let $fullName = element.querySelector(".names .first a");
    let $avatar = element.querySelector(".post-avatar .avatar");
    if (action === "add") {
      $fullName.setAttribute("style", "border:1px dotted red;padding:0px 5px;border-radius:5px;");
      let randomAvatar = `https://api.multiavatar.com/${getRandomString()}.png`;
      if ($avatar.getAttribute("src").indexOf("api.multiavatar.com") == -1) {
        $avatar.setAttribute("src", randomAvatar);
      }
    } else {
      $fullName.setAttribute("style", "");
    }
  }
  function onMutationObserver() {
    let mos = new MutationObserver(function(mutations, observer) {
      for (const mutation in mutations) {
        if (Object.hasOwnProperty.call(mutations, mutation)) {
          const element = mutations[mutation];
          if (element.target.nodeName == "DIV") {
            if (element.target.classList.contains("topic-post")) {
              insertSyncBlacklistBtn();
              let $fullName = element.target.querySelector(".names .first a");
              let cardName = $fullName.getAttribute("data-user-card");
              cardName = cardName.toLowerCase();
              if (cardName != "neo") {
                if (!element.target.querySelector(".add-blacklist-btn")) {
                  insertAddBlacklistBtn(element.target, cardName);
                }
                if (blacklist.includes(cardName)) {
                  changeFakeAvatar(element.target, "add");
                }
              }
            }
          }
        }
      }
    });
    if (document.querySelector("#main")) {
      mos.observe(document.querySelector("#main"), {
        attributes: true,
        childList: true,
        subtree: true
      });
    }
  }
  init();

})();