LinuxDo@真假始皇

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

// ==UserScript==
// @name       LinuxDo@真假始皇
// @namespace  bmqy.net
// @version    1.1.0
// @author     bmqy
// @icon       https://cdn.linux.do/uploads/default/original/1X/3a18b4b0da3e8cf96f7eea15241c3d251f28a39b.png
// @match      https://linux.do/*
// @connect    cfw.887776.xyz
// @grant      GM_addStyle
// @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 current = "";
  let storeKey = "TFShiHuangBlacklist";
  let panelTimer = null;
  let disableBlacklist = false;
  let noShihuang = false;
  let copyShihuang = false;
  function init() {
    getCurrent();
    getBlacklist();
    onMutationObserver();
    notShihuang();
    copyingShihuang();
    disBlacklist();
  }
  function getCurrent() {
    let $current = document.querySelector("#current-user>button");
    if ($current && $current.getAttribute("href")) {
      current = $current.getAttribute("href").replace("/u/", "");
      setStoreValue("current", current);
    }
  }
  function setStoreValue(key, value) {
    let storeVal = GM_getValue(storeKey) || {
      blacklist: [],
      update: 0,
      current: "",
      disableBlacklist: false,
      noShihuang: false,
      copyShihuang: false
    };
    storeVal[key] = value;
    GM_setValue(storeKey, storeVal);
  }
  function getBlacklist() {
    let storeVal = GM_getValue(storeKey) || {
      blacklist: [],
      update: 0,
      current: "",
      disableBlacklist: false,
      noShihuang: false,
      copyShihuang: false
    };
    blacklist = storeVal.blacklist;
    disableBlacklist = storeVal.disableBlacklist;
    noShihuang = storeVal.noShihuang;
    copyShihuang = storeVal.copyShihuang;
    update = storeVal.update;
    update = parseInt(update);
  }
  function syncBlacklist() {
    if (disableBlacklist)
      return false;
    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 = [];
        }
        setStoreValue("blacklist", blacklist);
        setStoreValue("update", 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) {
    if (disableBlacklist)
      return false;
    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 $settingPanel = document.createElement("div");
    $settingPanel.id = "setting-blacklist-panel";
    $settingPanel.style.display = "none";
    $settingPanel.innerHTML = `
  <div style="height:auto;padding:15px;background-color:#e9e9e9;color:#666;position:absolute;left:7px;right: 0px;bottom: 45px;z-index:1;border-radius: 5px;">
    <label title="为始皇增加特殊效果,开启后将禁用黑名单的标记和同步功能"><input type="checkbox" value="1" id="disableBlacklist" ${disableBlacklist ? "checked" : ""} /> 保护始皇(禁用天子庶民)</label>
    <label title="拒绝特殊化,清除始皇头像的特殊样式"><input type="checkbox" value="1" id="noShihuang" ${noShihuang ? "checked" : ""} /> 天子庶民(禁用保护始皇)</label>
    <label title="打不过就加入,借用始皇头像的特殊样式"><input type="checkbox" value="1" id="copyShihuang" ${copyShihuang ? "checked" : ""} /> 王侯将相</label>
  </div>
  `;
    $settingPanel.addEventListener("mouseover", function() {
      if (panelTimer) {
        clearTimeout(panelTimer);
        panelTimer = null;
      }
    });
    $settingPanel.addEventListener("mouseleave", function() {
      panelTimer = setTimeout(() => {
        $settingPanel.style.display = "none";
      }, 500);
    });
    $syncBtnBox.appendChild($settingPanel);
    let $settingBtn = document.createElement("button");
    $settingBtn.type = "button";
    $settingBtn.setAttribute("class", "setting-blacklist-btn btn btn-default create reply-to-post no-text btn-icon");
    $settingBtn.innerHTML = '<svg class="fa d-icon d-icon-ellipsis-v svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#ellipsis-v"></use></svg>';
    $settingBtn.addEventListener("mouseover", function() {
      if (panelTimer) {
        clearTimeout(panelTimer);
        panelTimer = null;
      }
      $settingPanel.style.display = "";
    });
    $settingBtn.addEventListener("mouseleave", function() {
      panelTimer = setTimeout(() => {
        $settingPanel.style.display = "none";
      }, 500);
    });
    $syncBtnBox.appendChild($settingBtn);
    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);
      bindSettingsBtn();
    }
  }
  function updateBlacklist(element, cardName, action) {
    if (disableBlacklist)
      return false;
    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 bindSettingsBtn() {
    document.querySelector("#disableBlacklist").addEventListener("click", function(e) {
      disableBlacklist = e.target.checked;
      if (disableBlacklist && noShihuang) {
        noShihuang = false;
      }
      setStoreValue("noShihuang", false);
      setStoreValue("disableBlacklist", disableBlacklist);
      location.reload();
    });
    document.querySelector("#noShihuang").addEventListener("click", function(e) {
      noShihuang = e.target.checked;
      if (noShihuang && disableBlacklist) {
        disableBlacklist = false;
      }
      setStoreValue("disableBlacklist", false);
      setStoreValue("noShihuang", noShihuang);
      location.reload();
    });
    document.querySelector("#copyShihuang").addEventListener("click", function(e) {
      copyShihuang = e.target.checked;
      setStoreValue("copyShihuang", copyShihuang);
      location.reload();
    });
  }
  function disBlacklist() {
    if (disableBlacklist) {
      GM_addStyle(`
      .topic-post article[data-user-id="1"]:before{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-image: url(https://cdn.linux.do/user_avatar/linux.do/neo/48/12_2.png);
        background-repeat: no-repeat;
        background-size: 100%;
        background-position: center bottom;
        opacity: 0.1;
      }
    `);
    }
  }
  function notShihuang() {
    if (noShihuang) {
      GM_addStyle(`
      .topic-post article[data-user-id="1"] img.avatar{
        border-radius: 50% !important;
      }
      .topic-post article[data-user-id="1"] .avatar-flair-admins{
        display: none !important;
      }
    `);
    }
  }
  function copyingShihuang() {
    if (copyShihuang) {
      GM_addStyle(`
      .topic-post .first a[data-user-card="${current}"]{
        color: #00aeff !important;
      }
      .topic-post a[data-user-card="${current}"] img.avatar{
        border-radius: 10% !important;
      }
    `);
    }
  }
  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();
              if (disableBlacklist)
                return false;
              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");
                }
              } else {
                if (noShihuang) {
                  element.target.querySelector("img.avatar").style.borderRadius = "50% !important";
                }
              }
            }
          }
        }
      }
    });
    if (document.querySelector("#main")) {
      mos.observe(document.querySelector("#main"), {
        attributes: true,
        childList: true,
        subtree: true
      });
    }
  }
  init();

})();