LinuxDo@真假始皇

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

当前为 2024-04-19 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==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();

})();