Greasy Fork is available in English.

S1战斗力屏蔽

屏蔽S1的战斗力系统,眼不见为净

// ==UserScript==
// @name         S1战斗力屏蔽
// @namespace    laster2800
// @version      2.4.1
// @description  屏蔽S1的战斗力系统,眼不见为净
// @author       Laster2800
// @icon         https://www.saraba1st.com/favicon.ico
// @require      https://greasyfork.org/scripts/409641-api/code/API.js?version=840383
// @match        *.saraba1st.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @run-at       document-start
// ==/UserScript==

/* global API */
var api = new API({ id: 'S1EShield' })

;(function() {
  var disableS1EShield = GM_getValue('disableS1EShield')
  if (disableS1EShield) {
    var disableS1EShieldTime = GM_getValue('disableS1EShieldTime')
    var now = new Date().getTime()
    // 若离上次禁用屏蔽已超过指定时间,则重新开启
    if (now - disableS1EShieldTime > 1 * 60 * 1000) { // 1分钟
      disableS1EShield = false
      GM_setValue('disableS1EShield', false)
    }
  }
  // 在导航栏中加入临时关闭脚本的按钮
  api.wait.executeAfterElementLoaded({
    selector: '#nv',
    callback: nv => {
      var btn = document.createElement('a')
      btn.href = 'javascript:void(0)'
      btn.innerText = disableS1EShield ? '屏蔽战斗力系统' : '开启战斗力系统'
      btn.title = disableS1EShield ? '屏蔽战斗力系统' : '临时开启战斗力系统'
      btn.style = 'float: right; padding: 0 15px; height: 33px; line-height: 33px; font-weight: bold; font-size: 1.2em;'
      btn.onclick = function() {
        var disable = !disableS1EShield
        GM_setValue('disableS1EShield', disable)
        if (disable) {
          GM_setValue('disableS1EShieldTime', new Date().getTime())
        }
        location.reload()
      }
      nv.appendChild(btn)
    },
  })

  // 系统提醒
  api.wait.executeAfterElementLoaded({
    selector: '#myprompt_menu',
    callback: menu => {
      // 有系统提醒时,每次打开页面时都会弹出一个通知菜单
      // 点击网页提供的关闭按键后,此菜单在有新提醒前不会再次弹出
      api.wait.executeAfterElementLoaded({
        selector: '.ignore_notice',
        callback: ignore_notice => {
          api.wait.executeAfterConditionPassed({
            condition: () => menu.getAttribute('initialized') === 'true',
            callback: () => ignore_notice.click(),
            interval: 5,
          })
        },
        interval: 5,
        timeout: 500,
      })
      // 有系统提醒处于未读状态时,相关位置会有高亮显示,网页标题也会有所不同
      // 将这些差异化显示,在用户没有反应出来之前去除
      api.wait.executeAfterElementLoaded({
        selector: '#myprompt',
        callback: menu_button => {
          var menu_mypost = menu.querySelector('.notice_mypost') // 右上角菜单“我的帖子”
          var menu_system = menu.querySelector('.notice_system') // 右上角菜单“系统提醒”
          if (menu_mypost || menu_system) {
            menu_button.innerText = '提醒'
          }
          if (menu_mypost && menu_system) {
            menu_button.className = 'a showmenu'
            // 极小概率的情况下,此时页面标题已经改变(貌似只会发生在后台打开的时),覆盖以确保处理
            replaceTitle()
            // 常规情况下的处理
            Object.defineProperty(document, 'title', {
              set: function() {
                setTimeout(replaceTitle)
              }
            })
          }
          menu_mypost && menu_mypost.parentNode.parentNode.remove()
          menu_system && menu_system.parentNode.parentNode.remove()
        },
        interval: 5,
      })
    },
    interval: 5,
  })

  // 临时关闭脚本,来查看SB被扣鹅的情况
  if (disableS1EShield) {
    return
  }

  // 右上角“积分”菜单移除
  api.wait.executeAfterElementLoaded({
    selector: '#extcreditmenu',
    callback: extcreditmenu => {
      extcreditmenu.className = ''
      extcreditmenu.style.paddingRight = '1em'
      extcreditmenu.onmouseover = null
    }
  })

  if (/thread-|mod=viewthread/.test(location.href)) {
    var s1 = '.tns.xg2 tr > th + th' // 头像下方的战斗力显示
    var s2 = '.psth.xs1' // 评分记录的标题
    var s3 = '.rate' // 评分记录
    api.wait.executeAfterElementLoaded({
      selector: '#postlist',
      callback: postlist => {
        // 这里分两种情况,一是直接打开帖子,另一种是后台打开。
        // 对于第一种情况不需要特殊处理(后面再解释),但是第二种情况后台新开的任务什么时候执行是不确定的。
        // 因此后台打开时,只有当用户切换到该标签页时才能保证执行(有可能更早),此时其实所有楼层有可能已经加载完毕,也可能加载了不确定的几层。
        //
        // 对于第一种情况,直接打开会直接运行到这里。
        // 此时网页处于半加载状态,对于普通帖子模式就是加载了第一层,对于viewthread就是加载了第一层以及pid指向的楼层,共两层。
        // (但无法通过这点来区分处于哪种情况,因为后台打开的情况下,已加载几层是不确定的)
        // 其他的楼层依然还处于未加载状态,还需通过MutationObserver监听处理。
        // 若是viewthread模式,在此处,第一层已经完全加载完毕,而pid指向的楼层处于半加载状态,无法在这里处理,只能移至MutationObserver内部处理。
        var first = true
        var ob = new MutationObserver(mutations => {
          if (first) {
            // 移除每页的第一层楼,以及viewthread模式下pid指向的楼层
            removeBySelector(s1)
            removeBySelector(s2)
            removeBySelector(s3)
            first = false
          }
          // 移除除此之外的普通楼层
          for (var mutation of mutations) {
            if (mutation.addedNodes) {
              for (var addedNode of mutation.addedNodes) {
                if (/^post_/.test(addedNode.id)) {
                  removeBySelector(s1, addedNode)
                  removeBySelector(s2, addedNode)
                  removeBySelector(s3, addedNode)
                }
              }
            }
          }

        })
        ob.observe(postlist, { childList: true })
        // 如果是后台打开的情况,此时添加的MutationObserver已经无法处理掉已经加载好的楼层,必须先执行一遍移除。
        removeBySelector(s1)
        removeBySelector(s2)
        removeBySelector(s3)
      },
    })
    // 回复后立即移除战斗力显示
    api.wait.executeAfterElementLoaded({
      selector: '#postlistreply',
      callback: reply => {
        var ob = new MutationObserver(() => {
          var e1s = reply.querySelector('#postlistreply ' + s1)
          e1s && e1s.remove()
        })
        ob.observe(reply, { childList: true })
      }
    })
  } else if (/ac=credit/.test(location.href)) {
    // [设置 > 积分] 页面中的相关项屏蔽
    api.wait.executeAfterElementLoaded({
      selector: '#ct .mn',
      callback: () => {
        // [我的积分] 页中战斗力显示
        removeBySelector('#ct .creditl > li:nth-child(2)')
        // [我的积分] 页中的 [积分显示]
        removeBySelector('#ct table.dt.mtm')
        // 移除 [积分记录]
        removeBySelector('#ct li:nth-child(4)')
      },
    })
  } else if (/mod=space(&|$)/.test(location.href)) {
    // 如果当前在 [通知 > 系统提醒],重定向
    if (/view=system/.test(location.href)) {
      location.replace('https://bbs.saraba1st.com/2b/home.php?mod=space&do=pm')
    }
    // 屏蔽个人资料中的战斗力显示
    if (/do=profile/.test(location.href)) {
      removeProfileE()
    }
    // [通知 > 系统提醒] 整项屏蔽
    api.wait.executeAfterElementLoaded({
      selector: '.appl .notice_system',
      callback: notice_system => notice_system.parentNode.remove()
    })
  } else if (/space-uid-/.test(location.href)) {
    // 屏蔽个人主页中的战斗力显示
    removeProfileE()
  }
})()

function removeBySelector(s, parent = document) {
  var cnt = 0
  parent.querySelectorAll(s).forEach(e => {
    e.remove()
    cnt += 1
  })
  return cnt
}

function removeProfileE() {
  api.wait.executeAfterElementLoaded({
    selector: '#psts li:nth-child(3)',
    callback: e => e.remove(),
  })
}

function replaceTitle() {
  var reg = /^【新提醒】|【   】/
  if (reg.test(document.title)) {
    document.title = document.title.replace(reg, '')
  }
}